View Javadoc

1   /**
2    * Copyright 2005-2012 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.field;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.uif.DataType;
20  import org.kuali.rice.core.api.util.ConcreteKeyValue;
21  import org.kuali.rice.core.api.util.KeyValue;
22  import org.kuali.rice.core.api.util.type.TypeUtils;
23  import org.kuali.rice.krad.datadictionary.AttributeDefinition;
24  import org.kuali.rice.krad.datadictionary.validation.capability.CaseConstrainable;
25  import org.kuali.rice.krad.datadictionary.validation.capability.Formatable;
26  import org.kuali.rice.krad.datadictionary.validation.capability.HierarchicallyConstrainable;
27  import org.kuali.rice.krad.datadictionary.validation.capability.LengthConstrainable;
28  import org.kuali.rice.krad.datadictionary.validation.capability.MustOccurConstrainable;
29  import org.kuali.rice.krad.datadictionary.validation.capability.PrerequisiteConstrainable;
30  import org.kuali.rice.krad.datadictionary.validation.capability.RangeConstrainable;
31  import org.kuali.rice.krad.datadictionary.validation.capability.SimpleConstrainable;
32  import org.kuali.rice.krad.datadictionary.validation.capability.ValidCharactersConstrainable;
33  import org.kuali.rice.krad.datadictionary.validation.constraint.CaseConstraint;
34  import org.kuali.rice.krad.datadictionary.validation.constraint.MustOccurConstraint;
35  import org.kuali.rice.krad.datadictionary.validation.constraint.PrerequisiteConstraint;
36  import org.kuali.rice.krad.datadictionary.validation.constraint.SimpleConstraint;
37  import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint;
38  import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
39  import org.kuali.rice.krad.uif.UifConstants;
40  import org.kuali.rice.krad.uif.control.TextControl;
41  import org.kuali.rice.krad.uif.control.UifKeyValuesFinder;
42  import org.kuali.rice.krad.uif.view.FormView;
43  import org.kuali.rice.krad.uif.view.View;
44  import org.kuali.rice.krad.uif.control.Control;
45  import org.kuali.rice.krad.uif.control.MultiValueControlBase;
46  import org.kuali.rice.krad.uif.component.Component;
47  import org.kuali.rice.krad.uif.util.ClientValidationUtils;
48  import org.kuali.rice.krad.uif.util.ComponentUtils;
49  import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
50  import org.kuali.rice.krad.uif.view.ViewModel;
51  import org.kuali.rice.krad.uif.widget.DirectInquiry;
52  import org.kuali.rice.krad.uif.widget.QuickFinder;
53  import org.kuali.rice.krad.uif.widget.Suggest;
54  import org.kuali.rice.krad.util.ObjectUtils;
55  
56  import java.util.ArrayList;
57  import java.util.List;
58  
59  /**
60   * Field that encapsulates data input/output captured by an attribute within the
61   * application
62   *
63   * <p>
64   * R
65   * The <code>InputField</code> provides the majority of the data input/output
66   * for the screen. Through these fields the model can be displayed and updated.
67   * For data input, the field contains a {@link Control} instance will
68   * render an HTML control element(s). The input field also contains a
69   * {@link LabelField}, summary, and widgets such as a quickfinder (for
70   * looking up values) and inquiry (for getting more information on the value).
71   * <code>InputField</code> instances can have associated messages (errors)
72   * due to invalid input or business rule failures. Security can also be
73   * configured to restrict who may view the fields value.
74   * </p>
75   *
76   * @author Kuali Rice Team (rice.collab@kuali.org)
77   */
78  public class InputField extends DataField implements SimpleConstrainable, CaseConstrainable, PrerequisiteConstrainable,
79          MustOccurConstrainable, LengthConstrainable, RangeConstrainable, ValidCharactersConstrainable {
80      private static final long serialVersionUID = -3703656713706343840L;
81  
82      // constraint variables
83      private String customValidatorClass;
84      private ValidCharactersConstraint validCharactersConstraint;
85      private CaseConstraint caseConstraint;
86      private List<PrerequisiteConstraint> dependencyConstraints;
87      private List<MustOccurConstraint> mustOccurConstraints;
88      private SimpleConstraint simpleConstraint;
89      private DataType dataType;
90  
91      // display props
92      private Control control;
93      private KeyValuesFinder optionsFinder;
94      private boolean performUppercase;
95  
96      private ErrorsField errorsField;
97  
98      // messages
99      private String constraintText;
100     private String instructionalText;
101 
102     private MessageField instructionalMessageField;
103     private MessageField constraintMessageField;
104 
105     private AttributeQuery fieldAttributeQuery;
106 
107     // widgets
108     private QuickFinder fieldLookup;
109     private DirectInquiry fieldDirectInquiry;
110     private Suggest fieldSuggest;
111 
112     public InputField() {
113         super();
114 
115         simpleConstraint = new SimpleConstraint();
116     }
117 
118     /**
119      * The following actions are performed:
120      *
121      * <ul>
122      * <li>Set the ids for the various attribute components</li>
123      * <li>Sets up the client side validation for constraints on this field. In
124      * addition, it sets up the messages applied to this field</li>
125      * </ul>
126      *
127      * @see org.kuali.rice.krad.uif.component.ComponentBase#performFinalize(org.kuali.rice.krad.uif.view.View,
128      *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
129      */
130     @Override
131     public void performFinalize(View view, Object model, Component parent) {
132         super.performFinalize(view, model, parent);
133 
134         setupIds();
135 
136         // invoke options finder if options not configured on the control
137         List<KeyValue> fieldOptions = new ArrayList<KeyValue>();
138 
139         // use options directly configured on the control first
140         if ((control != null) && control instanceof MultiValueControlBase) {
141             MultiValueControlBase multiValueControl = (MultiValueControlBase) control;
142             if ((multiValueControl.getOptions() != null) && !multiValueControl.getOptions().isEmpty()) {
143                 fieldOptions = multiValueControl.getOptions();
144             }
145         }
146 
147         // if options not configured on the control, invoke configured options finder
148         if (fieldOptions.isEmpty() && (optionsFinder != null)) {
149             if (optionsFinder instanceof UifKeyValuesFinder) {
150                 fieldOptions = ((UifKeyValuesFinder) optionsFinder).getKeyValues((ViewModel) model);
151 
152                 // check if blank option should be added
153                 if (((UifKeyValuesFinder) optionsFinder).isAddBlankOption()) {
154                     fieldOptions.add(0, new ConcreteKeyValue("", ""));
155                 }
156             } else {
157                 fieldOptions = optionsFinder.getKeyValues();
158             }
159 
160             if ((control != null) && control instanceof MultiValueControlBase) {
161                 ((MultiValueControlBase) control).setOptions(fieldOptions);
162             }
163         }
164 
165         // if read only do key/value translation if necessary (if alternative and additional properties not set)
166         if (isReadOnly()
167                 && !fieldOptions.isEmpty()
168                 && StringUtils.isBlank(getAlternateDisplayValue())
169                 && StringUtils.isBlank(getAdditionalDisplayValue())
170                 && StringUtils.isBlank(getAlternateDisplayPropertyName())
171                 && StringUtils.isBlank(getAdditionalDisplayPropertyName())) {
172 
173             Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());
174 
175             // TODO: can we translate Collections? (possibly combining output with delimiter
176             if ((fieldValue != null) && (TypeUtils.isSimpleType(fieldValue.getClass()))) {
177                 for (KeyValue keyValue : fieldOptions) {
178                     if (StringUtils.equals((String) fieldValue, keyValue.getKey())) {
179                         setAlternateDisplayValue(keyValue.getValue());
180                         break;
181                     }
182                 }
183             }
184         }
185 
186         // if read only or the control is null no input can be given so no need to setup validation
187         if (isReadOnly() || getControl() == null) {
188             return;
189         }
190 
191         // Sets message
192         if (StringUtils.isNotBlank(instructionalText)) {
193             instructionalMessageField.setMessageText(instructionalText);
194         }
195 
196         // Sets constraints
197         if (StringUtils.isNotBlank(constraintText)) {
198             constraintMessageField.setMessageText(constraintText);
199         }
200 
201         // adjust paths on PrerequisiteConstraint property names
202         adjustPrerequisiteConstraintBinding(dependencyConstraints);
203 
204         // adjust paths on MustOccurConstraints property names
205         adjustMustOccurConstraintBinding(mustOccurConstraints);
206 
207         // adjust paths on CaseConstraint property names
208         if (caseConstraint != null) {
209             String propertyName = getBindingInfo().getPropertyAdjustedBindingPath(caseConstraint.getPropertyName());
210             caseConstraint.setPropertyName(propertyName);
211         }
212 
213         setupFieldQuery();
214 
215         ClientValidationUtils.processAndApplyConstraints(this, view);
216     }
217 
218     /**
219      * Adjust paths on the must occur constrain bindings
220      *
221      * @param mustOccurConstraints
222      */
223     protected void adjustMustOccurConstraintBinding(List<MustOccurConstraint> mustOccurConstraints) {
224         if (mustOccurConstraints != null) {
225             for (MustOccurConstraint mustOccurConstraint : mustOccurConstraints) {
226                 adjustPrerequisiteConstraintBinding(mustOccurConstraint.getPrerequisiteConstraints());
227                 adjustMustOccurConstraintBinding(mustOccurConstraint.getMustOccurConstraints());
228             }
229         }
230     }
231 
232     /**
233      * Adjust paths on the prerequisite constraint bindings
234      * @param prerequisiteConstraints
235      */
236     protected void adjustPrerequisiteConstraintBinding(List<PrerequisiteConstraint> prerequisiteConstraints) {
237         if (prerequisiteConstraints != null) {
238             for (PrerequisiteConstraint prerequisiteConstraint : prerequisiteConstraints) {
239                 String propertyName = getBindingInfo().getPropertyAdjustedBindingPath(
240                         prerequisiteConstraint.getPropertyName());
241                 prerequisiteConstraint.setPropertyName(propertyName);
242             }
243         }
244     }
245 
246     /**
247      * Performs setup of the field attribute query and informational display properties. Paths
248      * are adjusted to match the binding for the this field, and the necessary onblur script for
249      * triggering the query client side is constructed
250      */
251     protected void setupFieldQuery() {
252         if (getFieldAttributeQuery() != null) {
253             // adjust paths on query mappings
254             getFieldAttributeQuery().updateQueryFieldMapping(getBindingInfo());
255             getFieldAttributeQuery().updateReturnFieldMapping(getBindingInfo());
256             getFieldAttributeQuery().updateQueryMethodArgumentFieldList(getBindingInfo());
257 
258             // build onblur script for field query
259             String script = "executeFieldQuery('" + getControl().getId() + "',";
260             script += "'" + getId() + "'," + getFieldAttributeQuery().getQueryFieldMappingJsString() + ",";
261             script += getFieldAttributeQuery().getQueryMethodArgumentFieldsJsString() + ",";
262             script += getFieldAttributeQuery().getReturnFieldMappingJsString() + ");";
263 
264             if (StringUtils.isNotBlank(getControl().getOnBlurScript())) {
265                 script = getControl().getOnBlurScript() + script;
266             }
267             getControl().setOnBlurScript(script);
268         }
269     }
270 
271     /**
272      * Sets the ids on all components the input field uses so they will all
273      * contain this input field's id in their ids. This is useful for jQuery
274      * manipulation.
275      */
276     protected void setupIds() {
277         // update ids so they all match the attribute
278         if (getControl() != null) {
279             getControl().setId(getId());
280         }
281 
282         setNestedComponentIdAndSuffix(getErrorsField(), UifConstants.IdSuffixes.ERRORS);
283         setNestedComponentIdAndSuffix(getLabelField(), UifConstants.IdSuffixes.LABEL);
284         setNestedComponentIdAndSuffix(getInstructionalMessageField(), UifConstants.IdSuffixes.INSTRUCTIONAL);
285         setNestedComponentIdAndSuffix(getConstraintMessageField(), UifConstants.IdSuffixes.CONSTRAINT);
286         setNestedComponentIdAndSuffix(getFieldLookup(), UifConstants.IdSuffixes.QUICK_FINDER);
287         setNestedComponentIdAndSuffix(getFieldDirectInquiry(), UifConstants.IdSuffixes.DIRECT_INQUIRY);
288         setNestedComponentIdAndSuffix(getFieldSuggest(), UifConstants.IdSuffixes.SUGGEST);
289 
290         setId(getId() + UifConstants.IdSuffixes.ATTRIBUTE);
291     }
292 
293     /**
294      * Helper method for suffixing the ids of the fields nested components
295      *
296      * @param component - component to adjust id for
297      * @param suffix - suffix to append to id
298      */
299     private void setNestedComponentIdAndSuffix(Component component, String suffix) {
300         if (component != null) {
301             String fieldId = getId();
302             fieldId += suffix;
303 
304             component.setId(fieldId);
305         }
306     }
307 
308     /**
309      * Defaults the properties of the <code>InputField</code> to the
310      * corresponding properties of its <code>AttributeDefinition</code>
311      * retrieved from the dictionary (if such an entry exists). If the field
312      * already contains a value for a property, the definitions value is not
313      * used.
314      *
315      * @param view - view instance the field belongs to
316      * @param attributeDefinition - AttributeDefinition instance the property values should be
317      * copied from
318      */
319     public void copyFromAttributeDefinition(View view, AttributeDefinition attributeDefinition) {
320         super.copyFromAttributeDefinition(view, attributeDefinition);
321 
322         // max length
323         if (getMaxLength() == null) {
324             setMaxLength(attributeDefinition.getMaxLength());
325         }
326 
327         // min length
328         if (getMinLength() == null) {
329             setMinLength(attributeDefinition.getMinLength());
330         }
331 
332         // valid characters
333         if (getValidCharactersConstraint() == null) {
334             setValidCharactersConstraint(attributeDefinition.getValidCharactersConstraint());
335         }
336 
337         if (getCaseConstraint() == null) {
338             setCaseConstraint(attributeDefinition.getCaseConstraint());
339         }
340 
341         if (getDependencyConstraints() == null) {
342             setDependencyConstraints(attributeDefinition.getPrerequisiteConstraints());
343         }
344 
345         if (getMustOccurConstraints() == null) {
346             setMustOccurConstraints(attributeDefinition.getMustOccurConstraints());
347         }
348 
349         // required
350         if (getRequired() == null) {
351             setRequired(attributeDefinition.isRequired());
352 
353             //if still null, default to false
354             if (getRequired() == null) {
355                 setRequired(false);
356             }
357         }
358         
359         if (this.dataType == null) {
360             setDataType(attributeDefinition.getDataType());
361             //Assume date if dataType is still null and using a DatePicker
362             if(this.dataType == null && control instanceof TextControl && ((TextControl) control).getDatePicker() != null) {
363                 setDataType(DataType.DATE);
364             }
365         }
366 
367         // control
368         if ((getControl() == null) && (attributeDefinition.getControlField() != null)) {
369             Control control = attributeDefinition.getControlField();
370             view.assignComponentIds(control);
371 
372             setControl(ComponentUtils.copy(control));
373         }
374 
375         // constraint
376         if (StringUtils.isEmpty(getConstraintText())) {
377             setConstraintText(attributeDefinition.getConstraintText());
378             getConstraintMessageField().setMessageText(attributeDefinition.getConstraintText());
379         }
380 
381         // options
382         if (getOptionsFinder() == null) {
383             setOptionsFinder(attributeDefinition.getOptionsFinder());
384         }
385     }
386 
387     /**
388      * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
389      */
390     @Override
391     public List<Component> getComponentsForLifecycle() {
392         List<Component> components = super.getComponentsForLifecycle();
393 
394         components.add(control);
395         components.add(errorsField);
396         components.add(fieldLookup);
397         components.add(fieldDirectInquiry);
398         components.add(fieldSuggest);
399 
400         return components;
401     }
402 
403     /**
404      * @see DataField#isInputAllowed()
405      */
406     @Override
407     public boolean isInputAllowed() {
408         return true;
409     }
410 
411     /**
412      * <code>Control</code> instance that should be used to input data for the
413      * field
414      *
415      * <p>
416      * When the field is editable, the control will be rendered so the user can
417      * input a value(s). Controls typically are part of a Form and render
418      * standard HTML control elements such as text input, select, and checkbox
419      * </p>
420      *
421      * @return Control instance
422      */
423     public Control getControl() {
424         return this.control;
425     }
426 
427     /**
428      * Setter for the field's control
429      *
430      * @param control
431      */
432     public void setControl(Control control) {
433         this.control = control;
434     }
435 
436     /**
437      * Field that contains the messages (errors) for the input field. The
438      * <code>ErrorsField</code> holds configuration on associated messages along
439      * with information on rendering the messages in the user interface
440      *
441      * @return ErrorsField instance
442      */
443     public ErrorsField getErrorsField() {
444         return this.errorsField;
445     }
446 
447     /**
448      * Setter for the input field's errors field
449      *
450      * @param errorsField
451      */
452     public void setErrorsField(ErrorsField errorsField) {
453         this.errorsField = errorsField;
454     }
455 
456     /**
457      * Instance of <code>KeyValuesFinder</code> that should be invoked to
458      * provide a List of values the field can have. Generally used to provide
459      * the options for a multi-value control or to validate the submitted field
460      * value
461      *
462      * @return KeyValuesFinder instance
463      */
464     public KeyValuesFinder getOptionsFinder() {
465         return this.optionsFinder;
466     }
467 
468     /**
469      * Setter for the field's KeyValuesFinder instance
470      *
471      * @param optionsFinder
472      */
473     public void setOptionsFinder(KeyValuesFinder optionsFinder) {
474         this.optionsFinder = optionsFinder;
475     }
476 
477     /**
478      * Setter that takes in the class name for the options finder and creates a
479      * new instance to use as the finder for the input field
480      *
481      * @param optionsFinderClass - the options finder class to set
482      */
483     public void setOptionsFinderClass(Class<? extends KeyValuesFinder> optionsFinderClass) {
484         this.optionsFinder = ObjectUtils.newInstance(optionsFinderClass);
485     }
486 
487     /**
488      * @see org.kuali.rice.krad.uif.component.ComponentBase#getSupportsOnLoad()
489      */
490     @Override
491     public boolean getSupportsOnLoad() {
492         return true;
493     }
494 
495     /**
496      * Lookup finder widget for the field
497      *
498      * <p>
499      * The quickfinder widget places a small icon next to the field that allows
500      * the user to bring up a search screen for finding valid field values. The
501      * <code>Widget</code> instance can be configured to point to a certain
502      * <code>LookupView</code>, or the framework will attempt to associate the
503      * field with a lookup based on its metadata (in particular its
504      * relationships in the model)
505      * </p>
506      *
507      * @return QuickFinder lookup widget
508      */
509     public QuickFinder getFieldLookup() {
510         return this.fieldLookup;
511     }
512 
513     /**
514      * Setter for the lookup widget
515      *
516      * @param fieldLookup - the field lookup widget to set
517      */
518     public void setFieldLookup(QuickFinder fieldLookup) {
519         this.fieldLookup = fieldLookup;
520     }
521 
522     /**
523      * Suggest box widget for the input field
524      *
525      * <p>
526      * If enabled (by render flag), as the user inputs data into the
527      * fields control a dynamic query is performed to provide the user
528      * suggestions on values which they can then select
529      * </p>
530      *
531      * <p>
532      * Note the Suggest widget is only valid when using a standard TextControl
533      * </p>
534      *
535      * @return Suggest instance
536      */
537     public Suggest getFieldSuggest() {
538         return fieldSuggest;
539     }
540 
541     /**
542      * Setter for the fields suggest widget
543      *
544      * @param fieldSuggest - the field suggest widget to  set
545      */
546     public void setFieldSuggest(Suggest fieldSuggest) {
547         this.fieldSuggest = fieldSuggest;
548     }
549 
550     /**
551      * Instructional text that display an explanation of the field usage
552      *
553      * <p>
554      * Text explaining how to use the field, including things like what values should be selected
555      * in certain cases and so on (instructions)
556      * </p>
557      *
558      * @return String instructional message
559      */
560     public String getInstructionalText() {
561         return this.instructionalText;
562     }
563 
564     /**
565      * Setter for the instructional message
566      *
567      * @param instructionalText - the instructional text to set
568      */
569     public void setInstructionalText(String instructionalText) {
570         this.instructionalText = instructionalText;
571     }
572 
573     /**
574      * Message field that displays instructional text
575      *
576      * <p>
577      * This message field can be configured to for adjusting how the instructional text will display. Generally
578      * the styleClasses property will be of most interest
579      * </p>
580      *
581      * @return MessageField instructional message field
582      */
583     public MessageField getInstructionalMessageField() {
584         return this.instructionalMessageField;
585     }
586 
587     /**
588      * Setter for the instructional text message field
589      *
590      * <p>
591      * Note this is the setter for the field that will render the instructional text. The actual text can be
592      * set on the field but can also be set using {@link #setInstructionalText(String)}
593      * </p>
594      *
595      * @param instructionalMessageField - the instructional message to set
596      */
597     public void setInstructionalMessageField(MessageField instructionalMessageField) {
598         this.instructionalMessageField = instructionalMessageField;
599     }
600 
601     /**
602      * Text that display a restriction on the value a field can hold
603      *
604      * <p>
605      * For example when the value must be a valid format (phone number, email), certain length, min/max value and
606      * so on this text can be used to indicate the constraint to the user. Generally displays with the control so
607      * it is visible when the user tabs to the field
608      * </p>
609      *
610      * @return String text to display for the constraint message
611      */
612     public String getConstraintText() {
613         return this.constraintText;
614     }
615 
616     /**
617      * Setter for the constraint message text
618      *
619      * @param constraintText - the constraint text to set
620      */
621     public void setConstraintText(String constraintText) {
622         this.constraintText = constraintText;
623     }
624 
625     /**
626      * Message field that displays constraint text
627      *
628      * <p>
629      * This message field can be configured to for adjusting how the constrain text will display. Generally
630      * the styleClasses property will be of most interest
631      * </p>
632      *
633      * @return MessageField constraint message field
634      */
635     public MessageField getConstraintMessageField() {
636         return this.constraintMessageField;
637     }
638 
639     /**
640      * Setter for the constraint text message field
641      *
642      * <p>
643      * Note this is the setter for the field that will render the constraint text. The actual text can be
644      * set on the field but can also be set using {@link #setConstraintText(String)}
645      * </p>
646      *
647      * @param constraintMessageField - the constrain message field to set
648      */
649     public void setConstraintMessageField(MessageField constraintMessageField) {
650         this.constraintMessageField = constraintMessageField;
651     }
652 
653     /**
654      * The <code>ValideCharacterConstraint</code> that applies to this <code>InputField</code>
655      *
656      * @return the valid characters constraint for this input field
657      */
658     public ValidCharactersConstraint getValidCharactersConstraint() {
659         return this.validCharactersConstraint;
660     }
661 
662     /**
663      * Setter for <code>validCharacterConstraint</code>
664      *
665      * @param validCharactersConstraint - the <code>ValidCharactersConstraint</code> to set
666      */
667     public void setValidCharactersConstraint(ValidCharactersConstraint validCharactersConstraint) {
668         this.validCharactersConstraint = validCharactersConstraint;
669     }
670 
671     /**
672      * The <code>CaseConstraint</code> that applies to this <code>InputField</code>
673      *
674      * @return the case constraint for this input field
675      */
676     public CaseConstraint getCaseConstraint() {
677         return this.caseConstraint;
678     }
679 
680     /**
681      * Setter for <code>caseConstraint</code>
682      *
683      * @param caseConstraint - the <code>CaseConstraint</code> to set
684      */
685     public void setCaseConstraint(CaseConstraint caseConstraint) {
686         this.caseConstraint = caseConstraint;
687     }
688 
689     /**
690      * List of <code>PrerequisiteConstraint</code> that apply to this <code>InputField</code>
691      *
692      * @return the dependency constraints for this input field
693      */
694     public List<PrerequisiteConstraint> getDependencyConstraints() {
695         return this.dependencyConstraints;
696     }
697 
698     /**
699      * Setter for <code>dependencyConstraints</code>
700      *
701      * @param dependencyConstraints - list of <code>PrerequisiteConstraint</code> to set
702      */
703     public void setDependencyConstraints(List<PrerequisiteConstraint> dependencyConstraints) {
704         this.dependencyConstraints = dependencyConstraints;
705     }
706 
707     /**
708      * List of <code>MustOccurConstraint</code> that apply to this <code>InputField</code>
709      *
710      * @return the must occur constraints for this input field
711      */
712     public List<MustOccurConstraint> getMustOccurConstraints() {
713         return this.mustOccurConstraints;
714     }
715 
716     /**
717      * Setter for <code>mustOccurConstraints</code>
718      *
719      * @param mustOccurConstraints - list of <code>MustOccurConstraint</code> to set
720      */
721     public void setMustOccurConstraints(List<MustOccurConstraint> mustOccurConstraints) {
722         this.mustOccurConstraints = mustOccurConstraints;
723     }
724 
725     /**
726      * Simple constraints for the input field
727      *
728      * <p>
729      * A simple constraint which store the values for constraints such as required,
730      * min/max length, and min/max value.
731      * </p>
732      *
733      * @return the simple constraint of the input field
734      */
735     public SimpleConstraint getSimpleConstraint() {
736         return this.simpleConstraint;
737     }
738 
739     /**
740      * Setter for simple constraint
741      *
742      * <p>
743      * When a simple constraint is set on this object ALL simple validation
744      * constraints set directly will be overridden - recommended to use this or
745      * the other gets/sets for defining simple constraints, not both.
746      * </p>
747      *
748      * @param simpleConstraint - the simple constraint to set
749      */
750     public void setSimpleConstraint(SimpleConstraint simpleConstraint) {
751         this.simpleConstraint = simpleConstraint;
752     }
753 
754     /**
755      * Maximum number of characters the input field value is allowed to have
756      *
757      * <p>
758      * The maximum length determines the maximum allowable length of the value
759      * for data entry editing purposes.  The maximum length is inclusive and can
760      * be smaller or longer than the actual control size.  The constraint
761      * is enforced on all data types (e.g. a numeric data type needs to meet the
762      * maximum length constraint in which digits and symbols are counted).
763      * </p>
764      *
765      * @return the maximum length of the input field
766      */
767     public Integer getMaxLength() {
768         return simpleConstraint.getMaxLength();
769     }
770 
771     /**
772      * Setter for input field max length
773      *
774      * @param maxLength - the maximum length to set
775      */
776     public void setMaxLength(Integer maxLength) {
777         simpleConstraint.setMaxLength(maxLength);
778     }
779 
780     /**
781      * Minimum number of characters the input field value needs to be
782      *
783      * <p>
784      * The minimum length determines the minimum required length of the value for
785      * data entry editing purposes.  The minimum length is inclusive. The constraint
786      * is enforced on all data types (e.g. a numeric data type needs to meet the
787      * minimum length requirement in which digits and symbols are counted).
788      * </p>
789      *
790      * @return the minimum length of the input field
791      */
792     public Integer getMinLength() {
793         return simpleConstraint.getMinLength();
794     }
795 
796     /**
797      * Setter for input field minimum length
798      *
799      * @param minLength - the minLength to set
800      */
801     public void setMinLength(Integer minLength) {
802         simpleConstraint.setMinLength(minLength);
803     }
804 
805     /**
806      * @see org.kuali.rice.krad.uif.component.ComponentBase#getRequired()
807      */
808     @Override
809     public Boolean getRequired() {
810         return this.simpleConstraint.getRequired();
811     }
812 
813     /**
814      * @see org.kuali.rice.krad.uif.component.ComponentBase#setRequired(java.lang.Boolean)
815      */
816     @Override
817     public void setRequired(Boolean required) {
818         this.simpleConstraint.setRequired(required);
819     }
820 
821     /**
822      * The exclusive minimum value for numeric or date field.
823      *
824      * <p>
825      * The exclusiveMin element determines the minimum allowable value for data
826      * entry editing purposes. This constrain is supported for numeric and
827      * date fields and to be used in conjunction with the appropriate
828      * {@link ValidCharactersConstraint}.
829      *
830      * For numeric constraint the value can be an integer or decimal such as -.001 or 99.
831      * </p>
832      *
833      * @return the exclusive minimum numeric value of the input field
834      */
835     public String getExclusiveMin() {
836         return simpleConstraint.getExclusiveMin();
837     }
838 
839     /**
840      * Setter for the field's exclusive minimum value
841      *
842      * @param exclusiveMin - the minimum value to set
843      */
844     public void setExclusiveMin(String exclusiveMin) {
845         simpleConstraint.setExclusiveMin(exclusiveMin);
846     }
847 
848     /**
849      * The inclusive maximum value for numeric or date field.
850      *
851      * <p>
852      * The inclusiveMax element determines the maximum allowable value for data
853      * entry editing purposes. This constrain is supported for numeric and
854      * date fields and to be used in conjunction with the appropriate
855      * {@link ValidCharactersConstraint}.
856      *
857      * For numeric constraint the value can be an integer or decimal such as -.001 or 99.
858      * </p>
859      *
860      * @return the inclusive maximum numeric value of the input field
861      */
862     public String getInclusiveMax() {
863         return simpleConstraint.getInclusiveMax();
864     }
865 
866     /**
867      * Setter for the field's inclusive maximum value
868      *
869      * @param inclusiveMax - the maximum value to set
870      */
871     public void setInclusiveMax(String inclusiveMax) {
872         simpleConstraint.setInclusiveMax(inclusiveMax);
873     }
874 
875     /**
876      * <code>DirectInquiry</code> widget for the field
877      *
878      * <p>
879      * The direct inquiry widget will render a button for the field value when
880      * that field is editable. It points to the associated inquiry view for the
881      * field. The inquiry can be configured to point to a certain
882      * <code>InquiryView</code>, or the framework will attempt to associate the
883      * field with a inquiry based on its metadata (in particular its
884      * relationships in the model)
885      * </p>
886      *
887      * @return the <code>DirectInquiry</code> field DirectInquiry
888      */
889     public DirectInquiry getFieldDirectInquiry() {
890         return fieldDirectInquiry;
891     }
892 
893     /**
894      * Setter for the field's direct inquiry widget
895      *
896      * @param fieldDirectInquiry - the <code>DirectInquiry</code> to set
897      */
898     public void setFieldDirectInquiry(DirectInquiry fieldDirectInquiry) {
899         this.fieldDirectInquiry = fieldDirectInquiry;
900     }
901 
902     /**
903      * Attribute query instance configured for this field to dynamically pull information back for
904      * updates other fields or providing messages
905      *
906      * <p>
907      * If field attribute query is not null, associated event script will be generated to trigger the
908      * query from the UI. This will invoke the <code>AttributeQueryService</code> to
909      * execute the query and return an instance of <code>AttributeQueryResult</code> that is then
910      * read by the script to update the UI. Typically used to update informational property values or
911      * other field values
912      * </p>
913      *
914      * @return AttributeQuery instance
915      */
916     public AttributeQuery getFieldAttributeQuery() {
917         return fieldAttributeQuery;
918     }
919 
920     /**
921      * Setter for this field's attribute query
922      *
923      * @param fieldAttributeQuery
924      */
925     public void setFieldAttributeQuery(AttributeQuery fieldAttributeQuery) {
926         this.fieldAttributeQuery = fieldAttributeQuery;
927     }
928 
929     /**
930      * Perform uppercase flag for this field to force input to uppercase.
931      *
932      * <p>
933      * It this flag is set to true the 'text-transform' style on the field will be set to 'uppercase'
934      * which will automatically change any text input into the field to uppercase.
935      * </p>
936      *
937      * @return performUppercase flag
938      */
939     public boolean isPerformUppercase() {
940         return performUppercase;
941     }
942 
943     /**
944      * Setter for this field's performUppercase flag
945      *
946      * @param performUppercase - boolean flag
947      */
948     public void setPerformUppercase(boolean performUppercase) {
949         this.performUppercase = performUppercase;
950     }
951 
952     /**
953      * Returns the full binding path (the path used in the name attribute of the input).
954      * This differs from propertyName in that it uses BindingInfo to determine the path.
955      * @return full binding path name
956      */
957     @Override
958     public String getName() {
959         return this.getBindingInfo().getBindingPath();
960     }
961 
962     public List<PrerequisiteConstraint> getPrerequisiteConstraints() {
963         return dependencyConstraints;
964     }
965 
966     /**
967      * This does not have to be set, represents the DataType constraint of this field.
968      * This is only checked during server side validation.
969      * @param dataType the dataType to set
970      */
971     public void setDataType(DataType dataType) {
972         this.simpleConstraint.setDataType(dataType);
973     }
974 
975     public void setDataType(String dataType) {
976         this.simpleConstraint.setDataType(DataType.valueOf(dataType));
977     }
978 
979     /**
980      * Gets the DataType of this InputField, note that DataType set to be date
981      * when this field is using a date picker with a TextControl and hasnt otherwise been
982      * explicitly set.
983      * @return
984      */
985     public DataType getDataType() {
986         return this.simpleConstraint.getDataType();
987     }
988 }