001 /** 002 * Copyright 2005-2013 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.view; 017 018 import com.google.common.collect.Lists; 019 import org.apache.commons.lang.StringUtils; 020 import org.kuali.rice.core.api.mo.common.active.Inactivatable; 021 import org.kuali.rice.krad.datadictionary.AttributeDefinition; 022 import org.kuali.rice.krad.datadictionary.parse.BeanTag; 023 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute; 024 import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 025 import org.kuali.rice.krad.uif.UifConstants.ViewType; 026 import org.kuali.rice.krad.uif.UifPropertyPaths; 027 import org.kuali.rice.krad.uif.container.CollectionGroup; 028 import org.kuali.rice.krad.uif.container.Group; 029 import org.kuali.rice.krad.uif.component.Component; 030 import org.kuali.rice.krad.uif.component.RequestParameter; 031 import org.kuali.rice.krad.uif.control.Control; 032 import org.kuali.rice.krad.uif.control.TextAreaControl; 033 import org.kuali.rice.krad.uif.control.TextControl; 034 import org.kuali.rice.krad.uif.element.Action; 035 import org.kuali.rice.krad.uif.element.Message; 036 import org.kuali.rice.krad.uif.field.FieldGroup; 037 import org.kuali.rice.krad.uif.field.InputField; 038 import org.kuali.rice.krad.uif.field.LookupInputField; 039 import org.kuali.rice.krad.uif.util.ComponentFactory; 040 import org.kuali.rice.krad.uif.util.ComponentUtils; 041 import org.kuali.rice.krad.util.KRADConstants; 042 import org.kuali.rice.krad.web.form.LookupForm; 043 044 import java.util.ArrayList; 045 import java.util.Arrays; 046 import java.util.HashMap; 047 import java.util.List; 048 049 /** 050 * View type for lookups 051 * 052 * <p> 053 * Supports doing a search against a data object class or performing a more advanced query. The view 054 * type is primarily made up of two groups, the search (or criteria) group and the results group. Many 055 * options are supported on the view to enable/disable certain features, like what actions are available 056 * on the search results. 057 * </p> 058 * 059 * <p> 060 * Works in conjunction with <code>LookupableImpl</code> which customizes the view and carries out the 061 * business functionality 062 * </p> 063 * 064 * @author Kuali Rice Team (rice.collab@kuali.org) 065 */ 066 @BeanTag(name = "lookupView-bean", parent = "Uif-LookupView") 067 public class LookupView extends FormView { 068 private static final long serialVersionUID = 716926008488403616L; 069 070 private Class<?> dataObjectClassName; 071 072 private Group criteriaGroup; 073 private CollectionGroup resultsGroup; 074 075 private List<Component> criteriaFields; 076 private List<Component> resultFields; 077 private List<String> defaultSortAttributeNames; 078 079 protected boolean defaultSortAscending = true; 080 081 @RequestParameter 082 private boolean hideReturnLinks = false; 083 @RequestParameter 084 private boolean suppressActions = false; 085 @RequestParameter 086 private boolean showMaintenanceLinks = false; 087 @RequestParameter 088 private boolean multipleValuesSelect = false; 089 @RequestParameter 090 private boolean renderLookupCriteria = true; 091 @RequestParameter 092 private boolean renderSearchButtons = true; 093 @RequestParameter 094 private boolean renderHeader = true; 095 096 @RequestParameter 097 private String returnTarget; 098 099 @RequestParameter 100 private boolean returnByScript; 101 102 private boolean triggerOnChange; 103 104 private Integer resultSetLimit = null; 105 private Integer multipleValuesSelectResultSetLimit = null; 106 107 private String maintenanceUrlMapping; 108 109 private FieldGroup rangeFieldGroupPrototype; 110 111 private Message rangedToMessage; 112 113 private boolean autoAddActiveCriteria; 114 115 public LookupView() { 116 super(); 117 118 setViewTypeName(ViewType.LOOKUP); 119 setApplyDirtyCheck(false); 120 setTriggerOnChange(false); 121 setAutoAddActiveCriteria(true); 122 } 123 124 /** 125 * The following initialization is performed: 126 * 127 * <ul> 128 * <li>Set the abstractTypeClasses map for the lookup object path</li> 129 * </ul> 130 * 131 * @see org.kuali.rice.krad.uif.container.ContainerBase#performInitialization(org.kuali.rice.krad.uif.view.View, 132 * java.lang.Object) 133 */ 134 @Override 135 public void performInitialization(View view, Object model) { 136 137 boolean isInactivatableClass = Inactivatable.class.isAssignableFrom(dataObjectClassName); 138 139 if (autoAddActiveCriteria && isInactivatableClass) { 140 autoAddActiveCriteria(); 141 } 142 143 initializeGroups(); 144 145 // since we don't have these as prototypes need to assign ids here 146 view.assignComponentIds(getCriteriaGroup()); 147 view.assignComponentIds(getResultsGroup()); 148 149 if (getItems().isEmpty()) { 150 setItems(Arrays.asList(getCriteriaGroup(), getResultsGroup())); 151 } 152 153 super.performInitialization(view, model); 154 155 // if this is a multi-value lookup, don't show return column 156 if (multipleValuesSelect) { 157 hideReturnLinks = true; 158 } 159 160 getObjectPathToConcreteClassMapping().put(UifPropertyPaths.LOOKUP_CRITERIA, getDataObjectClassName()); 161 if (StringUtils.isNotBlank(getDefaultBindingObjectPath())) { 162 getObjectPathToConcreteClassMapping().put(getDefaultBindingObjectPath(), getDataObjectClassName()); 163 } 164 } 165 166 /** 167 * Adds the 'active' property criteria to the criteria fields if the BO is inactivatable 168 */ 169 private void autoAddActiveCriteria() { 170 boolean hasActiveCriteria = false; 171 172 for (Component field : getCriteriaFields()) { 173 if (((InputField)field).getPropertyName().equals("active")) { 174 hasActiveCriteria = true; 175 } 176 } 177 178 if (!hasActiveCriteria) { 179 AttributeDefinition attributeDefinition = KRADServiceLocatorWeb.getDataDictionaryService().getAttributeDefinition( 180 dataObjectClassName.getName(), "active"); 181 LookupInputField activeField = new LookupInputField(); 182 183 if (attributeDefinition == null) { 184 activeField = (LookupInputField)ComponentFactory.getNewComponentInstance("Uif-LookupActiveInputField"); 185 }else{ 186 activeField = (LookupInputField)ComponentFactory.getNewComponentInstance("Uif-LookupCriteriaInputField"); 187 activeField.setPropertyName("active"); 188 activeField.copyFromAttributeDefinition(this, attributeDefinition); 189 } 190 191 getCriteriaFields().add(activeField); 192 } 193 } 194 195 protected void initializeGroups() { 196 if (renderLookupCriteria && (getCriteriaGroup() != null) && (getCriteriaGroup().getItems().isEmpty())) { 197 getCriteriaGroup().setItems(getCriteriaFields()); 198 } 199 200 if (getResultsGroup() != null) { 201 if ((getResultsGroup().getItems().isEmpty()) && (getResultFields() != null)) { 202 getResultsGroup().setItems(getResultFields()); 203 } 204 if (getResultsGroup().getCollectionObjectClass() == null) { 205 getResultsGroup().setCollectionObjectClass(getDataObjectClassName()); 206 } 207 } 208 } 209 210 /** 211 * @see org.kuali.rice.krad.uif.container.ContainerBase#performApplyModel(View, Object, 212 * org.kuali.rice.krad.uif.component.Component) 213 */ 214 @Override 215 public void performApplyModel(View view, Object model, Component parent) { 216 LookupForm lookupForm = (LookupForm) model; 217 218 if (!renderSearchButtons) { 219 criteriaGroup.getFooter().setRender(false); 220 } 221 222 if (!renderLookupCriteria) { 223 criteriaGroup.setRender(false); 224 } 225 226 if (!renderHeader) { 227 getHeader().setRender(false); 228 } 229 230 setupLookupCriteriaFields(view, model); 231 232 // Get the search action button for trigger on change and trigger on enter 233 Group actionGroup = criteriaGroup.getFooter(); 234 Action searchButton = findSearchButton(actionGroup.getItems()); 235 236 // Only add trigger on script if an action with methodToCall search exists 237 if (searchButton != null) { 238 String searchButtonId = searchButton.getId(); 239 240 for (Component criteriaField : criteriaGroup.getItems()) { 241 addTriggerScripts(searchButtonId, criteriaField); 242 } 243 } 244 245 super.performApplyModel(view, model, parent); 246 } 247 248 /** 249 * @see org.kuali.rice.krad.uif.container.ContainerBase#performFinalize(org.kuali.rice.krad.uif.view.View, 250 * Object, org.kuali.rice.krad.uif.component.Component) 251 */ 252 @Override 253 public void performFinalize(View view, Object model, Component parent) { 254 super.performFinalize(view, model, parent); 255 256 // force session persistence of criteria fields so we can validate the search input 257 List<InputField> fields = ComponentUtils.getComponentsOfTypeDeep(criteriaGroup, InputField.class); 258 for (InputField field : fields) { 259 field.setForceSessionPersistence(true); 260 } 261 } 262 263 /** 264 * Adds an on change script to fields with the isTriggerOnChange set to true. Also prevents adds script to execute 265 * search on enter when focus is in a criteris field 266 * 267 * @param searchButtonId the id of the search button 268 * @param criteriaField that the script will be added to 269 */ 270 private void addTriggerScripts(String searchButtonId, Component criteriaField) { 271 if (criteriaField instanceof LookupInputField) { 272 273 criteriaField.setOnKeyPressScript("if(e.which == 13) { e.preventDefault();jQuery('#" + searchButtonId + "' ).click();}"); 274 275 if (isTriggerOnChange() || ((LookupInputField)criteriaField).isTriggerOnChange()) { 276 criteriaField.setOnChangeScript("jQuery('#" + searchButtonId + "' ).click();"); 277 } 278 } 279 } 280 281 /** 282 * Finds an Action with the search methodToCall from a list of Actions 283 * 284 * @param componentList list of components 285 * @return the Action component with methodToCall of search 286 */ 287 private Action findSearchButton(List<? extends Component> componentList) { 288 List<? extends Action> actionList = ComponentUtils.getComponentsOfType(componentList, Action.class); 289 for (Action action : actionList) { 290 String methodToCall = action.getMethodToCall(); 291 if (methodToCall != null && methodToCall.equals("search")) { 292 return action; 293 } 294 } 295 return null; 296 } 297 298 /** 299 * Helper method to do any lookup specific changes to the criteria fields 300 */ 301 private void setupLookupCriteriaFields(View view, Object model) { 302 HashMap<Integer, Component> dateRangeFieldMap = new HashMap<Integer, Component>(); 303 304 ExpressionEvaluator expressionEvaluator = 305 view.getViewHelperService().getExpressionEvaluator(); 306 307 int rangeIndex = 0; 308 for (Component criteriaField : criteriaGroup.getItems()) { 309 // Set the max length on the controls to allow for wildcards 310 Control control = ((InputField)criteriaField).getControl(); 311 if (control instanceof TextControl) { 312 ((TextControl) control).setMaxLength(null); 313 } else if (control instanceof TextAreaControl) { 314 ((TextAreaControl) control).setMaxLength(null); 315 } 316 317 if (((LookupInputField)criteriaField).isRanged()) { 318 // Create field group 319 FieldGroup rangeFieldGroup = ComponentUtils.copy(rangeFieldGroupPrototype, criteriaField.getId()); 320 rangeFieldGroup.setLabel(((LookupInputField)criteriaField).getLabel()); 321 322 // Evaluate and set the required property and reset the required message on the 'to' label 323 expressionEvaluator.evaluatePropertyExpression(view, criteriaField.getContext(), criteriaField, 324 "required", true); 325 rangeFieldGroup.setRequired(criteriaField.getRequired()); 326 ((LookupInputField) criteriaField).getFieldLabel().setRequiredMessage(new Message()); 327 328 // Evaluate and set the render property 329 expressionEvaluator.evaluatePropertyExpression(view, criteriaField.getContext(), criteriaField, 330 UifPropertyPaths.RENDER, true); 331 rangeFieldGroup.setRender(criteriaField.isRender()); 332 333 List<Component> fieldGroupItems = new ArrayList<Component>(); 334 335 // Create a new from date field 336 LookupInputField fromDate = (LookupInputField) ComponentUtils.copy(criteriaField, 337 KRADConstants.LOOKUP_DEFAULT_RANGE_SEARCH_LOWER_BOUND_LABEL); 338 fromDate.getBindingInfo().setBindingName( 339 KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX + fromDate.getPropertyName()); 340 fromDate.setPropertyName( 341 KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX + fromDate.getPropertyName()); 342 343 // Set the criteria fields labels 344 fromDate.setLabel(""); 345 fromDate.getFieldLabel().setRenderColon(false); 346 ((LookupInputField)criteriaField).getFieldLabel().setRender(false); 347 348 // Add the cirteria fields to the field group 349 fieldGroupItems.add(fromDate); 350 fieldGroupItems.add(rangedToMessage); 351 fieldGroupItems.add(criteriaField); 352 rangeFieldGroup.setItems(fieldGroupItems); 353 354 // Add fieldgroup to map with index as key 355 dateRangeFieldMap.put(rangeIndex, rangeFieldGroup); 356 } 357 358 rangeIndex++; 359 } 360 361 // Replace original fields with range fieldgroups 362 List<Component> itemList = (List<Component>)criteriaGroup.getItems(); 363 for (Integer index : dateRangeFieldMap.keySet()) { 364 itemList.set(index, dateRangeFieldMap.get(index)); 365 } 366 367 criteriaGroup.setItems(itemList); 368 } 369 370 /** 371 * @see org.kuali.rice.krad.uif.component.Component#getComponentPrototypes() 372 */ 373 @Override 374 public List<Component> getComponentPrototypes() { 375 List<Component> components = super.getComponentPrototypes(); 376 377 components.add(rangeFieldGroupPrototype); 378 components.add(rangedToMessage); 379 380 return components; 381 } 382 383 public void applyConditionalLogicForFieldDisplay() { 384 // TODO: work into view lifecycle 385 // LookupViewHelperService lookupViewHelperService = (LookupViewHelperService) getViewHelperService(); 386 // Set<String> readOnlyFields = lookupViewHelperService.getConditionallyReadOnlyPropertyNames(); 387 // Set<String> requiredFields = lookupViewHelperService.getConditionallyRequiredPropertyNames(); 388 // Set<String> hiddenFields = lookupViewHelperService.getConditionallyHiddenPropertyNames(); 389 // if ( (readOnlyFields != null && !readOnlyFields.isEmpty()) || 390 // (requiredFields != null && !requiredFields.isEmpty()) || 391 // (hiddenFields != null && !hiddenFields.isEmpty()) 392 // ) { 393 // for (Field field : getResultsGroup().getItems()) { 394 // if (InputField.class.isAssignableFrom(field.getClass())) { 395 // InputField attributeField = (InputField) field; 396 // if (readOnlyFields != null && readOnlyFields.contains(attributeField.getBindingInfo().getBindingName())) { 397 // attributeField.setReadOnly(true); 398 // } 399 // if (requiredFields != null && requiredFields.contains(attributeField.getBindingInfo().getBindingName())) { 400 // attributeField.setRequired(Boolean.TRUE); 401 // } 402 // if (hiddenFields != null && hiddenFields.contains(attributeField.getBindingInfo().getBindingName())) { 403 // attributeField.setControl(LookupInquiryUtils.generateCustomLookupControlFromExisting(HiddenControl.class, null)); 404 // } 405 // } 406 // } 407 // } 408 } 409 410 /** 411 * Class name for the object the lookup applies to 412 * 413 * <p> 414 * The object class name is used to pick up a dictionary entry which will 415 * feed the attribute field definitions and other configuration. In addition 416 * it is to configure the <code>Lookupable</code> which will carry out the 417 * lookup action 418 * </p> 419 * 420 * @return lookup data object class 421 */ 422 @BeanTagAttribute(name="dataObjectClassName") 423 public Class<?> getDataObjectClassName() { 424 return this.dataObjectClassName; 425 } 426 427 /** 428 * Setter for the object class name 429 * 430 * @param dataObjectClassName 431 */ 432 public void setDataObjectClassName(Class<?> dataObjectClassName) { 433 this.dataObjectClassName = dataObjectClassName; 434 } 435 436 /** 437 * @return the hideReturnLinks 438 */ 439 @BeanTagAttribute(name="hideReturnLinks") 440 public boolean isHideReturnLinks() { 441 return this.hideReturnLinks; 442 } 443 444 /** 445 * @param hideReturnLinks the hideReturnLinks to set 446 */ 447 public void setHideReturnLinks(boolean hideReturnLinks) { 448 this.hideReturnLinks = hideReturnLinks; 449 } 450 451 /** 452 * @return the suppressActions 453 */ 454 @BeanTagAttribute(name="isSuppressActions") 455 public boolean isSuppressActions() { 456 return this.suppressActions; 457 } 458 459 /** 460 * @param suppressActions the suppressActions to set 461 */ 462 public void setSuppressActions(boolean suppressActions) { 463 this.suppressActions = suppressActions; 464 } 465 466 /** 467 * @return the showMaintenanceLinks 468 */ 469 @BeanTagAttribute(name="showMaintenanceLinks") 470 public boolean isShowMaintenanceLinks() { 471 return this.showMaintenanceLinks; 472 } 473 474 /** 475 * @param showMaintenanceLinks the showMaintenanceLinks to set 476 */ 477 public void setShowMaintenanceLinks(boolean showMaintenanceLinks) { 478 this.showMaintenanceLinks = showMaintenanceLinks; 479 } 480 481 /** 482 * Indicates whether multiple values select should be enabled for the lookup 483 * 484 * <p> 485 * When set to true, the select field is enabled for the lookup results group that allows the user 486 * to select one or more rows for returning 487 * </p> 488 * 489 * @return true if multiple values should be enabled, false otherwise 490 */ 491 @BeanTagAttribute(name="multipleValueSelect") 492 public boolean isMultipleValuesSelect() { 493 return multipleValuesSelect; 494 } 495 496 /** 497 * Setter for the multiple values select indicator 498 * 499 * @param multipleValuesSelect 500 */ 501 public void setMultipleValuesSelect(boolean multipleValuesSelect) { 502 this.multipleValuesSelect = multipleValuesSelect; 503 } 504 505 @BeanTagAttribute(name="criteriaGroup",type = BeanTagAttribute.AttributeType.SINGLEBEAN) 506 public Group getCriteriaGroup() { 507 return this.criteriaGroup; 508 } 509 510 public void setCriteriaGroup(Group criteriaGroup) { 511 this.criteriaGroup = criteriaGroup; 512 } 513 514 @BeanTagAttribute(name="resultsGroup",type= BeanTagAttribute.AttributeType.SINGLEBEAN) 515 public CollectionGroup getResultsGroup() { 516 return this.resultsGroup; 517 } 518 519 public void setResultsGroup(CollectionGroup resultsGroup) { 520 this.resultsGroup = resultsGroup; 521 } 522 523 @BeanTagAttribute(name="criteriaFields",type= BeanTagAttribute.AttributeType.LISTBEAN) 524 public List<Component> getCriteriaFields() { 525 return this.criteriaFields; 526 } 527 528 public void setCriteriaFields(List<Component> criteriaFields) { 529 this.criteriaFields = criteriaFields; 530 } 531 532 @BeanTagAttribute(name="resultFields",type= BeanTagAttribute.AttributeType.LISTBEAN) 533 public List<Component> getResultFields() { 534 return this.resultFields; 535 } 536 537 public void setResultFields(List<Component> resultFields) { 538 this.resultFields = resultFields; 539 } 540 541 @BeanTagAttribute(name="defaultSortAttributeNames",type= BeanTagAttribute.AttributeType.LISTVALUE) 542 public List<String> getDefaultSortAttributeNames() { 543 return this.defaultSortAttributeNames; 544 } 545 546 public void setDefaultSortAttributeNames(List<String> defaultSortAttributeNames) { 547 this.defaultSortAttributeNames = defaultSortAttributeNames; 548 } 549 550 @BeanTagAttribute(name="defaultSortAscending") 551 public boolean isDefaultSortAscending() { 552 return this.defaultSortAscending; 553 } 554 555 public void setDefaultSortAscending(boolean defaultSortAscending) { 556 this.defaultSortAscending = defaultSortAscending; 557 } 558 559 /** 560 * Retrieves the maximum number of records that will be listed 561 * as a result of the lookup search 562 * 563 * @return Integer result set limit 564 */ 565 @BeanTagAttribute(name="resultSetLimit") 566 public Integer getResultSetLimit() { 567 return resultSetLimit; 568 } 569 570 /** 571 * Setter for the result list limit 572 * 573 * @param resultSetLimit Integer specifying limit 574 */ 575 public void setResultSetLimit(Integer resultSetLimit) { 576 this.resultSetLimit = resultSetLimit; 577 } 578 579 /** 580 * Indicates whether a result set limit has been specified for the 581 * view 582 * 583 * @return true if this instance has a result set limit 584 */ 585 public boolean hasResultSetLimit() { 586 return (resultSetLimit != null); 587 } 588 589 /** 590 * Retrieves the maximum number of records that will be listed 591 * as a result of the multiple values select lookup search 592 * 593 * @return multiple values select result set limit 594 */ 595 @BeanTagAttribute(name="multipleValuesSelectResultSetLimit") 596 public Integer getMultipleValuesSelectResultSetLimit() { 597 return multipleValuesSelectResultSetLimit; 598 } 599 600 /** 601 * Setter for the multiple values select result set limit 602 * 603 * @param multipleValuesSelectResultSetLimit Integer specifying limit 604 */ 605 public void setMultipleValuesSelectResultSetLimit(Integer multipleValuesSelectResultSetLimit) { 606 this.multipleValuesSelectResultSetLimit = multipleValuesSelectResultSetLimit; 607 } 608 609 /** 610 * Indicates whether a multiple values select result 611 * set limit has been specified for the view 612 * 613 * @return true if this instance has a multiple values select result set limit 614 */ 615 public boolean hasMultipleValuesSelectResultSetLimit() { 616 return (multipleValuesSelectResultSetLimit != null); 617 } 618 619 /** 620 * @param returnTarget the returnTarget to set 621 */ 622 public void setReturnTarget(String returnTarget) { 623 this.returnTarget = returnTarget; 624 } 625 626 /** 627 * @return the returnTarget 628 */ 629 @BeanTagAttribute(name="returnTarget") 630 public String getReturnTarget() { 631 return returnTarget; 632 } 633 634 /** 635 * @return the returnByScript 636 */ 637 @BeanTagAttribute(name="returnByScript") 638 public boolean isReturnByScript() { 639 return returnByScript; 640 } 641 642 /** 643 * Setter for the flag to indicate that lookups will return the value 644 * by script and not a post 645 * 646 * @param returnByScript the returnByScript flag 647 */ 648 public void setReturnByScript(boolean returnByScript) { 649 this.returnByScript = returnByScript; 650 } 651 652 /** 653 * String that maps to the maintenance controller for the maintenance document (if any) associated with the 654 * lookup data object class 655 * 656 * <p> 657 * Mapping will be used to build the maintenance action links (such as edit, copy, and new). If not given, the 658 * default maintenance mapping will be used 659 * </p> 660 * 661 * @return mapping string 662 */ 663 @BeanTagAttribute(name="maintenanceUrlMapping") 664 public String getMaintenanceUrlMapping() { 665 return maintenanceUrlMapping; 666 } 667 668 /** 669 * Setter for the URL mapping string that will be used to build up maintenance action URLs 670 * 671 * @param maintenanceUrlMapping 672 */ 673 public void setMaintenanceUrlMapping(String maintenanceUrlMapping) { 674 this.maintenanceUrlMapping = maintenanceUrlMapping; 675 } 676 677 /** 678 * Indicates that the action buttons like search in the criteria section should be rendered 679 * 680 * @return boolean 681 */ 682 public boolean isRenderSearchButtons() { 683 return renderSearchButtons; 684 } 685 686 /** 687 * Setter for the render search buttons flag 688 * 689 * @param renderSearchButtons 690 */ 691 public void setRenderSearchButtons(boolean renderSearchButtons) { 692 this.renderSearchButtons = renderSearchButtons; 693 } 694 695 /** 696 * Indicates whether the lookup criteria group should be rendered 697 * 698 * <p> 699 * Defaults to true. Can be set as bean property or passed as a request parameter in the lookup url. 700 * </p> 701 * 702 * @return boolean 703 */ 704 public boolean isRenderLookupCriteria() { 705 return renderLookupCriteria; 706 } 707 708 /** 709 * Setter for the lookup criteria group render flag 710 * 711 * @param renderLookupCriteria 712 */ 713 public void setRenderLookupCriteria(boolean renderLookupCriteria) { 714 this.renderLookupCriteria = renderLookupCriteria; 715 } 716 717 /** 718 * Indicates whether the lookup header should be rendered 719 * 720 * <p> 721 * Defaults to true. Can be set as bean property or passed as a request parameter in the lookup url. 722 * </p> 723 * 724 * @return boolean 725 */ 726 public boolean isRenderHeader() { 727 return renderHeader; 728 } 729 730 /** 731 * Setter for the header render flag 732 * 733 * @param renderHeader 734 */ 735 public void setRenderHeader(boolean renderHeader) { 736 this.renderHeader = renderHeader; 737 } 738 739 /** 740 * Indicates that the search must execute on changing of a value in all lookup input fields 741 * 742 * @return boolean 743 */ 744 public boolean isTriggerOnChange() { 745 return triggerOnChange; 746 } 747 748 /** 749 * Setter for the trigger search on change flag 750 * 751 * @param triggerOnChange 752 */ 753 public void setTriggerOnChange(boolean triggerOnChange) { 754 this.triggerOnChange = triggerOnChange; 755 } 756 757 /** 758 * The field group prototype that will be copied and used for range fields 759 * 760 * @return FieldGroup 761 */ 762 public FieldGroup getRangeFieldGroupPrototype() { 763 return rangeFieldGroupPrototype; 764 } 765 766 /** 767 * Setter for the range FieldGroup prototype 768 * 769 * @param rangeFieldGroupPrototype 770 */ 771 public void setRangeFieldGroupPrototype(FieldGroup rangeFieldGroupPrototype) { 772 this.rangeFieldGroupPrototype = rangeFieldGroupPrototype; 773 } 774 775 /** 776 * Indicates whether the 'active' criteria field must be added automatically for Inactivatable BO's 777 * 778 * @return boolean 779 */ 780 public boolean isAutoAddActiveCriteria() { 781 return autoAddActiveCriteria; 782 } 783 784 /** 785 * Setter for the flag that indicates whether the 'active' criteria field must be added automatically for 786 * Inactivatable BO's 787 * 788 * @param autoAddActiveCriteria 789 */ 790 public void setAutoAddActiveCriteria(boolean autoAddActiveCriteria) { 791 this.autoAddActiveCriteria = autoAddActiveCriteria; 792 } 793 794 /** 795 * The Message to render between the two range fields for ranged criteria fields 796 * 797 * @return 798 */ 799 public Message getRangedToMessage() { 800 return rangedToMessage; 801 } 802 803 /** 804 * Setter for the Message rendered between the two range fields for ranged criteria fields 805 * 806 * @param rangedToMessage 807 */ 808 public void setRangedToMessage(Message rangedToMessage) { 809 this.rangedToMessage = rangedToMessage; 810 } 811 812 /** 813 * @see org.kuali.rice.krad.uif.component.ComponentBase#copy() 814 */ 815 @Override 816 protected <T> void copyProperties(T component) { 817 super.copyProperties(component); 818 819 LookupView lookupViewCopy = (LookupView) component; 820 821 if (this.dataObjectClassName != null) { 822 lookupViewCopy.setDataObjectClassName(this.getDataObjectClassName()); 823 } 824 825 if (this.criteriaGroup != null) { 826 lookupViewCopy.setCriteriaGroup((Group) this.getCriteriaGroup().copy()); 827 } 828 829 if (this.resultsGroup != null) { 830 lookupViewCopy.setResultsGroup((CollectionGroup) this.getResultsGroup().copy()); 831 } 832 833 if (this.criteriaFields != null) { 834 List<Component> criteriaFieldsCopy = Lists.newArrayListWithExpectedSize(criteriaFields.size()); 835 for (Component criteriaField : criteriaFields) { 836 criteriaFieldsCopy.add((Component) criteriaField.copy()); 837 } 838 lookupViewCopy.setCriteriaFields(criteriaFieldsCopy); 839 } 840 841 if (this.resultFields != null) { 842 List<Component> resultFieldsCopy = Lists.newArrayListWithExpectedSize(resultFields.size()); 843 for (Component resultField : resultFields) { 844 resultFieldsCopy.add((Component) resultField.copy()); 845 } 846 lookupViewCopy.setResultFields(resultFieldsCopy); 847 } 848 849 if (this.defaultSortAttributeNames != null) { 850 lookupViewCopy.setDefaultSortAttributeNames(new ArrayList<String>(defaultSortAttributeNames)); 851 } 852 853 lookupViewCopy.setDefaultSortAscending(this.isDefaultSortAscending()); 854 lookupViewCopy.setHideReturnLinks(this.hideReturnLinks); 855 lookupViewCopy.setSuppressActions(this.suppressActions); 856 lookupViewCopy.setShowMaintenanceLinks(this.showMaintenanceLinks); 857 lookupViewCopy.setMaintenanceUrlMapping(this.maintenanceUrlMapping); 858 lookupViewCopy.setMultipleValuesSelect(this.multipleValuesSelect); 859 lookupViewCopy.setRenderLookupCriteria(this.renderLookupCriteria); 860 lookupViewCopy.setRenderSearchButtons(this.renderSearchButtons); 861 lookupViewCopy.setRenderHeader(this.renderHeader); 862 lookupViewCopy.setResultSetLimit(this.resultSetLimit); 863 lookupViewCopy.setReturnTarget(this.returnTarget); 864 lookupViewCopy.setTriggerOnChange(this.triggerOnChange); 865 lookupViewCopy.setResultSetLimit(this.resultSetLimit); 866 lookupViewCopy.setMultipleValuesSelectResultSetLimit(this.multipleValuesSelectResultSetLimit); 867 lookupViewCopy.setMaintenanceUrlMapping(this.maintenanceUrlMapping); 868 869 if (this.rangeFieldGroupPrototype != null) { 870 lookupViewCopy.setRangeFieldGroupPrototype((FieldGroup) this.rangeFieldGroupPrototype.copy()); 871 } 872 873 if (this.rangedToMessage != null) { 874 lookupViewCopy.setRangedToMessage((Message) this.rangedToMessage.copy()); 875 } 876 877 lookupViewCopy.setAutoAddActiveCriteria(this.autoAddActiveCriteria); 878 } 879 880 }