View Javadoc

1   /**
2    * Copyright 2005-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.uif.component;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
20  import org.kuali.rice.krad.uif.CssConstants;
21  import org.kuali.rice.krad.uif.control.ControlBase;
22  import org.kuali.rice.krad.uif.modifier.ComponentModifier;
23  import org.kuali.rice.krad.uif.service.ExpressionEvaluatorService;
24  import org.kuali.rice.krad.uif.util.ExpressionUtils;
25  import org.kuali.rice.krad.uif.util.ScriptUtils;
26  import org.kuali.rice.krad.uif.view.View;
27  import org.kuali.rice.krad.uif.widget.Tooltip;
28  import org.kuali.rice.krad.util.ObjectUtils;
29  
30  import java.util.ArrayList;
31  import java.util.HashMap;
32  import java.util.List;
33  import java.util.Map;
34  
35  /**
36   * Base implementation of <code>Component</code> which other component
37   * implementations should extend
38   *
39   * <p>
40   * Provides base component properties such as id and template. Also provides
41   * default implementation for the <code>ScriptEventSupport</code> and
42   * <code>Ordered</code> interfaces. By default no script events except the
43   * onDocumentReady are supported.
44   * </p>
45   *
46   * @author Kuali Rice Team (rice.collab@kuali.org)
47   */
48  public abstract class ComponentBase extends ConfigurableBase implements Component {
49      private static final long serialVersionUID = -4449335748129894350L;
50  
51      private String id;
52      private String baseId;
53      private String template;
54      private String templateName;
55  
56      private String title;
57  
58      private boolean render;
59  
60      @KeepExpression
61      private String progressiveRender;
62      private boolean progressiveRenderViaAJAX;
63      private boolean progressiveRenderAndRefresh;
64      private List<String> progressiveDisclosureControlNames;
65      private String progressiveDisclosureConditionJs;
66  
67      @KeepExpression
68      private String conditionalRefresh;
69      private String conditionalRefreshConditionJs;
70      private List<String> conditionalRefreshControlNames;
71  
72      private List<String> refreshWhenChangedPropertyNames;
73      private boolean refreshedByAction;
74  
75      private boolean resetDataOnRefresh;
76      private String methodToCallOnRefresh;
77  
78      private boolean hidden;
79      private boolean readOnly;
80      private Boolean required;
81  
82      private String align;
83      private String valign;
84      private String width;
85  
86      private int colSpan;
87      private int rowSpan;
88  
89      private String style;
90      private List<String> cssClasses;
91  
92      private Tooltip toolTip;
93  
94      private int order;
95  
96      private boolean skipInTabOrder;
97  
98      private String finalizeMethodToCall;
99      private List<Object> finalizeMethodAdditionalArguments;
100     private MethodInvokerConfig finalizeMethodInvoker;
101 
102     private boolean selfRendered;
103     private String renderedHtmlOutput;
104 
105     private boolean disableSessionPersistence;
106     private boolean forceSessionPersistence;
107 
108     private ComponentSecurity componentSecurity;
109 
110     private String onLoadScript;
111     private String onUnloadScript;
112     private String onCloseScript;
113     private String onBlurScript;
114     private String onChangeScript;
115     private String onClickScript;
116     private String onDblClickScript;
117     private String onFocusScript;
118     private String onSubmitScript;
119     private String onKeyPressScript;
120     private String onKeyUpScript;
121     private String onKeyDownScript;
122     private String onMouseOverScript;
123     private String onMouseOutScript;
124     private String onMouseUpScript;
125     private String onMouseDownScript;
126     private String onMouseMoveScript;
127     private String onDocumentReadyScript;
128 
129     private List<ComponentModifier> componentModifiers;
130 
131     private Map<String, String> templateOptions;
132     private String templateOptionsJSString;
133 
134     @ReferenceCopy(newCollectionInstance = true)
135     private transient Map<String, Object> context;
136 
137     private List<PropertyReplacer> propertyReplacers;
138     
139     private Map<String,String> dataAttributes;
140     private String dataRoleAttribute;
141     private String dataTypeAttribute;
142     private String dataMetaAttribute;
143 
144     public ComponentBase() {
145         super();
146 
147         order = 0;
148         colSpan = 1;
149         rowSpan = 1;
150 
151         render = true;
152         selfRendered = false;
153         progressiveRenderViaAJAX = false;
154         progressiveRenderAndRefresh = false;
155         refreshedByAction = false;
156         resetDataOnRefresh = false;
157         disableSessionPersistence = false;
158         forceSessionPersistence = false;
159 
160         componentSecurity = ObjectUtils.newInstance(getComponentSecurityClass());
161 
162         refreshWhenChangedPropertyNames = new ArrayList<String>();
163         finalizeMethodAdditionalArguments = new ArrayList<Object>();
164         cssClasses = new ArrayList<String>();
165         componentModifiers = new ArrayList<ComponentModifier>();
166         templateOptions = new HashMap<String, String>();
167         context = new HashMap<String, Object>();
168         propertyReplacers = new ArrayList<PropertyReplacer>();
169         dataAttributes = new HashMap<String, String>();
170     }
171 
172     /**
173      * The following updates are done here:
174      *
175      * <ul>
176      * <li></li>
177      * </ul>
178      *
179      * @see Component#performInitialization(org.kuali.rice.krad.uif.view.View, java.lang.Object)
180      */
181     public void performInitialization(View view, Object model) {
182 
183     }
184 
185     /**
186      * The following updates are done here:
187      *
188      * <ul>
189      * <li>Evaluate the progressive render condition (if set) and combine with the current render status to set the
190      * render status</li>
191      * </ul>
192      *
193      * @see Component#performApplyModel(org.kuali.rice.krad.uif.view.View, java.lang.Object, org.kuali.rice.krad.uif.component.Component)
194      */
195     public void performApplyModel(View view, Object model, Component parent) {
196         if (this.render && StringUtils.isNotEmpty(progressiveRender)) {
197             // progressive anded with render, will not render at least one of the two are false
198             ExpressionEvaluatorService expressionEvaluatorService =
199                     KRADServiceLocatorWeb.getExpressionEvaluatorService();
200             String adjustedProgressiveRender = expressionEvaluatorService.replaceBindingPrefixes(view, this,
201                     progressiveRender);
202             Boolean progRenderEval = (Boolean) expressionEvaluatorService.evaluateExpression(model, context,
203                     adjustedProgressiveRender);
204 
205             this.setRender(progRenderEval);
206         }
207     }
208 
209     /**
210      * The following finalization is done here:
211      *
212      * <ul>
213      * <li>progressiveRender and conditionalRefresh variables are processed if set</li>
214      * <li>If any of the style properties were given, sets the style string on
215      * the style property</li>
216      * <li>Set the skipInTabOrder flag for nested components</li>
217      * </ul>
218      *
219      * @see Component#performFinalize(org.kuali.rice.krad.uif.view.View, java.lang.Object, org.kuali.rice.krad.uif.component.Component)
220      */
221     public void performFinalize(View view, Object model, Component parent) {
222         if (StringUtils.isNotEmpty(progressiveRender)) {
223             progressiveRender = KRADServiceLocatorWeb.getExpressionEvaluatorService().replaceBindingPrefixes(view, this,
224                     progressiveRender);
225             progressiveDisclosureControlNames = new ArrayList<String>();
226             progressiveDisclosureConditionJs = ExpressionUtils.parseExpression(progressiveRender,
227                     progressiveDisclosureControlNames);
228         }
229 
230         if (StringUtils.isNotEmpty(conditionalRefresh)) {
231             conditionalRefresh = KRADServiceLocatorWeb.getExpressionEvaluatorService().replaceBindingPrefixes(view,
232                     this, conditionalRefresh);
233             conditionalRefreshControlNames = new ArrayList<String>();
234             conditionalRefreshConditionJs = ExpressionUtils.parseExpression(conditionalRefresh,
235                     conditionalRefreshControlNames);
236         }
237 
238         List<String> adjustedRefreshPropertyNames = new ArrayList<String>();
239         for (String refreshPropertyName : refreshWhenChangedPropertyNames) {
240             adjustedRefreshPropertyNames.add(
241                     KRADServiceLocatorWeb.getExpressionEvaluatorService().replaceBindingPrefixes(view, this,
242                             refreshPropertyName));
243         }
244         refreshWhenChangedPropertyNames = adjustedRefreshPropertyNames;
245 
246         // add the align, valign, and width settings to style
247         if (StringUtils.isNotBlank(getAlign()) && !StringUtils.contains(getStyle(), CssConstants.TEXT_ALIGN)) {
248             appendToStyle(CssConstants.TEXT_ALIGN + getAlign() + ";");
249         }
250 
251         if (StringUtils.isNotBlank(getValign()) && !StringUtils.contains(getStyle(), CssConstants.VERTICAL_ALIGN)) {
252             appendToStyle(CssConstants.VERTICAL_ALIGN + getValign() + ";");
253         }
254 
255         if (StringUtils.isNotBlank(getWidth()) && !StringUtils.contains(getStyle(), CssConstants.WIDTH)) {
256             appendToStyle(CssConstants.WIDTH + getWidth() + ";");
257         }
258 
259         // Set the skipInTabOrder flag on all nested components
260         // Set the tabIndex on controls to -1 in order to be skipped on tabbing
261         for (Component component : getComponentsForLifecycle()) {
262             if (component != null && component instanceof ComponentBase && skipInTabOrder) {
263                 ((ComponentBase) component).setSkipInTabOrder(skipInTabOrder);
264                 if (component instanceof ControlBase) {
265                     ((ControlBase) component).setTabIndex(-1);
266                 }
267             }
268         }
269 
270         // if this is not rendering and it is not rendering via an ajax call, but still has a progressive render
271         // condition we still want to render the component, but hide it (in ajax cases, template creates a placeholder)
272         boolean hide = false;
273         if (!this.render && !this.progressiveRenderViaAJAX && !this.progressiveRenderAndRefresh && StringUtils
274                 .isNotBlank(progressiveRender)) {
275             hide = true;
276         } else if (this.isHidden()) {
277             hide = true;
278         }
279 
280         if (hide) {
281             if (StringUtils.isNotBlank(this.getStyle())) {
282                 if (this.getStyle().endsWith(";")) {
283                     this.setStyle(this.getStyle() + " display: none;");
284                 } else {
285                     this.setStyle(this.getStyle() + "; display: none;");
286                 }
287             } else {
288                 this.setStyle("display: none;");
289             }
290         }
291     }
292 
293     /**
294      * @see org.kuali.rice.krad.uif.component.Component#getComponentsForLifecycle()
295      */
296     public List<Component> getComponentsForLifecycle() {
297         List<Component> components = new ArrayList<Component>();
298 
299         return components;
300     }
301 
302     /**
303      * @see org.kuali.rice.krad.uif.component.Component#getComponentPrototypes()
304      */
305     public List<Component> getComponentPrototypes() {
306         List<Component> components = new ArrayList<Component>();
307 
308         for (ComponentModifier modifier : componentModifiers) {
309             components.addAll(modifier.getComponentPrototypes());
310         }
311 
312         components.addAll(getPropertyReplacerComponents());
313 
314         return components;
315     }
316 
317     /**
318      * Returns list of components that are being held in property replacers configured for this component
319      *
320      * @return List<Component>
321      */
322     public List<Component> getPropertyReplacerComponents() {
323         List<Component> components = new ArrayList<Component>();
324         for (Object replacer : propertyReplacers) {
325             components.addAll(((PropertyReplacer) replacer).getNestedComponents());
326         }
327 
328         return components;
329     }
330 
331     /**
332      * @see org.kuali.rice.krad.uif.component.Component#getId()
333      */
334     public String getId() {
335         return this.id;
336     }
337 
338     /**
339      * @see org.kuali.rice.krad.uif.component.Component#setId(java.lang.String)
340      */
341     public void setId(String id) {
342         this.id = id;
343     }
344 
345     /**
346      * @see org.kuali.rice.krad.uif.component.Component#getBaseId()
347      */
348     public String getBaseId() {
349         return this.baseId;
350     }
351 
352     /**
353      * @see org.kuali.rice.krad.uif.component.Component#setBaseId(java.lang.String)
354      */
355     public void setBaseId(String baseId) {
356         this.baseId = baseId;
357     }
358 
359     /**
360      * @see org.kuali.rice.krad.uif.component.Component#getTemplate()
361      */
362     public String getTemplate() {
363         return this.template;
364     }
365 
366     /**
367      * @see org.kuali.rice.krad.uif.component.Component#setTemplate(java.lang.String)
368      */
369     public void setTemplate(String template) {
370         this.template = template;
371     }
372 
373     public String getTemplateName() {
374         return templateName;
375     }
376 
377     public void setTemplateName(String templateName) {
378         this.templateName = templateName;
379     }
380 
381     /**
382      * @see org.kuali.rice.krad.uif.component.Component#getTitle()
383      */
384     public String getTitle() {
385         return this.title;
386     }
387 
388     /**
389      * @see org.kuali.rice.krad.uif.component.Component#setTitle(java.lang.String)
390      */
391     public void setTitle(String title) {
392         this.title = title;
393     }
394 
395     /**
396      * @see org.kuali.rice.krad.uif.component.Component#isHidden()
397      */
398     public boolean isHidden() {
399         return this.hidden;
400     }
401 
402     /**
403      * @see org.kuali.rice.krad.uif.component.Component#setHidden(boolean)
404      */
405     public void setHidden(boolean hidden) {
406         this.hidden = hidden;
407     }
408 
409     /**
410      * @see org.kuali.rice.krad.uif.component.Component#isReadOnly()
411      */
412     public boolean isReadOnly() {
413         return this.readOnly;
414     }
415 
416     /**
417      * @see org.kuali.rice.krad.uif.component.Component#setReadOnly(boolean)
418      */
419     public void setReadOnly(boolean readOnly) {
420         this.readOnly = readOnly;
421     }
422 
423     /**
424      * @see org.kuali.rice.krad.uif.component.Component#getRequired()
425      */
426     public Boolean getRequired() {
427         return this.required;
428     }
429 
430     /**
431      * @see org.kuali.rice.krad.uif.component.Component#setRequired(java.lang.Boolean)
432      */
433     public void setRequired(Boolean required) {
434         this.required = required;
435     }
436 
437     /**
438      * @see org.kuali.rice.krad.uif.component.Component#isRender()
439      */
440     public boolean isRender() {
441         return this.render;
442     }
443 
444     /**
445      * @see org.kuali.rice.krad.uif.component.Component#setRender(boolean)
446      */
447     public void setRender(boolean render) {
448         this.render = render;
449     }
450 
451     /**
452      * @see org.kuali.rice.krad.uif.component.Component#getColSpan()
453      */
454     public int getColSpan() {
455         return this.colSpan;
456     }
457 
458     /**
459      * @see org.kuali.rice.krad.uif.component.Component#setColSpan(int)
460      */
461     public void setColSpan(int colSpan) {
462         this.colSpan = colSpan;
463     }
464 
465     /**
466      * @see org.kuali.rice.krad.uif.component.Component#getRowSpan()
467      */
468     public int getRowSpan() {
469         return this.rowSpan;
470     }
471 
472     /**
473      * @see org.kuali.rice.krad.uif.component.Component#setRowSpan(int)
474      */
475     public void setRowSpan(int rowSpan) {
476         this.rowSpan = rowSpan;
477     }
478 
479     /**
480      * Horizontal alignment of the component within its container
481      * <p>
482      * All components belong to a <code>Container</code> and are placed using a
483      * <code>LayoutManager</code>. This property specifies how the component
484      * should be aligned horizontally within the container. During the finalize
485      * phase the CSS text-align style will be created for the align setting.
486      * </p>
487      *
488      * @return String horizontal align
489      * @see org.kuali.rice.krad.uif.CssConstants.TextAligns
490      */
491     public String getAlign() {
492         return this.align;
493     }
494 
495     /**
496      * Sets the components horizontal alignment
497      *
498      * @param align
499      */
500     public void setAlign(String align) {
501         this.align = align;
502     }
503 
504     /**
505      * Vertical alignment of the component within its container
506      *
507      * <p>
508      * All components belong to a <code>Container</code> and are placed using a
509      * <code>LayoutManager</code>. This property specifies how the component
510      * should be aligned vertically within the container. During the finalize
511      * phase the CSS vertical-align style will be created for the valign
512      * setting.
513      * </p>
514      *
515      * @return String vertical align
516      * @see org.kuali.rice.krad.uif.CssConstants.VerticalAligns
517      */
518     public String getValign() {
519         return this.valign;
520     }
521 
522     /**
523      * Setter for the component's vertical align
524      *
525      * @param valign
526      */
527     public void setValign(String valign) {
528         this.valign = valign;
529     }
530 
531     /**
532      * Width the component should take up in the container
533      * <p>
534      * All components belong to a <code>Container</code> and are placed using a
535      * <code>LayoutManager</code>. This property specifies a width the component
536      * should take up in the Container. This is not applicable for all layout
537      * managers. During the finalize phase the CSS width style will be created
538      * for the width setting.
539      * </p>
540      * <p>
541      * e.g. '30%', '55px'
542      * </p>
543      *
544      * @return String width string
545      */
546     public String getWidth() {
547         return this.width;
548     }
549 
550     /**
551      * Setter for the components width
552      *
553      * @param width
554      */
555     public void setWidth(String width) {
556         this.width = width;
557     }
558 
559     /**
560      * @see org.kuali.rice.krad.uif.component.Component#getStyle()
561      */
562     public String getStyle() {
563         return this.style;
564     }
565 
566     /**
567      * @see org.kuali.rice.krad.uif.component.Component#setStyle(java.lang.String)
568      */
569     public void setStyle(String style) {
570         this.style = style;
571     }
572 
573     /**
574      * @see org.kuali.rice.krad.uif.component.Component#getCssClasses()
575      */
576     public List<String> getCssClasses() {
577         return this.cssClasses;
578     }
579 
580     /**
581      * @see org.kuali.rice.krad.uif.component.Component#setCssClasses(java.util.List)
582      */
583     public void setCssClasses(List<String> cssClasses) {
584         this.cssClasses = cssClasses;
585     }
586 
587     /**
588      * Builds the HTML class attribute string by combining the styleClasses list
589      * with a space delimiter
590      *
591      * @return String class attribute string
592      */
593     public String getStyleClassesAsString() {
594         if (cssClasses != null) {
595             return StringUtils.join(cssClasses, " ");
596         }
597 
598         return "";
599     }
600 
601     /**
602      * @see org.kuali.rice.krad.uif.component.Component#addStyleClass(java.lang.String)
603      */
604     public void addStyleClass(String styleClass) {
605         if (!cssClasses.contains(styleClass)) {
606             cssClasses.add(styleClass);
607         }
608     }
609 
610     /**
611      * @see org.kuali.rice.krad.uif.component.Component#appendToStyle(java.lang.String)
612      */
613     public void appendToStyle(String styleRules) {
614         if (style == null) {
615             style = "";
616         }
617         style = style + styleRules;
618     }
619 
620     /**
621      * @see org.kuali.rice.krad.uif.component.Component#getFinalizeMethodToCall()
622      */
623     public String getFinalizeMethodToCall() {
624         return this.finalizeMethodToCall;
625     }
626 
627     /**
628      * Setter for the finalize method
629      *
630      * @param finalizeMethodToCall
631      */
632     public void setFinalizeMethodToCall(String finalizeMethodToCall) {
633         this.finalizeMethodToCall = finalizeMethodToCall;
634     }
635 
636     /**
637      * @see org.kuali.rice.krad.uif.component.Component#getFinalizeMethodAdditionalArguments()
638      */
639     public List<Object> getFinalizeMethodAdditionalArguments() {
640         return finalizeMethodAdditionalArguments;
641     }
642 
643     /**
644      * Setter for the finalize additional arguments list
645      *
646      * @param finalizeMethodAdditionalArguments
647      */
648     public void setFinalizeMethodAdditionalArguments(List<Object> finalizeMethodAdditionalArguments) {
649         this.finalizeMethodAdditionalArguments = finalizeMethodAdditionalArguments;
650     }
651 
652     /**
653      * @see org.kuali.rice.krad.uif.component.Component#getFinalizeMethodInvoker()
654      */
655     public MethodInvokerConfig getFinalizeMethodInvoker() {
656         return this.finalizeMethodInvoker;
657     }
658 
659     /**
660      * Setter for the method invoker instance
661      *
662      * @param finalizeMethodInvoker
663      */
664     public void setFinalizeMethodInvoker(MethodInvokerConfig finalizeMethodInvoker) {
665         this.finalizeMethodInvoker = finalizeMethodInvoker;
666     }
667 
668     /**
669      * @see org.kuali.rice.krad.uif.component.Component#isSelfRendered()
670      */
671     public boolean isSelfRendered() {
672         return this.selfRendered;
673     }
674 
675     /**
676      * @see org.kuali.rice.krad.uif.component.Component#setSelfRendered(boolean)
677      */
678     public void setSelfRendered(boolean selfRendered) {
679         this.selfRendered = selfRendered;
680     }
681 
682     /**
683      * @see org.kuali.rice.krad.uif.component.Component#getRenderedHtmlOutput()
684      */
685     public String getRenderedHtmlOutput() {
686         return this.renderedHtmlOutput;
687     }
688 
689     /**
690      * @see org.kuali.rice.krad.uif.component.Component#setRenderedHtmlOutput(java.lang.String)
691      */
692     public void setRenderedHtmlOutput(String renderedHtmlOutput) {
693         this.renderedHtmlOutput = renderedHtmlOutput;
694     }
695 
696     /**
697      * @see Component#isDisableSessionPersistence()
698      */
699     public boolean isDisableSessionPersistence() {
700         return disableSessionPersistence;
701     }
702 
703     /**
704      * @see Component#setDisableSessionPersistence(boolean)
705      */
706     public void setDisableSessionPersistence(boolean disableSessionPersistence) {
707         this.disableSessionPersistence = disableSessionPersistence;
708     }
709 
710     /**
711      * @see Component#isForceSessionPersistence()
712      */
713     public boolean isForceSessionPersistence() {
714         return forceSessionPersistence;
715     }
716 
717     /**
718      * @see Component#setForceSessionPersistence(boolean)
719      */
720     public void setForceSessionPersistence(boolean forceSessionPersistence) {
721         this.forceSessionPersistence = forceSessionPersistence;
722     }
723 
724     /**
725      * @see Component#getComponentSecurity()
726      */
727     public ComponentSecurity getComponentSecurity() {
728         return componentSecurity;
729     }
730 
731     /**
732      * @see Component#setComponentSecurity(org.kuali.rice.krad.uif.component.ComponentSecurity)
733      */
734     public void setComponentSecurity(ComponentSecurity componentSecurity) {
735         this.componentSecurity = componentSecurity;
736     }
737 
738     /**
739      * Returns the security class that is associated with the component (used for initialization and validation)
740      *
741      * @return Class<? extends ComponentSecurity>
742      */
743     protected Class<? extends ComponentSecurity> getComponentSecurityClass() {
744         return ComponentSecurity.class;
745     }
746 
747     /**
748      * @see org.kuali.rice.krad.uif.component.Component#getComponentModifiers()
749      */
750     public List<ComponentModifier> getComponentModifiers() {
751         return this.componentModifiers;
752     }
753 
754     /**
755      * @see org.kuali.rice.krad.uif.component.Component#setComponentModifiers(java.util.List)
756      */
757     public void setComponentModifiers(List<ComponentModifier> componentModifiers) {
758         this.componentModifiers = componentModifiers;
759     }
760 
761     /**
762      * @see org.kuali.rice.krad.uif.component.Component#getContext()
763      */
764     public Map<String, Object> getContext() {
765         return this.context;
766     }
767 
768     /**
769      * @see org.kuali.rice.krad.uif.component.Component#setContext(java.util.Map)
770      */
771     public void setContext(Map<String, Object> context) {
772         this.context = context;
773     }
774 
775     /**
776      * @see org.kuali.rice.krad.uif.component.Component#pushObjectToContext(java.lang.String,
777      *      java.lang.Object)
778      */
779     public void pushObjectToContext(String objectName, Object object) {
780         if (this.context == null) {
781             this.context = new HashMap<String, Object>();
782         }
783         pushToPropertyReplacerContext(objectName, object);
784         this.context.put(objectName, object);
785     }
786 
787     /*
788     * Adds the object to the context of the components in the
789     * PropertyReplacer object. Only checks for a list, map or component.
790     */
791     protected void pushToPropertyReplacerContext(String objectName, Object object) {
792         for (Component replacerComponent : getPropertyReplacerComponents()) {
793             replacerComponent.pushObjectToContext(objectName, object);
794         }
795     }
796 
797     /**
798      * @see org.kuali.rice.krad.uif.component.ComponentBase#pushAllToContext
799      */
800     public void pushAllToContext(Map<String, Object> objects) {
801         if (objects != null) {
802             for (Map.Entry<String, Object> objectEntry : objects.entrySet()) {
803                 pushObjectToContext(objectEntry.getKey(), objectEntry.getValue());
804             }
805         }
806     }
807 
808     /**
809      * @see org.kuali.rice.krad.uif.component.Component#getPropertyReplacers()
810      */
811     public List<PropertyReplacer> getPropertyReplacers() {
812         return this.propertyReplacers;
813     }
814 
815     /**
816      * @see org.kuali.rice.krad.uif.component.Component#setPropertyReplacers(java.util.List)
817      */
818     public void setPropertyReplacers(List<PropertyReplacer> propertyReplacers) {
819         this.propertyReplacers = propertyReplacers;
820     }
821 
822     /**
823      * @see org.springframework.core.Ordered#getOrder()
824      */
825     public int getOrder() {
826         return this.order;
827     }
828 
829     /**
830      * Setter for the component's order
831      *
832      * @param order
833      */
834     public void setOrder(int order) {
835         this.order = order;
836     }
837 
838     /**
839      * @see org.kuali.rice.krad.uif.component.Component#getToolTip()
840      */
841     public Tooltip getToolTip() {
842         return toolTip;
843     }
844 
845     /**
846      * @see org.kuali.rice.krad.uif.component.Component#setToolTip(Tooltip)
847      */
848     public void setToolTip(Tooltip toolTip) {
849         this.toolTip = toolTip;
850     }
851 
852     /**
853      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnLoadScript()
854      */
855     public String getOnLoadScript() {
856         return onLoadScript;
857     }
858 
859     /**
860      * Setter for the components onLoad script
861      *
862      * @param onLoadScript
863      */
864     public void setOnLoadScript(String onLoadScript) {
865         this.onLoadScript = onLoadScript;
866     }
867 
868     /**
869      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnDocumentReadyScript()
870      */
871     public String getOnDocumentReadyScript() {
872         return onDocumentReadyScript;
873     }
874 
875     /**
876      * Setter for the components onDocumentReady script
877      *
878      * @param onDocumentReadyScript
879      */
880     public void setOnDocumentReadyScript(String onDocumentReadyScript) {
881         this.onDocumentReadyScript = onDocumentReadyScript;
882     }
883 
884     /**
885      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnUnloadScript()
886      */
887     public String getOnUnloadScript() {
888         return onUnloadScript;
889     }
890 
891     /**
892      * Setter for the components onUnload script
893      *
894      * @param onUnloadScript
895      */
896     public void setOnUnloadScript(String onUnloadScript) {
897         this.onUnloadScript = onUnloadScript;
898     }
899 
900     /**
901      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnCloseScript()
902      */
903     public String getOnCloseScript() {
904         return onCloseScript;
905     }
906 
907     /**
908      * Setter for the components onClose script
909      *
910      * @param onCloseScript
911      */
912     public void setOnCloseScript(String onCloseScript) {
913         this.onCloseScript = onCloseScript;
914     }
915 
916     /**
917      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnBlurScript()
918      */
919     public String getOnBlurScript() {
920         return onBlurScript;
921     }
922 
923     /**
924      * Setter for the components onBlur script
925      *
926      * @param onBlurScript
927      */
928     public void setOnBlurScript(String onBlurScript) {
929         this.onBlurScript = onBlurScript;
930     }
931 
932     /**
933      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnChangeScript()
934      */
935     public String getOnChangeScript() {
936         return onChangeScript;
937     }
938 
939     /**
940      * Setter for the components onChange script
941      *
942      * @param onChangeScript
943      */
944     public void setOnChangeScript(String onChangeScript) {
945         this.onChangeScript = onChangeScript;
946     }
947 
948     /**
949      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnClickScript()
950      */
951     public String getOnClickScript() {
952         return onClickScript;
953     }
954 
955     /**
956      * Setter for the components onClick script
957      *
958      * @param onClickScript
959      */
960     public void setOnClickScript(String onClickScript) {
961         this.onClickScript = onClickScript;
962     }
963 
964     /**
965      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnDblClickScript()
966      */
967     public String getOnDblClickScript() {
968         return onDblClickScript;
969     }
970 
971     /**
972      * Setter for the components onDblClick script
973      *
974      * @param onDblClickScript
975      */
976     public void setOnDblClickScript(String onDblClickScript) {
977         this.onDblClickScript = onDblClickScript;
978     }
979 
980     /**
981      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnFocusScript()
982      */
983     public String getOnFocusScript() {
984         return onFocusScript;
985     }
986 
987     /**
988      * Setter for the components onFocus script
989      *
990      * @param onFocusScript
991      */
992     public void setOnFocusScript(String onFocusScript) {
993         this.onFocusScript = onFocusScript;
994     }
995 
996     /**
997      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnSubmitScript()
998      */
999     public String getOnSubmitScript() {
1000         return onSubmitScript;
1001     }
1002 
1003     /**
1004      * Setter for the components onSubmit script
1005      *
1006      * @param onSubmitScript
1007      */
1008     public void setOnSubmitScript(String onSubmitScript) {
1009         this.onSubmitScript = onSubmitScript;
1010     }
1011 
1012     /**
1013      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnKeyPressScript()
1014      */
1015     public String getOnKeyPressScript() {
1016         return onKeyPressScript;
1017     }
1018 
1019     /**
1020      * Setter for the components onKeyPress script
1021      *
1022      * @param onKeyPressScript
1023      */
1024     public void setOnKeyPressScript(String onKeyPressScript) {
1025         this.onKeyPressScript = onKeyPressScript;
1026     }
1027 
1028     /**
1029      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnKeyUpScript()
1030      */
1031     public String getOnKeyUpScript() {
1032         return onKeyUpScript;
1033     }
1034 
1035     /**
1036      * Setter for the components onKeyUp script
1037      *
1038      * @param onKeyUpScript
1039      */
1040     public void setOnKeyUpScript(String onKeyUpScript) {
1041         this.onKeyUpScript = onKeyUpScript;
1042     }
1043 
1044     /**
1045      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnKeyDownScript()
1046      */
1047     public String getOnKeyDownScript() {
1048         return onKeyDownScript;
1049     }
1050 
1051     /**
1052      * Setter for the components onKeyDown script
1053      *
1054      * @param onKeyDownScript
1055      */
1056     public void setOnKeyDownScript(String onKeyDownScript) {
1057         this.onKeyDownScript = onKeyDownScript;
1058     }
1059 
1060     /**
1061      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnMouseOverScript()
1062      */
1063     public String getOnMouseOverScript() {
1064         return onMouseOverScript;
1065     }
1066 
1067     /**
1068      * Setter for the components onMouseOver script
1069      *
1070      * @param onMouseOverScript
1071      */
1072     public void setOnMouseOverScript(String onMouseOverScript) {
1073         this.onMouseOverScript = onMouseOverScript;
1074     }
1075 
1076     /**
1077      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnMouseOutScript()
1078      */
1079     public String getOnMouseOutScript() {
1080         return onMouseOutScript;
1081     }
1082 
1083     /**
1084      * Setter for the components onMouseOut script
1085      *
1086      * @param onMouseOutScript
1087      */
1088     public void setOnMouseOutScript(String onMouseOutScript) {
1089         this.onMouseOutScript = onMouseOutScript;
1090     }
1091 
1092     /**
1093      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnMouseUpScript()
1094      */
1095     public String getOnMouseUpScript() {
1096         return onMouseUpScript;
1097     }
1098 
1099     /**
1100      * Setter for the components onMouseUp script
1101      *
1102      * @param onMouseUpScript
1103      */
1104     public void setOnMouseUpScript(String onMouseUpScript) {
1105         this.onMouseUpScript = onMouseUpScript;
1106     }
1107 
1108     /**
1109      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnMouseDownScript()
1110      */
1111     public String getOnMouseDownScript() {
1112         return onMouseDownScript;
1113     }
1114 
1115     /**
1116      * Setter for the components onMouseDown script
1117      *
1118      * @param onMouseDownScript
1119      */
1120     public void setOnMouseDownScript(String onMouseDownScript) {
1121         this.onMouseDownScript = onMouseDownScript;
1122     }
1123 
1124     /**
1125      * @see org.kuali.rice.krad.uif.component.ScriptEventSupport#getOnMouseMoveScript()
1126      */
1127     public String getOnMouseMoveScript() {
1128         return onMouseMoveScript;
1129     }
1130 
1131     /**
1132      * Setter for the components onMouseMove script
1133      *
1134      * @param onMouseMoveScript
1135      */
1136     public void setOnMouseMoveScript(String onMouseMoveScript) {
1137         this.onMouseMoveScript = onMouseMoveScript;
1138     }
1139 
1140     /**
1141      * @see org.kuali.rice.krad.uif.component.Component#getTemplateOptions()
1142      * @return
1143      */
1144     public Map<String, String> getTemplateOptions() {
1145         if (templateOptions == null) {
1146             templateOptions = new HashMap<String, String>();
1147         }
1148         return this.templateOptions;
1149     }
1150 
1151     /**
1152      * @see Component#setTemplateOptions(java.util.Map)
1153      * @param templateOptions
1154      */
1155     public void setTemplateOptions(Map<String, String> templateOptions) {
1156         this.templateOptions = templateOptions;
1157     }
1158 
1159     /**
1160      * Builds a string from the underlying <code>Map</code> of template options
1161      * that will export that options as a JavaScript Map for use in js and
1162      * jQuery plugins
1163      *
1164      * @return String of widget options formatted as JS Map
1165      */
1166     @Override
1167     public String getTemplateOptionsJSString() {
1168         if (templateOptionsJSString != null) {
1169             return templateOptionsJSString;
1170         }
1171 
1172         if (templateOptions == null) {
1173             templateOptions = new HashMap<String, String>();
1174         }
1175         StringBuilder sb = new StringBuilder();
1176 
1177         sb.append("{");
1178 
1179         for (String optionKey : templateOptions.keySet()) {
1180             String optionValue = templateOptions.get(optionKey);
1181 
1182             if (sb.length() > 1) {
1183                 sb.append(",");
1184             }
1185 
1186             sb.append(optionKey);
1187             sb.append(":");
1188 
1189             sb.append(ScriptUtils.convertToJsValue(optionValue));
1190         }
1191 
1192         sb.append("}");
1193 
1194         return sb.toString();
1195     }
1196 
1197     @Override
1198     public void setTemplateOptionsJSString(String templateOptionsJSString) {
1199         this.templateOptionsJSString = templateOptionsJSString;
1200     }
1201 
1202     /**
1203      * When set if the condition is satisfied, the component will be displayed. The component MUST BE a
1204      * container or field type. progressiveRender is defined in a limited Spring EL syntax. Only valid
1205      * form property names, and, or, logical comparison operators (non-arithmetic), and the matches
1206      * clause are allowed. String and regex values must use single quotes ('), booleans must be either true or false,
1207      * numbers must be a valid double, either negative or positive.
1208      *
1209      * <p>
1210      * DO NOT use progressiveRender and a conditional refresh statement on the same component
1211      * unless it is known that the component will always be visible in all cases when a conditional refresh happens
1212      * (ie conditional refresh has progressiveRender's condition anded with its own condition).
1213      * </p>
1214      *
1215      * <p>
1216      * <b>If a component should be refreshed every time it is shown, use the progressiveRenderAndRefresh option
1217      * with this property instead.</b>
1218      * </p>
1219      *
1220      * @return String progressiveRender expression
1221      */
1222     public String getProgressiveRender() {
1223         return this.progressiveRender;
1224     }
1225 
1226     /**
1227      * @param progressiveRender the progressiveRender to set
1228      */
1229     public void setProgressiveRender(String progressiveRender) {
1230         this.progressiveRender = progressiveRender;
1231     }
1232 
1233     /**
1234      * When set if the condition is satisfied, the component will be refreshed.
1235      * The component MUST BE a container or field type. conditionalRefresh is
1236      * defined in a limited Spring EL syntax. Only valid form property names,
1237      * and, or, logical comparison operators (non-arithmetic), and the matches
1238      * clause are allowed. String and regex values must use single quotes ('),
1239      * booleans must be either true or false, numbers must be a valid double
1240      * either negative or positive. <br>
1241      * DO NOT use progressiveRender and conditionalRefresh on the same component
1242      * unless it is known that the component will always be visible in all cases
1243      * when a conditionalRefresh happens (ie conditionalRefresh has
1244      * progressiveRender's condition anded with its own condition). <b>If a
1245      * component should be refreshed every time it is shown, use the
1246      * progressiveRenderAndRefresh option with this property instead.</b>
1247      *
1248      * @return the conditionalRefresh
1249      */
1250     public String getConditionalRefresh() {
1251         return this.conditionalRefresh;
1252     }
1253 
1254     /**
1255      * @param conditionalRefresh the conditionalRefresh to set
1256      */
1257     public void setConditionalRefresh(String conditionalRefresh) {
1258         this.conditionalRefresh = conditionalRefresh;
1259     }
1260 
1261     /**
1262      * Control names used to control progressive disclosure, set internally
1263      * cannot be set.
1264      *
1265      * @return the progressiveDisclosureControlNames
1266      */
1267     public List<String> getProgressiveDisclosureControlNames() {
1268         return this.progressiveDisclosureControlNames;
1269     }
1270 
1271     /**
1272      * The condition to show this component progressively converted to a js
1273      * expression, set internally cannot be set.
1274      *
1275      * @return the progressiveDisclosureConditionJs
1276      */
1277     public String getProgressiveDisclosureConditionJs() {
1278         return this.progressiveDisclosureConditionJs;
1279     }
1280 
1281     /**
1282      * The condition to refresh this component converted to a js expression, set
1283      * internally cannot be set.
1284      *
1285      * @return the conditionalRefreshConditionJs
1286      */
1287     public String getConditionalRefreshConditionJs() {
1288         return this.conditionalRefreshConditionJs;
1289     }
1290 
1291     /**
1292      * Control names used to control conditional refresh, set internally cannot
1293      * be set.
1294      *
1295      * @return the conditionalRefreshControlNames
1296      */
1297     public List<String> getConditionalRefreshControlNames() {
1298         return this.conditionalRefreshControlNames;
1299     }
1300 
1301     /**
1302      * When progressiveRenderViaAJAX is true, this component will be retrieved
1303      * from the server when it first satisfies its progressive render condition.
1304      * After the first retrieval, it is hidden/shown in the html by the js when
1305      * its progressive condition result changes. <b>By default, this is false,
1306      * so components with progressive render capabilities will always be already
1307      * within the client html and toggled to be hidden or visible.</b>
1308      *
1309      * @return the progressiveRenderViaAJAX
1310      */
1311     public boolean isProgressiveRenderViaAJAX() {
1312         return this.progressiveRenderViaAJAX;
1313     }
1314 
1315     /**
1316      * @param progressiveRenderViaAJAX the progressiveRenderViaAJAX to set
1317      */
1318     public void setProgressiveRenderViaAJAX(boolean progressiveRenderViaAJAX) {
1319         this.progressiveRenderViaAJAX = progressiveRenderViaAJAX;
1320     }
1321 
1322     /**
1323      * If true, when the progressiveRender condition is satisfied, the component
1324      * will always be retrieved from the server and shown(as opposed to being
1325      * stored on the client, but hidden, after the first retrieval as is the
1326      * case with the progressiveRenderViaAJAX option). <b>By default, this is
1327      * false, so components with progressive render capabilities will always be
1328      * already within the client html and toggled to be hidden or visible.</b>
1329      *
1330      * @return the progressiveRenderAndRefresh
1331      */
1332     public boolean isProgressiveRenderAndRefresh() {
1333         return this.progressiveRenderAndRefresh;
1334     }
1335 
1336     /**
1337      * @param progressiveRenderAndRefresh the progressiveRenderAndRefresh to set
1338      */
1339     public void setProgressiveRenderAndRefresh(boolean progressiveRenderAndRefresh) {
1340         this.progressiveRenderAndRefresh = progressiveRenderAndRefresh;
1341     }
1342 
1343     /**
1344      * @see Component#getRefreshWhenChangedPropertyNames()
1345      */
1346     public List<String> getRefreshWhenChangedPropertyNames() {
1347         return this.refreshWhenChangedPropertyNames;
1348     }
1349 
1350     /**
1351      * @see Component#setRefreshWhenChangedPropertyNames(java.util.List<java.lang.String>)
1352      */
1353     public void setRefreshWhenChangedPropertyNames(List<String> refreshWhenChangedPropertyNames) {
1354         this.refreshWhenChangedPropertyNames = refreshWhenChangedPropertyNames;
1355     }
1356 
1357     /**
1358      * @see Component#isRefreshedByAction()
1359      */
1360     public boolean isRefreshedByAction() {
1361         return refreshedByAction;
1362     }
1363 
1364     /**
1365      * @see Component#setRefreshedByAction(boolean)
1366      */
1367     public void setRefreshedByAction(boolean refreshedByAction) {
1368         this.refreshedByAction = refreshedByAction;
1369     }
1370 
1371     /**
1372      * @see Component#isResetDataOnRefresh()
1373      */
1374     public boolean isResetDataOnRefresh() {
1375         return resetDataOnRefresh;
1376     }
1377 
1378     /**
1379      * @see Component#setResetDataOnRefresh(boolean)
1380      */
1381     public void setResetDataOnRefresh(boolean resetDataOnRefresh) {
1382         this.resetDataOnRefresh = resetDataOnRefresh;
1383     }
1384 
1385     /**
1386      * Name of a method on the controller that should be invoked as part of the component refresh and disclosure process
1387      *
1388      * <p>
1389      * During the component refresh or disclosure process it might be necessary to perform other operations, such as
1390      * preparing data or executing a business process. This allows the configuration of a method on the underlying
1391      * controller that should be called for the component refresh action. In this method, the necessary logic can be
1392      * performed and then the base component update method invoked to carry out the component refresh.
1393      * </p>
1394      *
1395      * <p>
1396      * Controller method to invoke must accept the form, binding result, request, and response arguments
1397      * </p>
1398      *
1399      * @return String valid controller method name
1400      */
1401     public String getMethodToCallOnRefresh() {
1402         return methodToCallOnRefresh;
1403     }
1404 
1405     /**
1406      * Setter for the controller method to call for a refresh or disclosure action on this component
1407      *
1408      * @param methodToCallOnRefresh
1409      */
1410     public void setMethodToCallOnRefresh(String methodToCallOnRefresh) {
1411         this.methodToCallOnRefresh = methodToCallOnRefresh;
1412     }
1413 
1414     /**
1415      * @param skipInTabOrder flag
1416      */
1417     public void setSkipInTabOrder(boolean skipInTabOrder) {
1418         this.skipInTabOrder = skipInTabOrder;
1419     }
1420 
1421     /**
1422      * Flag indicating that this component and its nested components must be
1423      * skipped when keyboard tabbing.
1424      *
1425      * @return the skipInTabOrder flag
1426      */
1427     public boolean isSkipInTabOrder() {
1428         return skipInTabOrder;
1429     }
1430 
1431     /**
1432      * Add a data attribute to the dataAttributes map
1433      * @param key
1434      * @param value
1435      */
1436     public void addDataAttribute(String key, String value){
1437         dataAttributes.put(key,value);    
1438     }
1439 
1440     public Map<String, String> getDataAttributes() {
1441         return dataAttributes;
1442     }
1443 
1444     /**
1445      *  the data role - used as a html5 data attribute (data-role) to specify the role
1446      * @return the data role attribute value
1447      */
1448     public String getDataRoleAttribute() {
1449         return dataRoleAttribute;
1450     }
1451 
1452     /**
1453      * set the value of data-role attribute
1454      * @param dataRoleAttribute the data role value
1455      */
1456     public void setDataRoleAttribute(String dataRoleAttribute) {
1457         this.dataRoleAttribute = dataRoleAttribute;
1458     }
1459 
1460     /**
1461      *  the data type - used as a html5 data attribute (data-type)
1462      * @return the data type attribute value
1463      */
1464     public String getDataTypeAttribute() {
1465         return dataTypeAttribute;
1466     }
1467 
1468     /**
1469      * set the value of data-type attribute
1470      * @param dataTypeAttribute the data type value
1471      */
1472     public void setDataTypeAttribute(String dataTypeAttribute) {
1473         this.dataTypeAttribute = dataTypeAttribute;
1474     }
1475 
1476     /**
1477      *  the data meta - used as a html5 data attribute (data-meta) for custom information
1478      * @return the data meta attribute value
1479      */
1480     public String getDataMetaAttribute() {
1481         return dataMetaAttribute;
1482     }
1483 
1484     /**
1485      * set the value of data-meta attribute
1486      * @param dataMetaAttribute the data meta value
1487      */
1488     public void setDataMetaAttribute(String dataMetaAttribute) {
1489         this.dataMetaAttribute = dataMetaAttribute;
1490     }
1491 
1492     /**
1493      * DataAttributes that will be written to the html and/or through script to be consumed by jQuery.
1494      * The attributes that are complex objects (contain {}) they will be written through script.
1495      * The attritubes that are simple (contain no objects) will be written directly to the html of the
1496      * component using standard data-.
1497      * Either way they can be access through .data() call in jQuery
1498      * @param dataAttributes
1499      */
1500     public void setDataAttributes(Map<String, String> dataAttributes) {
1501         this.dataAttributes = dataAttributes;
1502     }
1503 
1504     /**
1505      * Returns js that will add data to this component by the element which matches its id.
1506      * This will return script for only the complex data elements (containing {});
1507      * @return jQuery data script for adding complex data attributes
1508      */
1509     public String getComplexDataAttributesJs(){
1510         String js = "";
1511         if (getDataAttributes() == null) {
1512             return js;
1513         } else {
1514             for(Map.Entry<String,String> data: getDataAttributes().entrySet()){
1515                 if(data.getValue().trim().startsWith("{") && data.getValue().trim().endsWith("}")){
1516                     js = js + "jQuery('#" + this.getId() + "').data('" + data.getKey()
1517                             +"', " + data.getValue() +");";
1518                 }
1519             }
1520             return js;
1521         }
1522     }
1523 
1524     /**
1525      * Returns a string that can be put into a the tag of a component to add data attributes inline.
1526      * This does not include the complex attributes which contain {}
1527      * @return html string for data attributes for the simple attributes
1528      */
1529     public String getSimpleDataAttributes(){
1530         String attributes = "";
1531         if (getDataAttributes() == null) {
1532             return attributes;
1533         } else {
1534             for(Map.Entry<String,String> data: getDataAttributes().entrySet()){
1535                 if(!data.getValue().trim().startsWith("{")){
1536                     attributes = attributes + " " + "data-" + data.getKey() + "=\"" + data.getValue() + "\"";
1537                 }
1538             }
1539             return attributes;
1540         }
1541     }
1542 
1543     @Override
1544     /**
1545      * @see org.kuali.rice.krad.uif.component.Component#getAllDataAttributesJs()
1546      */
1547     public String getAllDataAttributesJs() {
1548         String js = "";
1549         if (getDataAttributes() == null) {
1550             return js;
1551         } else {
1552             for(Map.Entry<String,String> data: getDataAttributes().entrySet()){
1553                 js = js + "jQuery('#" + this.getId() + "').data('" + data.getKey()
1554                         +"', " + ScriptUtils.convertToJsValue(data.getValue()) +");";
1555             }
1556             return js;
1557         }
1558     }
1559 
1560 }