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 }