1 /**
2 * Copyright 2005-2013 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.uif.widget;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import org.apache.commons.lang.StringUtils;
24 import org.kuali.rice.krad.bo.DataObjectRelationship;
25 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
26 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
27 import org.kuali.rice.krad.datadictionary.parse.BeanTags;
28 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
29 import org.kuali.rice.krad.uif.UifConstants;
30 import org.kuali.rice.krad.uif.UifParameters;
31 import org.kuali.rice.krad.uif.component.BindingInfo;
32 import org.kuali.rice.krad.uif.component.Component;
33 import org.kuali.rice.krad.uif.container.CollectionGroup;
34 import org.kuali.rice.krad.uif.element.Action;
35 import org.kuali.rice.krad.uif.field.InputField;
36 import org.kuali.rice.krad.uif.lifecycle.LifecycleEventListener;
37 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
38 import org.kuali.rice.krad.uif.service.ViewHelperService;
39 import org.kuali.rice.krad.uif.util.ScriptUtils;
40 import org.kuali.rice.krad.uif.util.ViewModelUtils;
41 import org.kuali.rice.krad.uif.view.View;
42 import org.kuali.rice.krad.util.KRADConstants;
43 import org.kuali.rice.krad.util.KRADUtils;
44
45 /**
46 * Widget for navigating to a lookup from a field (called a quickfinder).
47 *
48 * @author Kuali Rice Team (rice.collab@kuali.org)
49 */
50 @BeanTags({@BeanTag(name = "quickFinder-bean", parent = "Uif-QuickFinder"),
51 @BeanTag(name = "quickFinderByScript-bean", parent = "Uif-QuickFinderByScript"),
52 @BeanTag(name = "collectionQuickFinder-bean", parent = "Uif-CollectionQuickFinder")})
53 public class QuickFinder extends WidgetBase implements LifecycleEventListener {
54 private static final long serialVersionUID = 3302390972815386785L;
55
56 // lookup configuration
57 private String baseLookupUrl;
58 private String dataObjectClassName;
59 private String viewName;
60
61 private boolean returnByScript;
62 private String readOnlyLookupFields;
63 private String referencesToRefresh;
64 private String lookupCollectionName;
65
66 private Map<String, String> fieldConversions;
67 private Map<String, String> lookupParameters;
68
69 private Action quickfinderAction;
70 private LightBox lightBox;
71
72 // lookup view options
73 private Boolean renderReturnLink;
74 private Boolean renderResultActions;
75 private Boolean autoSearch;
76 private Boolean renderLookupCriteria;
77 private Boolean renderCriteriaActions;
78 private Boolean renderMaintenanceLinks;
79 private Boolean multipleValuesSelect;
80
81 public QuickFinder() {
82 super();
83
84 fieldConversions = new HashMap<String, String>();
85 lookupParameters = new HashMap<String, String>();
86 }
87
88 /**
89 * The following initialization is performed:
90 *
91 * <ul>
92 * <li>Registers an event on the quickfinder action</li>
93 * </ul>
94 *
95 * {@inheritDoc}
96 */
97 @Override
98 public void performInitialization(Object model) {
99 super.performInitialization(model);
100
101 ViewLifecycle viewLifecycle = ViewLifecycle.getActiveLifecycle();
102 viewLifecycle.registerLifecycleCompleteListener(quickfinderAction, this);
103 }
104
105 /**
106 * The following finalization is performed:
107 *
108 * <ul>
109 * <li>Sets up the quickfinder based on whether the parent is an input field or collection group</li>
110 * <li>Adds action parameters to the quickfinder action based on the quickfinder configuration</li>
111 * </ul>
112 *
113 * {@inheritDoc}
114 */
115 @Override
116 public void performFinalize(Object model, Component parent) {
117 super.performFinalize(model, parent);
118
119 if (parent.isReadOnly()) {
120 setRender(false);
121 }
122
123 if (!isRender()) {
124 return;
125 }
126
127 View view = ViewLifecycle.getActiveLifecycle().getView();
128
129 if (parent instanceof InputField) {
130 setupForInputField(view, model, (InputField) parent);
131 } else if (parent instanceof CollectionGroup) {
132 setupForCollectionGroup(view, model, (CollectionGroup) parent);
133 }
134
135 setupQuickfinderAction(view, model, parent);
136 }
137
138 /**
139 * If quickfinder not manually configured attempts to find a relationship to build the quickfinder on, then also
140 * adjusts the path for any configured field conversions, lookup parameters, and refresh refreshes.
141 *
142 * @param view view instance the quickfinder is associated with
143 * @param model object containing the view data
144 * @param inputField input field instance the quickfinder should apply to
145 */
146 protected void setupForInputField(View view, Object model, InputField inputField) {
147 // if quickfinder class name not specified, attempt to find a relationship to build the quickfinder from
148 if (StringUtils.isBlank(dataObjectClassName)) {
149 DataObjectRelationship relationship = getRelationshipForField(view, model, inputField);
150
151 // if no relationship found cannot have a quickfinder
152 if (relationship == null) {
153 setRender(false);
154
155 return;
156 }
157
158 dataObjectClassName = relationship.getRelatedClass().getName();
159
160 if ((fieldConversions == null) || fieldConversions.isEmpty()) {
161 generateFieldConversions(relationship);
162 }
163
164 if ((lookupParameters == null) || lookupParameters.isEmpty()) {
165 generateLookupParameters(relationship);
166 }
167 }
168
169 // adjust paths based on associated attribute field
170 updateFieldConversions(inputField.getBindingInfo());
171 updateLookupParameters(inputField.getBindingInfo());
172 updateReferencesToRefresh(inputField.getBindingInfo());
173 }
174
175 /**
176 * Retrieves any {@link org.kuali.rice.krad.bo.DataObjectRelationship} that is associated with the given
177 * field and has a configured lookup view.
178 *
179 * @param view view instance the quickfinder is associated with
180 * @param model object containing the view data
181 * @param field input field instance the quickfinder should apply to
182 * @return data object relationship for the field, or null if one could not be found
183 */
184 protected DataObjectRelationship getRelationshipForField(View view, Object model, InputField field) {
185 String propertyName = field.getBindingInfo().getBindingName();
186
187 // get object instance and class for parent
188 Object parentObject = ViewModelUtils.getParentObjectForMetadata(view, model, field);
189 Class<?> parentObjectClass = null;
190 if (parentObject != null) {
191 parentObjectClass = parentObject.getClass();
192 }
193
194 // get relationship from metadata service
195 return KRADServiceLocatorWeb.getLegacyDataAdapter().getDataObjectRelationship(parentObject,
196 parentObjectClass, propertyName, "", true, true, false);
197 }
198
199 /**
200 * Generates the lookup field conversions based on the references from the given relationship.
201 *
202 * @param relationship relationship field conversions will be generated from
203 */
204 protected void generateFieldConversions(DataObjectRelationship relationship) {
205 fieldConversions = new HashMap<String, String>();
206
207 for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) {
208 String fromField = entry.getValue();
209 String toField = entry.getKey();
210
211 fieldConversions.put(fromField, toField);
212 }
213 }
214
215 /**
216 * Generates the lookup parameters based on the references from the given relationship.
217 *
218 * @param relationship relationship lookup parameters will be generated from
219 */
220 protected void generateLookupParameters(DataObjectRelationship relationship) {
221 lookupParameters = new HashMap<String, String>();
222
223 for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) {
224 String fromField = entry.getKey();
225 String toField = entry.getValue();
226
227 if (relationship.getUserVisibleIdentifierKey() == null || relationship.getUserVisibleIdentifierKey().equals(
228 fromField)) {
229 lookupParameters.put(fromField, toField);
230 }
231 }
232 }
233
234 /**
235 * Adjusts the path on the field conversion to property to match the binding path prefix of the
236 * given {@link org.kuali.rice.krad.uif.component.BindingInfo}.
237 *
238 * @param bindingInfo binding info instance to copy binding path prefix from
239 */
240 protected void updateFieldConversions(BindingInfo bindingInfo) {
241 Map<String, String> adjustedFieldConversions = new HashMap<String, String>();
242 for (String fromField : fieldConversions.keySet()) {
243 String toField = fieldConversions.get(fromField);
244 String adjustedToFieldPath = bindingInfo.getPropertyAdjustedBindingPath(toField);
245
246 adjustedFieldConversions.put(fromField, adjustedToFieldPath);
247 }
248
249 this.fieldConversions = adjustedFieldConversions;
250 }
251
252 /**
253 * Adjusts the path on the lookup parameter from property to match the binding path prefix of the
254 * given {@link org.kuali.rice.krad.uif.component.BindingInfo}.
255 *
256 * @param bindingInfo binding info instance to copy binding path prefix from
257 */
258 protected void updateLookupParameters(BindingInfo bindingInfo) {
259 Map<String, String> adjustedLookupParameters = new HashMap<String, String>();
260 for (String fromField : lookupParameters.keySet()) {
261 String toField = lookupParameters.get(fromField);
262 String adjustedFromFieldPath = bindingInfo.getPropertyAdjustedBindingPath(fromField);
263
264 adjustedLookupParameters.put(adjustedFromFieldPath, toField);
265 }
266
267 this.lookupParameters = adjustedLookupParameters;
268 }
269
270 /**
271 * Adjust the path on the referencesToRefresh parameter to match the binding path prefix of the
272 * given {@link org.kuali.rice.krad.uif.component.BindingInfo}.
273 *
274 * @param bindingInfo binding info instance to copy binding path prefix from
275 */
276 protected void updateReferencesToRefresh(BindingInfo bindingInfo) {
277 List<String> adjustedReferencesToRefresh = new ArrayList<String>();
278
279 if (referencesToRefresh == null) {
280 referencesToRefresh = new String();
281 }
282
283 for (String reference : StringUtils.split(referencesToRefresh, KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR)) {
284 adjustedReferencesToRefresh.add(bindingInfo.getPropertyAdjustedBindingPath(reference));
285 }
286
287 this.referencesToRefresh = StringUtils.join(adjustedReferencesToRefresh,
288 KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR);
289 }
290
291 /**
292 * Configures the quickfinder for the given collection group instance by setting the data object class,
293 * field conversions, and lookup collection name (if necessary).
294 *
295 * @param view view instance the quickfinder is associated with
296 * @param model object containing the view data
297 * @param collectionGroup collection group instance to build quickfinder for
298 */
299 protected void setupForCollectionGroup(View view, Object model, CollectionGroup collectionGroup) {
300 // check to see if data object class is configured for lookup, if so we will assume it should be enabled
301 // if not and the class configured for the collection group is lookupable, use that
302 if (StringUtils.isBlank(getDataObjectClassName())) {
303 Class<?> collectionObjectClass = collectionGroup.getCollectionObjectClass();
304
305 boolean isCollectionClassLookupable = KRADServiceLocatorWeb.getViewDictionaryService().isLookupable(
306 collectionObjectClass);
307 if (isCollectionClassLookupable) {
308 setDataObjectClassName(collectionObjectClass.getName());
309
310 // use PK fields for collection class as default field conversions
311 if ((fieldConversions == null) || fieldConversions.isEmpty()) {
312 List<String> collectionObjectPKFields =
313 KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(
314 collectionObjectClass);
315
316 fieldConversions = new HashMap<String, String>();
317 for (String pkField : collectionObjectPKFields) {
318 fieldConversions.put(pkField, pkField);
319 }
320 }
321 } else {
322 // no available data object class to lookup so disable quickfinder
323 setRender(false);
324 }
325 }
326
327 // set the lookup return collection name to this collection path
328 if (isRender() && StringUtils.isBlank(getLookupCollectionName())) {
329 setLookupCollectionName(collectionGroup.getBindingInfo().getBindingPath());
330 }
331 }
332
333 /**
334 * Adjusts the id for the quickfinder action, and then adds action parameters for passing along the
335 * quickfinder configuration to the lookup view.
336 *
337 * @param view view instance the quickfinder is associated with
338 * @param model object containing the view data
339 * @param parent component instance the quickfinder is associated with
340 */
341 protected void setupQuickfinderAction(View view, Object model, Component parent) {
342 quickfinderAction.setId(getId() + UifConstants.IdSuffixes.ACTION);
343
344 if ((lightBox != null) && lightBox.isRender()) {
345 String lightboxScript = UifConstants.JsFunctions.CREATE_LIGHTBOX_POST + "(\"" + quickfinderAction.getId()
346 + "\"," + lightBox.getTemplateOptionsJSString() + "," + returnByScript + ");";
347
348 quickfinderAction.setActionScript(lightboxScript);
349 }
350
351 quickfinderAction.addActionParameter(UifParameters.BASE_LOOKUP_URL, baseLookupUrl);
352 quickfinderAction.addActionParameter(UifParameters.DATA_OBJECT_CLASS_NAME, dataObjectClassName);
353
354 if (!fieldConversions.isEmpty()) {
355 quickfinderAction.addActionParameter(UifParameters.CONVERSION_FIELDS, KRADUtils.buildMapParameterString(
356 fieldConversions));
357 }
358
359 if (!lookupParameters.isEmpty()) {
360 quickfinderAction.addActionParameter(UifParameters.LOOKUP_PARAMETERS, KRADUtils.buildMapParameterString(
361 lookupParameters));
362 }
363
364 addActionParameterIfNotNull(UifParameters.VIEW_NAME, viewName);
365 addActionParameterIfNotNull(UifParameters.READ_ONLY_FIELDS, readOnlyLookupFields);
366 addActionParameterIfNotNull(UifParameters.RENDER_RETURN_LINK, renderReturnLink);
367 addActionParameterIfNotNull(UifParameters.RENDER_RESULT_ACTIONS, renderResultActions);
368 addActionParameterIfNotNull(UifParameters.REFERENCES_TO_REFRESH, referencesToRefresh);
369 addActionParameterIfNotNull(UifParameters.AUTO_SEARCH, autoSearch);
370 addActionParameterIfNotNull(UifParameters.RENDER_LOOKUP_CRITERIA, renderLookupCriteria);
371 addActionParameterIfNotNull(UifParameters.RENDER_CRITERIA_ACTIONS, renderCriteriaActions);
372 addActionParameterIfNotNull(UifParameters.RENDER_MAINTENANCE_LINKS, renderMaintenanceLinks);
373 addActionParameterIfNotNull(UifParameters.MULTIPLE_VALUES_SELECT, multipleValuesSelect);
374 addActionParameterIfNotNull(UifParameters.LOOKUP_COLLECTION_NAME, lookupCollectionName);
375 addActionParameterIfNotNull(UifParameters.QUICKFINDER_ID, getId());
376 }
377
378 /**
379 * Utility method to add an action parameter to the quickfinder action if the given parameter value
380 * is non blank.
381 *
382 * @param parameterName name of the parameter to add
383 * @param parameterValue value for the parameter to add
384 */
385 protected void addActionParameterIfNotNull(String parameterName, Object parameterValue) {
386 if ((parameterValue != null) && StringUtils.isNotBlank(parameterValue.toString())) {
387 quickfinderAction.addActionParameter(parameterName, parameterValue.toString());
388 }
389 }
390
391 /**
392 * {@inheritDoc}
393 */
394 @Override
395 public List<Component> getComponentsForLifecycle() {
396 List<Component> components = super.getComponentsForLifecycle();
397
398 components.add(quickfinderAction);
399 components.add(lightBox);
400
401 return components;
402 }
403
404 /**
405 * Adds post context data for the quickfinder so when the lookup return occurs the focus and jump point
406 * of the quickfinder action can be retrieved.
407 *
408 * @see org.kuali.rice.krad.uif.lifecycle.LifecycleEventListener#processEvent(org.kuali.rice.krad.uif.lifecycle.ViewLifecycle.LifecycleEvent,
409 * org.kuali.rice.krad.uif.view.View, java.lang.Object, org.kuali.rice.krad.uif.component.Component)
410 */
411 @Override
412 public void processEvent(ViewLifecycle.LifecycleEvent lifecycleEvent, View view, Object model,
413 Component eventComponent) {
414 Action finalQuickfinderAction = (Action) eventComponent;
415
416 // add post metadata for focus point when the associated lookup returns
417 view.getViewIndex().addPostContextEntry(getId(), UifConstants.PostContextKeys.QUICKFINDER_FOCUS_ID,
418 finalQuickfinderAction.getFocusOnIdAfterSubmit());
419 view.getViewIndex().addPostContextEntry(getId(), UifConstants.PostContextKeys.QUICKFINDER_JUMP_TO_ID,
420 finalQuickfinderAction.getJumpToIdAfterSubmit());
421 }
422
423 /**
424 * Returns the URL for the lookup for which parameters will be added.
425 *
426 * <p>The base URL includes the domain, context, and controller mapping for the lookup invocation. Parameters are
427 * then added based on configuration to complete the URL. This is generally defaulted to the application URL and
428 * internal KRAD servlet mapping, but can be changed to invoke another application such as the Rice standalone
429 * server</p>
430 *
431 * @return lookup base URL
432 */
433 @BeanTagAttribute(name = "baseLookupUrl")
434 public String getBaseLookupUrl() {
435 return this.baseLookupUrl;
436 }
437
438 /**
439 * @see QuickFinder#getBaseLookupUrl()
440 */
441 public void setBaseLookupUrl(String baseLookupUrl) {
442 this.baseLookupUrl = baseLookupUrl;
443 }
444
445 /**
446 * Full class name the lookup should be provided for.
447 *
448 * <p>This is passed on to the lookup request for the data object the lookup should be rendered for. This is then
449 * used by the lookup framework to select the lookup view (if more than one lookup view exists for the same
450 * data object class name, the {@link #getViewName()} property should be specified to select the view to
451 * render).</p>
452 *
453 * @return lookup class name
454 */
455 @BeanTagAttribute(name = "dataOjbectClassName")
456 public String getDataObjectClassName() {
457 return this.dataObjectClassName;
458 }
459
460 /**
461 * @see QuickFinder#getDataObjectClassName()
462 */
463 public void setDataObjectClassName(String dataObjectClassName) {
464 this.dataObjectClassName = dataObjectClassName;
465 }
466
467 /**
468 * When multiple target lookup views exists for the same data object class, the view name can be set to
469 * determine which one to use.
470 *
471 * <p>When creating multiple lookup views for the same data object class, the view name can be specified for the
472 * different versions (for example 'simple' and 'advanced'). When multiple lookup views exist the view name must
473 * be sent with the data object class for the request. Note the view id can be alternatively used to uniquely
474 * identify the lookup view</p>
475 *
476 * @return String name of lookup view
477 */
478 @BeanTagAttribute(name = "viewName")
479 public String getViewName() {
480 return this.viewName;
481 }
482
483 /**
484 * @see QuickFinder#getViewName()
485 */
486 public void setViewName(String viewName) {
487 this.viewName = viewName;
488 }
489
490 /**
491 * Indicates whether the lookup return should occur through script, or by refresing the page (making server
492 * request).
493 *
494 * <p>For quickfinders that do not need any additional server side action, return through script can be
495 * much faster and prevents a page refresh.</p>
496 *
497 * @return boolean true if the return should occur through script, false if not (default)
498 */
499 public boolean isReturnByScript() {
500 return returnByScript;
501 }
502
503 /**
504 * @see QuickFinder#isReturnByScript()
505 */
506 public void setReturnByScript(boolean returnByScript) {
507 this.returnByScript = returnByScript;
508 }
509
510 /**
511 * Comma delimited String of property names on the lookup view that should be read only.
512 *
513 * <p>When requesting a lookup view, property names for fields that are rendered as search criteria can be marked
514 * as read-only. This is usually done when a lookup parameter for that property is sent in and the user should
515 * not be allowed to change the value</p>
516 *
517 * @return property names (delimited by a comma) whose criteria fields should be read-only on the
518 * lookup view
519 */
520 @BeanTagAttribute(name = "readOnlyLookupFields")
521 public String getReadOnlyLookupFields() {
522 return this.readOnlyLookupFields;
523 }
524
525 /**
526 * @see QuickFinder#setReadOnlyLookupFields(java.lang.String)
527 */
528 public void setReadOnlyLookupFields(String readOnlyLookupFields) {
529 this.readOnlyLookupFields = readOnlyLookupFields;
530 }
531
532 /**
533 * List of property names on the model that should be refreshed when the lookup returns.
534 *
535 * <p>Note this is only relevant when the return by script option is not enabled (meaning the server will be
536 * invoked
537 * on the lookup return call)</p>
538 *
539 * <p>When a lookup return call is made (to return a result value) the controller refresh method will be invoked.
540 * If
541 * refresh properties are configured, a call to refresh those references from the database will be made. This is
542 * useful if the lookup returns a foreign key field and the related record is needed.</p>
543 *
544 * @return list of property names to refresh
545 */
546 @BeanTagAttribute(name = "referencesToRefresh")
547 public String getReferencesToRefresh() {
548 return this.referencesToRefresh;
549 }
550
551 /**
552 * @see QuickFinder#getReferencesToRefresh()
553 */
554 public void setReferencesToRefresh(String referencesToRefresh) {
555 this.referencesToRefresh = referencesToRefresh;
556 }
557
558 /**
559 * Map that determines what properties from a result lookup row (if selected) will be returned to properties on
560 * the calling view.
561 *
562 * <p>The purpose of using the lookup is to search for a particular value and return that value to the form being
563 * completed. In order for the lookup framework to return the field back to us, we must specify the name of the
564 * field on the data object class whose value we need, and the name of the field on the calling view. Furthermore,
565 * we can choose to have the lookup return additional fields that populate other form fields or informational
566 * properties (see ‘Field Queries and Informational Properties’). These pairs of fields are known as
567 * ‘field conversions’.</p>
568 *
569 * <p>The fieldConversions property is a Map. Each entry represents a field that will be returned back from the
570 * lookup, with the entry key being the field name on the data object class, and the entry value being the field
571 * name on the calling view. It is helpful to think of this as a from-to mapping. Pulling from the data object
572 * field (map key) to the calling view field (map value).</p>
573 *
574 * @return mapping of lookup data object property names to view property names
575 */
576 @BeanTagAttribute(name = "fieldConversions", type = BeanTagAttribute.AttributeType.MAPVALUE)
577 public Map<String, String> getFieldConversions() {
578 return this.fieldConversions;
579 }
580
581 /**
582 * @see QuickFinder#getFieldConversions()
583 */
584 public void setFieldConversions(Map<String, String> fieldConversions) {
585 this.fieldConversions = fieldConversions;
586 }
587
588 /**
589 * Map that determines what properties from a calling view will be sent to properties on that are rendered
590 * for the lookup view's search fields (they can be hidden).
591 *
592 * <p> When invoking a lookup view, we can pre-populate search fields on the lookup view with data from the view
593 * that called the lookup. The user can then perform the search with these values, or (if edited is allowed or
594 * the fields are not hidden) change the passed in values. When the lookup is invoked, the values for the
595 * properties configured within the lookup parameters Map will be pulled and passed along as values for the
596 * lookup view properties</p>
597 *
598 * @return mapping of calling view properties to lookup view search fields
599 */
600 @BeanTagAttribute(name = "lookupParameters", type = BeanTagAttribute.AttributeType.MAPVALUE)
601 public Map<String, String> getLookupParameters() {
602 return this.lookupParameters;
603 }
604
605 /**
606 * @see QuickFinder#getLookupParameters()
607 */
608 public void setLookupParameters(Map<String, String> lookupParameters) {
609 this.lookupParameters = lookupParameters;
610 }
611
612 /**
613 * Indicates whether the return links for lookup results should be rendered.
614 *
615 * <p>A lookup view can be invoked to allow the user to select a value (or set of values) to return back to the
616 * calling view. For single value lookups this is done with a return link that is rendered for each row. This
617 * return link can be disabled by setting this property to false</p>
618 *
619 * @return true if the return link should not be shown, false if it should be
620 */
621 @BeanTagAttribute(name = "renderReturnLink")
622 public Boolean getRenderReturnLink() {
623 return this.renderReturnLink;
624 }
625
626 /**
627 * @see QuickFinder#getRenderReturnLink()
628 */
629 public void setRenderReturnLink(Boolean renderReturnLink) {
630 this.renderReturnLink = renderReturnLink;
631 }
632
633 /**
634 * Indicates whether the maintenance actions (or others) are rendered on the invoked lookup view.
635 *
636 * <p>By default a lookup view will add an actions column for the result table that display maintenance links (in
637 * addition to a new link at the top of the page) if a maintenance action is available. Custom links can also be
638 * added to the action column as necessary. This flag can be set to true to suppress the rendering of the actions
639 * for the lookup call.</p>
640 *
641 * @return true if actions should be rendered, false if not
642 */
643 @BeanTagAttribute(name = "renderResultActions")
644 public Boolean getRenderResultActions() {
645 return renderResultActions;
646 }
647
648 /**
649 * @see QuickFinder#getRenderResultActions()
650 */
651 public void setRenderResultActions(Boolean renderResultActions) {
652 this.renderResultActions = renderResultActions;
653 }
654
655 /**
656 * Indicates whether the search should be executed when first rendering the lookup view.
657 *
658 * <p>By default the lookup view is rendered, the user enters search values and executes the results. This flag can
659 * be set to true to indicate the search should be performed before showing the screen to the user. This is
660 * generally used when search criteria is being passed in as well</p>
661 *
662 * @return true if the search should be performed initially, false if not
663 */
664 @BeanTagAttribute(name = "autoSearch")
665 public Boolean getAutoSearch() {
666 return this.autoSearch;
667 }
668
669 /**
670 * @see org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute#name()
671 */
672 public void setAutoSearch(Boolean autoSearch) {
673 this.autoSearch = autoSearch;
674 }
675
676 /**
677 * Indicates whether the lookup criteria (search group) should be enabled on the invoked lookup view.
678 *
679 * <p> Setting the this to false will not display the lookup criteria but only the results. Therefore this is only
680 * useful when setting {@link #getAutoSearch()} to true and passing in criteria</p>
681 *
682 * @return true if lookup criteria should be displayed, false if not
683 */
684 @BeanTagAttribute(name = "renderLookupCriteria")
685 public Boolean getRenderLookupCriteria() {
686 return this.renderLookupCriteria;
687 }
688
689 /**
690 * @see QuickFinder#getRenderLookupCriteria()
691 */
692 public void setRenderLookupCriteria(Boolean renderLookupCriteria) {
693 this.renderLookupCriteria = renderLookupCriteria;
694 }
695
696 /**
697 * Indicates whether the criteria actions (footer) should be rendered on the invoked lookup view.
698 *
699 * @return boolean true if actions should be rendered (default), false if not
700 */
701 @BeanTagAttribute(name = "renderCriteriaActions")
702 public Boolean getRenderCriteriaActions() {
703 return this.renderCriteriaActions;
704 }
705
706 /**
707 * @see QuickFinder#getRenderCriteriaActions()
708 */
709 public void setRenderCriteriaActions(Boolean renderCriteriaActions) {
710 this.renderCriteriaActions = renderCriteriaActions;
711 }
712
713 /**
714 * Indicates whether the maintenance action links should be rendered for the invoked lookup view.
715 *
716 * <p>If a maintenance view exists for the data object associated with the lookup view, the framework will add
717 * links to initiate a new maintenance document. This flag can be used to disable the rendering of these links</p>
718 *
719 * <p> Note this serves similar purpose to {@link #getRenderResultActions()} but the intent is to only remove the
720 * maintenance links in this situation, not the complete actions column</p>
721 *
722 * @return true if maintenance links should be shown on the lookup view, false if not
723 */
724 @BeanTagAttribute(name = "renderMaintenanceLinks")
725 public Boolean getRenderMaintenanceLinks() {
726 return this.renderMaintenanceLinks;
727 }
728
729 /**
730 * @see QuickFinder#getRenderMaintenanceLinks()
731 */
732 public void setRenderMaintenanceLinks(Boolean renderMaintenanceLinks) {
733 this.renderMaintenanceLinks = renderMaintenanceLinks;
734 }
735
736 /**
737 * Action component that is used to rendered for the field for invoking the quickfinder action (bringing up the
738 * lookup).
739 *
740 * <p>Through the action configuration the image (or link, button) rendered for the quickfinder can be modified. In
741 * addition to other action component settings</p>
742 *
743 * @return Action instance rendered for quickfinder
744 */
745 @BeanTagAttribute(name = "quickfinderAction", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
746 public Action getQuickfinderAction() {
747 return this.quickfinderAction;
748 }
749
750 /**
751 * @see QuickFinder#getQuickfinderAction()
752 */
753 public void setQuickfinderAction(Action quickfinderAction) {
754 this.quickfinderAction = quickfinderAction;
755 }
756
757 /**
758 * Lightbox widget that will be used to view the invoked lookup view.
759 *
760 * <p>Note if the lightbox is not configured, or set to not render the lookup will be invoked based on
761 * the action alone (for example a new tab/window)</p>
762 *
763 * @return lightbox instance for viewing the lookup
764 */
765 @BeanTagAttribute(name = "lightBox", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
766 public LightBox getLightBox() {
767 return lightBox;
768 }
769
770 /**
771 * @see QuickFinder#getLightBox()
772 */
773 public void setLightBox(LightBox lightBox) {
774 this.lightBox = lightBox;
775 }
776
777 /**
778 * Indicates whether the invoked lookup view should allow multiple values to be selected and returned.
779 *
780 * @return true if multi-value lookup should be requested, false for normal lookup
781 */
782 @BeanTagAttribute(name = "MultipleValuesSelect")
783 public Boolean getMultipleValuesSelect() {
784 return multipleValuesSelect;
785 }
786
787 /**
788 * @see QuickFinder#getMultipleValuesSelect()
789 */
790 public void setMultipleValuesSelect(Boolean multipleValuesSelect) {
791 this.multipleValuesSelect = multipleValuesSelect;
792 }
793
794 /**
795 * For the case of multi-value lookup, indicates the collection that should be populated with
796 * the return results.
797 *
798 * <p>Note when the quickfinder is associated with a {@link CollectionGroup}, this property is
799 * set automatically from the collection name associated with the group</p>
800 *
801 * @return collection name (must be full binding path)
802 */
803 @BeanTagAttribute(name = "lookupCollectionName")
804 public String getLookupCollectionName() {
805 return lookupCollectionName;
806 }
807
808 /**
809 * @see QuickFinder#getLookupCollectionName()
810 */
811 public void setLookupCollectionName(String lookupCollectionName) {
812 this.lookupCollectionName = lookupCollectionName;
813 }
814
815 /**
816 * @see org.kuali.rice.krad.datadictionary.DictionaryBeanBase#copyProperties(Object)
817 */
818 @Override
819 protected <T> void copyProperties(T component) {
820 super.copyProperties(component);
821
822 QuickFinder quickFinderCopy = (QuickFinder) component;
823
824 quickFinderCopy.setBaseLookupUrl(this.baseLookupUrl);
825 quickFinderCopy.setDataObjectClassName(this.dataObjectClassName);
826 quickFinderCopy.setViewName(this.viewName);
827 quickFinderCopy.setReferencesToRefresh(this.referencesToRefresh);
828
829 if (fieldConversions != null) {
830 quickFinderCopy.setFieldConversions(new HashMap<String, String>(this.fieldConversions));
831 }
832
833 if (lookupParameters != null) {
834 quickFinderCopy.setLookupParameters(new HashMap<String, String>(this.lookupParameters));
835 }
836
837 quickFinderCopy.setReturnByScript(this.returnByScript);
838 quickFinderCopy.setReadOnlyLookupFields(this.readOnlyLookupFields);
839 quickFinderCopy.setRenderReturnLink(this.renderReturnLink);
840 quickFinderCopy.setRenderResultActions(this.renderResultActions);
841 quickFinderCopy.setAutoSearch(this.autoSearch);
842 quickFinderCopy.setRenderLookupCriteria(this.renderLookupCriteria);
843 quickFinderCopy.setRenderCriteriaActions(this.renderCriteriaActions);
844 quickFinderCopy.setRenderMaintenanceLinks(this.renderMaintenanceLinks);
845 quickFinderCopy.setMultipleValuesSelect(this.multipleValuesSelect);
846 quickFinderCopy.setLookupCollectionName(this.lookupCollectionName);
847
848 if (lightBox != null) {
849 quickFinderCopy.setLightBox((LightBox) this.lightBox.copy());
850 }
851
852 if (this.quickfinderAction != null) {
853 quickFinderCopy.setQuickfinderAction((Action) this.quickfinderAction.copy());
854 }
855 }
856 }