View Javadoc

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