View Javadoc

1   /**
2    * Copyright 2005-2011 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.config.property.ConfigurationService;
20  import org.kuali.rice.krad.service.KRADServiceLocator;
21  import org.kuali.rice.krad.uif.container.ContainerBase;
22  import org.kuali.rice.krad.uif.container.PageGroup;
23  import org.kuali.rice.krad.uif.view.View;
24  import org.kuali.rice.krad.uif.component.Component;
25  import org.kuali.rice.krad.util.ErrorMessage;
26  import org.kuali.rice.krad.util.GlobalVariables;
27  import org.kuali.rice.krad.util.MessageMap;
28  import org.springframework.util.AutoPopulatingList;
29  
30  import java.text.MessageFormat;
31  import java.util.ArrayList;
32  import java.util.Arrays;
33  import java.util.List;
34  
35  /**
36   * Field that displays error, warning, and info messages for the keys that are
37   * matched. By default, an ErrorsField will match on id and bindingPath (if this
38   * ErrorsField is for an InputField), but can be set to match on
39   * additionalKeys and nested components keys (of the its parentComponent).
40   * 
41   * In addition, there are a variety of options which can be toggled to effect
42   * the display of these messages during both client and server side validation
43   * display. See documentation on each get method for more details on the effect
44   * of each option.
45   * 
46   * @author Kuali Rice Team (rice.collab@kuali.org)
47   */
48  public class ErrorsField extends FieldBase {
49  	private static final long serialVersionUID = 780940788435330077L;
50  
51  	private List<String> additionalKeysToMatch;
52  
53  	// Title variables
54  	private String errorTitle;
55  	private String warningTitle;
56  	private String infoTitle;
57  
58  	private boolean displayErrorTitle;
59  	private boolean displayWarningTitle;
60  	private boolean displayInfoTitle;
61  
62  	// Field variables
63  	private boolean highlightOnError;
64  	private boolean displayFieldErrorIcon;
65  
66  	// Message construction variables
67  	private boolean displayFieldLabelWithMessages;
68  	private boolean combineMessages;
69  
70  	// Message display flags
71  	private boolean displayNestedMessages;
72  	private boolean allowMessageRepeat;
73  
74  	private boolean displayMessages;
75  	private boolean displayErrorMessages;
76  	private boolean displayInfoMessages;
77  	private boolean displayWarningMessages;
78  	private boolean displayCounts;
79  	private boolean alternateContainer;
80  
81  	// Error messages
82  	private List<String> errors;
83  	private List<String> warnings;
84  	private List<String> infos;
85  
86  	// Counts
87  	private int errorCount;
88  	private int warningCount;
89  	private int infoCount;
90  
91  	// internal
92  	private int tempCount;
93  
94  	// not used
95  	private boolean displayLockMessages;
96  
97  	public ErrorsField() {
98  		super();
99          alternateContainer = false;
100 	}
101 
102 	/**
103 	 * PerformFinalize will generate the messages and counts used by the
104 	 * errorsField based on the keys that were matched from the MessageMap for
105 	 * this ErrorsField. It will also set up nestedComponents of its
106 	 * parentComponent correctly based on the flags that were chosen for this
107 	 * ErrorsField.
108 	 * 
109 	 * @see org.kuali.rice.krad.uif.field.FieldBase#performFinalize(org.kuali.rice.krad.uif.view.View,
110 	 *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
111 	 */
112 	@Override
113 	public void performFinalize(View view, Object model, Component parent) {
114 		super.performFinalize(view, model, parent);
115 
116 		List<String> masterKeyList = getKeys(parent);
117 		errors = new ArrayList<String>();
118 		warnings = new ArrayList<String>();
119 		infos = new ArrayList<String>();
120 		errorCount = 0;
121 		warningCount = 0;
122 		infoCount = 0;
123 		MessageMap messageMap = GlobalVariables.getMessageMap();
124 
125 		if (!displayFieldLabelWithMessages) {
126 			this.addStyleClass("noLabels");
127 		}
128 		if (!highlightOnError) {
129 			this.addStyleClass("noHighlight");
130 		}
131 		if (displayFieldErrorIcon) {
132 			this.addStyleClass("addFieldIcon");
133 		}
134 
135 		if (displayMessages) {
136 			if (displayNestedMessages) {
137 				this.addNestedKeys(masterKeyList, parent);
138 			}
139 
140 			for (String key : masterKeyList) {
141 				if (displayErrorMessages) {
142 					errors.addAll(getMessages(view, key,
143 							messageMap.getErrorMessagesForProperty(key, true)));
144 					errorCount = errorCount + tempCount;
145 				}
146 				if (displayWarningMessages) {
147 					warnings.addAll(getMessages(view, key,
148 							messageMap.getWarningMessagesForProperty(key, true)));
149 					warningCount = warningCount + tempCount;
150 				}
151 				if (displayInfoMessages) {
152 					infos.addAll(getMessages(view, key,
153 							messageMap.getInfoMessagesForProperty(key, true)));
154 					infoCount = infoCount + tempCount;
155 				}
156 			}
157 		} else if (displayFieldErrorIcon) {
158 			// Checks to see if any errors exist for this field, if they do set
159 			// errorCount as positive
160 			// so the jsp will call the corresponding js to show the icon
161 			// messages do not need to be generated because they are not being shown
162 			for (String key : masterKeyList) {
163 				if (!messageMap.getErrorMessagesForProperty(key, true)
164 						.isEmpty()) {
165 					errorCount = 1;
166 					break;
167 				}
168 			}
169 		}
170 		
171 		//Check for errors that are not matched on the page(only applies when parent is page)
172 		if(parent instanceof PageGroup){
173 			if(errorCount < messageMap.getErrorCount()){
174 				List<String> diff = messageMap.getPropertiesWithErrors();
175 				diff.removeAll(masterKeyList);
176 				for (String key : diff) {
177     				errors.addAll(getMessages(view, key,
178                             messageMap.getErrorMessagesForProperty(key, true)));
179     				errorCount = errorCount+ tempCount;
180 				}
181 				
182 			}
183 			if(warningCount < messageMap.getWarningCount()){
184 				List<String> diff = messageMap.getPropertiesWithWarnings();
185 				diff.removeAll(masterKeyList);
186 				for (String key : diff) {
187 				    warnings.addAll(getMessages(view, key,
188                             messageMap.getWarningMessagesForProperty(key, true)));
189                     warningCount = warningCount + tempCount;
190                 }
191 			}
192 			if(infoCount < messageMap.getInfoCount()){
193 				List<String> diff = messageMap.getPropertiesWithInfo();
194 				diff.removeAll(masterKeyList);
195                 for (String key : diff) {
196                     infos.addAll(getMessages(view, key,
197                             messageMap.getInfoMessagesForProperty(key, true)));
198                     infoCount = infoCount + tempCount;
199                 }
200 			}
201 		}
202 		
203 		// dont display anything if there are no messages
204 		if (errorCount + warningCount + infoCount == 0 || !displayMessages) {
205 			this.setStyle("display: none;");
206 		} else {
207 			this.setStyle("display: visible");
208 		}
209 	}
210 
211 	/**
212 	 * Gets all the messages from the list of lists passed in (which are
213 	 * lists of ErrorMessages associated to the key) and uses the configuration
214 	 * service to get the message String associated. This will also combine
215 	 * error messages per a field if that option is turned on. If
216 	 * displayFieldLabelWithMessages is turned on, it will also find the label
217 	 * by key passed in.
218 	 * 
219 	 * @param view
220 	 * @param key
221 	 * @param lists
222 	 * @return
223 	 */
224 	private List<String> getMessages(View view, String key,
225 			List<AutoPopulatingList<ErrorMessage>> lists) {
226 		List<String> result = new ArrayList<String>();
227 		tempCount = 0;
228 		for (List<ErrorMessage> errorList : lists) {
229 			if (errorList != null && StringUtils.isNotBlank(key)) {
230 				ConfigurationService configService = KRADServiceLocator
231 						.getKualiConfigurationService();
232 				String comboMessage = "";
233 				String label = "";
234 
235 				for (ErrorMessage e : errorList) {
236 					tempCount++;
237 					String message = configService.getPropertyValueAsString(e.getErrorKey());
238 					if (e.getMessageParameters() != null) {
239 						message = message.replace("'", "''");
240 						message = MessageFormat.format(message,
241 								(Object[]) e.getMessageParameters());
242 					}
243                     if (displayFieldLabelWithMessages) {
244                         InputField field = (InputField) view.getViewIndex().getDataFieldByPath(key);
245 						if (field != null && field.getLabel() != null) {
246 							label = field.getLabel();
247 						}
248 						else{
249 						    label = key;
250 						}
251 					}
252 
253 					// adding them to combo string instead of the list
254 					if (combineMessages) {
255 						if (comboMessage.isEmpty()) {
256 							comboMessage = message;
257 						} else {
258 							comboMessage = comboMessage + ", " + message;
259 						}
260 					} else {
261 						// add it directly to the list - non combined messages
262 						if (StringUtils.isNotEmpty(label)) {
263 							result.add(label + " - " + message);
264 						} else {
265 							result.add(message);
266 						}
267 
268 					}
269 				}
270 				// add the single combo string to the returned list
271 				// combineMessages will also be checked in the template to
272 				// further
273 				// combine them
274 				if (StringUtils.isNotEmpty(comboMessage)) {
275 					if (StringUtils.isNotEmpty(label)) {
276 						result.add(label + " - " + comboMessage);
277 					} else {
278 						result.add(comboMessage);
279 					}
280 				}
281 			}
282 		}
283 
284 		return result;
285 	}
286 
287 	/**
288 	 * Gets all the keys associated to this ErrorsField. This includes the id of
289 	 * the parent component, additional keys to match, and the bindingPath if
290 	 * this is an ErrorsField for an InputField. These are the keys that are
291 	 * used to match errors with their component and display them as part of its
292 	 * ErrorsField.
293 	 * 
294 	 * @return
295 	 */
296 	protected List<String> getKeys(Component parent) {
297 		List<String> keyList = new ArrayList<String>();
298 		if (additionalKeysToMatch != null) {
299 			keyList.addAll(additionalKeysToMatch);
300 		}
301 		if (StringUtils.isNotBlank(parent.getId())) {
302 			keyList.add(parent.getId());
303 		}
304 		if (parent instanceof InputField) {
305 			if (((InputField) parent).getBindingInfo() != null
306 					&& StringUtils.isNotEmpty(((InputField) parent)
307 							.getBindingInfo().getBindingPath())) {
308 				keyList.add(((InputField) parent).getBindingInfo()
309 						.getBindingPath());
310 			}
311 		}
312 		// Will there be additional components to check beyond InputField?
313 
314 		return keyList;
315 	}
316 
317 	/**
318 	 * Adds all the nestedKeys of this component by calling getKeys on each of
319 	 * its nestedComponents' ErrorsFields and adding them to the list. If
320 	 * allowMessageRepeat is false, it will also turn off error display for its
321 	 * parent's nestedComponents' ErrorsFields.
322 	 * 
323 	 * @param keyList
324 	 * @param component
325 	 */
326 	private void addNestedKeys(List<String> keyList, Component component) {
327 		for (Component c : component.getComponentsForLifecycle()) {
328 			ErrorsField ef = null;
329 			if (c instanceof InputField) {
330 				ef = ((InputField) c).getErrorsField();
331 			} else if (c instanceof ContainerBase) {
332 				ef = ((ContainerBase) c).getErrorsField();
333 			}
334 			if (ef != null) {
335 				if (!allowMessageRepeat) {
336 					ef.setDisplayMessages(false);
337 				}
338 				keyList.addAll(ef.getKeys(c));
339 				addNestedKeys(keyList, c);
340 			}
341 		}
342 	}
343 
344 	/**
345 	 * ErrorTitle is the title that will be shown before any error
346 	 * messages/error counts are displayed
347 	 * 
348 	 * @return
349 	 */
350 	public String getErrorTitle() {
351 		return this.errorTitle;
352 	}
353 
354 	public void setErrorTitle(String errorTitle) {
355 		this.errorTitle = errorTitle;
356 	}
357 
358 	/**
359 	 * WarningTitle is the title that will be shown before any warning
360 	 * messages/warning counts are displayed
361 	 * 
362 	 * @return
363 	 */
364 	public String getWarningTitle() {
365 		return this.warningTitle;
366 	}
367 
368 	public void setWarningTitle(String warningTitle) {
369 		this.warningTitle = warningTitle;
370 	}
371 
372 	/**
373 	 * InfoTitle is the title that will be shown before any info messages/info
374 	 * counts are displayed
375 	 * 
376 	 * @return
377 	 */
378 	public String getInfoTitle() {
379 		return this.infoTitle;
380 	}
381 
382 	public void setInfoTitle(String infoTitle) {
383 		this.infoTitle = infoTitle;
384 	}
385 
386 	/**
387 	 * If displayErrorMessages is true, error messages will be displayed,
388 	 * otherwise they will not. Unlike many of the options contained on
389 	 * ErrorsField, this will not effect client side validations; ie this will
390 	 * not turn off errorMessage display for client side validation, as it may
391 	 * prevent a user from completing a form. To turn off client side validation
392 	 * AND its messaging use the applyClientSide flag on the Constraint itself.
393 	 * 
394 	 * TODO this may be changed to: if this is set on a field it will attempt
395 	 * show client side validation errors in the closest parent container error
396 	 * container
397 	 * 
398 	 * @return
399 	 */
400 	public boolean isDisplayErrorMessages() {
401 		return this.displayErrorMessages;
402 	}
403 
404 	public void setDisplayErrorMessages(boolean displayErrorMessages) {
405 		this.displayErrorMessages = displayErrorMessages;
406 	}
407 
408 	/**
409 	 * If displayInfoMessages is true, info messages will be displayed,
410 	 * otherwise they will not. Client side validation has no concept of warning
411 	 * or info messages, so this will not effect client side functionality.
412 	 * 
413 	 * @return
414 	 */
415 	public boolean isDisplayInfoMessages() {
416 		return this.displayInfoMessages;
417 	}
418 
419 	public void setDisplayInfoMessages(boolean displayInfoMessages) {
420 		this.displayInfoMessages = displayInfoMessages;
421 	}
422 
423 	public boolean isDisplayLockMessages() {
424 		return this.displayLockMessages;
425 	}
426 
427 	/**
428 	 * This has no use - needs to be removed(?)
429 	 * 
430 	 * @param displayLockMessages
431 	 */
432 	public void setDisplayLockMessages(boolean displayLockMessages) {
433 		this.displayLockMessages = displayLockMessages;
434 	}
435 
436 	/**
437 	 * If displayWarningMessages is true, warning messages will be displayed,
438 	 * otherwise they will not. Client side validation has no concept of warning
439 	 * or info messages, so this will not effect client side functionality.
440 	 * 
441 	 * @return
442 	 */
443 	public boolean isDisplayWarningMessages() {
444 		return this.displayWarningMessages;
445 	}
446 
447 	public void setDisplayWarningMessages(boolean displayWarningMessages) {
448 		this.displayWarningMessages = displayWarningMessages;
449 	}
450 
451 	/**
452 	 * AdditionalKeysToMatch is an additional list of keys outside of the
453 	 * default keys that will be matched when messages are returned after a form
454 	 * is submitted. These keys are only used for displaying messages generated
455 	 * by the server and have no effect on client side validation error display.
456 	 * 
457 	 * @return the additionalKeysToMatch
458 	 */
459 	public List<String> getAdditionalKeysToMatch() {
460 		return this.additionalKeysToMatch;
461 	}
462 	
463     /**
464      * Convenience setter for additional keys to match that takes a string argument and
465      * splits on comma to build the list
466      * 
467      * @param additionalKeysToMatch String to parse
468      */
469     public void setAdditionalKeysToMatch(String additionalKeysToMatch) {
470         if (StringUtils.isNotBlank(additionalKeysToMatch)) {
471             this.additionalKeysToMatch = Arrays.asList(StringUtils.split(additionalKeysToMatch, ","));
472         }
473     }
474 
475 	/**
476 	 * @param additionalKeysToMatch
477 	 *            the additionalKeysToMatch to set
478 	 */
479 	public void setAdditionalKeysToMatch(List<String> additionalKeysToMatch) {
480 		this.additionalKeysToMatch = additionalKeysToMatch;
481 	}
482 
483 	/**
484 	 * If true, the errorTitle set on this ErrorsField will be displayed along
485 	 * with the error messages. Otherwise, the title will not be displayed.
486 	 * 
487 	 * @return the displayErrorTitle
488 	 */
489 	public boolean isDisplayErrorTitle() {
490 		return this.displayErrorTitle;
491 	}
492 
493 	/**
494 	 * @param displayErrorTitle
495 	 *            the displayErrorTitle to set
496 	 */
497 	public void setDisplayErrorTitle(boolean displayErrorTitle) {
498 		this.displayErrorTitle = displayErrorTitle;
499 	}
500 
501 	/**
502 	 * If true, the warningTitle set on this ErrorsField will be displayed along
503 	 * with the warning messages. Otherwise, the title will not be displayed.
504 	 * 
505 	 * @return the displayWarningTitle
506 	 */
507 	public boolean isDisplayWarningTitle() {
508 		return this.displayWarningTitle;
509 	}
510 
511 	/**
512 	 * @param displayWarningTitle
513 	 *            the displayWarningTitle to set
514 	 */
515 	public void setDisplayWarningTitle(boolean displayWarningTitle) {
516 		this.displayWarningTitle = displayWarningTitle;
517 	}
518 
519 	/**
520 	 * If true, the infoTitle set on this ErrorsField will be displayed along
521 	 * with the info messages. Otherwise, the title will not be displayed.
522 	 * 
523 	 * @return the displayInfoTitle
524 	 */
525 	public boolean isDisplayInfoTitle() {
526 		return this.displayInfoTitle;
527 	}
528 
529 	/**
530 	 * @param displayInfoTitle
531 	 *            the displayInfoTitle to set
532 	 */
533 	public void setDisplayInfoTitle(boolean displayInfoTitle) {
534 		this.displayInfoTitle = displayInfoTitle;
535 	}
536 
537 	/**
538 	 * If true, the error messages will display the an InputField's title
539 	 * alongside the error, warning, and info messages related to it. This
540 	 * setting has no effect on messages which do not relate directly to a
541 	 * single InputField.
542 	 * 
543 	 * @return the displayFieldLabelWithMessages
544 	 */
545 	public boolean isDisplayFieldLabelWithMessages() {
546 		return this.displayFieldLabelWithMessages;
547 	}
548 
549 	/**
550 	 * @param displayFieldLabelWithMessages
551 	 *            the displayFieldLabelWithMessages to set
552 	 */
553 	public void setDisplayFieldLabelWithMessages(
554 			boolean displayFieldLabelWithMessages) {
555 		this.displayFieldLabelWithMessages = displayFieldLabelWithMessages;
556 	}
557 
558 	/**
559 	 * If true, error, warning, and info messages will be displayed (provided
560 	 * they are also set to display). Otherwise, no messages for this
561 	 * ErrorsField container will be displayed (including ones set to display).
562 	 * This is a global display on/off switch for all messages.
563 	 * 
564 	 * @return the displayMessages
565 	 */
566 	public boolean isDisplayMessages() {
567 		return this.displayMessages;
568 	}
569 
570 	/**
571 	 * @param displayMessages
572 	 *            the displayMessages to set
573 	 */
574 	public void setDisplayMessages(boolean displayMessages) {
575 		this.displayMessages = displayMessages;
576 	}
577 
578 	/**
579 	 * If true, this ErrorsField will show messages related to the nested
580 	 * components of its parent component, and not just those related only to
581 	 * its parent component. Otherwise, it will be up to the individual
582 	 * components to display their messages, if any, in their ErrorsField.
583 	 * 
584 	 * @return the displayNestedMessages
585 	 */
586 	public boolean isDisplayNestedMessages() {
587 		return this.displayNestedMessages;
588 	}
589 
590 	/**
591 	 * @param displayNestedMessages
592 	 *            the displayNestedMessages to set
593 	 */
594 	public void setDisplayNestedMessages(boolean displayNestedMessages) {
595 		this.displayNestedMessages = displayNestedMessages;
596 	}
597 
598 	/**
599 	 * Combines the messages for a single key into one concatenated message per
600 	 * key being matched, seperated by a comma
601 	 * 
602 	 * @return the combineMessages
603 	 */
604 	public boolean isCombineMessages() {
605 		return this.combineMessages;
606 	}
607 
608 	/**
609 	 * @param combineMessages
610 	 *            the combineMessages to set
611 	 */
612 	public void setCombineMessages(boolean combineMessages) {
613 		this.combineMessages = combineMessages;
614 	}
615 
616 	/**
617 	 * If true, when this is set on an ErrorsField whose parentComponent has
618 	 * nested Containers or AttributeFields, it will allow those fields to also
619 	 * show their ErrorsField messages. Otherwise, it will turn off the the
620 	 * display of those messages. This can be used to avoid repeating
621 	 * information to the user per field, if errors are already being displayed
622 	 * at the parent's level. This flag has no effect if displayNestedMessages
623 	 * is false on this ErrorsField.
624 	 * 
625 	 * @return the allowMessageRepeat
626 	 */
627 	public boolean isAllowMessageRepeat() {
628 		return this.allowMessageRepeat;
629 	}
630 
631 	/**
632 	 * 
633 	 * @param allowMessageRepeat
634 	 *            the allowMessageRepeat to set
635 	 */
636 	public void setAllowMessageRepeat(boolean allowMessageRepeat) {
637 		this.allowMessageRepeat = allowMessageRepeat;
638 	}
639 
640 	/**
641 	 * displayCounts is true if the counts of errors, warning, and info messages
642 	 * within this ErrorsField should be displayed (includes count of nested
643 	 * messages if displayNestedMessages is true).
644 	 * 
645 	 * @return
646 	 */
647 	public boolean isDisplayCounts() {
648 		return this.displayCounts;
649 	}
650 
651 	/**
652 	 * @param displayCounts
653 	 *            the displayCounts to set
654 	 */
655 	public void setDisplayCounts(boolean displayCounts) {
656 		this.displayCounts = displayCounts;
657 	}
658 
659 	/**
660 	 * The list of error messages found for the keys that were matched on this
661 	 * ErrorsField This is generated and cannot be set
662 	 * 
663 	 * @return the errors
664 	 */
665 	public List<String> getErrors() {
666 		return this.errors;
667 	}
668 
669 	/**
670 	 * The list of warning messages found for the keys that were matched on this
671 	 * ErrorsField This is generated and cannot be set
672 	 * 
673 	 * @return the warnings
674 	 */
675 	public List<String> getWarnings() {
676 		return this.warnings;
677 	}
678 
679 	/**
680 	 * The list of info messages found for the keys that were matched on this
681 	 * ErrorsField This is generated and cannot be set
682 	 * 
683 	 * @return the infos
684 	 */
685 	public List<String> getInfos() {
686 		return this.infos;
687 	}
688 
689 	/**
690 	 * The count of error messages found for the keys that were matched on this
691 	 * ErrorsField This is generated and cannot be set
692 	 * 
693 	 * @return the errorCount
694 	 */
695 	public int getErrorCount() {
696 		return this.errorCount;
697 	}
698 
699 	/**
700 	 * The count of warning messages found for the keys that were matched on
701 	 * this ErrorsField This is generated and cannot be set
702 	 * 
703 	 * @return the warningCount
704 	 */
705 	public int getWarningCount() {
706 		return this.warningCount;
707 	}
708 
709 	/**
710 	 * The count of info messages found for the keys that were matched on this
711 	 * ErrorsField This is generated and cannot be set
712 	 * 
713 	 * @return the infoCount
714 	 */
715 	public int getInfoCount() {
716 		return this.infoCount;
717 	}
718 
719 	/**
720 	 * If this is true, the display of messages is being handled by another
721 	 * container. The ErrorsField html generated by the jsp will still be used,
722 	 * but it will be placed in different location within the page than the
723 	 * default to accommodate an alternate layout. This flag is used by
724 	 * BoxLayoutManager.
725 	 * 
726 	 * This flag only applies to ErrorsFields whose parentComponents are
727 	 * AttributeFields.
728 	 * 
729 	 * @return the alternateContainer
730 	 */
731 	public boolean isAlternateContainer() {
732 		return this.alternateContainer;
733 	}
734 
735 	/**
736 	 * @param alternateContainer
737 	 *            the alternateContainer to set
738 	 */
739 	public void setAlternateContainer(boolean alternateContainer) {
740 		this.alternateContainer = alternateContainer;
741 	}
742 
743 	/**
744 	 * If true, displays an icon next to each field that has an error (default
745 	 * KNS look). Otherwise, this icon will not be displayed. Note that any icon
746 	 * set through css for the message containers will still appear and this
747 	 * only relates to the icon directly to the right of an input field.
748 	 * 
749 	 * This flag should only be set on InputField ErrorsFields.
750 	 * 
751 	 * @return the displayFieldErrorIcon
752 	 */
753 	public boolean isDisplayFieldErrorIcon() {
754 		return this.displayFieldErrorIcon;
755 	}
756 
757 	/**
758 	 * @param displayFieldErrorIcon
759 	 *            the displayFieldErrorIcon to set
760 	 */
761 	public void setDisplayFieldErrorIcon(boolean displayFieldErrorIcon) {
762 		this.displayFieldErrorIcon = displayFieldErrorIcon;
763 	}
764 
765 	/**
766 	 * If true, highlights the parentComponent's container when it has an
767 	 * error/warning/info. Otherwise, this highlighting will not be displayed.
768 	 * Note that the css can be changed per a type of highlighting, if showing a
769 	 * different color or no color per type of message is desired.
770 	 * 
771 	 * @return the highlightOnError
772 	 */
773 	public void setHighlightOnError(boolean highlightOnError) {
774 		this.highlightOnError = highlightOnError;
775 	}
776 
777 	/**
778 	 * @return the highlightOnError
779 	 */
780 	public boolean isHighlightOnError() {
781 		return highlightOnError;
782 	}
783 
784 }