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