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 */ 016package org.kuali.rice.krad.uif.widget; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.commons.lang.StringUtils; 024import org.kuali.rice.krad.bo.DataObjectRelationship; 025import org.kuali.rice.krad.bo.ExternalizableBusinessObject; 026import org.kuali.rice.krad.datadictionary.parse.BeanTag; 027import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute; 028import org.kuali.rice.krad.datadictionary.parse.BeanTags; 029import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 030import org.kuali.rice.krad.service.ModuleService; 031import org.kuali.rice.krad.uif.UifConstants; 032import org.kuali.rice.krad.uif.UifParameters; 033import org.kuali.rice.krad.uif.component.BindingInfo; 034import org.kuali.rice.krad.uif.component.Component; 035import org.kuali.rice.krad.uif.component.MethodInvokerConfig; 036import org.kuali.rice.krad.uif.container.CollectionGroup; 037import org.kuali.rice.krad.uif.element.Action; 038import org.kuali.rice.krad.uif.field.InputField; 039import org.kuali.rice.krad.uif.lifecycle.LifecycleEventListener; 040import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle; 041import org.kuali.rice.krad.uif.util.LifecycleElement; 042import org.kuali.rice.krad.uif.util.ViewModelUtils; 043import org.kuali.rice.krad.uif.view.View; 044import org.kuali.rice.krad.util.KRADConstants; 045import org.kuali.rice.krad.util.KRADUtils; 046 047/** 048 * Widget for navigating to a lookup from a field (called a quickfinder). 049 * 050 * @author Kuali Rice Team (rice.collab@kuali.org) 051 */ 052@BeanTags({@BeanTag(name = "quickFinder", parent = "Uif-QuickFinder"), 053 @BeanTag(name = "quickFinderByScript", parent = "Uif-QuickFinderByScript"), 054 @BeanTag(name = "collectionQuickFinder", parent = "Uif-CollectionQuickFinder")}) 055public class QuickFinder extends WidgetBase implements LifecycleEventListener { 056 private static final long serialVersionUID = 3302390972815386785L; 057 058 // lookup configuration 059 private String baseLookupUrl; 060 private String dataObjectClassName; 061 private String viewName; 062 063 private boolean returnByScript; 064 private String readOnlyLookupFields; 065 private String referencesToRefresh; 066 private String lookupCollectionName; 067 private String lookupCollectionId; 068 069 private Map<String, String> fieldConversions; 070 private Map<String, String> lookupParameters; 071 private Map<String, String> additionalLookupParameters; 072 073 private Action quickfinderAction; 074 075 private String lookupDialogId; 076 private boolean openInDialog; 077 078 // lookup view options 079 private Boolean renderReturnLink; 080 private Boolean renderResultActions; 081 private Boolean autoSearch; 082 private Boolean renderLookupCriteria; 083 private Boolean renderCriteriaActions; 084 private Boolean hideCriteriaOnSearch; 085 private Boolean renderMaintenanceLinks; 086 private Boolean multipleValuesSelect; 087 088 private String callbackMethodToCall; 089 private MethodInvokerConfig callbackMethod; 090 private Map<String, String> callbackContext; 091 092 public QuickFinder() { 093 super(); 094 095 fieldConversions = new HashMap<String, String>(); 096 lookupParameters = new HashMap<String, String>(); 097 lookupDialogId = ""; 098 } 099 100 /** 101 * The following initialization is performed: 102 * 103 * <ul> 104 * <li>Registers an event on the quickfinder action</li> 105 * </ul> 106 * 107 * {@inheritDoc} 108 */ 109 @Override 110 public void performInitialization(Object model) { 111 super.performInitialization(model); 112 113 ViewLifecycle viewLifecycle = ViewLifecycle.getActiveLifecycle(); 114 viewLifecycle.registerLifecycleCompleteListener(quickfinderAction, this); 115 } 116 117 /** 118 * Inherits readOnly from parent if not explicitly populated. 119 * 120 * {@inheritDoc} 121 */ 122 @Override 123 public void afterEvaluateExpression() { 124 super.afterEvaluateExpression(); 125 126 if (getReadOnly() == null) { 127 Component parent = ViewLifecycle.getPhase().getParent(); 128 setReadOnly(parent == null ? null : parent.getReadOnly()); 129 } 130 } 131 132 /** 133 * The following finalization is performed: 134 * 135 * <ul> 136 * <li>Sets up the quickfinder based on whether the parent is an input field or collection group</li> 137 * <li>Adds action parameters to the quickfinder action based on the quickfinder configuration</li> 138 * <li>Adds callback parameters to post data if present</li> 139 * </ul> 140 * 141 * {@inheritDoc} 142 */ 143 @Override 144 public void performFinalize(Object model, LifecycleElement parent) { 145 super.performFinalize(model, parent); 146 147 if (parent instanceof Component && Boolean.TRUE.equals(((Component) parent).getReadOnly())) { 148 setRender(false); 149 } 150 151 if (!isRender()) { 152 return; 153 } 154 155 View view = ViewLifecycle.getActiveLifecycle().getView(); 156 157 if (parent instanceof InputField) { 158 setupForInputField(view, model, (InputField) parent); 159 160 // add field conversions as accessible binding paths 161 if (isRender()) { 162 for (String toField : fieldConversions.values()) { 163 ViewLifecycle.getViewPostMetadata().addAccessibleBindingPath(toField); 164 } 165 } 166 } else if (parent instanceof CollectionGroup) { 167 setupForCollectionGroup(view, model, (CollectionGroup) parent); 168 } 169 170 setupQuickfinderAction(view, model, parent); 171 172 addCallbackParametersIfPresent(); 173 } 174 175 /** 176 * If quickfinder not manually configured attempts to find a relationship to build the quickfinder on, then also 177 * adjusts the path for any configured field conversions, lookup parameters, and refresh refreshes. 178 * 179 * @param view view instance the quickfinder is associated with 180 * @param model object containing the view data 181 * @param inputField input field instance the quickfinder should apply to 182 */ 183 protected void setupForInputField(View view, Object model, InputField inputField) { 184 // if quickfinder class name not specified, attempt to find a relationship to build the quickfinder from 185 if (StringUtils.isBlank(dataObjectClassName)) { 186 DataObjectRelationship relationship = getRelationshipForField(view, model, inputField); 187 188 // if no relationship found cannot have a quickfinder 189 if (relationship == null) { 190 setRender(false); 191 192 return; 193 } 194 195 dataObjectClassName = relationship.getRelatedClass().getName(); 196 197 if ((fieldConversions == null) || fieldConversions.isEmpty()) { 198 generateFieldConversions(relationship); 199 } 200 201 if ((lookupParameters == null) || lookupParameters.isEmpty()) { 202 generateLookupParameters(relationship); 203 } 204 } 205 206 // adjust paths based on associated attribute field 207 updateFieldConversions(inputField.getBindingInfo()); 208 updateLookupParameters(inputField.getBindingInfo()); 209 updateReferencesToRefresh(inputField.getBindingInfo()); 210 211 // add the quickfinders action as an input field addon 212 inputField.addPostInputAddon(quickfinderAction); 213 } 214 215 /** 216 * Retrieves any {@link org.kuali.rice.krad.bo.DataObjectRelationship} that is associated with the given 217 * field and has a configured lookup view. 218 * 219 * @param view view instance the quickfinder is associated with 220 * @param model object containing the view data 221 * @param field input field instance the quickfinder should apply to 222 * @return data object relationship for the field, or null if one could not be found 223 */ 224 protected DataObjectRelationship getRelationshipForField(View view, Object model, InputField field) { 225 String propertyName = field.getBindingInfo().getBindingName(); 226 227 // get object instance and class for parent 228 Object parentObject = ViewModelUtils.getParentObjectForMetadata(view, model, field); 229 Class<?> parentObjectClass = null; 230 if (parentObject != null) { 231 parentObjectClass = parentObject.getClass(); 232 } 233 234 // get relationship from metadata service 235 if (parentObjectClass != null) { 236 return KRADServiceLocatorWeb.getLegacyDataAdapter().getDataObjectRelationship(parentObject, 237 parentObjectClass, propertyName, "", true, true, false); 238 } 239 240 return null; 241 } 242 243 /** 244 * Generates the lookup field conversions based on the references from the given relationship. 245 * 246 * @param relationship relationship field conversions will be generated from 247 */ 248 protected void generateFieldConversions(DataObjectRelationship relationship) { 249 fieldConversions = new HashMap<String, String>(); 250 251 for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) { 252 String fromField = entry.getValue(); 253 String toField = entry.getKey(); 254 255 fieldConversions.put(fromField, toField); 256 } 257 } 258 259 /** 260 * Generates the lookup parameters based on the references from the given relationship. 261 * 262 * @param relationship relationship lookup parameters will be generated from 263 */ 264 protected void generateLookupParameters(DataObjectRelationship relationship) { 265 lookupParameters = new HashMap<String, String>(); 266 267 for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) { 268 String fromField = entry.getKey(); 269 String toField = entry.getValue(); 270 271 if (relationship.getUserVisibleIdentifierKey() == null || relationship.getUserVisibleIdentifierKey().equals( 272 fromField)) { 273 lookupParameters.put(fromField, toField); 274 } 275 } 276 } 277 278 /** 279 * Adjusts the path on the field conversion to property to match the binding path prefix of the 280 * given {@link org.kuali.rice.krad.uif.component.BindingInfo}. 281 * 282 * @param bindingInfo binding info instance to copy binding path prefix from 283 */ 284 protected void updateFieldConversions(BindingInfo bindingInfo) { 285 Map<String, String> adjustedFieldConversions = new HashMap<String, String>(); 286 for (String fromField : fieldConversions.keySet()) { 287 String toField = fieldConversions.get(fromField); 288 289 if (!StringUtils.startsWith(toField, bindingInfo.getBindingPathPrefix())) { 290 String adjustedToFieldPath = bindingInfo.getPropertyAdjustedBindingPath(toField); 291 adjustedFieldConversions.put(fromField, adjustedToFieldPath); 292 } else { 293 adjustedFieldConversions.put(fromField, toField); 294 } 295 } 296 297 this.fieldConversions = adjustedFieldConversions; 298 } 299 300 /** 301 * Adjusts the path on the lookup parameter from property to match the binding path prefix of the 302 * given {@link org.kuali.rice.krad.uif.component.BindingInfo}. 303 * 304 * @param bindingInfo binding info instance to copy binding path prefix from 305 */ 306 protected void updateLookupParameters(BindingInfo bindingInfo) { 307 Map<String, String> adjustedLookupParameters = new HashMap<String, String>(); 308 for (String fromField : lookupParameters.keySet()) { 309 String toField = lookupParameters.get(fromField); 310 String adjustedFromFieldPath = bindingInfo.getPropertyAdjustedBindingPath(fromField); 311 312 adjustedLookupParameters.put(adjustedFromFieldPath, toField); 313 } 314 315 this.lookupParameters = adjustedLookupParameters; 316 } 317 318 /** 319 * Adjust the path on the referencesToRefresh parameter to match the binding path prefix of the 320 * given {@link org.kuali.rice.krad.uif.component.BindingInfo}. 321 * 322 * @param bindingInfo binding info instance to copy binding path prefix from 323 */ 324 protected void updateReferencesToRefresh(BindingInfo bindingInfo) { 325 List<String> adjustedReferencesToRefresh = new ArrayList<String>(); 326 327 if (referencesToRefresh == null) { 328 referencesToRefresh = new String(); 329 } 330 331 for (String reference : StringUtils.split(referencesToRefresh, KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR)) { 332 adjustedReferencesToRefresh.add(bindingInfo.getPropertyAdjustedBindingPath(reference)); 333 } 334 335 this.referencesToRefresh = StringUtils.join(adjustedReferencesToRefresh, 336 KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR); 337 } 338 339 /** 340 * Configures the quickfinder for the given collection group instance by setting the data object class, 341 * field conversions, and lookup collection name (if necessary). 342 * 343 * @param view view instance the quickfinder is associated with 344 * @param model object containing the view data 345 * @param collectionGroup collection group instance to build quickfinder for 346 */ 347 protected void setupForCollectionGroup(View view, Object model, CollectionGroup collectionGroup) { 348 // check to see if data object class is configured for lookup, if so we will assume it should be enabled 349 // if not and the class configured for the collection group is lookupable, use that 350 if (StringUtils.isBlank(getDataObjectClassName())) { 351 Class<?> collectionObjectClass = collectionGroup.getCollectionObjectClass(); 352 353 boolean isCollectionClassLookupable = KRADServiceLocatorWeb.getViewDictionaryService().isLookupable( 354 collectionObjectClass); 355 if (isCollectionClassLookupable) { 356 setDataObjectClassName(collectionObjectClass.getName()); 357 358 // use PK fields for collection class as default field conversions 359 if ((fieldConversions == null) || fieldConversions.isEmpty()) { 360 List<String> collectionObjectPKFields = 361 KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames( 362 collectionObjectClass); 363 364 fieldConversions = new HashMap<String, String>(); 365 for (String pkField : collectionObjectPKFields) { 366 fieldConversions.put(pkField, pkField); 367 } 368 } 369 } else { 370 // no available data object class to lookup so disable quickfinder 371 setRender(false); 372 } 373 } 374 375 // set the lookup return collection name to this collection path 376 if (isRender() && StringUtils.isBlank(getLookupCollectionName())) { 377 setLookupCollectionName(collectionGroup.getBindingInfo().getBindingPath()); 378 } 379 380 if (isRender() && StringUtils.isBlank(getLookupCollectionId())) { 381 setLookupCollectionId(collectionGroup.getId()); 382 } 383 } 384 385 /** 386 * Adjusts the id for the quickfinder action, and then adds action parameters for passing along the 387 * quickfinder configuration to the lookup view. 388 * 389 * @param view view instance the quickfinder is associated with 390 * @param model object containing the view data 391 * @param parent component instance the quickfinder is associated with 392 */ 393 protected void setupQuickfinderAction(View view, Object model, LifecycleElement parent) { 394 quickfinderAction.setId(getId() + UifConstants.IdSuffixes.ACTION); 395 396 if (openInDialog) { 397 String lightboxScript = UifConstants.JsFunctions.SHOW_LOOKUP_DIALOG + "(\"" + quickfinderAction.getId() 398 + "\"," + returnByScript + ",\"" + lookupDialogId + "\");"; 399 400 quickfinderAction.setActionScript(lightboxScript); 401 } 402 403 quickfinderAction.addActionParameter(UifParameters.BASE_LOOKUP_URL, baseLookupUrl); 404 405 Class dataObjectClass = getDataObjectClass(dataObjectClassName); 406 ModuleService responsibleModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(dataObjectClass); 407 if (responsibleModuleService != null && responsibleModuleService.isExternalizable(dataObjectClass)) { 408 if (ExternalizableBusinessObject.class.isAssignableFrom(dataObjectClass)) { 409 Class implementationClass = responsibleModuleService.getExternalizableBusinessObjectImplementation(dataObjectClass.asSubclass( 410 ExternalizableBusinessObject.class)); 411 if (implementationClass != null) { 412 dataObjectClassName = implementationClass.getName(); 413 } 414 } 415 } 416 417 quickfinderAction.addActionParameter(UifParameters.DATA_OBJECT_CLASS_NAME, dataObjectClassName); 418 419 if (!fieldConversions.isEmpty()) { 420 quickfinderAction.addActionParameter(UifParameters.CONVERSION_FIELDS, KRADUtils.buildMapParameterString( 421 fieldConversions)); 422 } 423 424 if (!lookupParameters.isEmpty()) { 425 quickfinderAction.addActionParameter(UifParameters.LOOKUP_PARAMETERS, KRADUtils.buildMapParameterString( 426 lookupParameters)); 427 } 428 429 addActionParameterIfNotNull(UifParameters.VIEW_NAME, viewName); 430 addActionParameterIfNotNull(UifParameters.READ_ONLY_FIELDS, readOnlyLookupFields); 431 addActionParameterIfNotNull(UifParameters.RENDER_RETURN_LINK, renderReturnLink); 432 addActionParameterIfNotNull(UifParameters.RENDER_RESULT_ACTIONS, renderResultActions); 433 addActionParameterIfNotNull(UifParameters.REFERENCES_TO_REFRESH, referencesToRefresh); 434 addActionParameterIfNotNull(UifParameters.AUTO_SEARCH, autoSearch); 435 addActionParameterIfNotNull(UifParameters.RENDER_LOOKUP_CRITERIA, renderLookupCriteria); 436 addActionParameterIfNotNull(UifParameters.RENDER_CRITERIA_ACTIONS, renderCriteriaActions); 437 addActionParameterIfNotNull(UifParameters.HIDE_CRITERIA_ON_SEARCH, hideCriteriaOnSearch); 438 addActionParameterIfNotNull(UifParameters.RENDER_MAINTENANCE_LINKS, renderMaintenanceLinks); 439 addActionParameterIfNotNull(UifParameters.MULTIPLE_VALUES_SELECT, multipleValuesSelect); 440 addActionParameterIfNotNull(UifParameters.LOOKUP_COLLECTION_NAME, lookupCollectionName); 441 addActionParameterIfNotNull(UifParameters.LOOKUP_COLLECTION_ID, lookupCollectionId); 442 addActionParameterIfNotNull(UifParameters.QUICKFINDER_ID, getId()); 443 444 //insert additional lookup parameters. 445 if (additionalLookupParameters != null) { 446 //copy additional parameters to actionParameters 447 Map<String, String> actionParameters = quickfinderAction.getActionParameters(); 448 actionParameters.putAll(additionalLookupParameters); 449 quickfinderAction.setActionParameters(actionParameters); 450 } 451 } 452 453 private Class<?> getDataObjectClass(String className) { 454 Class<?> dataObjectClass; 455 456 try { 457 dataObjectClass = Class.forName(className); 458 } catch (ClassNotFoundException e) { 459 throw new RuntimeException("Unable to get class for name: " + className, e); 460 } 461 462 return dataObjectClass; 463 } 464 465 /** 466 * Utility method to add an action parameter to the quickfinder action if the given parameter value 467 * is non blank. 468 * 469 * @param parameterName name of the parameter to add 470 * @param parameterValue value for the parameter to add 471 */ 472 protected void addActionParameterIfNotNull(String parameterName, Object parameterValue) { 473 if ((parameterValue != null) && StringUtils.isNotBlank(parameterValue.toString())) { 474 quickfinderAction.addActionParameter(parameterName, parameterValue.toString()); 475 } 476 } 477 478 /** 479 * Adds post context data for the quickfinder so when the lookup return occurs the focus and jump point 480 * of the quickfinder action can be retrieved. 481 * 482 * {@inheritDoc} 483 */ 484 @Override 485 public void processEvent(ViewLifecycle.LifecycleEvent lifecycleEvent, View view, Object model, 486 LifecycleElement eventComponent) { 487 Action finalQuickfinderAction = (Action) eventComponent; 488 489 // add post metadata for focus point when the associated lookup returns 490 ViewLifecycle.getViewPostMetadata().addComponentPostData(this, 491 UifConstants.PostMetadata.QUICKFINDER_FOCUS_ID, finalQuickfinderAction.getFocusOnIdAfterSubmit()); 492 ViewLifecycle.getViewPostMetadata().addComponentPostData(this, 493 UifConstants.PostMetadata.QUICKFINDER_JUMP_TO_ID, finalQuickfinderAction.getJumpToIdAfterSubmit()); 494 } 495 496 /** 497 * Adds callback method and its parameters to post data so that when a refresh occurs it knows 498 * which view is returned from and possibly which collection line the quickfinder was on. 499 */ 500 protected void addCallbackParametersIfPresent() { 501 if (StringUtils.isNotBlank(callbackMethodToCall)) { 502 ViewLifecycle.getViewPostMetadata().addComponentPostData(this, 503 UifConstants.PostMetadata.QUICKFINDER_CALLBACK_METHOD_TO_CALL, callbackMethodToCall); 504 } 505 506 if (callbackMethod != null) { 507 ViewLifecycle.getViewPostMetadata().addComponentPostData(this, 508 UifConstants.PostMetadata.QUICKFINDER_CALLBACK_METHOD, callbackMethod); 509 } 510 511 if (callbackContext != null && !callbackContext.isEmpty()) { 512 ViewLifecycle.getViewPostMetadata().addComponentPostData(this, 513 UifConstants.PostMetadata.QUICKFINDER_CALLBACK_CONTEXT, callbackContext); 514 } 515 } 516 517 /** 518 * Returns the URL for the lookup for which parameters will be added. 519 * 520 * <p>The base URL includes the domain, context, and controller mapping for the lookup invocation. Parameters are 521 * then added based on configuration to complete the URL. This is generally defaulted to the application URL and 522 * internal KRAD servlet mapping, but can be changed to invoke another application such as the Rice standalone 523 * server</p> 524 * 525 * @return lookup base URL 526 */ 527 @BeanTagAttribute 528 public String getBaseLookupUrl() { 529 return this.baseLookupUrl; 530 } 531 532 /** 533 * @see QuickFinder#getBaseLookupUrl() 534 */ 535 public void setBaseLookupUrl(String baseLookupUrl) { 536 this.baseLookupUrl = baseLookupUrl; 537 } 538 539 /** 540 * Full class name the lookup should be provided for. 541 * 542 * <p>This is passed on to the lookup request for the data object the lookup should be rendered for. This is then 543 * used by the lookup framework to select the lookup view (if more than one lookup view exists for the same 544 * data object class name, the {@link #getViewName()} property should be specified to select the view to 545 * render).</p> 546 * 547 * @return lookup class name 548 */ 549 @BeanTagAttribute 550 public String getDataObjectClassName() { 551 return this.dataObjectClassName; 552 } 553 554 /** 555 * @see QuickFinder#getDataObjectClassName() 556 */ 557 public void setDataObjectClassName(String dataObjectClassName) { 558 this.dataObjectClassName = dataObjectClassName; 559 } 560 561 /** 562 * When multiple target lookup views exists for the same data object class, the view name can be set to 563 * determine which one to use. 564 * 565 * <p>When creating multiple lookup views for the same data object class, the view name can be specified for the 566 * different versions (for example 'simple' and 'advanced'). When multiple lookup views exist the view name must 567 * be sent with the data object class for the request. Note the view id can be alternatively used to uniquely 568 * identify the lookup view</p> 569 * 570 * @return String name of lookup view 571 */ 572 @BeanTagAttribute 573 public String getViewName() { 574 return this.viewName; 575 } 576 577 /** 578 * @see QuickFinder#getViewName() 579 */ 580 public void setViewName(String viewName) { 581 this.viewName = viewName; 582 } 583 584 /** 585 * Indicates whether the lookup return should occur through script, or by refresing the page (making server 586 * request). 587 * 588 * <p>For quickfinders that do not need any additional server side action, return through script can be 589 * much faster and prevents a page refresh.</p> 590 * 591 * @return boolean true if the return should occur through script, false if not (default) 592 */ 593 @BeanTagAttribute 594 public boolean isReturnByScript() { 595 return returnByScript; 596 } 597 598 /** 599 * @see QuickFinder#isReturnByScript() 600 */ 601 public void setReturnByScript(boolean returnByScript) { 602 this.returnByScript = returnByScript; 603 } 604 605 /** 606 * Comma delimited String of property names on the lookup view that should be read only. 607 * 608 * <p>When requesting a lookup view, property names for fields that are rendered as search criteria can be marked 609 * as read-only. This is usually done when a lookup parameter for that property is sent in and the user should 610 * not be allowed to change the value</p> 611 * 612 * @return property names (delimited by a comma) whose criteria fields should be read-only on the 613 * lookup view 614 */ 615 @BeanTagAttribute 616 public String getReadOnlyLookupFields() { 617 return this.readOnlyLookupFields; 618 } 619 620 /** 621 * @see QuickFinder#setReadOnlyLookupFields(java.lang.String) 622 */ 623 public void setReadOnlyLookupFields(String readOnlyLookupFields) { 624 this.readOnlyLookupFields = readOnlyLookupFields; 625 } 626 627 /** 628 * List of property names on the model that should be refreshed when the lookup returns. 629 * 630 * <p>Note this is only relevant when the return by script option is not enabled (meaning the server will be 631 * invoked 632 * on the lookup return call)</p> 633 * 634 * <p>When a lookup return call is made (to return a result value) the controller refresh method will be invoked. 635 * If 636 * refresh properties are configured, a call to refresh those references from the database will be made. This is 637 * useful if the lookup returns a foreign key field and the related record is needed.</p> 638 * 639 * @return list of property names to refresh 640 */ 641 @BeanTagAttribute 642 public String getReferencesToRefresh() { 643 return this.referencesToRefresh; 644 } 645 646 /** 647 * @see QuickFinder#getReferencesToRefresh() 648 */ 649 public void setReferencesToRefresh(String referencesToRefresh) { 650 this.referencesToRefresh = referencesToRefresh; 651 } 652 653 /** 654 * Map that determines what properties from a result lookup row (if selected) will be returned to properties on 655 * the calling view. 656 * 657 * <p>The purpose of using the lookup is to search for a particular value and return that value to the form being 658 * completed. In order for the lookup framework to return the field back to us, we must specify the name of the 659 * field on the data object class whose value we need, and the name of the field on the calling view. Furthermore, 660 * we can choose to have the lookup return additional fields that populate other form fields or informational 661 * properties (see ‘Field Queries and Informational Properties’). These pairs of fields are known as 662 * ‘field conversions’.</p> 663 * 664 * <p>The fieldConversions property is a Map. Each entry represents a field that will be returned back from the 665 * lookup, with the entry key being the field name on the data object class, and the entry value being the field 666 * name on the calling view. It is helpful to think of this as a from-to mapping. Pulling from the data object 667 * field (map key) to the calling view field (map value).</p> 668 * 669 * @return mapping of lookup data object property names to view property names 670 */ 671 @BeanTagAttribute 672 public Map<String, String> getFieldConversions() { 673 return this.fieldConversions; 674 } 675 676 /** 677 * @see QuickFinder#getFieldConversions() 678 */ 679 public void setFieldConversions(Map<String, String> fieldConversions) { 680 this.fieldConversions = fieldConversions; 681 } 682 683 /** 684 * Map that determines what properties from a calling view will be sent to properties on that are rendered 685 * for the lookup view's search fields (they can be hidden). 686 * 687 * <p> When invoking a lookup view, we can pre-populate search fields on the lookup view with data from the view 688 * that called the lookup. The user can then perform the search with these values, or (if edited is allowed or 689 * the fields are not hidden) change the passed in values. When the lookup is invoked, the values for the 690 * properties configured within the lookup parameters Map will be pulled and passed along as values for the 691 * lookup view properties</p> 692 * 693 * @return mapping of calling view properties to lookup view search fields 694 */ 695 @BeanTagAttribute 696 public Map<String, String> getLookupParameters() { 697 return this.lookupParameters; 698 } 699 700 /** 701 * @see QuickFinder#getLookupParameters() 702 */ 703 public void setLookupParameters(Map<String, String> lookupParameters) { 704 this.lookupParameters = lookupParameters; 705 } 706 707 /** 708 * Indicates whether the return links for lookup results should be rendered. 709 * 710 * <p>A lookup view can be invoked to allow the user to select a value (or set of values) to return back to the 711 * calling view. For single value lookups this is done with a return link that is rendered for each row. This 712 * return link can be disabled by setting this property to false</p> 713 * 714 * @return true if the return link should not be shown, false if it should be 715 */ 716 @BeanTagAttribute 717 public Boolean getRenderReturnLink() { 718 return this.renderReturnLink; 719 } 720 721 /** 722 * @see QuickFinder#getRenderReturnLink() 723 */ 724 public void setRenderReturnLink(Boolean renderReturnLink) { 725 this.renderReturnLink = renderReturnLink; 726 } 727 728 /** 729 * Indicates whether the maintenance actions (or others) are rendered on the invoked lookup view. 730 * 731 * <p>By default a lookup view will add an actions column for the result table that display maintenance links (in 732 * addition to a new link at the top of the page) if a maintenance action is available. Custom links can also be 733 * added to the action column as necessary. This flag can be set to true to suppress the rendering of the actions 734 * for the lookup call.</p> 735 * 736 * @return true if actions should be rendered, false if not 737 */ 738 @BeanTagAttribute 739 public Boolean getRenderResultActions() { 740 return renderResultActions; 741 } 742 743 /** 744 * @see QuickFinder#getRenderResultActions() 745 */ 746 public void setRenderResultActions(Boolean renderResultActions) { 747 this.renderResultActions = renderResultActions; 748 } 749 750 /** 751 * Indicates whether the search should be executed when first rendering the lookup view. 752 * 753 * <p>By default the lookup view is rendered, the user enters search values and executes the results. This flag can 754 * be set to true to indicate the search should be performed before showing the screen to the user. This is 755 * generally used when search criteria is being passed in as well</p> 756 * 757 * @return true if the search should be performed initially, false if not 758 */ 759 @BeanTagAttribute 760 public Boolean getAutoSearch() { 761 return this.autoSearch; 762 } 763 764 /** 765 * @see org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute#name() 766 */ 767 public void setAutoSearch(Boolean autoSearch) { 768 this.autoSearch = autoSearch; 769 } 770 771 /** 772 * Indicates whether the lookup criteria (search group) should be enabled on the invoked lookup view. 773 * 774 * <p> Setting the this to false will not display the lookup criteria but only the results. Therefore this is only 775 * useful when setting {@link #getAutoSearch()} to true and passing in criteria</p> 776 * 777 * @return true if lookup criteria should be displayed, false if not 778 */ 779 @BeanTagAttribute 780 public Boolean getRenderLookupCriteria() { 781 return this.renderLookupCriteria; 782 } 783 784 /** 785 * @see QuickFinder#getRenderLookupCriteria() 786 */ 787 public void setRenderLookupCriteria(Boolean renderLookupCriteria) { 788 this.renderLookupCriteria = renderLookupCriteria; 789 } 790 791 /** 792 * Indicates whether the criteria actions (footer) should be rendered on the invoked lookup view. 793 * 794 * @return boolean true if actions should be rendered (default), false if not 795 */ 796 @BeanTagAttribute 797 public Boolean getRenderCriteriaActions() { 798 return this.renderCriteriaActions; 799 } 800 801 /** 802 * @see QuickFinder#getRenderCriteriaActions() 803 */ 804 public void setRenderCriteriaActions(Boolean renderCriteriaActions) { 805 this.renderCriteriaActions = renderCriteriaActions; 806 } 807 808 /** 809 * Indicates whether the lookup criteria should be hidden when a search is executed. 810 * 811 * @return boolean true if criteria should be hidden, false if not 812 */ 813 @BeanTagAttribute 814 public Boolean getHideCriteriaOnSearch() { 815 return hideCriteriaOnSearch; 816 } 817 818 /** 819 * @see QuickFinder#getHideCriteriaOnSearch() 820 */ 821 public void setHideCriteriaOnSearch(Boolean hideCriteriaOnSearch) { 822 this.hideCriteriaOnSearch = hideCriteriaOnSearch; 823 } 824 825 /** 826 * Indicates whether the maintenance action links should be rendered for the invoked lookup view. 827 * 828 * <p>If a maintenance view exists for the data object associated with the lookup view, the framework will add 829 * links to initiate a new maintenance document. This flag can be used to disable the rendering of these links</p> 830 * 831 * <p> Note this serves similar purpose to {@link #getRenderResultActions()} but the intent is to only remove the 832 * maintenance links in this situation, not the complete actions column</p> 833 * 834 * @return true if maintenance links should be shown on the lookup view, false if not 835 */ 836 @BeanTagAttribute 837 public Boolean getRenderMaintenanceLinks() { 838 return this.renderMaintenanceLinks; 839 } 840 841 /** 842 * @see QuickFinder#getRenderMaintenanceLinks() 843 */ 844 public void setRenderMaintenanceLinks(Boolean renderMaintenanceLinks) { 845 this.renderMaintenanceLinks = renderMaintenanceLinks; 846 } 847 848 /** 849 * Action component that is used to rendered for the field for invoking the quickfinder action (bringing up the 850 * lookup). 851 * 852 * <p>Through the action configuration the image (or link, button) rendered for the quickfinder can be modified. In 853 * addition to other action component settings</p> 854 * 855 * @return Action instance rendered for quickfinder 856 */ 857 @BeanTagAttribute(type = BeanTagAttribute.AttributeType.BYTYPE) 858 public Action getQuickfinderAction() { 859 return this.quickfinderAction; 860 } 861 862 /** 863 * @see QuickFinder#getQuickfinderAction() 864 */ 865 public void setQuickfinderAction(Action quickfinderAction) { 866 this.quickfinderAction = quickfinderAction; 867 } 868 869 /** 870 * The id of the DialogGroup to use when the openInDialog property is true. 871 * 872 * <p>The DialogGroup should only contain an iframe for its items. When not set, a default dialog 873 * will be used.</p> 874 * 875 * @return the id of the dialog to use for this quickfinder 876 */ 877 @BeanTagAttribute 878 public String getLookupDialogId() { 879 return lookupDialogId; 880 } 881 882 /** 883 * @see QuickFinder#getLookupDialogId() 884 */ 885 public void setLookupDialogId(String lookupDialogId) { 886 this.lookupDialogId = lookupDialogId; 887 } 888 889 /** 890 * True if the quickfinder's lookup should be opened in a dialog; true is the default setting for the 891 * bean. 892 * 893 * @return true if the lookup should be opened in a dialog, false to open in a new window 894 */ 895 @BeanTagAttribute 896 public boolean isOpenInDialog() { 897 return openInDialog; 898 } 899 900 /** 901 * @see QuickFinder#isOpenInDialog() 902 */ 903 public void setOpenInDialog(boolean openInDialog) { 904 this.openInDialog = openInDialog; 905 } 906 907 /** 908 * Indicates whether the invoked lookup view should allow multiple values to be selected and returned. 909 * 910 * @return true if multi-value lookup should be requested, false for normal lookup 911 */ 912 @BeanTagAttribute 913 public Boolean getMultipleValuesSelect() { 914 return multipleValuesSelect; 915 } 916 917 /** 918 * @see QuickFinder#getMultipleValuesSelect() 919 */ 920 public void setMultipleValuesSelect(Boolean multipleValuesSelect) { 921 this.multipleValuesSelect = multipleValuesSelect; 922 } 923 924 /** 925 * For the case of multi-value lookup, indicates the collection that should be populated with 926 * the return results. 927 * 928 * <p>Note when the quickfinder is associated with a {@link CollectionGroup}, this property is 929 * set automatically from the collection name associated with the group</p> 930 * 931 * @return collection name (must be full binding path) 932 */ 933 @BeanTagAttribute 934 public String getLookupCollectionName() { 935 return lookupCollectionName; 936 } 937 938 /** 939 * @see QuickFinder#getLookupCollectionName() 940 */ 941 public void setLookupCollectionName(String lookupCollectionName) { 942 this.lookupCollectionName = lookupCollectionName; 943 } 944 945 /** 946 * For the case of multi-value lookup, indicates the collection id that should be populated with 947 * the return results. 948 * 949 * <p>Note when the quickfinder is associated with a {@link CollectionGroup}, this property is 950 * set automatically from the collection id associated with the group</p> 951 * 952 * @return collection id 953 */ 954 @BeanTagAttribute 955 public String getLookupCollectionId() { 956 return lookupCollectionId; 957 } 958 959 /** 960 * @see QuickFinder#getLookupCollectionId() 961 */ 962 public void setLookupCollectionId(String lookupCollectionId) { 963 this.lookupCollectionId = lookupCollectionId; 964 } 965 966 /** 967 * The additional parameters that were passed to the quickFinder. 968 * 969 * @return additionalLookupParameters - map of additional lookup parameters 970 */ 971 @BeanTagAttribute 972 public Map<String, String> getAdditionalLookupParameters() { 973 return additionalLookupParameters; 974 } 975 976 /** 977 * @see QuickFinder#getAdditionalLookupParameters() 978 */ 979 public void setAdditionalLookupParameters(Map<String, String> additionalLookupParameters) { 980 this.additionalLookupParameters = additionalLookupParameters; 981 } 982 983 /** 984 * The name of the callback method to invoke in the view helper service that checks 985 * request parameters to indicate what view is being returned from. 986 * 987 * @return callbackMethodToCall - the name of the callback method 988 */ 989 public String getCallbackMethodToCall() { 990 return callbackMethodToCall; 991 } 992 993 /** 994 * @see QuickFinder#getCallbackMethodToCall() 995 */ 996 public void setCallbackMethodToCall(String callbackMethodToCall) { 997 this.callbackMethodToCall = callbackMethodToCall; 998 } 999 1000 /** 1001 * The specific method invoker to use to invoke the callback method to call. 1002 * 1003 * @return callbackMethod - the method invoker 1004 */ 1005 public MethodInvokerConfig getCallbackMethod() { 1006 return callbackMethod; 1007 } 1008 1009 /** 1010 * @see QuickFinder#getCallbackMethod() 1011 */ 1012 public void setCallbackMethod(MethodInvokerConfig callbackMethod) { 1013 this.callbackMethod = callbackMethod; 1014 } 1015 1016 /** 1017 * The context of parameters to be provided to the callback method to call. 1018 * 1019 * @return callbackContext - map of parameters 1020 */ 1021 public Map<String, String> getCallbackContext() { 1022 return callbackContext; 1023 } 1024 1025 /** 1026 * @see QuickFinder#getCallbackContext() 1027 */ 1028 public void setCallbackContext(Map<String, String> callbackContext) { 1029 this.callbackContext = callbackContext; 1030 } 1031}