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 }