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 }