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