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