001 /** 002 * Copyright 2005-2014 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.widget; 017 018 import com.google.common.collect.Maps; 019 import org.apache.commons.lang.StringUtils; 020 import org.kuali.rice.krad.bo.DataObjectRelationship; 021 import org.kuali.rice.krad.datadictionary.parse.BeanTag; 022 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute; 023 import org.kuali.rice.krad.datadictionary.parse.BeanTags; 024 import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 025 import org.kuali.rice.krad.uif.UifParameters; 026 import org.kuali.rice.krad.uif.component.BindingInfo; 027 import org.kuali.rice.krad.uif.component.Component; 028 import org.kuali.rice.krad.uif.container.CollectionGroup; 029 import org.kuali.rice.krad.uif.element.Action; 030 import org.kuali.rice.krad.uif.field.InputField; 031 import org.kuali.rice.krad.uif.util.ViewModelUtils; 032 import org.kuali.rice.krad.uif.view.View; 033 import org.kuali.rice.krad.util.KRADConstants; 034 import org.kuali.rice.krad.util.KRADUtils; 035 036 import java.util.HashMap; 037 import java.util.List; 038 import java.util.Map; 039 040 /** 041 * Widget for navigating to a lookup from a field (called a quickfinder) 042 * 043 * @author Kuali Rice Team (rice.collab@kuali.org) 044 */ 045 @BeanTags({@BeanTag(name = "quickFinder-bean", parent = "Uif-QuickFinder"), 046 @BeanTag(name = "quickFinderByScript-bean", parent = "Uif-QuickFinderByScript"), 047 @BeanTag(name = "collectionQuickFinder-bean", parent = "Uif-CollectionQuickFinder")}) 048 public class QuickFinder extends WidgetBase { 049 private static final long serialVersionUID = 3302390972815386785L; 050 051 // lookup configuration 052 private String baseLookupUrl; 053 private String dataObjectClassName; 054 private String viewName; 055 056 private String referencesToRefresh; 057 058 private Map<String, String> fieldConversions; 059 private Map<String, String> lookupParameters; 060 061 // lookup view options 062 private String readOnlySearchFields; 063 064 private Boolean hideReturnLink; 065 private Boolean suppressActions; 066 private Boolean autoSearch; 067 private Boolean renderLookupCriteria; 068 private Boolean supplementalActionsEnabled; 069 private Boolean renderSearchButtons; 070 private Boolean renderHeader; 071 private Boolean showMaintenanceLinks; 072 073 private Boolean multipleValuesSelect; 074 private String lookupCollectionName; 075 076 private Action quickfinderAction; 077 private LightBox lightBoxLookup; 078 079 public QuickFinder() { 080 super(); 081 082 fieldConversions = new HashMap<String, String>(); 083 lookupParameters = new HashMap<String, String>(); 084 } 085 086 /** 087 * The following initialization is performed: 088 * 089 * <ul> 090 * <li>Set defaults for binding</li> 091 * </ul> 092 * 093 * @see org.kuali.rice.krad.uif.component.ComponentBase#performInitialization(org.kuali.rice.krad.uif.view.View, 094 * java.lang.Object) 095 */ 096 @Override 097 public void performInitialization(View view, Object model) { 098 super.performInitialization(view, model); 099 100 if (quickfinderAction != null && (lightBoxLookup != null && lightBoxLookup.isRender())) { 101 quickfinderAction.setActionScript("voidAction"); 102 } 103 } 104 105 /** 106 * The following finalization is performed: 107 * 108 * <ul> 109 * <li> 110 * Sets defaults on collectionLookup such as collectionName, and the class if not set 111 * 112 * <p> 113 * If the data object class was not configured for the lookup, the class configured for the collection group will 114 * be used if it has a lookup defined. If not data object class is found for the lookup it will be disabled. The 115 * collection name is also defaulted to the binding path for this collection group, so the results returned from 116 * the lookup will populate this collection. Finally field conversions will be generated based on the PK fields of 117 * the collection object class 118 * </p> 119 * </li> 120 * </ul> 121 * 122 * @see org.kuali.rice.krad.uif.widget.Widget#performFinalize(org.kuali.rice.krad.uif.view.View, 123 * java.lang.Object, org.kuali.rice.krad.uif.component.Component) 124 */ 125 @Override 126 public void performFinalize(View view, Object model, Component parent) { 127 super.performFinalize(view, model, parent); 128 129 // TODO: add flag to enable quick finder when the input field (parent) is read-only 130 if (parent.isReadOnly()) { 131 setRender(false); 132 } 133 134 if (!isRender()) { 135 return; 136 } 137 138 if (parent instanceof InputField) { 139 InputField field = (InputField) parent; 140 141 // determine lookup class, field conversions and lookup parameters in 142 // not set 143 if (StringUtils.isBlank(dataObjectClassName)) { 144 DataObjectRelationship relationship = getRelationshipForField(view, model, field); 145 146 // if no relationship found cannot have a quickfinder 147 if (relationship == null) { 148 setRender(false); 149 return; 150 } 151 152 dataObjectClassName = relationship.getRelatedClass().getName(); 153 154 if ((fieldConversions == null) || fieldConversions.isEmpty()) { 155 generateFieldConversions(field, relationship); 156 } 157 158 if ((lookupParameters == null) || lookupParameters.isEmpty()) { 159 generateLookupParameters(field, relationship); 160 } 161 } 162 163 // adjust paths based on associated attribute field 164 updateFieldConversions(field.getBindingInfo()); 165 updateLookupParameters(field.getBindingInfo()); 166 updateReferencesToRefresh(field.getBindingInfo()); 167 } else if (parent instanceof CollectionGroup) { 168 CollectionGroup collectionGroup = (CollectionGroup) parent; 169 170 // check to see if data object class is configured for lookup, if so we will assume it should be enabled 171 // if not and the class configured for the collection group is lookupable, use that 172 if (StringUtils.isBlank(getDataObjectClassName())) { 173 Class<?> collectionObjectClass = collectionGroup.getCollectionObjectClass(); 174 boolean isCollectionClassLookupable = KRADServiceLocatorWeb.getViewDictionaryService().isLookupable( 175 collectionObjectClass); 176 if (isCollectionClassLookupable) { 177 setDataObjectClassName(collectionObjectClass.getName()); 178 179 if ((fieldConversions == null) || fieldConversions.isEmpty()) { 180 // use PK fields for collection class 181 List<String> collectionObjectPKFields = 182 KRADServiceLocatorWeb.getDataObjectMetaDataService().listPrimaryKeyFieldNames( 183 collectionObjectClass); 184 185 for (String pkField : collectionObjectPKFields) { 186 fieldConversions.put(pkField, pkField); 187 } 188 } 189 } else { 190 // no available data object class to lookup so need to disable quickfinder 191 setRender(false); 192 } 193 } 194 195 // set the lookup return collection name to this collection path 196 if (isRender() && StringUtils.isBlank(getLookupCollectionName())) { 197 setLookupCollectionName(collectionGroup.getBindingInfo().getBindingPath()); 198 } 199 } 200 201 quickfinderAction.addActionParameter(UifParameters.BASE_LOOKUP_URL, baseLookupUrl); 202 quickfinderAction.addActionParameter(UifParameters.DATA_OBJECT_CLASS_NAME, dataObjectClassName); 203 204 if (!fieldConversions.isEmpty()) { 205 quickfinderAction.addActionParameter(UifParameters.CONVERSION_FIELDS, KRADUtils.buildMapParameterString( 206 fieldConversions)); 207 } 208 209 if (!lookupParameters.isEmpty()) { 210 quickfinderAction.addActionParameter(UifParameters.LOOKUP_PARAMETERS, KRADUtils.buildMapParameterString( 211 lookupParameters)); 212 } 213 214 addActionParameterIfNotNull(UifParameters.VIEW_NAME, viewName); 215 addActionParameterIfNotNull(UifParameters.READ_ONLY_FIELDS, readOnlySearchFields); 216 addActionParameterIfNotNull(UifParameters.HIDE_RETURN_LINK, hideReturnLink); 217 addActionParameterIfNotNull(UifParameters.SUPPRESS_ACTIONS, suppressActions); 218 addActionParameterIfNotNull(UifParameters.REFERENCES_TO_REFRESH, referencesToRefresh); 219 addActionParameterIfNotNull(UifParameters.AUTO_SEARCH, autoSearch); 220 addActionParameterIfNotNull(UifParameters.RENDER_LOOKUP_CRITERIA, renderLookupCriteria); 221 addActionParameterIfNotNull(UifParameters.SUPPLEMENTAL_ACTIONS_ENABLED, supplementalActionsEnabled); 222 addActionParameterIfNotNull(UifParameters.RENDER_SEARCH_BUTTONS, renderSearchButtons); 223 addActionParameterIfNotNull(UifParameters.RENDER_HEADER, renderHeader); 224 addActionParameterIfNotNull(UifParameters.SHOW_MAINTENANCE_LINKS, showMaintenanceLinks); 225 addActionParameterIfNotNull(UifParameters.MULTIPLE_VALUES_SELECT, multipleValuesSelect); 226 addActionParameterIfNotNull(UifParameters.LOOKUP_COLLECTION_NAME, lookupCollectionName); 227 228 // TODO: 229 // org.kuali.rice.kns.util.FieldUtils.populateQuickfinderDefaultsForLookup(Class, 230 // String, Field) 231 } 232 233 protected void addActionParameterIfNotNull(String parameterName, Object parameterValue) { 234 if ((parameterValue != null) && StringUtils.isNotBlank(parameterValue.toString())) { 235 quickfinderAction.addActionParameter(parameterName, parameterValue.toString()); 236 } 237 } 238 239 protected DataObjectRelationship getRelationshipForField(View view, Object model, InputField field) { 240 String propertyName = field.getBindingInfo().getBindingName(); 241 242 // get object instance and class for parent 243 Object parentObject = ViewModelUtils.getParentObjectForMetadata(view, model, field); 244 Class<?> parentObjectClass = null; 245 if (parentObject != null) { 246 parentObjectClass = parentObject.getClass(); 247 } 248 249 // get relationship from metadata service 250 return KRADServiceLocatorWeb.getDataObjectMetaDataService().getDataObjectRelationship(parentObject, 251 parentObjectClass, propertyName, "", true, true, false); 252 } 253 254 protected void generateFieldConversions(InputField field, DataObjectRelationship relationship) { 255 fieldConversions = new HashMap<String, String>(); 256 for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) { 257 String fromField = entry.getValue(); 258 String toField = entry.getKey(); 259 260 // TODO: displayedFieldnames in 261 // org.kuali.rice.kns.lookup.LookupUtils.generateFieldConversions(BusinessObject, 262 // String, DataObjectRelationship, String, List, String) 263 264 fieldConversions.put(fromField, toField); 265 } 266 } 267 268 protected void generateLookupParameters(InputField field, DataObjectRelationship relationship) { 269 lookupParameters = new HashMap<String, String>(); 270 for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) { 271 String fromField = entry.getKey(); 272 String toField = entry.getValue(); 273 274 // TODO: displayedFieldnames and displayedQFFieldNames in 275 // generateLookupParameters(BusinessObject, 276 // String, DataObjectRelationship, String, List, String) 277 278 if (relationship.getUserVisibleIdentifierKey() == null || relationship.getUserVisibleIdentifierKey().equals( 279 fromField)) { 280 lookupParameters.put(fromField, toField); 281 } 282 } 283 } 284 285 /** 286 * Adjusts the path on the field conversion to property to match the binding 287 * path prefix of the given <code>BindingInfo</code> 288 * 289 * @param bindingInfo binding info instance to copy binding path prefix from 290 */ 291 public void updateFieldConversions(BindingInfo bindingInfo) { 292 Map<String, String> adjustedFieldConversions = new HashMap<String, String>(); 293 for (String fromField : fieldConversions.keySet()) { 294 String toField = fieldConversions.get(fromField); 295 String adjustedToFieldPath = bindingInfo.getPropertyAdjustedBindingPath(toField); 296 297 adjustedFieldConversions.put(fromField, adjustedToFieldPath); 298 } 299 300 this.fieldConversions = adjustedFieldConversions; 301 } 302 303 /** 304 * Adjusts the path on the lookup parameter from property to match the binding 305 * path prefix of the given <code>BindingInfo</code> 306 * 307 * @param bindingInfo binding info instance to copy binding path prefix from 308 */ 309 public void updateLookupParameters(BindingInfo bindingInfo) { 310 Map<String, String> adjustedLookupParameters = new HashMap<String, String>(); 311 for (String fromField : lookupParameters.keySet()) { 312 String toField = lookupParameters.get(fromField); 313 String adjustedFromFieldPath = bindingInfo.getPropertyAdjustedBindingPath(fromField); 314 315 adjustedLookupParameters.put(adjustedFromFieldPath, toField); 316 } 317 318 this.lookupParameters = adjustedLookupParameters; 319 } 320 321 /** 322 * Adjust the path on the referencesToRefresh parameter to match the binding path 323 * prefix of the given <code>BindingInfo</code> 324 * 325 * @param bindingInfo binding info instance to copy binding path prefix from 326 */ 327 public void updateReferencesToRefresh (BindingInfo bindingInfo) { 328 String adjustedReferencesToRefresh = new String(); 329 330 if (referencesToRefresh == null) { 331 referencesToRefresh = adjustedReferencesToRefresh; 332 } 333 334 for (String reference : StringUtils.split(referencesToRefresh, KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR )){ 335 336 // add separator between references to refresh 337 if (StringUtils.isNotBlank(adjustedReferencesToRefresh)) { 338 adjustedReferencesToRefresh = adjustedReferencesToRefresh + KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR; 339 } 340 341 String adjustedReference = bindingInfo.getPropertyAdjustedBindingPath(reference); 342 adjustedReferencesToRefresh = adjustedReferencesToRefresh + adjustedReference; 343 } 344 this.referencesToRefresh = adjustedReferencesToRefresh; 345 } 346 347 /** 348 * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle() 349 */ 350 @Override 351 public List<Component> getComponentsForLifecycle() { 352 List<Component> components = super.getComponentsForLifecycle(); 353 354 components.add(quickfinderAction); 355 components.add(lightBoxLookup); 356 357 return components; 358 } 359 360 /** 361 * Returns the URL for the lookup for which parameters will be added 362 * 363 * <p> 364 * The base URL includes the domain, context, and controller mapping for the lookup invocation. Parameters are 365 * then added based on configuration to complete the URL. This is generally defaulted to the application URL and 366 * internal KRAD servlet mapping, but can be changed to invoke another application such as the Rice standalone 367 * server 368 * </p> 369 * 370 * @return lookup base URL 371 */ 372 @BeanTagAttribute(name = "baseLookupUrl") 373 public String getBaseLookupUrl() { 374 return this.baseLookupUrl; 375 } 376 377 /** 378 * Setter for the lookup base url (domain, context, and controller) 379 * 380 * @param baseLookupUrl 381 */ 382 public void setBaseLookupUrl(String baseLookupUrl) { 383 this.baseLookupUrl = baseLookupUrl; 384 } 385 386 /** 387 * Full class name the lookup should be provided for 388 * 389 * <p> 390 * This is passed on to the lookup request for the data object the lookup should be rendered for. This is then 391 * used by the lookup framework to select the lookup view (if more than one lookup view exists for the same 392 * data object class name, the {@link #getViewName()} property should be specified to select the view to render). 393 * </p> 394 * 395 * @return lookup class name 396 */ 397 @BeanTagAttribute(name = "dataOjbectClassName") 398 public String getDataObjectClassName() { 399 return this.dataObjectClassName; 400 } 401 402 /** 403 * Setter for the class name that lookup should be provided for 404 * 405 * @param dataObjectClassName 406 */ 407 public void setDataObjectClassName(String dataObjectClassName) { 408 this.dataObjectClassName = dataObjectClassName; 409 } 410 411 /** 412 * When multiple target lookup views exists for the same data object class, the view name can be set to 413 * determine which one to use 414 * 415 * <p> 416 * When creating multiple lookup views for the same data object class, the view name can be specified for the 417 * different versions (for example 'simple' and 'advanced'). When multiple lookup views exist the view name must 418 * be sent with the data object class for the request. Note the view id can be alternatively used to uniquely 419 * identify the lookup view 420 * </p> 421 */ 422 @BeanTagAttribute(name = "viewName") 423 public String getViewName() { 424 return this.viewName; 425 } 426 427 /** 428 * Setter for the view name configured on the lookup view that should be invoked by the quickfinder widget 429 * 430 * @param viewName 431 */ 432 public void setViewName(String viewName) { 433 this.viewName = viewName; 434 } 435 436 /** 437 * List of property names on the model that should be refreshed when the lookup returns 438 * 439 * <p> 440 * Note this is only relevant when the return by script option is not enabled (meaning the server will be invoked 441 * on the lookup return call) 442 * </p> 443 * 444 * <p> 445 * When a lookup return call is made (to return a result value) the controller refresh method will be invoked. If 446 * refresh properties are configured, a call to refresh those references from the database will be made. This is 447 * useful if the lookup returns a foreign key field and the related record is needed. 448 * </p> 449 * 450 * @return list of property names to refresh 451 * TODO: refactor this to be a List type 452 */ 453 @BeanTagAttribute(name = "referencesToRefresh") 454 public String getReferencesToRefresh() { 455 return this.referencesToRefresh; 456 } 457 458 /** 459 * Setter for the list of property names that should be refreshed when the lookup returns 460 * 461 * @param referencesToRefresh 462 */ 463 public void setReferencesToRefresh(String referencesToRefresh) { 464 this.referencesToRefresh = referencesToRefresh; 465 } 466 467 /** 468 * Map that determines what properties from a result lookup row (if selected) will be returned to properties on 469 * the calling view 470 * 471 * <p> 472 * The purpose of using the lookup is to search for a particular value and return that value to the form being 473 * completed. In order for the lookup framework to return the field back to us, we must specify the name of the 474 * field on the data object class whose value we need, and the name of the field on the calling view. Furthermore, 475 * we can choose to have the lookup return additional fields that populate other form fields or informational 476 * properties (see ‘Field Queries and Informational Properties’). These pairs of fields are known as 477 * ‘field conversions’. 478 * </p> 479 * 480 * <p> 481 * The fieldConversions property is a Map. Each entry represents a field that will be returned back from the 482 * lookup, with the entry key being the field name on the data object class, and the entry value being the field 483 * name on the calling view. It is helpful to think of this as a from-to mapping. Pulling from the data object 484 * field (map key) to the calling view field (map value). 485 * </p> 486 * 487 * @return mapping of lookup data object property names to view property names 488 */ 489 @BeanTagAttribute(name = "fieldConversions", type = BeanTagAttribute.AttributeType.MAPVALUE) 490 public Map<String, String> getFieldConversions() { 491 return this.fieldConversions; 492 } 493 494 /** 495 * Setter for the map that determines what properties on a lookup result row are returned and how they map to 496 * properties on the calling view 497 * 498 * @param fieldConversions 499 */ 500 public void setFieldConversions(Map<String, String> fieldConversions) { 501 this.fieldConversions = fieldConversions; 502 } 503 504 /** 505 * Map that determines what properties from a calling view will be sent to properties on that are rendered 506 * for the lookup view's search fields (they can be hidden) 507 * 508 * <p> 509 * When invoking a lookup view, we can pre-populate search fields on the lookup view with data from the view 510 * that called the lookup. The user can then perform the search with these values, or (if edited is allowed or 511 * the fields are not hidden) change the passed in values. When the lookup is invoked, the values for the 512 * properties configured within the lookup parameters Map will be pulled and passed along as values for the 513 * lookup view properties 514 * </p> 515 * 516 * @return mapping of calling view properties to lookup view search fields 517 */ 518 @BeanTagAttribute(name = "lookupParameters", type = BeanTagAttribute.AttributeType.MAPVALUE) 519 public Map<String, String> getLookupParameters() { 520 return this.lookupParameters; 521 } 522 523 /** 524 * Setter for the map that determines what property values on the calling view will be sent to properties on the 525 * lookup views search fields 526 * 527 * @param lookupParameters 528 */ 529 public void setLookupParameters(Map<String, String> lookupParameters) { 530 this.lookupParameters = lookupParameters; 531 } 532 533 /** 534 * Comma delimited String of property names on the lookup view that should be read only 535 * 536 * <p> 537 * When requesting a lookup view, property names for fields that are rendered as search criteria can be marked 538 * as read-only. This is usually done when a lookup parameter for that property is sent in and the user should 539 * not be allowed to change the value 540 * </p> 541 * 542 * @return property names (delimited by a comma) whose criteria fields should be read-only on the 543 * lookup view 544 */ 545 @BeanTagAttribute(name = "readOnlySearchFields") 546 public String getReadOnlySearchFields() { 547 return this.readOnlySearchFields; 548 } 549 550 /** 551 * Setter for property names for criteria fields on the lookup view that should be read-only (multiple property 552 * names are specified using a comma delimiter) 553 * 554 * @param readOnlySearchFields 555 */ 556 public void setReadOnlySearchFields(String readOnlySearchFields) { 557 this.readOnlySearchFields = readOnlySearchFields; 558 } 559 560 /** 561 * Indicates whether the return links for lookup results should be rendered 562 * 563 * <p> 564 * A lookup view can be invoked to allow the user to select a value (or set of values) to return back to the 565 * calling view. For single value lookups this is done with a return link that is rendered for each row. This 566 * return link can be disabled by setting this property to true 567 * </p> 568 * 569 * @return true if the return link should not be shown, false if it should be 570 */ 571 @BeanTagAttribute(name = "hideReturnLink") 572 public Boolean getHideReturnLink() { 573 return this.hideReturnLink; 574 } 575 576 /** 577 * Setter for the hide return link indicator 578 * 579 * @param hideReturnLink 580 */ 581 public void setHideReturnLink(Boolean hideReturnLink) { 582 this.hideReturnLink = hideReturnLink; 583 } 584 585 /** 586 * Indicates whether the maintenance actions (or others) are rendered on the invoked lookup view 587 * 588 * <p> 589 * By default a lookup view will add an actions column for the result table that display maintenance links (in 590 * addition to a new link at the top of the page) if a maintenance action is available. Custom links can also be 591 * added to the action column as necessary. This flag can be set to true to suppress the rendering of the actions 592 * for the lookup call. 593 * </p> 594 * 595 * <p> 596 * An example of when this might be useful is when invoking a lookup to return a value to a value. Generally in 597 * these cases you don't want to the user going off to another view (such as the maintenance view) 598 * </p> 599 * 600 * @return true if actions should be rendered, false if not 601 */ 602 @BeanTagAttribute(name = "suppressActions") 603 public Boolean getSuppressActions() { 604 return suppressActions; 605 } 606 607 /** 608 * Setter for the suppress actions indicator 609 * 610 * @param suppressActions 611 */ 612 public void setSuppressActions(Boolean suppressActions) { 613 this.suppressActions = suppressActions; 614 } 615 616 /** 617 * Indicates whether the search should be executed when first rendering the lookup view 618 * 619 * <p> 620 * By default the lookup view is rendered, the user enters search values and executes the results. This flag can 621 * be set to true to indicate the search should be performed before showing the screen to the user. This is 622 * generally used when search criteria is being passed in as well 623 * </p> 624 * 625 * @return true if the search should be performed initially, false if not 626 */ 627 @BeanTagAttribute(name = "autoSearch") 628 public Boolean getAutoSearch() { 629 return this.autoSearch; 630 } 631 632 /** 633 * Setter for the auto search indicator 634 * 635 * @param autoSearch 636 */ 637 public void setAutoSearch(Boolean autoSearch) { 638 this.autoSearch = autoSearch; 639 } 640 641 /** 642 * Indicates whether the lookup criteria (search group) should be enabled on the invoked lookup view 643 * 644 * <p> 645 * Setting the this to false will not display the lookup criteria but only the results. Therefore this is only 646 * useful when setting {@link #getAutoSearch()} to true and passing in criteria 647 * </p> 648 * 649 * @return true if lookup criteria should be displayed, false if not 650 */ 651 @BeanTagAttribute(name = "renderLookupCriteria") 652 public Boolean getRenderLookupCriteria() { 653 return this.renderLookupCriteria; 654 } 655 656 /** 657 * Setter for enabling the lookup criteria group 658 * 659 * @param renderLookupCriteria 660 */ 661 public void setRenderLookupCriteria(Boolean renderLookupCriteria) { 662 this.renderLookupCriteria = renderLookupCriteria; 663 } 664 665 /** 666 * TODO: not implemented currently 667 * 668 * @return Boolean 669 */ 670 @BeanTagAttribute(name = "supplementalActionsEnabled") 671 public Boolean getSupplementalActionsEnabled() { 672 return this.supplementalActionsEnabled; 673 } 674 675 public void setSupplementalActionsEnabled(Boolean supplementalActionsEnabled) { 676 this.supplementalActionsEnabled = supplementalActionsEnabled; 677 } 678 679 /** 680 * Indicates that the action buttons like search in the criteria section should be rendered 681 * 682 * @return Boolean 683 */ 684 @BeanTagAttribute(name = "renderSearchButtons") 685 public Boolean getRenderSearchButtons() { 686 return this.renderSearchButtons; 687 } 688 689 /** 690 * Setter for the render search buttons flag 691 * 692 * @param renderSearchButtons 693 */ 694 public void setRenderSearchButtons(Boolean renderSearchButtons) { 695 this.renderSearchButtons = renderSearchButtons; 696 } 697 698 /** 699 * Indicates whether the lookup header should be rendered 700 * 701 * <p> 702 * Defaults to true. Can be set as bean property or passed as a request parameter in the lookup url. 703 * </p> 704 * 705 * @return boolean 706 */ 707 @BeanTagAttribute(name = "renderHeader") 708 public Boolean getRenderHeader() { 709 return this.renderHeader; 710 } 711 712 /** 713 * Setter for the header render flag 714 * 715 * @param renderHeader 716 */ 717 public void setRenderHeader(Boolean renderHeader) { 718 this.renderHeader = renderHeader; 719 } 720 721 /** 722 * Indicates whether the maintenance action links should be rendered for the invoked lookup view 723 * 724 * <p> 725 * If a maintenance view exists for the data object associated with the lookup view, the framework will add 726 * links to initiate a new maintenance document. This flag can be used to disable the rendering of these links 727 * </p> 728 * 729 * <p> 730 * Note this serves similar purpose to {@link #getSuppressActions()} but the intent is to only remove the 731 * maintenance links in this situation, not the complete actions column TODO: this is not in place! 732 * </p> 733 * 734 * @return true if maintenance links should be shown on the lookup view, false if not 735 */ 736 @BeanTagAttribute(name = "showMaintenanceLinks") 737 public Boolean getShowMaintenanceLinks() { 738 return this.showMaintenanceLinks; 739 } 740 741 /** 742 * Setter for the show maintenance links indicator 743 * 744 * @param showMaintenanceLinks 745 */ 746 public void setShowMaintenanceLinks(Boolean showMaintenanceLinks) { 747 this.showMaintenanceLinks = showMaintenanceLinks; 748 } 749 750 /** 751 * Action component that is used to rendered for the field for invoking the quickfinder action (bringin up the 752 * lookup) 753 * 754 * <p> 755 * Through the action configuration the image (or link, button) rendered for the quickfinder can be modified. In 756 * addition to other action component settings 757 * </p> 758 * 759 * @return Action instance rendered for quickfinder 760 */ 761 @BeanTagAttribute(name = "quickfinderAction", type = BeanTagAttribute.AttributeType.SINGLEBEAN) 762 public Action getQuickfinderAction() { 763 return this.quickfinderAction; 764 } 765 766 /** 767 * Setter for the action field component to render for the quickfinder 768 * 769 * @param quickfinderAction 770 */ 771 public void setQuickfinderAction(Action quickfinderAction) { 772 this.quickfinderAction = quickfinderAction; 773 } 774 775 /** 776 * Setter for the light box lookup widget 777 * 778 * @param lightBoxLookup <code>LightBoxLookup</code> widget to set 779 */ 780 public void setLightBoxLookup(LightBox lightBoxLookup) { 781 this.lightBoxLookup = lightBoxLookup; 782 } 783 784 /** 785 * LightBoxLookup widget for the field 786 * 787 * <p> 788 * The light box lookup widget will change the lookup behaviour to open the 789 * lookup in a light box. 790 * </p> 791 * 792 * @return the <code>DirectInquiry</code> field DirectInquiry 793 */ 794 @BeanTagAttribute(name = "lightBoxLookup", type = BeanTagAttribute.AttributeType.SINGLEBEAN) 795 public LightBox getLightBoxLookup() { 796 return lightBoxLookup; 797 } 798 799 /** 800 * Indicates whether a multi-values lookup should be requested 801 * 802 * @return true if multi-value lookup should be requested, false for normal lookup 803 */ 804 @BeanTagAttribute(name = "MultipleValuesSelect") 805 public Boolean getMultipleValuesSelect() { 806 return multipleValuesSelect; 807 } 808 809 /** 810 * Setter for the multi-values lookup indicator 811 * 812 * @param multipleValuesSelect 813 */ 814 public void setMultipleValuesSelect(Boolean multipleValuesSelect) { 815 this.multipleValuesSelect = multipleValuesSelect; 816 } 817 818 /** 819 * For the case of multi-value lookup, indicates the collection that should be populated with 820 * the return results 821 * 822 * <p> 823 * Note when the quickfinder is associated with a <code>CollectionGroup</code>, this property is 824 * set automatically from the collection name associated with the group 825 * </p> 826 * 827 * @return collection name (must be full binding path) 828 */ 829 @BeanTagAttribute(name = "lookupCollectionName") 830 public String getLookupCollectionName() { 831 return lookupCollectionName; 832 } 833 834 /** 835 * Setter for the name of the collection that should be populated with lookup results 836 * 837 * @param lookupCollectionName 838 */ 839 public void setLookupCollectionName(String lookupCollectionName) { 840 this.lookupCollectionName = lookupCollectionName; 841 } 842 843 /** 844 * @see org.kuali.rice.krad.uif.component.ComponentBase#copy() 845 */ 846 @Override 847 protected <T> void copyProperties(T component) { 848 super.copyProperties(component); 849 QuickFinder quickFinderCopy = (QuickFinder) component; 850 quickFinderCopy.setBaseLookupUrl(this.getBaseLookupUrl()); 851 quickFinderCopy.setDataObjectClassName(this.getDataObjectClassName()); 852 quickFinderCopy.setViewName(this.getViewName()); 853 quickFinderCopy.setReferencesToRefresh(this.getReferencesToRefresh()); 854 855 if(fieldConversions != null) { 856 Map<String, String> fieldConversionsCopy = Maps.newHashMapWithExpectedSize(fieldConversions.size()); 857 for(Map.Entry fieldConversion : fieldConversions.entrySet()) { 858 fieldConversionsCopy.put(fieldConversion.getKey().toString(),fieldConversion.getValue().toString()); 859 } 860 quickFinderCopy.setFieldConversions(fieldConversionsCopy); 861 } 862 863 if(lookupParameters != null) { 864 Map<String, String> lookupParametersCopy = Maps.newHashMapWithExpectedSize(lookupParameters.size()); 865 for(Map.Entry lookupParameter : lookupParameters.entrySet()) { 866 lookupParametersCopy.put(lookupParameter.getKey().toString(),lookupParameter.getValue().toString()); 867 } 868 quickFinderCopy.setLookupParameters(lookupParametersCopy); 869 } 870 871 quickFinderCopy.setReadOnlySearchFields(this.getReadOnlySearchFields()); 872 quickFinderCopy.setHideReturnLink(this.getHideReturnLink()); 873 quickFinderCopy.setSuppressActions(this.getSuppressActions()); 874 quickFinderCopy.setAutoSearch(this.getAutoSearch()); 875 quickFinderCopy.setRenderLookupCriteria(this.getRenderLookupCriteria()); 876 quickFinderCopy.setSupplementalActionsEnabled(this.getSupplementalActionsEnabled()); 877 quickFinderCopy.setRenderSearchButtons(this.getRenderSearchButtons()); 878 quickFinderCopy.setRenderHeader(this.getRenderHeader()); 879 quickFinderCopy.setShowMaintenanceLinks(this.getShowMaintenanceLinks()); 880 quickFinderCopy.setMultipleValuesSelect(this.getMultipleValuesSelect()); 881 quickFinderCopy.setLookupCollectionName(this.getLookupCollectionName()); 882 883 if(lightBoxLookup != null) { 884 quickFinderCopy.setLightBoxLookup((LightBox)this.getLightBoxLookup().copy()); 885 } 886 887 if (this.quickfinderAction != null) { 888 quickFinderCopy.setQuickfinderAction((Action)this.quickfinderAction.copy()); 889 } 890 } 891 }