001/** 002 * Copyright 2005-2018 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 */ 016package org.kuali.rice.krad.uif.component; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.krad.datadictionary.parse.BeanTag; 020import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute; 021import org.kuali.rice.krad.datadictionary.uif.UifDictionaryBeanBase; 022import org.kuali.rice.krad.datadictionary.validator.ValidationTrace; 023import org.kuali.rice.krad.datadictionary.validator.Validator; 024import org.kuali.rice.krad.uif.CssConstants; 025import org.kuali.rice.krad.uif.UifConstants; 026import org.kuali.rice.krad.uif.UifConstants.ViewStatus; 027import org.kuali.rice.krad.uif.control.ControlBase; 028import org.kuali.rice.krad.uif.field.DataField; 029import org.kuali.rice.krad.uif.field.Field; 030import org.kuali.rice.krad.uif.layout.CssGridSizes; 031import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle; 032import org.kuali.rice.krad.uif.lifecycle.ViewLifecyclePhase; 033import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleRestriction; 034import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleUtils; 035import org.kuali.rice.krad.uif.modifier.ComponentModifier; 036import org.kuali.rice.krad.uif.util.LifecycleAwareMap; 037import org.kuali.rice.krad.uif.util.LifecycleElement; 038import org.kuali.rice.krad.uif.util.ScriptUtils; 039import org.kuali.rice.krad.uif.view.ExpressionEvaluator; 040import org.kuali.rice.krad.uif.view.View; 041import org.kuali.rice.krad.uif.view.ViewIndex; 042import org.kuali.rice.krad.uif.widget.Tooltip; 043import org.kuali.rice.krad.util.KRADConstants; 044import org.kuali.rice.krad.util.KRADUtils; 045import org.kuali.rice.krad.web.form.UifFormBase; 046 047import java.util.ArrayList; 048import java.util.Collections; 049import java.util.HashMap; 050import java.util.LinkedHashSet; 051import java.util.List; 052import java.util.Map; 053import java.util.Map.Entry; 054import java.util.Set; 055 056/** 057 * Base implementation of Component which other component implementations should extend. 058 * 059 * <p> 060 * Provides base component properties such as id and template. Also provides default implementation 061 * for the <code>ScriptEventSupport</code> and <code>Ordered</code> interfaces. By default no script 062 * events except the onDocumentReady are supported. 063 * </p> 064 * 065 * @author Kuali Rice Team (rice.collab@kuali.org) 066 */ 067@BeanTag(name = "componentBase", parent = "Uif-ComponentBase") 068public abstract class ComponentBase extends UifDictionaryBeanBase implements Component { 069 070 private static final long serialVersionUID = -4449335748129894350L; 071 072 private String id; 073 private String containerIdSuffix; 074 private String viewPath; 075 private Map<String, String> phasePathMapping; 076 077 private String template; 078 private String templateName; 079 080 private String viewStatus; 081 082 private String title; 083 084 private boolean render; 085 private boolean retrieveViaAjax; 086 087 @KeepExpression 088 private String progressiveRender; 089 private boolean progressiveRenderViaAJAX; 090 private boolean progressiveRenderAndRefresh; 091 private List<String> progressiveDisclosureControlNames; 092 private String progressiveDisclosureConditionJs; 093 094 @KeepExpression 095 private String conditionalRefresh; 096 private String conditionalRefreshConditionJs; 097 private List<String> conditionalRefreshControlNames; 098 099 private List<String> refreshWhenChangedPropertyNames; 100 private List<String> additionalComponentsToRefresh; 101 private String additionalComponentsToRefreshJs; 102 private boolean refreshedByAction; 103 private boolean disclosedByAction; 104 105 private int refreshTimer; 106 107 private boolean resetDataOnRefresh; 108 private String methodToCallOnRefresh; 109 private List<String> fieldsToSendOnRefresh; 110 111 private boolean hidden; 112 private Boolean readOnly; 113 private Boolean canCopyOnReadOnly; 114 private Boolean required; 115 116 private String align; 117 private String valign; 118 private String width; 119 120 // optional table-backed layout options 121 private int colSpan; 122 private int rowSpan; 123 private List<String> wrapperCssClasses; 124 private String wrapperStyle; 125 private String cellWidth; 126 private CssGridSizes cssGridSizes; 127 128 private List<String> layoutCssClasses; 129 130 private String style; 131 132 private List<String> libraryCssClasses; 133 private List<String> cssClasses; 134 private List<String> additionalCssClasses; 135 136 @DelayedCopy 137 private Tooltip toolTip; 138 139 private int order; 140 141 private boolean skipInTabOrder; 142 143 private String finalizeMethodToCall; 144 private List<Object> finalizeMethodAdditionalArguments; 145 private MethodInvokerConfig finalizeMethodInvoker; 146 147 private boolean selfRendered; 148 private String renderedHtmlOutput; 149 150 private boolean disableSessionPersistence; 151 private boolean forceSessionPersistence; 152 153 private ComponentSecurity componentSecurity; 154 155 private String onLoadScript; 156 private String onUnloadScript; 157 private String onCloseScript; 158 private String onBlurScript; 159 private String onChangeScript; 160 private String onClickScript; 161 private String onDblClickScript; 162 private String onFocusScript; 163 private String onSubmitScript; 164 private String onInputScript; 165 private String onKeyPressScript; 166 private String onKeyUpScript; 167 private String onKeyDownScript; 168 private String onMouseOverScript; 169 private String onMouseOutScript; 170 private String onMouseUpScript; 171 private String onMouseDownScript; 172 private String onMouseMoveScript; 173 private String onDocumentReadyScript; 174 175 private List<ComponentModifier> componentModifiers; 176 177 protected Map<String, String> templateOptions; 178 179 private String templateOptionsJSString; 180 181 @ReferenceCopy(newCollectionInstance = true) 182 private transient Map<String, Object> context; 183 184 private List<PropertyReplacer> propertyReplacers; 185 186 private Map<String, String> dataAttributes; 187 private Map<String, String> scriptDataAttributes; 188 189 private String role; 190 private Map<String, String> ariaAttributes; 191 192 private String preRenderContent; 193 private String postRenderContent; 194 195 private String excludeIf; 196 private String excludeUnless; 197 198 private boolean omitFromFormPost; 199 200 public ComponentBase() { 201 super(); 202 203 order = 0; 204 colSpan = 1; 205 rowSpan = 1; 206 cssGridSizes = new CssGridSizes(); 207 208 viewStatus = ViewStatus.CREATED; 209 210 render = true; 211 canCopyOnReadOnly = false; 212 selfRendered = false; 213 progressiveRenderViaAJAX = false; 214 progressiveRenderAndRefresh = false; 215 refreshedByAction = false; 216 resetDataOnRefresh = false; 217 disableSessionPersistence = false; 218 forceSessionPersistence = false; 219 220 phasePathMapping = new HashMap<String, String>(); 221 context = Collections.emptyMap(); 222 dataAttributes = Collections.emptyMap(); 223 scriptDataAttributes = Collections.emptyMap(); 224 ariaAttributes = Collections.emptyMap(); 225 templateOptions = Collections.emptyMap(); 226 227 cssClasses = Collections.emptyList(); 228 libraryCssClasses = Collections.emptyList(); 229 additionalCssClasses = Collections.emptyList(); 230 } 231 232 /** 233 * {@inheritDoc} 234 */ 235 @Override 236 public boolean skipLifecycle() { 237 return this.isRetrieveViaAjax(); 238 } 239 240 /** 241 * @see LifecycleElement#checkMutable(boolean) 242 */ 243 public void checkMutable(boolean legalDuringInitialization) { 244 if (UifConstants.ViewStatus.CACHED.equals(viewStatus)) { 245 ViewLifecycle.reportIllegalState("Cached component " + getClass() + " " + getId() 246 + " is immutable, use copy() to get a mutable instance"); 247 return; 248 } 249 250 if (ViewLifecycle.isActive()) { 251 return; 252 } 253 254 if (UifConstants.ViewStatus.CREATED.equals(viewStatus) && !legalDuringInitialization) { 255 ViewLifecycle.reportIllegalState( 256 "View has not been fully initialized, attempting to change component " + getClass() + " " 257 + getId()); 258 return; 259 } 260 } 261 262 /** 263 * @see LifecycleElement#isMutable(boolean) 264 */ 265 public boolean isMutable(boolean legalDuringInitialization) { 266 return (UifConstants.ViewStatus.CREATED.equals(viewStatus) && legalDuringInitialization) || ViewLifecycle 267 .isActive(); 268 } 269 270 /** 271 * Indicates what lifecycle phase the component instance is in 272 * 273 * <p> 274 * The view lifecycle begins with the CREATED status. In this status a new instance of the view 275 * has been retrieved from the dictionary, but no further processing has been done. After the 276 * initialize phase has been run the status changes to INITIALIZED. After the model has been 277 * applied and the view is ready for render the status changes to FINAL 278 * </p> 279 * 280 * @return view status 281 * 282 * @see org.kuali.rice.krad.uif.UifConstants.ViewStatus 283 */ 284 public String getViewStatus() { 285 return this.viewStatus; 286 } 287 288 /** 289 * Setter for the view status 290 * 291 * @param status view status 292 */ 293 @Override 294 public void setViewStatus(String status) { 295 if (!UifConstants.ViewStatus.CREATED.equals(status) && !UifConstants.ViewStatus.CACHED.equals(status)) { 296 checkMutable(true); 297 } 298 299 this.viewStatus = status; 300 } 301 302 /** 303 * {@inheritDoc} 304 */ 305 @Override 306 public void notifyCompleted(ViewLifecyclePhase phase) { 307 if (!UifConstants.ViewPhases.PRE_PROCESS.equals(phase.getViewPhase())) { 308 ViewIndex viewIndex = ViewLifecycle.getView().getViewIndex(); 309 if (viewIndex != null) { 310 viewIndex.indexComponent(this); 311 } 312 } 313 } 314 315 /** 316 * Indicates whether the component has been initialized. 317 * 318 * @return True if the component has been initialized, false if not. 319 */ 320 public boolean isInitialized() { 321 return StringUtils.equals(viewStatus, ViewStatus.INITIALIZED) || isModelApplied(); 322 } 323 324 /** 325 * Indicates whether the component has been updated from the model. 326 * 327 * @return True if the component has been updated, false if not. 328 */ 329 public boolean isModelApplied() { 330 return StringUtils.equals(viewStatus, ViewStatus.MODEL_APPLIED) || isFinal(); 331 } 332 333 /** 334 * Indicates whether the component has been updated from the model and final updates made. 335 * 336 * @return True if the component has been updated, false if not. 337 */ 338 public boolean isFinal() { 339 return StringUtils.equals(viewStatus, ViewStatus.FINAL) || isRendered(); 340 } 341 342 /** 343 * Indicates whether the component has been fully rendered. 344 * 345 * @return True if the component has fully rendered, false if not. 346 */ 347 public boolean isRendered() { 348 return StringUtils.equals(viewStatus, ViewStatus.RENDERED); 349 } 350 351 /** 352 * The following updates are done here: 353 * 354 * <ul> 355 * <li>Invoke performInitialize on component modifiers</li> 356 * </ul> 357 * 358 * {@inheritDoc} 359 */ 360 @Override 361 public void performInitialization(Object model) { 362 if (this.componentModifiers != null) { 363 for (ComponentModifier modifier : this.componentModifiers) { 364 modifier.performInitialization(model, this); 365 } 366 } 367 } 368 369 /** 370 * The following updates are done here: 371 * 372 * <ul> 373 * <li>Evaluate the progressive render condition (if set) and combine with the current render 374 * status to set the render status</li> 375 * </ul> 376 * 377 * {@inheritDoc} 378 */ 379 @Override 380 public void performApplyModel(Object model, LifecycleElement parent) { 381 View view = ViewLifecycle.getView(); 382 383 if (this.render && StringUtils.isNotEmpty(progressiveRender)) { 384 // progressive anded with render, will not render at least one of the two are false 385 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator(); 386 387 String adjustedProgressiveRender = expressionEvaluator.replaceBindingPrefixes(view, this, 388 progressiveRender); 389 390 Boolean progRenderEval = (Boolean) expressionEvaluator.evaluateExpression(context, 391 adjustedProgressiveRender); 392 393 this.setRender(progRenderEval); 394 } 395 } 396 397 /** 398 * No-op implementation. Override for custom behavior in subclasses. 399 * 400 * {@inheritDoc} 401 */ 402 @Override 403 public void afterEvaluateExpression() { 404 } 405 406 /** 407 * The following finalization is done here: 408 * 409 * <ul> 410 * <li>progressiveRender and conditionalRefresh variables are processed if set</li> 411 * <li>If any of the style properties were given, sets the style string on the style property</li> 412 * <li>Set the skipInTabOrder flag for nested components</li> 413 * </ul> 414 * 415 * {@inheritDoc} 416 */ 417 @Override 418 public void performFinalize(Object model, LifecycleElement parent) { 419 View view = ViewLifecycle.getView(); 420 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator(); 421 // progressiveRender expression setup 422 if (StringUtils.isNotEmpty(progressiveRender)) { 423 progressiveRender = expressionEvaluator.replaceBindingPrefixes(view, this, progressiveRender); 424 progressiveDisclosureControlNames = new ArrayList<String>(); 425 progressiveDisclosureConditionJs = expressionEvaluator.parseExpression(progressiveRender, 426 progressiveDisclosureControlNames, this.getContext()); 427 } 428 429 // conditional refresh expression setup 430 if (StringUtils.isNotEmpty(conditionalRefresh)) { 431 conditionalRefresh = expressionEvaluator.replaceBindingPrefixes(view, this, conditionalRefresh); 432 conditionalRefreshControlNames = new ArrayList<String>(); 433 conditionalRefreshConditionJs = expressionEvaluator.parseExpression(conditionalRefresh, 434 conditionalRefreshControlNames, this.getContext()); 435 } 436 437 if (refreshWhenChangedPropertyNames != null) { 438 List<String> adjustedRefreshPropertyNames = new ArrayList<String>(refreshWhenChangedPropertyNames.size()); 439 for (String refreshPropertyName : refreshWhenChangedPropertyNames) { 440 adjustedRefreshPropertyNames.add(expressionEvaluator.replaceBindingPrefixes(view, this, 441 refreshPropertyName)); 442 } 443 refreshWhenChangedPropertyNames = adjustedRefreshPropertyNames; 444 if (!retrieveViaAjax) { 445 //need to add the "refresh" method so that regular calls will work 446 ViewLifecycle.getViewPostMetadata().addAccessibleMethodToCall(KRADConstants.RETURN_METHOD_TO_CALL); 447 } 448 } 449 450 // retrieveViaAjax forces session persistence because it assumes that this component will be retrieved by 451 // some ajax retrieval call 452 if (retrieveViaAjax) { 453 forceSessionPersistence = true; 454 } 455 456 // add the align, valign, and width settings to style 457 if (StringUtils.isNotBlank(getAlign()) && !StringUtils.contains(getStyle(), CssConstants.TEXT_ALIGN)) { 458 appendToStyle(CssConstants.TEXT_ALIGN + getAlign() + ";"); 459 } 460 461 if (StringUtils.isNotBlank(getValign()) && !StringUtils.contains(getStyle(), CssConstants.VERTICAL_ALIGN)) { 462 appendToStyle(CssConstants.VERTICAL_ALIGN + getValign() + ";"); 463 } 464 465 if (StringUtils.isNotBlank(getWidth()) && !StringUtils.contains(getStyle(), CssConstants.WIDTH)) { 466 appendToStyle(CssConstants.WIDTH + getWidth() + ";"); 467 } 468 469 // Set the skipInTabOrder flag on all nested components 470 // Set the tabIndex on controls to -1 in order to be skipped on tabbing 471 if (skipInTabOrder) { 472 for (LifecycleElement component : ViewLifecycleUtils.getElementsForLifecycle(this).values()) { 473 if (component != null && component instanceof ComponentBase) { 474 ((ComponentBase) component).setSkipInTabOrder(skipInTabOrder); 475 if (component instanceof ControlBase) { 476 ((ControlBase) component).setTabIndex(-1); 477 } 478 } 479 } 480 } 481 482 // if this is not rendering and it is not rendering via an ajax call, but still has a progressive render 483 // condition we still want to render the component, but hide it (in ajax cases, template creates a placeholder) 484 boolean hide = false; 485 if (!this.render && !this.progressiveRenderViaAJAX && !this.progressiveRenderAndRefresh && StringUtils 486 .isNotBlank(progressiveRender)) { 487 hide = true; 488 } else if (this.isHidden()) { 489 hide = true; 490 } 491 492 if (hide) { 493 if (StringUtils.isNotBlank(this.getStyle())) { 494 if (this.getStyle().endsWith(";")) { 495 this.setStyle(this.getStyle() + " display: none;"); 496 } else { 497 this.setStyle(this.getStyle() + "; display: none;"); 498 } 499 } else { 500 this.setStyle("display: none;"); 501 } 502 } 503 504 // setup refresh timer 505 // if the refreshTimer property has been set then pre-append the call to refreshComponetUsingTimer 506 // to the onDocumentReadyScript 507 if (refreshTimer > 0) { 508 String timerScript = getOnDocumentReadyScript(); 509 510 if (StringUtils.isBlank(this.methodToCallOnRefresh)) { 511 this.methodToCallOnRefresh = "refresh"; 512 } 513 514 timerScript = (null == timerScript) ? "" : timerScript; 515 timerScript = 516 "refreshComponentUsingTimer('" + this.id + "','" + this.methodToCallOnRefresh + "'," + refreshTimer 517 + ");" + timerScript; 518 519 setOnDocumentReadyScript(timerScript); 520 } 521 522 // Add tooltip class 523 if (this.getToolTip() != null && StringUtils.isNotBlank(this.getToolTip().getTooltipContent())) { 524 this.addStyleClass(CssConstants.Classes.TOOLTIP); 525 } 526 527 // put together all css class names for this component, in order 528 Set<String> finalCssClasses = new LinkedHashSet<>(); 529 530 if (libraryCssClasses != null && (!ViewLifecycle.isActive() || ViewLifecycle.getView() 531 .isUseLibraryCssClasses())) { 532 finalCssClasses.addAll(libraryCssClasses); 533 libraryCssClasses.clear(); 534 } 535 536 if (cssClasses != null) { 537 finalCssClasses.addAll(cssClasses); 538 cssClasses.clear(); 539 } 540 541 if (additionalCssClasses != null) { 542 finalCssClasses.addAll(additionalCssClasses); 543 additionalCssClasses.clear(); 544 } 545 546 // need to do this since cssClasses may be unmodifiable 547 List<String> newCssClasses = new ArrayList<>(); 548 newCssClasses.addAll(finalCssClasses); 549 cssClasses = newCssClasses; 550 551 // add the method to call as an available method 552 if (StringUtils.isNotBlank(methodToCallOnRefresh)) { 553 ViewLifecycle.getViewPostMetadata().addAvailableMethodToCall(methodToCallOnRefresh); 554 } 555 556 if ((isRender() || StringUtils.isNotBlank(getProgressiveRender())) && StringUtils.isNotBlank( 557 methodToCallOnRefresh)) { 558 ViewLifecycle.getViewPostMetadata().addAccessibleMethodToCall(methodToCallOnRefresh); 559 } 560 } 561 562 /** 563 * Returns list of components that are being held in property replacers configured for this 564 * component 565 * 566 * @return List<Component> 567 */ 568 @ViewLifecycleRestriction 569 public List<Component> getPropertyReplacerComponents() { 570 if (propertyReplacers == null) { 571 return Collections.emptyList(); 572 } 573 574 List<Component> components = new ArrayList<Component>(); 575 for (Object replacer : propertyReplacers) { 576 components.addAll(((PropertyReplacer) replacer).getNestedComponents()); 577 } 578 579 return components; 580 } 581 582 /** 583 * {@inheritDoc} 584 */ 585 @BeanTagAttribute 586 @Override 587 public String getId() { 588 return this.id; 589 } 590 591 /** 592 * {@inheritDoc} 593 */ 594 @Override 595 public void setId(String id) { 596 checkMutable(true); 597 this.id = id; 598 } 599 600 /** 601 * {@inheritDoc} 602 */ 603 @Override 604 public String getContainerIdSuffix() { 605 return containerIdSuffix; 606 } 607 608 /** 609 * {@inheritDoc} 610 */ 611 @Override 612 public void setContainerIdSuffix(String containerIdSuffix) { 613 this.containerIdSuffix = containerIdSuffix; 614 } 615 616 /** 617 * {@inheritDoc} 618 */ 619 @Override 620 public String getViewPath() { 621 return this.viewPath; 622 } 623 624 /** 625 * {@inheritDoc} 626 */ 627 @Override 628 public void setViewPath(String viewPath) { 629 checkMutable(true); 630 this.viewPath = viewPath; 631 } 632 633 /** 634 * {@inheritDoc} 635 */ 636 @Override 637 public Map<String, String> getPhasePathMapping() { 638 return phasePathMapping; 639 } 640 641 /** 642 * {@inheritDoc} 643 */ 644 @Override 645 public void setPhasePathMapping(Map<String, String> phasePathMapping) { 646 this.phasePathMapping = phasePathMapping; 647 } 648 649 /** 650 * {@inheritDoc} 651 */ 652 @BeanTagAttribute 653 @Override 654 public String getTemplate() { 655 return this.template; 656 } 657 658 /** 659 * {@inheritDoc} 660 */ 661 @Override 662 public void setTemplate(String template) { 663 checkMutable(true); 664 this.template = template; 665 } 666 667 /** 668 * {@inheritDoc} 669 */ 670 @Override 671 public List<String> getAdditionalTemplates() { 672 return Collections.emptyList(); 673 } 674 675 /** 676 * {@inheritDoc} 677 */ 678 @BeanTagAttribute 679 @Override 680 public String getTemplateName() { 681 return templateName; 682 } 683 684 /** 685 * {@inheritDoc} 686 */ 687 @Override 688 public void setTemplateName(String templateName) { 689 checkMutable(true); 690 this.templateName = templateName; 691 } 692 693 /** 694 * {@inheritDoc} 695 */ 696 @BeanTagAttribute 697 @Override 698 public String getTitle() { 699 return this.title; 700 } 701 702 /** 703 * {@inheritDoc} 704 */ 705 @Override 706 public void setTitle(String title) { 707 checkMutable(true); 708 this.title = title; 709 } 710 711 /** 712 * {@inheritDoc} 713 */ 714 @BeanTagAttribute 715 @Override 716 public boolean isHidden() { 717 return this.hidden; 718 } 719 720 /** 721 * {@inheritDoc} 722 */ 723 @Override 724 public void setHidden(boolean hidden) { 725 checkMutable(true); 726 this.hidden = hidden; 727 } 728 729 /** 730 * {@inheritDoc} 731 */ 732 @BeanTagAttribute 733 @Override 734 public Boolean getReadOnly() { 735 return this.readOnly; 736 } 737 738 /** 739 * {@inheritDoc} 740 */ 741 @Override 742 public void setReadOnly(Boolean readOnly) { 743 checkMutable(true); 744 this.readOnly = readOnly; 745 } 746 747 /** 748 * {@inheritDoc} 749 */ 750 @Override 751 public Boolean getCanCopyOnReadOnly() { 752 return canCopyOnReadOnly; 753 } 754 755 /** 756 * {@inheritDoc} 757 */ 758 @Override 759 public void setCanCopyOnReadOnly(Boolean canCopyOnReadOnly) { 760 this.canCopyOnReadOnly = canCopyOnReadOnly; 761 } 762 763 764 /** 765 * {@inheritDoc} 766 */ 767 @BeanTagAttribute 768 @Override 769 public Boolean getRequired() { 770 return this.required; 771 } 772 773 /** 774 * {@inheritDoc} 775 */ 776 @Override 777 public void setRequired(Boolean required) { 778 checkMutable(true); 779 this.required = required; 780 } 781 782 /** 783 * {@inheritDoc} 784 */ 785 @BeanTagAttribute 786 @Override 787 public boolean isRender() { 788 return this.render; 789 } 790 791 /** 792 * {@inheritDoc} 793 */ 794 @Override 795 public void setRender(boolean render) { 796 checkMutable(true); 797 this.render = render; 798 } 799 800 /** 801 * {@inheritDoc} 802 */ 803 @BeanTagAttribute 804 @Override 805 public boolean isRetrieveViaAjax() { 806 return retrieveViaAjax; 807 } 808 809 /** 810 * {@inheritDoc} 811 */ 812 @Override 813 public void setRetrieveViaAjax(boolean retrieveViaAjax) { 814 checkMutable(true); 815 this.retrieveViaAjax = retrieveViaAjax; 816 } 817 818 /** 819 * {@inheritDoc} 820 */ 821 @BeanTagAttribute 822 @Override 823 public int getColSpan() { 824 return this.colSpan; 825 } 826 827 /** 828 * {@inheritDoc} 829 */ 830 @Override 831 public void setColSpan(int colSpan) { 832 checkMutable(true); 833 this.colSpan = colSpan; 834 } 835 836 /** 837 * {@inheritDoc} 838 */ 839 @BeanTagAttribute 840 @Override 841 public int getRowSpan() { 842 return this.rowSpan; 843 } 844 845 /** 846 * {@inheritDoc} 847 */ 848 @Override 849 public void setRowSpan(int rowSpan) { 850 checkMutable(true); 851 this.rowSpan = rowSpan; 852 } 853 854 /** 855 * {@inheritDoc} 856 */ 857 @BeanTagAttribute 858 @Override 859 public List<String> getWrapperCssClasses() { 860 return wrapperCssClasses; 861 } 862 863 /** 864 * {@inheritDoc} 865 */ 866 @Override 867 public void setWrapperCssClasses(List<String> wrapperCssClasses) { 868 checkMutable(true); 869 this.wrapperCssClasses = wrapperCssClasses; 870 } 871 872 /** 873 * {@inheritDoc} 874 */ 875 @Override 876 public void addWrapperCssClass(String cssClass) { 877 checkMutable(false); 878 if (this.wrapperCssClasses == null) { 879 this.wrapperCssClasses = new ArrayList<String>(); 880 } 881 882 if (cssClass != null) { 883 this.wrapperCssClasses.add(cssClass); 884 } 885 } 886 887 /** 888 * Builds the HTML class attribute string by combining the cellStyleClasses list with a space 889 * delimiter. 890 * 891 * @return class attribute string 892 */ 893 public String getWrapperCssClassesAsString() { 894 if (wrapperCssClasses != null) { 895 return StringUtils.join(wrapperCssClasses, " ").trim(); 896 } 897 898 return ""; 899 } 900 901 /** 902 * {@inheritDoc} 903 */ 904 @BeanTagAttribute 905 @Override 906 public String getWrapperStyle() { 907 return wrapperStyle; 908 } 909 910 /** 911 * {@inheritDoc} 912 */ 913 @Override 914 public void setWrapperStyle(String wrapperStyle) { 915 checkMutable(true); 916 this.wrapperStyle = wrapperStyle; 917 } 918 919 /** 920 * {@inheritDoc} 921 */ 922 @BeanTagAttribute 923 @Override 924 public String getCellWidth() { 925 return cellWidth; 926 } 927 928 /** 929 * {@inheritDoc} 930 */ 931 @Override 932 public void setCellWidth(String cellWidth) { 933 checkMutable(true); 934 this.cellWidth = cellWidth; 935 } 936 937 /** 938 * {@inheritDoc} 939 */ 940 @Override 941 @BeanTagAttribute 942 public CssGridSizes getCssGridSizes() { 943 return cssGridSizes; 944 } 945 946 /** 947 * {@inheritDoc} 948 */ 949 @Override 950 public void setCssGridSizes(CssGridSizes cssGridSizes) { 951 this.cssGridSizes = cssGridSizes; 952 } 953 954 /** 955 * {@inheritDoc} 956 */ 957 @Override 958 @BeanTagAttribute 959 public String getAlign() { 960 return this.align; 961 } 962 963 /** 964 * {@inheritDoc} 965 */ 966 @Override 967 public void setAlign(String align) { 968 checkMutable(true); 969 this.align = align; 970 } 971 972 /** 973 * {@inheritDoc} 974 */ 975 @Override 976 @BeanTagAttribute 977 public String getValign() { 978 return this.valign; 979 } 980 981 /** 982 * {@inheritDoc} 983 */ 984 @Override 985 public void setValign(String valign) { 986 checkMutable(true); 987 this.valign = valign; 988 } 989 990 /** 991 * {@inheritDoc} 992 */ 993 @Override 994 @BeanTagAttribute 995 public String getWidth() { 996 return this.width; 997 } 998 999 /** 1000 * {@inheritDoc} 1001 */ 1002 @Override 1003 public void setWidth(String width) { 1004 checkMutable(true); 1005 this.width = width; 1006 } 1007 1008 /** 1009 * {@inheritDoc} 1010 */ 1011 @Override 1012 @BeanTagAttribute 1013 public String getStyle() { 1014 return this.style; 1015 } 1016 1017 /** 1018 * {@inheritDoc} 1019 */ 1020 @Override 1021 public void setStyle(String style) { 1022 checkMutable(true); 1023 this.style = style; 1024 } 1025 1026 /** 1027 * Additional css classes that come before css classes listed in the cssClasses property 1028 * 1029 * <p> 1030 * These are used by the framework for styling with a library (for example, bootstrap), and 1031 * should normally not be overridden. 1032 * </p> 1033 * 1034 * @return the library cssClasses 1035 */ 1036 public List<String> getLibraryCssClasses() { 1037 if (libraryCssClasses == Collections.EMPTY_LIST && isMutable(true)) { 1038 libraryCssClasses = new ArrayList<String>(); 1039 } 1040 1041 return libraryCssClasses; 1042 } 1043 1044 /** 1045 * Set the libraryCssClasses 1046 */ 1047 public void setLibraryCssClasses(List<String> libraryCssClasses) { 1048 checkMutable(true); 1049 1050 if (libraryCssClasses == null) { 1051 this.libraryCssClasses = Collections.emptyList(); 1052 } else { 1053 this.libraryCssClasses = libraryCssClasses; 1054 } 1055 } 1056 1057 /** 1058 * {@inheritDoc} 1059 */ 1060 @Override 1061 @BeanTagAttribute 1062 public List<String> getCssClasses() { 1063 if (cssClasses == Collections.EMPTY_LIST && isMutable(true)) { 1064 cssClasses = new ArrayList<String>(); 1065 } 1066 1067 return cssClasses; 1068 } 1069 1070 /** 1071 * {@inheritDoc} 1072 */ 1073 @Override 1074 public void setCssClasses(List<String> cssClasses) { 1075 checkMutable(true); 1076 1077 if (cssClasses == null) { 1078 this.cssClasses = Collections.emptyList(); 1079 } else { 1080 this.cssClasses = cssClasses; 1081 } 1082 } 1083 1084 /** 1085 * {@inheritDoc} 1086 */ 1087 @Override 1088 @BeanTagAttribute 1089 public List<String> getAdditionalCssClasses() { 1090 if (additionalCssClasses == Collections.EMPTY_LIST && isMutable(true)) { 1091 additionalCssClasses = new ArrayList<String>(); 1092 } 1093 1094 return additionalCssClasses; 1095 } 1096 1097 /** 1098 * {@inheritDoc} 1099 */ 1100 @Override 1101 public void setAdditionalCssClasses(List<String> additionalCssClasses) { 1102 checkMutable(true); 1103 if (additionalCssClasses == null) { 1104 this.additionalCssClasses = Collections.emptyList(); 1105 } else { 1106 this.additionalCssClasses = additionalCssClasses; 1107 } 1108 } 1109 1110 /** 1111 * Builds the HTML class attribute string by combining the styleClasses list with a space 1112 * delimiter 1113 * 1114 * @return class attribute string 1115 */ 1116 public String getStyleClassesAsString() { 1117 if (cssClasses != null) { 1118 return StringUtils.join(cssClasses, " ").trim(); 1119 } 1120 1121 return ""; 1122 } 1123 1124 /** 1125 * {@inheritDoc} 1126 */ 1127 @Override 1128 public void addStyleClass(String styleClass) { 1129 checkMutable(false); 1130 if (StringUtils.isEmpty(styleClass)) { 1131 return; 1132 } 1133 1134 if (cssClasses.isEmpty()) { 1135 setCssClasses(new ArrayList<String>()); 1136 } 1137 1138 if (!cssClasses.contains(styleClass)) { 1139 cssClasses.add(styleClass); 1140 } 1141 } 1142 1143 /** 1144 * {@inheritDoc} 1145 */ 1146 @Override 1147 public void appendToStyle(String styleRules) { 1148 checkMutable(false); 1149 if (style == null) { 1150 style = ""; 1151 } 1152 style = style + styleRules; 1153 } 1154 1155 /** 1156 * {@inheritDoc} 1157 */ 1158 @Override 1159 @BeanTagAttribute 1160 public String getFinalizeMethodToCall() { 1161 return this.finalizeMethodToCall; 1162 } 1163 1164 /** 1165 * Setter for the finalize method 1166 */ 1167 public void setFinalizeMethodToCall(String finalizeMethodToCall) { 1168 checkMutable(true); 1169 this.finalizeMethodToCall = finalizeMethodToCall; 1170 } 1171 1172 /** 1173 * {@inheritDoc} 1174 */ 1175 @Override 1176 @BeanTagAttribute 1177 public List<Object> getFinalizeMethodAdditionalArguments() { 1178 return finalizeMethodAdditionalArguments; 1179 } 1180 1181 /** 1182 * Setter for the finalize additional arguments list 1183 */ 1184 public void setFinalizeMethodAdditionalArguments(List<Object> finalizeMethodAdditionalArguments) { 1185 checkMutable(true); 1186 this.finalizeMethodAdditionalArguments = finalizeMethodAdditionalArguments; 1187 } 1188 1189 /** 1190 * {@inheritDoc} 1191 */ 1192 @Override 1193 @BeanTagAttribute 1194 public MethodInvokerConfig getFinalizeMethodInvoker() { 1195 return this.finalizeMethodInvoker; 1196 } 1197 1198 /** 1199 * Setter for the method invoker instance 1200 */ 1201 public void setFinalizeMethodInvoker(MethodInvokerConfig finalizeMethodInvoker) { 1202 checkMutable(true); 1203 this.finalizeMethodInvoker = finalizeMethodInvoker; 1204 } 1205 1206 /** 1207 * {@inheritDoc} 1208 */ 1209 @Override 1210 @BeanTagAttribute 1211 public boolean isSelfRendered() { 1212 return this.selfRendered; 1213 } 1214 1215 /** 1216 * {@inheritDoc} 1217 */ 1218 @Override 1219 public void setSelfRendered(boolean selfRendered) { 1220 this.selfRendered = selfRendered; 1221 } 1222 1223 /** 1224 * {@inheritDoc} 1225 */ 1226 @Override 1227 @BeanTagAttribute 1228 public String getRenderedHtmlOutput() { 1229 return this.renderedHtmlOutput; 1230 } 1231 1232 /** 1233 * {@inheritDoc} 1234 */ 1235 @Override 1236 public void setRenderedHtmlOutput(String renderedHtmlOutput) { 1237 this.renderedHtmlOutput = renderedHtmlOutput; 1238 } 1239 1240 /** 1241 * {@inheritDoc} 1242 */ 1243 @Override 1244 @BeanTagAttribute 1245 public boolean isDisableSessionPersistence() { 1246 return disableSessionPersistence; 1247 } 1248 1249 /** 1250 * {@inheritDoc} 1251 */ 1252 @Override 1253 public void setDisableSessionPersistence(boolean disableSessionPersistence) { 1254 checkMutable(true); 1255 this.disableSessionPersistence = disableSessionPersistence; 1256 } 1257 1258 /** 1259 * {@inheritDoc} 1260 */ 1261 @Override 1262 @BeanTagAttribute 1263 public boolean isForceSessionPersistence() { 1264 return forceSessionPersistence; 1265 } 1266 1267 /** 1268 * {@inheritDoc} 1269 */ 1270 @Override 1271 public void setForceSessionPersistence(boolean forceSessionPersistence) { 1272 checkMutable(true); 1273 this.forceSessionPersistence = forceSessionPersistence; 1274 } 1275 1276 /** 1277 * {@inheritDoc} 1278 */ 1279 @Override 1280 @BeanTagAttribute(type = BeanTagAttribute.AttributeType.DIRECTORBYTYPE) 1281 public ComponentSecurity getComponentSecurity() { 1282 return componentSecurity; 1283 } 1284 1285 /** 1286 * {@inheritDoc} 1287 */ 1288 @Override 1289 public void setComponentSecurity(ComponentSecurity componentSecurity) { 1290 checkMutable(true); 1291 this.componentSecurity = componentSecurity; 1292 } 1293 1294 /** 1295 * Initializes (if necessary) the component security instance for the component type 1296 */ 1297 protected void initializeComponentSecurity() { 1298 if (this.componentSecurity == null) { 1299 this.componentSecurity = KRADUtils.createNewObjectFromClass(ComponentSecurity.class); 1300 } 1301 } 1302 1303 /** 1304 * @see org.kuali.rice.krad.uif.component.ComponentSecurity#isEditAuthz() 1305 */ 1306 @BeanTagAttribute 1307 public Boolean isEditAuthz() { 1308 initializeComponentSecurity(); 1309 1310 return this.componentSecurity.isEditAuthz(); 1311 } 1312 1313 /** 1314 * Setter for {@link #isEditAuthz()} 1315 * 1316 * @param editAuthz property value 1317 */ 1318 public void setEditAuthz(Boolean editAuthz) { 1319 checkMutable(true); 1320 initializeComponentSecurity(); 1321 1322 this.componentSecurity.setEditAuthz(editAuthz); 1323 } 1324 1325 /** 1326 * @see org.kuali.rice.krad.uif.component.ComponentSecurity#isViewAuthz() 1327 */ 1328 @BeanTagAttribute 1329 public Boolean isViewAuthz() { 1330 initializeComponentSecurity(); 1331 1332 return this.componentSecurity.isViewAuthz(); 1333 } 1334 1335 /** 1336 * Setter for {@link #isViewAuthz()} 1337 * 1338 * @param viewAuthz property value 1339 */ 1340 public void setViewAuthz(Boolean viewAuthz) { 1341 checkMutable(true); 1342 initializeComponentSecurity(); 1343 1344 this.componentSecurity.setViewAuthz(viewAuthz); 1345 } 1346 1347 /** 1348 * {@inheritDoc} 1349 */ 1350 @Override 1351 @BeanTagAttribute 1352 public List<ComponentModifier> getComponentModifiers() { 1353 return this.componentModifiers; 1354 } 1355 1356 /** 1357 * {@inheritDoc} 1358 */ 1359 @Override 1360 public void setComponentModifiers(List<ComponentModifier> componentModifiers) { 1361 checkMutable(true); 1362 this.componentModifiers = 1363 componentModifiers == null ? Collections.<ComponentModifier>emptyList() : componentModifiers; 1364 } 1365 1366 /** 1367 * {@inheritDoc} 1368 */ 1369 @Override 1370 @BeanTagAttribute 1371 public Map<String, Object> getContext() { 1372 if (context == Collections.EMPTY_MAP && isMutable(true)) { 1373 context = new HashMap<String, Object>(); 1374 } 1375 1376 return context; 1377 } 1378 1379 /** 1380 * {@inheritDoc} 1381 */ 1382 @Override 1383 public void setContext(Map<String, Object> context) { 1384 checkMutable(true); 1385 1386 if (context == null) { 1387 this.context = Collections.emptyMap(); 1388 } else { 1389 this.context = context; 1390 } 1391 } 1392 1393 /** 1394 * {@inheritDoc} 1395 */ 1396 @Override 1397 public void pushObjectToContext(String objectName, Object object) { 1398 checkMutable(true); 1399 if (context == Collections.EMPTY_MAP && isMutable(true)) { 1400 context = new HashMap<String, Object>(); 1401 } 1402 1403 pushToPropertyReplacerContext(objectName, object); 1404 context.put(objectName, object); 1405 } 1406 1407 /* 1408 * Adds the object to the context of the components in the 1409 * PropertyReplacer object. Only checks for a list, map or component. 1410 */ 1411 protected void pushToPropertyReplacerContext(String objectName, Object object) { 1412 checkMutable(true); 1413 List<Component> propertyReplacerComponents = getPropertyReplacerComponents(); 1414 if (propertyReplacerComponents != null) { 1415 for (Component replacerComponent : propertyReplacerComponents) { 1416 replacerComponent.pushObjectToContext(objectName, object); 1417 } 1418 } 1419 } 1420 1421 /** 1422 * {@inheritDoc} 1423 */ 1424 @Override 1425 public void pushAllToContext(Map<String, Object> objects) { 1426 checkMutable(true); 1427 if (objects == null || objects.isEmpty()) { 1428 return; 1429 } 1430 1431 if (context == Collections.EMPTY_MAP && isMutable(true)) { 1432 context = new HashMap<String, Object>(); 1433 } 1434 1435 context.putAll(objects); 1436 1437 List<Component> propertyReplacerComponents = getPropertyReplacerComponents(); 1438 if (propertyReplacerComponents != null) { 1439 for (Component replacerComponent : propertyReplacerComponents) { 1440 replacerComponent.pushAllToContext(objects); 1441 } 1442 } 1443 } 1444 1445 /** 1446 * {@inheritDoc} 1447 */ 1448 @Override 1449 @BeanTagAttribute 1450 public List<PropertyReplacer> getPropertyReplacers() { 1451 return this.propertyReplacers; 1452 } 1453 1454 /** 1455 * {@inheritDoc} 1456 */ 1457 @Override 1458 public void setPropertyReplacers(List<PropertyReplacer> propertyReplacers) { 1459 checkMutable(true); 1460 this.propertyReplacers = 1461 propertyReplacers == null ? Collections.<PropertyReplacer>emptyList() : propertyReplacers; 1462 } 1463 1464 /** 1465 * {@inheritDoc} 1466 */ 1467 @Override 1468 @BeanTagAttribute 1469 public int getOrder() { 1470 return this.order; 1471 } 1472 1473 /** 1474 * Setter for the component's order 1475 */ 1476 public void setOrder(int order) { 1477 checkMutable(true); 1478 this.order = order; 1479 } 1480 1481 /** 1482 * {@inheritDoc} 1483 */ 1484 @Override 1485 @BeanTagAttribute(type = BeanTagAttribute.AttributeType.DIRECTORBYTYPE) 1486 public Tooltip getToolTip() { 1487 return toolTip; 1488 } 1489 1490 /** 1491 * {@inheritDoc} 1492 */ 1493 @Override 1494 public void setToolTip(Tooltip toolTip) { 1495 checkMutable(true); 1496 this.toolTip = toolTip; 1497 } 1498 1499 /** 1500 * {@inheritDoc} 1501 */ 1502 @Override 1503 public String getEventHandlerScript() { 1504 StringBuilder sb = new StringBuilder(); 1505 1506 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "load", getOnLoadScript())); 1507 1508 // special handling for ready since it needs to bind to the document 1509 if (StringUtils.isNotBlank(getOnDocumentReadyScript())) { 1510 sb.append("jQuery(document).ready(function(e) {"); 1511 sb.append(getOnDocumentReadyScript()); 1512 sb.append("});"); 1513 } 1514 1515 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "unload", getOnUnloadScript())); 1516 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "blur", getOnBlurScript())); 1517 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "change", getOnChangeScript())); 1518 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "click", getOnClickScript())); 1519 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "dblclick", getOnDblClickScript())); 1520 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "focus", getOnFocusScript())); 1521 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "input", getOnInputScript())); 1522 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "keypress", getOnKeyPressScript())); 1523 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "keyup", getOnKeyUpScript())); 1524 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "keydown", getOnKeyDownScript())); 1525 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "mouseover", getOnMouseOverScript())); 1526 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "mouseout", getOnMouseOutScript())); 1527 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "mouseup", getOnMouseUpScript())); 1528 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "mousedown", getOnMouseDownScript())); 1529 sb.append(ScriptUtils.buildEventHandlerScript(getId(), "mousemove", getOnMouseMoveScript())); 1530 1531 return sb.toString(); 1532 } 1533 1534 /** 1535 * {@inheritDoc} 1536 */ 1537 @Override 1538 @BeanTagAttribute 1539 public String getOnLoadScript() { 1540 return onLoadScript; 1541 } 1542 1543 /** 1544 * @see ScriptEventSupport#setOnLoadScript(java.lang.String) 1545 */ 1546 public void setOnLoadScript(String onLoadScript) { 1547 checkMutable(true); 1548 this.onLoadScript = onLoadScript; 1549 } 1550 1551 /** 1552 * {@inheritDoc} 1553 */ 1554 @Override 1555 @BeanTagAttribute 1556 public String getOnDocumentReadyScript() { 1557 return this.onDocumentReadyScript; 1558 } 1559 1560 /** 1561 * @see ScriptEventSupport#setOnDocumentReadyScript(java.lang.String) 1562 */ 1563 public void setOnDocumentReadyScript(String onDocumentReadyScript) { 1564 checkMutable(true); 1565 this.onDocumentReadyScript = onDocumentReadyScript; 1566 } 1567 1568 /** 1569 * {@inheritDoc} 1570 */ 1571 @Override 1572 @BeanTagAttribute 1573 public String getOnUnloadScript() { 1574 return onUnloadScript; 1575 } 1576 1577 /** 1578 * @see ScriptEventSupport#setOnUnloadScript(java.lang.String) 1579 */ 1580 @Override 1581 public void setOnUnloadScript(String onUnloadScript) { 1582 checkMutable(true); 1583 this.onUnloadScript = onUnloadScript; 1584 } 1585 1586 /** 1587 * {@inheritDoc} 1588 */ 1589 @Override 1590 @BeanTagAttribute 1591 public String getOnCloseScript() { 1592 return onCloseScript; 1593 } 1594 1595 /** 1596 * @see ScriptEventSupport#setOnCloseScript(java.lang.String) 1597 */ 1598 @Override 1599 public void setOnCloseScript(String onCloseScript) { 1600 checkMutable(true); 1601 this.onCloseScript = onCloseScript; 1602 } 1603 1604 /** 1605 * {@inheritDoc} 1606 */ 1607 @Override 1608 @BeanTagAttribute 1609 public String getOnBlurScript() { 1610 return onBlurScript; 1611 } 1612 1613 /** 1614 * @see ScriptEventSupport#setOnBlurScript(java.lang.String) 1615 */ 1616 @Override 1617 public void setOnBlurScript(String onBlurScript) { 1618 checkMutable(true); 1619 this.onBlurScript = onBlurScript; 1620 } 1621 1622 /** 1623 * {@inheritDoc} 1624 */ 1625 @Override 1626 @BeanTagAttribute 1627 public String getOnChangeScript() { 1628 return onChangeScript; 1629 } 1630 1631 /** 1632 * @see ScriptEventSupport#setOnChangeScript(java.lang.String) 1633 */ 1634 @Override 1635 public void setOnChangeScript(String onChangeScript) { 1636 checkMutable(true); 1637 this.onChangeScript = onChangeScript; 1638 } 1639 1640 /** 1641 * {@inheritDoc} 1642 */ 1643 @Override 1644 @BeanTagAttribute 1645 public String getOnClickScript() { 1646 return onClickScript; 1647 } 1648 1649 /** 1650 * @see ScriptEventSupport#setOnClickScript(java.lang.String) 1651 */ 1652 @Override 1653 public void setOnClickScript(String onClickScript) { 1654 checkMutable(true); 1655 this.onClickScript = onClickScript; 1656 } 1657 1658 /** 1659 * {@inheritDoc} 1660 */ 1661 @Override 1662 @BeanTagAttribute 1663 public String getOnDblClickScript() { 1664 return onDblClickScript; 1665 } 1666 1667 /** 1668 * @see ScriptEventSupport#setOnDblClickScript(java.lang.String) 1669 */ 1670 @Override 1671 public void setOnDblClickScript(String onDblClickScript) { 1672 checkMutable(true); 1673 this.onDblClickScript = onDblClickScript; 1674 } 1675 1676 /** 1677 * {@inheritDoc} 1678 */ 1679 @Override 1680 @BeanTagAttribute 1681 public String getOnFocusScript() { 1682 return onFocusScript; 1683 } 1684 1685 /** 1686 * @see ScriptEventSupport#setOnFocusScript(java.lang.String) 1687 */ 1688 @Override 1689 public void setOnFocusScript(String onFocusScript) { 1690 checkMutable(true); 1691 this.onFocusScript = onFocusScript; 1692 } 1693 1694 /** 1695 * {@inheritDoc} 1696 */ 1697 @Override 1698 @BeanTagAttribute 1699 public String getOnSubmitScript() { 1700 return onSubmitScript; 1701 } 1702 1703 /** 1704 * @see ScriptEventSupport#setOnSubmitScript(java.lang.String) 1705 */ 1706 @Override 1707 public void setOnSubmitScript(String onSubmitScript) { 1708 checkMutable(true); 1709 this.onSubmitScript = onSubmitScript; 1710 } 1711 1712 /** 1713 * {@inheritDoc} 1714 */ 1715 @Override 1716 @BeanTagAttribute 1717 public String getOnInputScript() { 1718 return onInputScript; 1719 } 1720 1721 /** 1722 * @see ScriptEventSupport#setOnInputScript(java.lang.String) 1723 */ 1724 @Override 1725 public void setOnInputScript(String onInputScript) { 1726 checkMutable(true); 1727 this.onInputScript = onInputScript; 1728 } 1729 1730 /** 1731 * {@inheritDoc} 1732 */ 1733 @Override 1734 @BeanTagAttribute 1735 public String getOnKeyPressScript() { 1736 return onKeyPressScript; 1737 } 1738 1739 /** 1740 * @see ScriptEventSupport#setOnKeyPressScript(java.lang.String) 1741 */ 1742 @Override 1743 public void setOnKeyPressScript(String onKeyPressScript) { 1744 checkMutable(true); 1745 this.onKeyPressScript = onKeyPressScript; 1746 } 1747 1748 /** 1749 * {@inheritDoc} 1750 */ 1751 @Override 1752 @BeanTagAttribute 1753 public String getOnKeyUpScript() { 1754 return onKeyUpScript; 1755 } 1756 1757 /** 1758 * @see ScriptEventSupport#setOnKeyUpScript(java.lang.String) 1759 */ 1760 @Override 1761 public void setOnKeyUpScript(String onKeyUpScript) { 1762 checkMutable(true); 1763 this.onKeyUpScript = onKeyUpScript; 1764 } 1765 1766 /** 1767 * {@inheritDoc} 1768 */ 1769 @Override 1770 @BeanTagAttribute 1771 public String getOnKeyDownScript() { 1772 return onKeyDownScript; 1773 } 1774 1775 /** 1776 * @see ScriptEventSupport#setOnKeyDownScript(java.lang.String) 1777 */ 1778 @Override 1779 public void setOnKeyDownScript(String onKeyDownScript) { 1780 checkMutable(true); 1781 this.onKeyDownScript = onKeyDownScript; 1782 } 1783 1784 /** 1785 * {@inheritDoc} 1786 */ 1787 @Override 1788 @BeanTagAttribute 1789 public String getOnMouseOverScript() { 1790 return onMouseOverScript; 1791 } 1792 1793 /** 1794 * @see ScriptEventSupport#setOnMouseOverScript(java.lang.String) 1795 */ 1796 @Override 1797 public void setOnMouseOverScript(String onMouseOverScript) { 1798 checkMutable(true); 1799 this.onMouseOverScript = onMouseOverScript; 1800 } 1801 1802 /** 1803 * {@inheritDoc} 1804 */ 1805 @Override 1806 @BeanTagAttribute 1807 public String getOnMouseOutScript() { 1808 return onMouseOutScript; 1809 } 1810 1811 /** 1812 * @see ScriptEventSupport#setOnMouseOutScript(java.lang.String) 1813 */ 1814 @Override 1815 public void setOnMouseOutScript(String onMouseOutScript) { 1816 checkMutable(true); 1817 this.onMouseOutScript = onMouseOutScript; 1818 } 1819 1820 /** 1821 * {@inheritDoc} 1822 */ 1823 @Override 1824 @BeanTagAttribute 1825 public String getOnMouseUpScript() { 1826 return onMouseUpScript; 1827 } 1828 1829 /** 1830 * @see ScriptEventSupport#setOnMouseUpScript(java.lang.String) 1831 */ 1832 @Override 1833 public void setOnMouseUpScript(String onMouseUpScript) { 1834 checkMutable(true); 1835 this.onMouseUpScript = onMouseUpScript; 1836 } 1837 1838 /** 1839 * {@inheritDoc} 1840 */ 1841 @Override 1842 @BeanTagAttribute 1843 public String getOnMouseDownScript() { 1844 return onMouseDownScript; 1845 } 1846 1847 /** 1848 * @see ScriptEventSupport#setOnMouseDownScript(java.lang.String) 1849 */ 1850 @Override 1851 public void setOnMouseDownScript(String onMouseDownScript) { 1852 checkMutable(true); 1853 this.onMouseDownScript = onMouseDownScript; 1854 } 1855 1856 /** 1857 * {@inheritDoc} 1858 */ 1859 @Override 1860 @BeanTagAttribute 1861 public String getOnMouseMoveScript() { 1862 return onMouseMoveScript; 1863 } 1864 1865 /** 1866 * @see ScriptEventSupport#setOnMouseMoveScript(java.lang.String) 1867 */ 1868 @Override 1869 public void setOnMouseMoveScript(String onMouseMoveScript) { 1870 checkMutable(true); 1871 this.onMouseMoveScript = onMouseMoveScript; 1872 } 1873 1874 /** 1875 * {@inheritDoc} 1876 */ 1877 @Override 1878 @BeanTagAttribute 1879 public Map<String, String> getTemplateOptions() { 1880 if (templateOptions == Collections.EMPTY_MAP && isMutable(true)) { 1881 templateOptions = new HashMap<String, String>(); 1882 } 1883 1884 return templateOptions; 1885 } 1886 1887 /** 1888 * {@inheritDoc} 1889 */ 1890 @Override 1891 public void setTemplateOptions(Map<String, String> templateOptions) { 1892 checkMutable(true); 1893 if (templateOptions == null) { 1894 this.templateOptions = Collections.emptyMap(); 1895 } else { 1896 this.templateOptions = templateOptions; 1897 } 1898 } 1899 1900 /** 1901 * {@inheritDoc} 1902 */ 1903 @Override 1904 @BeanTagAttribute 1905 public String getTemplateOptionsJSString() { 1906 if (templateOptionsJSString != null) { 1907 return templateOptionsJSString; 1908 } 1909 1910 if (templateOptions == null) { 1911 return "{}"; 1912 } 1913 1914 StringBuilder sb = new StringBuilder(); 1915 sb.append("{"); 1916 1917 for (Entry<String, String> option : templateOptions.entrySet()) { 1918 1919 if (sb.length() > 1) { 1920 sb.append(","); 1921 } 1922 1923 sb.append(option.getKey()); 1924 sb.append(":"); 1925 1926 sb.append(ScriptUtils.convertToJsValue(option.getValue())); 1927 } 1928 1929 sb.append("}"); 1930 1931 return sb.toString(); 1932 } 1933 1934 /** 1935 * {@inheritDoc} 1936 */ 1937 @Override 1938 public void setTemplateOptionsJSString(String templateOptionsJSString) { 1939 checkMutable(true); 1940 this.templateOptionsJSString = templateOptionsJSString; 1941 } 1942 1943 /** 1944 * When set if the condition is satisfied, the component will be displayed. The component MUST 1945 * BE a container or field type. progressiveRender is defined in a limited Spring EL syntax. 1946 * Only valid form property names, and, or, logical comparison operators (non-arithmetic), 1947 * #listContains, #emptyList, matches clause are allowed. String and regex values must use 1948 * single quotes ('), booleans must be either true or false, numbers must be a valid double, 1949 * either negative or positive. 1950 * 1951 * <p> 1952 * DO NOT use progressiveRender and a conditional refresh statement on the same component unless 1953 * it is known that the component will always be visible in all cases when a conditional refresh 1954 * happens (ie conditional refresh has progressiveRender's condition anded with its own 1955 * condition). 1956 * </p> 1957 * 1958 * <p> 1959 * <b>If a component should be refreshed every time it is shown, use the 1960 * progressiveRenderAndRefresh option with this property instead.</b> 1961 * </p> 1962 * 1963 * @return progressiveRender expression 1964 */ 1965 @BeanTagAttribute 1966 public String getProgressiveRender() { 1967 return this.progressiveRender; 1968 } 1969 1970 /** 1971 * @param progressiveRender the progressiveRender to set. 1972 */ 1973 public void setProgressiveRender(String progressiveRender) { 1974 checkMutable(true); 1975 this.progressiveRender = progressiveRender; 1976 } 1977 1978 /** 1979 * When set if the condition is satisfied, the component will be refreshed. 1980 * 1981 * <p> 1982 * The component MUST BE a container or field type. conditionalRefresh is defined in a limited 1983 * Spring EL syntax. Only valid form property names, and, or, logical comparison operators 1984 * (non-arithmetic), #listContains, #emptyList, and the matches clause are allowed. String and 1985 * regex values must use single quotes ('), booleans must be either true or false, numbers must 1986 * be a valid double either negative or positive. 1987 * 1988 * <p> 1989 * DO NOT use progressiveRender and conditionalRefresh on the same component unless it is known 1990 * that the component will always be visible in all cases when a conditionalRefresh happens (ie 1991 * conditionalRefresh has progressiveRender's condition anded with its own condition). <b>If a 1992 * component should be refreshed every time it is shown, use the progressiveRenderAndRefresh 1993 * option with this property instead.</b> 1994 * </p> 1995 * 1996 * @return the conditionalRefresh 1997 */ 1998 @BeanTagAttribute 1999 public String getConditionalRefresh() { 2000 return this.conditionalRefresh; 2001 } 2002 2003 /** 2004 * Set the conditional refresh condition 2005 * 2006 * @param conditionalRefresh the conditionalRefresh to set 2007 */ 2008 public void setConditionalRefresh(String conditionalRefresh) { 2009 checkMutable(true); 2010 this.conditionalRefresh = conditionalRefresh; 2011 } 2012 2013 /** 2014 * Control names used to control progressive disclosure, set internally cannot be set. 2015 * 2016 * @return the progressiveDisclosureControlNames 2017 */ 2018 public List<String> getProgressiveDisclosureControlNames() { 2019 return this.progressiveDisclosureControlNames; 2020 } 2021 2022 /** 2023 * The condition to show this component progressively converted to a js expression, set 2024 * internally cannot be set. 2025 * 2026 * @return the progressiveDisclosureConditionJs 2027 */ 2028 public String getProgressiveDisclosureConditionJs() { 2029 return this.progressiveDisclosureConditionJs; 2030 } 2031 2032 /** 2033 * The condition to refresh this component converted to a js expression, set internally cannot 2034 * be set. 2035 * 2036 * @return the conditionalRefreshConditionJs 2037 */ 2038 public String getConditionalRefreshConditionJs() { 2039 return this.conditionalRefreshConditionJs; 2040 } 2041 2042 /** 2043 * Control names used to control conditional refresh, set internally cannot be set. 2044 * 2045 * @return the conditionalRefreshControlNames 2046 */ 2047 public List<String> getConditionalRefreshControlNames() { 2048 return this.conditionalRefreshControlNames; 2049 } 2050 2051 /** 2052 * When progressiveRenderViaAJAX is true, this component will be retrieved from the server when 2053 * it first satisfies its progressive render condition. 2054 * 2055 * <p> 2056 * After the first retrieval, it is hidden/shown in the html by the js when its progressive 2057 * condition result changes. <b>By default, this is false, so components with progressive render 2058 * capabilities will always be already within the client html and toggled to be hidden or 2059 * visible.</b> 2060 * </p> 2061 * 2062 * @return the progressiveRenderViaAJAX 2063 */ 2064 @BeanTagAttribute 2065 public boolean isProgressiveRenderViaAJAX() { 2066 return this.progressiveRenderViaAJAX; 2067 } 2068 2069 /** 2070 * @param progressiveRenderViaAJAX the progressiveRenderViaAJAX to set. 2071 */ 2072 public void setProgressiveRenderViaAJAX(boolean progressiveRenderViaAJAX) { 2073 checkMutable(true); 2074 this.progressiveRenderViaAJAX = progressiveRenderViaAJAX; 2075 } 2076 2077 /** 2078 * If true, when the progressiveRender condition is satisfied, the component will always be 2079 * retrieved from the server and shown(as opposed to being stored on the client, but hidden, 2080 * after the first retrieval as is the case with the progressiveRenderViaAJAX option). 2081 * 2082 * <p> 2083 * <b>By default, this is false, so components with progressive render capabilities will always 2084 * be already within the client html and toggled to be hidden or visible.</b> 2085 * </p> 2086 * 2087 * @return the progressiveRenderAndRefresh 2088 */ 2089 @BeanTagAttribute 2090 public boolean isProgressiveRenderAndRefresh() { 2091 return this.progressiveRenderAndRefresh; 2092 } 2093 2094 /** 2095 * Set the progressive render and refresh option. 2096 * 2097 * @param progressiveRenderAndRefresh the progressiveRenderAndRefresh to set. 2098 */ 2099 public void setProgressiveRenderAndRefresh(boolean progressiveRenderAndRefresh) { 2100 checkMutable(true); 2101 this.progressiveRenderAndRefresh = progressiveRenderAndRefresh; 2102 } 2103 2104 /** 2105 * {@inheritDoc} 2106 */ 2107 @Override 2108 @BeanTagAttribute 2109 public List<String> getRefreshWhenChangedPropertyNames() { 2110 return this.refreshWhenChangedPropertyNames; 2111 } 2112 2113 /** 2114 * {@inheritDoc} 2115 */ 2116 @Override 2117 public void setRefreshWhenChangedPropertyNames(List<String> refreshWhenChangedPropertyNames) { 2118 checkMutable(true); 2119 this.refreshWhenChangedPropertyNames = 2120 refreshWhenChangedPropertyNames == null ? Collections.<String>emptyList() : 2121 Collections.<String>unmodifiableList(refreshWhenChangedPropertyNames); 2122 } 2123 2124 /** 2125 * {@inheritDoc} 2126 */ 2127 @Override 2128 @BeanTagAttribute(name = "additionalComponentsToRefresh", type = BeanTagAttribute.AttributeType.LISTVALUE) 2129 public List<String> getAdditionalComponentsToRefresh() { 2130 return additionalComponentsToRefresh; 2131 } 2132 2133 /** 2134 * {@inheritDoc} 2135 */ 2136 @Override 2137 public void setAdditionalComponentsToRefresh(List<String> additionalComponentsToRefresh) { 2138 checkMutable(true); 2139 this.additionalComponentsToRefresh = additionalComponentsToRefresh == null ? Collections.<String>emptyList() : 2140 Collections.<String>unmodifiableList(additionalComponentsToRefresh); 2141 this.additionalComponentsToRefreshJs = null; 2142 } 2143 2144 /** 2145 * {@inheritDoc} 2146 */ 2147 @Override 2148 public String getAdditionalComponentsToRefreshJs() { 2149 if (additionalComponentsToRefreshJs == null && additionalComponentsToRefresh != null 2150 && !additionalComponentsToRefresh.isEmpty()) { 2151 additionalComponentsToRefreshJs = ScriptUtils.convertStringListToJsArray( 2152 this.getAdditionalComponentsToRefresh()); 2153 } 2154 2155 return additionalComponentsToRefreshJs; 2156 } 2157 2158 /** 2159 * {@inheritDoc} 2160 */ 2161 @Override 2162 public boolean isRefreshedByAction() { 2163 return refreshedByAction; 2164 } 2165 2166 /** 2167 * {@inheritDoc} 2168 */ 2169 @Override 2170 public void setRefreshedByAction(boolean refreshedByAction) { 2171 checkMutable(true); 2172 this.refreshedByAction = refreshedByAction; 2173 } 2174 2175 /** 2176 * {@inheritDoc} 2177 */ 2178 @Override 2179 public boolean isDisclosedByAction() { 2180 return disclosedByAction; 2181 } 2182 2183 /** 2184 * {@inheritDoc} 2185 */ 2186 @Override 2187 public void setDisclosedByAction(boolean disclosedByAction) { 2188 checkMutable(true); 2189 this.disclosedByAction = disclosedByAction; 2190 } 2191 2192 /** 2193 * Time in seconds that the component will be automatically refreshed 2194 * 2195 * <p> 2196 * This will invoke the refresh process just like the conditionalRefresh and 2197 * refreshWhenChangedPropertyNames. When using this property methodToCallOnRefresh and id should 2198 * also be specified 2199 * </p> 2200 * 2201 * @return refreshTimer 2202 */ 2203 @BeanTagAttribute 2204 public int getRefreshTimer() { 2205 return refreshTimer; 2206 } 2207 2208 /** 2209 * Setter for refreshTimer 2210 */ 2211 public void setRefreshTimer(int refreshTimer) { 2212 checkMutable(true); 2213 this.refreshTimer = refreshTimer; 2214 } 2215 2216 /** 2217 * {@inheritDoc} 2218 */ 2219 @Override 2220 @BeanTagAttribute 2221 public boolean isResetDataOnRefresh() { 2222 return resetDataOnRefresh; 2223 } 2224 2225 /** 2226 * {@inheritDoc} 2227 */ 2228 @Override 2229 public void setResetDataOnRefresh(boolean resetDataOnRefresh) { 2230 checkMutable(true); 2231 this.resetDataOnRefresh = resetDataOnRefresh; 2232 } 2233 2234 /** 2235 * Name of a method on the controller that should be invoked as part of the component refresh 2236 * and disclosure process 2237 * 2238 * <p> 2239 * During the component refresh or disclosure process it might be necessary to perform other 2240 * operations, such as preparing data or executing a business process. This allows the 2241 * configuration of a method on the underlying controller that should be called for the 2242 * component refresh action. In this method, the necessary logic can be performed and then the 2243 * base component update method invoked to carry out the component refresh. 2244 * </p> 2245 * 2246 * <p> 2247 * Controller method to invoke must accept the form, binding result, request, and response 2248 * arguments 2249 * </p> 2250 * 2251 * @return valid controller method name 2252 */ 2253 @BeanTagAttribute 2254 public String getMethodToCallOnRefresh() { 2255 return methodToCallOnRefresh; 2256 } 2257 2258 /** 2259 * Setter for the controller method to call for a refresh or disclosure action on this component 2260 */ 2261 public void setMethodToCallOnRefresh(String methodToCallOnRefresh) { 2262 checkMutable(true); 2263 this.methodToCallOnRefresh = methodToCallOnRefresh; 2264 } 2265 2266 /** 2267 * {@inheritDoc} 2268 */ 2269 @BeanTagAttribute 2270 public List<String> getFieldsToSendOnRefresh() { 2271 return fieldsToSendOnRefresh; 2272 } 2273 2274 /** 2275 * {@inheritDoc} 2276 */ 2277 public void setFieldsToSendOnRefresh(List<String> fieldsToSendOnRefresh) { 2278 this.fieldsToSendOnRefresh = fieldsToSendOnRefresh; 2279 } 2280 2281 /** 2282 * Flag indicating that this component and its nested components must be skipped when keyboard 2283 * tabbing. 2284 * 2285 * @return the skipInTabOrder flag 2286 */ 2287 @BeanTagAttribute 2288 public boolean isSkipInTabOrder() { 2289 return skipInTabOrder; 2290 } 2291 2292 /** 2293 * @see ComponentBase#isSkipInTabOrder() 2294 */ 2295 public void setSkipInTabOrder(boolean skipInTabOrder) { 2296 checkMutable(true); 2297 this.skipInTabOrder = skipInTabOrder; 2298 } 2299 2300 /** 2301 * {@inheritDoc} 2302 */ 2303 @Override 2304 @BeanTagAttribute 2305 public Map<String, String> getDataAttributes() { 2306 if (dataAttributes == Collections.EMPTY_MAP) { 2307 dataAttributes = new HashMap<String, String>(); 2308 } 2309 2310 return dataAttributes; 2311 } 2312 2313 /** 2314 * {@inheritDoc} 2315 */ 2316 @Override 2317 public void setDataAttributes(Map<String, String> dataAttributes) { 2318 checkMutable(true); 2319 if (dataAttributes == null) { 2320 this.dataAttributes = Collections.emptyMap(); 2321 } else { 2322 this.dataAttributes = dataAttributes; 2323 } 2324 } 2325 2326 /** 2327 * {@inheritDoc} 2328 */ 2329 @Override 2330 @BeanTagAttribute 2331 public Map<String, String> getScriptDataAttributes() { 2332 if (scriptDataAttributes == Collections.EMPTY_MAP) { 2333 scriptDataAttributes = new HashMap<String, String>(); 2334 } 2335 2336 return scriptDataAttributes; 2337 } 2338 2339 /** 2340 * {@inheritDoc} 2341 */ 2342 @Override 2343 public void setScriptDataAttributes(Map<String, String> scriptDataAttributes) { 2344 this.scriptDataAttributes = scriptDataAttributes; 2345 } 2346 2347 /** 2348 * {@inheritDoc} 2349 */ 2350 @Override 2351 public void addDataAttribute(String key, String value) { 2352 checkMutable(true); 2353 2354 if (dataAttributes == Collections.EMPTY_MAP) { 2355 dataAttributes = new HashMap<String, String>(); 2356 } 2357 2358 dataAttributes.put(key, value); 2359 } 2360 2361 /** 2362 * {@inheritDoc} 2363 */ 2364 @Override 2365 public void addScriptDataAttribute(String key, String value) { 2366 checkMutable(true); 2367 2368 if (scriptDataAttributes == Collections.EMPTY_MAP) { 2369 scriptDataAttributes = new HashMap<String, String>(); 2370 } 2371 2372 scriptDataAttributes.put(key, value); 2373 } 2374 2375 /** 2376 * {@inheritDoc} 2377 */ 2378 @Override 2379 public String getSimpleDataAttributes() { 2380 String attributes = ""; 2381 2382 if (getDataAttributes() == null) { 2383 return attributes; 2384 } 2385 2386 for (Map.Entry<String, String> data : getDataAttributes().entrySet()) { 2387 if (data != null && data.getValue() != null) { 2388 attributes = attributes + " " + "data-" + data.getKey() + "=\"" + 2389 KRADUtils.convertToHTMLAttributeSafeString(data.getValue()) + "\""; 2390 } 2391 } 2392 2393 return attributes; 2394 } 2395 2396 @Override 2397 public String getScriptDataAttributesJs() { 2398 String script = ""; 2399 2400 if (getScriptDataAttributes() == null || getScriptDataAttributes().isEmpty()) { 2401 return script; 2402 } 2403 2404 String id = this.getId().replace(".", "\\\\."); 2405 String selector = "var dataComponent = jQuery('#" + id + "');"; 2406 script = ScriptUtils.appendScript(script, selector); 2407 2408 for (Map.Entry<String, String> data : getScriptDataAttributes().entrySet()) { 2409 if (data != null && data.getValue() != null) { 2410 script = ScriptUtils.appendScript(script, 2411 "dataComponent.data('" + data.getKey() + "'," + ScriptUtils.convertToJsValue(data.getValue()) 2412 + ");"); 2413 } 2414 } 2415 2416 return script; 2417 } 2418 2419 /** 2420 * {@inheritDoc} 2421 */ 2422 @Override 2423 @BeanTagAttribute 2424 public String getRole() { 2425 return role; 2426 } 2427 2428 /** 2429 * {@inheritDoc} 2430 */ 2431 public void setRole(String role) { 2432 this.role = role; 2433 } 2434 2435 /** 2436 * {@inheritDoc} 2437 */ 2438 @Override 2439 @BeanTagAttribute 2440 public Map<String, String> getAriaAttributes() { 2441 if (ariaAttributes == Collections.EMPTY_MAP) { 2442 ariaAttributes = new LifecycleAwareMap<String, String>(this); 2443 } 2444 2445 return ariaAttributes; 2446 } 2447 2448 /** 2449 * {@inheritDoc} 2450 */ 2451 @Override 2452 public void setAriaAttributes(Map<String, String> ariaAttributes) { 2453 checkMutable(true); 2454 if (ariaAttributes == null) { 2455 this.ariaAttributes = Collections.emptyMap(); 2456 } else { 2457 this.ariaAttributes = new LifecycleAwareMap<String, String>(this, ariaAttributes); 2458 } 2459 } 2460 2461 /** 2462 * {@inheritDoc} 2463 */ 2464 @Override 2465 public void addAriaAttribute(String key, String value) { 2466 checkMutable(true); 2467 2468 if (ariaAttributes == Collections.EMPTY_MAP) { 2469 ariaAttributes = new LifecycleAwareMap<String, String>(this); 2470 } 2471 2472 ariaAttributes.put(key, value); 2473 } 2474 2475 /** 2476 * {@inheritDoc} 2477 */ 2478 @Override 2479 public String getAriaAttributesAsString() { 2480 String attributes = ""; 2481 2482 if (getAriaAttributes() == null) { 2483 return attributes; 2484 } 2485 2486 for (Map.Entry<String, String> aria : getAriaAttributes().entrySet()) { 2487 if (aria != null && aria.getValue() != null) { 2488 attributes = attributes + " " + "aria-" + aria.getKey() + "=\"" + 2489 KRADUtils.convertToHTMLAttributeSafeString(aria.getValue()) + "\""; 2490 } 2491 } 2492 2493 return attributes; 2494 } 2495 2496 /** 2497 * {@inheritDoc} 2498 */ 2499 @BeanTagAttribute(name = "preContent", type = BeanTagAttribute.AttributeType.ANY) 2500 public String getPreRenderContent() { 2501 return preRenderContent; 2502 } 2503 2504 /** 2505 * {@inheritDoc} 2506 */ 2507 @Override 2508 public void setPreRenderContent(String preRenderContent) { 2509 checkMutable(true); 2510 this.preRenderContent = preRenderContent; 2511 } 2512 2513 /** 2514 * {@inheritDoc} 2515 */ 2516 @Override 2517 @BeanTagAttribute(name = "postContent", type = BeanTagAttribute.AttributeType.ANY) 2518 public String getPostRenderContent() { 2519 return postRenderContent; 2520 } 2521 2522 /** 2523 * {@inheritDoc} 2524 */ 2525 @Override 2526 public void setPostRenderContent(String postRenderContent) { 2527 checkMutable(true); 2528 this.postRenderContent = postRenderContent; 2529 } 2530 2531 /** 2532 * {@inheritDoc} 2533 */ 2534 @Override 2535 public String getExcludeIf() { 2536 return this.excludeIf; 2537 } 2538 2539 /** 2540 * @see #getExcludeIf() 2541 */ 2542 public void setExcludeIf(String excludeIf) { 2543 this.excludeIf = excludeIf; 2544 } 2545 2546 /** 2547 * {@inheritDoc} 2548 */ 2549 @Override 2550 public String getExcludeUnless() { 2551 return this.excludeUnless; 2552 } 2553 2554 /** 2555 * @see #getExcludeIf() 2556 */ 2557 public void setExcludeUnless(String excludeUnless) { 2558 this.excludeUnless = excludeUnless; 2559 } 2560 2561 /** 2562 * {@inheritDoc} 2563 */ 2564 @Override 2565 public ComponentBase clone() throws CloneNotSupportedException { 2566 ComponentBase copy = (ComponentBase) super.clone(); 2567 2568 // Copy initialized status, but reset to created for others. 2569 // This allows prototypes to bypass repeating the initialized phase. 2570 if (UifConstants.ViewStatus.INITIALIZED.equals(viewStatus)) { 2571 copy.viewStatus = UifConstants.ViewStatus.INITIALIZED; 2572 } else { 2573 copy.viewStatus = UifConstants.ViewStatus.CREATED; 2574 } 2575 2576 return copy; 2577 } 2578 2579 /** 2580 * {@inheritDoc} 2581 */ 2582 @Override 2583 public void completeValidation(ValidationTrace tracer) { 2584 tracer.addBean(this); 2585 2586 // Check for invalid characters in the components id 2587 if (getId() != null) { 2588 if (getId().contains("'") || getId().contains("\"") || getId().contains("[]") || getId().contains(".") 2589 || getId().contains("#")) { 2590 String currentValues[] = {"id = " + getId()}; 2591 tracer.createError("Id contains invalid characters", currentValues); 2592 } 2593 } 2594 2595 if (tracer.getValidationStage() == ValidationTrace.BUILD) { 2596 // Check for a render presence if the component is set to render 2597 if ((isProgressiveRenderViaAJAX() || isProgressiveRenderAndRefresh()) && (getProgressiveRender() == null)) { 2598 String currentValues[] = {"progressiveRenderViaAJAX = " + isProgressiveRenderViaAJAX(), 2599 "progressiveRenderAndRefresh = " + isProgressiveRenderAndRefresh(), 2600 "progressiveRender = " + getProgressiveRender()}; 2601 tracer.createError( 2602 "ProgressiveRender must be set if progressiveRenderViaAJAX or progressiveRenderAndRefresh are true", 2603 currentValues); 2604 } 2605 } 2606 2607 // Check for rendered html if the component is set to self render 2608 if (isSelfRendered() && getRenderedHtmlOutput() == null) { 2609 String currentValues[] = 2610 {"selfRendered = " + isSelfRendered(), "renderedHtmlOutput = " + getRenderedHtmlOutput()}; 2611 tracer.createError("RenderedHtmlOutput must be set if selfRendered is true", currentValues); 2612 } 2613 2614 // Check to prevent over writing of session persistence status 2615 if (isDisableSessionPersistence() && isForceSessionPersistence()) { 2616 String currentValues[] = {"disableSessionPersistence = " + isDisableSessionPersistence(), 2617 "forceSessionPersistence = " + isForceSessionPersistence()}; 2618 tracer.createWarning("DisableSessionPersistence and forceSessionPersistence cannot be both true", 2619 currentValues); 2620 } 2621 2622 // Check for un-executable data resets when no refresh option is set 2623 if (getMethodToCallOnRefresh() != null || isResetDataOnRefresh()) { 2624 if (!isProgressiveRenderAndRefresh() && !isRefreshedByAction() && !isProgressiveRenderViaAJAX() 2625 && !StringUtils.isNotEmpty(conditionalRefresh) && !(refreshTimer > 0)) { 2626 String currentValues[] = {"methodToCallONRefresh = " + getMethodToCallOnRefresh(), 2627 "resetDataONRefresh = " + isResetDataOnRefresh(), 2628 "progressiveRenderAndRefresh = " + isProgressiveRenderAndRefresh(), 2629 "refreshedByAction = " + isRefreshedByAction(), 2630 "progressiveRenderViaAJAX = " + isProgressiveRenderViaAJAX(), 2631 "conditionalRefresh = " + getConditionalRefresh(), "refreshTimer = " + getRefreshTimer()}; 2632 tracer.createWarning( 2633 "MethodToCallONRefresh and resetDataONRefresh should only be set when a trigger event is set", 2634 currentValues); 2635 } 2636 } 2637 2638 // Check to prevent complications with rendering and refreshing a component that is not always shown 2639 if (StringUtils.isNotEmpty(getProgressiveRender()) && StringUtils.isNotEmpty(conditionalRefresh)) { 2640 String currentValues[] = {"progressiveRender = " + getProgressiveRender(), 2641 "conditionalRefresh = " + getConditionalRefresh()}; 2642 tracer.createWarning("DO NOT use progressiveRender and conditionalRefresh on the same component unless " 2643 + "it is known that the component will always be visible in all cases when a conditionalRefresh " 2644 + "happens (ie conditionalRefresh has progressiveRender's condition anded with its own condition). " 2645 + "If a component should be refreshed every time it is shown, use the progressiveRenderAndRefresh " 2646 + "option with this property instead.", currentValues); 2647 } 2648 2649 // Check for valid Spring EL format for progressiveRender 2650 if (!Validator.validateSpringEL(getProgressiveRender())) { 2651 String currentValues[] = {"progressiveRender =" + getProgressiveRender()}; 2652 tracer.createError("ProgressiveRender must follow the Spring EL @{} format", currentValues); 2653 } 2654 2655 // Check for valid Spring EL format for conditionalRefresh 2656 if (!Validator.validateSpringEL(getConditionalRefresh())) { 2657 String currentValues[] = {"conditionalRefresh =" + getConditionalRefresh()}; 2658 tracer.createError("conditionalRefresh must follow the Spring EL @{} format", currentValues); 2659 } 2660 } 2661 2662 /** 2663 * @see org.kuali.rice.krad.uif.container.Field#isOmitFromFormPost() 2664 */ 2665 public boolean isOmitFromFormPost() { 2666 return omitFromFormPost; 2667 } 2668 2669 /** 2670 * @see #isOmitFromFormPost() 2671 */ 2672 public void setOmitFromFormPost(boolean omitFromFormPost) { 2673 this.omitFromFormPost = omitFromFormPost; 2674 } 2675}