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