Coverage Report - org.kuali.student.common.ui.client.widgets.field.layout.element.FieldElement
 
Classes in this File Line Coverage Branch Coverage Complexity
FieldElement
0%
0/265
0%
0/140
2.636
FieldElement$1
0%
0/1
N/A
2.636
FieldElement$LineNum
0%
0/1
N/A
2.636
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.common.ui.client.widgets.field.layout.element;
 17  
 
 18  
 import org.kuali.student.common.assembly.data.Metadata;
 19  
 import org.kuali.student.common.ui.client.application.Application;
 20  
 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
 21  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.ValidationMessagePanel;
 22  
 import org.kuali.student.common.ui.client.util.DebugIdUtils;
 23  
 import org.kuali.student.common.ui.client.widgets.HasInputWidget;
 24  
 import org.kuali.student.common.ui.client.widgets.HasWatermark;
 25  
 import org.kuali.student.common.ui.client.widgets.KSLabel;
 26  
 import org.kuali.student.common.ui.client.widgets.KSTitleDescPanel;
 27  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.AbbrButton.AbbrButtonType;
 28  
 import org.kuali.student.common.ui.client.widgets.field.layout.layouts.FieldLayout;
 29  
 import org.kuali.student.common.ui.client.widgets.field.layout.layouts.FieldLayoutComponent;
 30  
 import org.kuali.student.common.validation.dto.ValidationResultInfo;
 31  
 import org.kuali.student.common.validation.dto.ValidationResultInfo.ErrorLevel;
 32  
 
 33  
 import com.google.gwt.user.client.Element;
 34  
 import com.google.gwt.user.client.ui.Composite;
 35  
 import com.google.gwt.user.client.ui.FlowPanel;
 36  
 import com.google.gwt.user.client.ui.HTMLPanel;
 37  
 import com.google.gwt.user.client.ui.Panel;
 38  
 import com.google.gwt.user.client.ui.UIObject;
 39  
 import com.google.gwt.user.client.ui.Widget;
 40  
 
 41  
 /**
 42  
  * A ui field element.  Areas which contain a field for user data entry should use
 43  
  * this class for visual and behavior consistency.  Used by FieldDescriptor for its layout.
 44  
  * 
 45  
  * General layout of a field element, all elements are conditional based on the field's
 46  
  * configuration through set methods on this class: <br>
 47  
  * <b>[label][requiredness indicator][help]<br>
 48  
  * [input widget]<br>
 49  
  * [constraint text]<br></b>
 50  
  * <br>
 51  
  * 
 52  
  * The messageKeyInfo passed in is used to generate the messages needed for a field these include:<br>
 53  
  * Field Label<br>
 54  
  * Help text<br>
 55  
  * Instructions<br>
 56  
  * Example text<br>
 57  
  * Constraint text<br>
 58  
  * Watermark text - only if the widget one that accepts text input<br><br>
 59  
  * These are generated by the single key, the additional text is determined by special suffixes on keys within
 60  
  * the messages data - example - you pass in "sampleField" for the message key - it is automatically determined
 61  
  * that if there is a message in the messages data named "sampleField-instruct", instructions will be added to the field
 62  
  * in the appropriate location.<br>
 63  
  * List of the appended keys for use in messages data:<br>
 64  
  * "-help" for help text<br>
 65  
  * "-instruct" for instructions<br>
 66  
  * "-examples" for examples<br>
 67  
  * "-constraints" for constraint text<br>
 68  
  * "-watermark" for watermark text<br>
 69  
  * 
 70  
  * @author Kuali Student Team
 71  
  * @see FieldDescriptor
 72  
  * @see FieldLayout
 73  
  */
 74  
 public class FieldElement extends Composite implements FieldLayoutComponent{
 75  
 
 76  
         //Layout
 77  0
         private KSTitleDescPanel titlePanel = new KSTitleDescPanel();
 78  0
         private FlowPanel layout = new FlowPanel();
 79  
         private FieldTitle fieldTitle;
 80  0
         private SpanPanel instructions = new SpanPanel();
 81  0
         private AbbrButton examplesButton = new AbbrButton(AbbrButtonType.EXAMPLES);
 82  0
         private SpanPanel constraints = new SpanPanel();
 83  0
         private AbbrPanel required = new AbbrPanel("Required", "ks-form-module-elements-required", " * ");
 84  0
         private AbbrButton help = new AbbrButton(AbbrButtonType.HELP);
 85  
         private Widget fieldWidget;
 86  0
         private SpanPanel widgetSpan = new SpanPanel();
 87  
         private String fieldHTMLId;
 88  0
         private String watermarkText = null;
 89  0
         public static enum LineNum{SINGLE, DOUBLE, TRIPLE}
 90  
 
 91  
         private ValidationMessagePanel validationPanel;
 92  
         private String fieldKey;
 93  0
         private boolean labelShown = true;
 94  
         
 95  
         private Panel parentPanel;
 96  
         private Element parentElement;
 97  
         
 98  0
         private ErrorLevel status = ErrorLevel.OK;
 99  
         
 100  
 
 101  
         /**
 102  
          * Sets this field's validation panel, note that this does not add it to the ui.  Attaching must be done
 103  
          * elsewhere.  Most FieldLayout implementations handle this attachment.
 104  
          * @param validationPanel
 105  
          */
 106  
         public void setValidationPanel(ValidationMessagePanel validationPanel) {
 107  0
                 this.validationPanel = validationPanel;
 108  0
         }
 109  
 
 110  
 
 111  
         public Panel getParentPanel() {
 112  0
                 return parentPanel;
 113  
         }
 114  
 
 115  
         public void setParentPanel(Panel parentPanel) {
 116  0
                 this.parentPanel = parentPanel;
 117  0
                 this.parentElement = parentPanel.getElement();
 118  0
         }
 119  
 
 120  
         public void setParentElement(Element element){
 121  0
                 parentElement = element;
 122  0
         }
 123  
 
 124  
         private String fieldName;
 125  
         private String instructionText;
 126  
 
 127  
     public String getInstructionText() {
 128  0
                 return instructionText;
 129  
         }
 130  
 
 131  0
         public FieldElement(String title, Widget widget) {
 132  0
             generateLayout(title, title, null, null, null, null, widget);
 133  
 
 134  0
     }
 135  
 
 136  0
     public FieldElement(String key, String title, Widget widget){
 137  0
             generateLayout(key, title, null, null, null, null, widget);
 138  0
     }
 139  
 
 140  
     /**
 141  
      * Standard constructor for FieldElement
 142  
      * @param key unique key to identify this field
 143  
      * @param info key for the messages used in this field element - see class description
 144  
      */
 145  0
     public FieldElement(String key, MessageKeyInfo info){
 146  0
             init(key, info, null, null);
 147  0
     }
 148  
 
 149  
     /**
 150  
      * Standard constructor for FieldElement
 151  
      * @param key unique key to identify this field
 152  
      * @param info key for the messages used in this field element - see class description
 153  
      * @param widget widget used for input/display on this field
 154  
      */
 155  0
     public FieldElement(String key, MessageKeyInfo info, Widget widget, Metadata metadata){
 156  0
         init(key, info, widget, metadata);
 157  
     
 158  0
     }
 159  
     
 160  
     private void init(String key, MessageKeyInfo info, Widget widget, Metadata metadata ){
 161  0
             String title = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(), info.getId());
 162  
 
 163  0
             String help = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(),
 164  
                             info.getId() + HELP_MESSAGE_KEY, metadata);
 165  0
             if(help.equals(info.getId() + HELP_MESSAGE_KEY)){
 166  0
                     help = null;
 167  
             }
 168  
             
 169  0
             String instructions = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(),
 170  
                             info.getId() + INSTRUCT_MESSAGE_KEY, metadata);
 171  0
             if(instructions.equals(info.getId() + INSTRUCT_MESSAGE_KEY)){
 172  0
                     instructions = null;
 173  
             }
 174  
             
 175  0
             String examplesText = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(),
 176  
                 info.getId() + EXAMPLES_MESSAGE_KEY, metadata);
 177  0
             if (examplesText.equals(info.getId() + EXAMPLES_MESSAGE_KEY)) {
 178  0
                 examplesText = null;
 179  
             }
 180  
             
 181  0
         String constraints = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(),
 182  
                 info.getId() + CONSTRAINT_MESSAGE_KEY, metadata);
 183  0
             if(constraints.equals(info.getId() + CONSTRAINT_MESSAGE_KEY)){
 184  0
                     constraints = null;
 185  
             }
 186  
             
 187  0
             watermarkText = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(),
 188  
                             info.getId() + WATERMARK_MESSAGE_KEY, metadata);
 189  0
             if(watermarkText.equals(info.getId() + WATERMARK_MESSAGE_KEY)){
 190  0
                     watermarkText = null;
 191  
             }
 192  
             
 193  0
             generateLayout(key, title, help, instructions, examplesText, constraints, widget);
 194  0
     }
 195  
 
 196  
     private void generateLayout(String key, String title, String helpText, String instructText, String examplesText, String constraintText, Widget widget){
 197  0
             this.setKey(key);
 198  0
                 fieldName = title;
 199  0
                 fieldHTMLId = HTMLPanel.createUniqueId();
 200  0
                 fieldTitle = new LabelPanel(title, fieldHTMLId);
 201  0
                 required.setVisible(false);
 202  0
                 fieldTitle.add(required);
 203  0
                 if(helpText != null){
 204  0
                         this.setHelp(helpText);
 205  
                 }
 206  
                 else{
 207  0
                         help.setVisible(false);
 208  
                 }
 209  0
                 fieldTitle.add(help);
 210  0
                 layout.add(fieldTitle);
 211  0
                 if(instructText != null){
 212  0
                         this.setInstructions(instructText);
 213  
                 }
 214  
                 else{
 215  0
                         instructions.setVisible(false);
 216  
                 }
 217  0
                 if (examplesText != null) {
 218  0
                     this.setExamples(examplesText);
 219  
                 }
 220  
                 else {
 221  0
                     examplesButton.setVisible(false);
 222  
                 }
 223  0
                 if(constraintText != null){
 224  0
                         this.setConstraintText(constraintText);
 225  
                 }
 226  
                 else{
 227  0
                         constraints.setVisible(false);
 228  
                 }
 229  0
                 instructions.setStyleName("ks-form-module-elements-instruction");
 230  0
                 layout.add(instructions);
 231  0
                 instructions.add(examplesButton);
 232  0
                 layout.add(widgetSpan);
 233  0
                 constraints.setStyleName("ks-form-module-elements-help-text");
 234  0
                 layout.add(constraints);
 235  0
         initWidget(layout);
 236  0
         layout.addStyleName("ks-form-module-elements");
 237  0
         layout.addStyleName("ks-form-module-single-line-margin");
 238  0
         layout.ensureDebugId(DebugIdUtils.createWebDriverSafeDebugId(key != null ? key : title));
 239  
         //Set the widget here to ensure the debug Ids are set properly
 240  0
         if(widget != null){
 241  0
             this.setWidget(widget);
 242  
         }
 243  0
     }
 244  
 
 245  
     /**
 246  
      * Sets the widget for this field, automatically adds an id which will match this field's label-for tag in
 247  
      * its label
 248  
      * @see com.google.gwt.user.client.ui.Composite#setWidget(com.google.gwt.user.client.ui.Widget)
 249  
      */
 250  
     public void setWidget(Widget w){
 251  0
             if(fieldWidget != null){
 252  0
                     widgetSpan.remove(fieldWidget);
 253  
             }
 254  0
             fieldWidget = w;
 255  
             //TODO Do a check here to change the type of label based on widget type eventually
 256  0
             if(fieldWidget != null){
 257  
                     
 258  
                     //Checks for input widgets that may be incased in a more complex widget layout
 259  0
                     if(fieldWidget instanceof HasInputWidget){
 260  0
                             Widget input = ((HasInputWidget)fieldWidget).getInputWidget();
 261  0
                             if(input != null){
 262  0
                                     if(input instanceof HasWatermark && watermarkText != null){
 263  0
                                             ((HasWatermark)input).setWatermarkText(watermarkText);
 264  
                                     }
 265  0
                                     input.getElement().setAttribute("id", fieldHTMLId);
 266  0
                                     setDebugId(fieldWidget);
 267  
                                     //The fieldWidget debugId might have set the input field debug id to something different depending on how 'onEnsureDebugId' was overridden.
 268  
                                     //Override the input widget to have same id as fieldWidget
 269  0
                                     setDebugId(input);
 270  
                             }
 271  
                             else{
 272  0
                                     fieldWidget.getElement().setAttribute("id", fieldHTMLId);
 273  0
                                     setDebugId(fieldWidget);
 274  
                             }
 275  0
                     }
 276  
                     else{
 277  0
                         if(fieldWidget instanceof HasWatermark && watermarkText != null){
 278  0
                                 ((HasWatermark)fieldWidget).setWatermarkText(watermarkText);
 279  
                         }
 280  0
                             fieldWidget.getElement().setAttribute("id", fieldHTMLId);
 281  0
                             setDebugId(fieldWidget);
 282  
                             
 283  
                     }
 284  
                     
 285  0
                     widgetSpan.add(fieldWidget);
 286  
             }
 287  0
     }
 288  
 
 289  
 
 290  
     private void setDebugId(final Widget widget) {
 291  0
         widget.ensureDebugId(DebugIdUtils.createWebDriverSafeDebugId(layout.getElement().getId()));
 292  0
     }
 293  
     
 294  
     /**
 295  
      * Sets the required string key to be used for when a field is required.  For example, in most cases this
 296  
      * key maps to a "*"
 297  
      * 
 298  
      * @param requiredKey
 299  
      */
 300  
     public void setRequiredString(String requiredKey){
 301  0
             String requiredText = Application.getApplicationContext().getMessage(requiredKey);
 302  0
             required.setText(requiredText);
 303  0
             required.setVisible(true);
 304  0
     }
 305  
     
 306  
     public void setRequiredString(String requiredKey, String style){
 307  0
             String requiredText = Application.getApplicationContext().getMessage(requiredKey);
 308  0
             required.setText(requiredText);
 309  0
             required.setStyleName(style);
 310  0
             required.setVisible(true);
 311  0
     }
 312  
 
 313  
     public AbbrPanel getRequiredPanel(){
 314  0
             return required;
 315  
     }
 316  
     
 317  
     public void clearRequiredText(){
 318  0
         required.setText("");
 319  0
     }
 320  
 
 321  
     public Widget getFieldWidget(){
 322  0
             return fieldWidget;
 323  
     }
 324  
 
 325  
     public FlowPanel getFieldDetailsLayout(){
 326  0
             FlowPanel div = new FlowPanel();
 327  0
                 div.add(fieldTitle);
 328  0
                 div.add(instructions);
 329  0
                 div.addStyleName("ks-form-module-elements");
 330  0
                 return div;
 331  
     }
 332  
 
 333  
     public FlowPanel getFieldWidgetAreaLayout(){
 334  0
             FlowPanel div = new FlowPanel();
 335  0
             div.add(fieldWidget);
 336  0
             div.add(constraints);
 337  0
             div.addStyleName("ks-form-module-elements");
 338  0
             return div;
 339  
     }
 340  
     
 341  
     public boolean isRequired() {
 342  0
         return required.isVisible();
 343  
     }
 344  
 
 345  
     public void setRequired(boolean isRequired){
 346  0
             required.setVisible(isRequired);
 347  0
     }
 348  
 
 349  
     public void setInstructions(String text){
 350  0
             instructionText = text;
 351  0
             if(instructionText != null && !instructionText.trim().equals("")){
 352  0
                     instructions.setHTML(text);
 353  0
                     instructions.setVisible(true);
 354  
             } else {
 355  0
                     instructions.setVisible(false);
 356  
         }
 357  0
     }
 358  
     
 359  
     public void setExamples(String examplesText) {
 360  0
         if (examplesText != null && !"".equals(examplesText.trim())) {
 361  0
             examplesButton.setVisible(true);
 362  
             //since the examplesButton is displayed in the instructions panel we need to set it visible if it's not
 363  0
             instructions.setVisible(true);
 364  0
             examplesButton.setHoverHTML(examplesText);
 365  0
             examplesButton.getHoverPopup().addStyleName("ks-example-popup");
 366  
         } else {
 367  0
             examplesButton.setVisible(false);
 368  
         }
 369  0
     }
 370  
 
 371  
     public void setConstraintText(String text){
 372  0
             if(text != null && !text.trim().equals("")){
 373  0
                     constraints.setHTML(text);
 374  0
                     constraints.setVisible(true);
 375  
             }else{
 376  0
                     constraints.setVisible(false);
 377  
             }
 378  0
     }
 379  
 
 380  
     public void setHelp(final String html){
 381  0
             if(html != null && !html.trim().equals("")){
 382  0
                     help.setVisible(true);
 383  0
                     help.setHoverHTML(html);
 384  
                     /*help.addClickHandler(new ClickHandler(){
 385  
 
 386  
                                 @Override
 387  
                                 public void onClick(ClickEvent event) {
 388  
                                         //TODO show actual help window
 389  
                                         Window.alert(html);
 390  
 
 391  
                                 }
 392  
                         });*/
 393  
             }
 394  
             else{
 395  0
                     help.setVisible(false);
 396  
             }
 397  0
     }
 398  
 
 399  
         public Widget getTitleWidget() {
 400  0
             return titlePanel.getTitleWidget();
 401  
         }
 402  
 
 403  
         public ValidationMessagePanel getValidationPanel() {
 404  0
                 return validationPanel;
 405  
         }
 406  
 
 407  
         public Panel getEncapsulatingPanel() {
 408  0
                 return parentPanel;
 409  
         }
 410  
 
 411  
         public String getFieldName() {
 412  0
                 return fieldName;
 413  
         }
 414  
 
 415  
         /**
 416  
          * Turn on/off styling for errors on field element
 417  
          * 
 418  
          * @param error When true turns on error styling, when false turns off error styling
 419  
          */
 420  
         public void setErrorState(boolean error){
 421  0
                 if(error){
 422  0
                         fieldTitle.addStyleName("invalid");
 423  0
                         if(parentPanel != null){
 424  0
                                 parentPanel.addStyleName("error");
 425  
                         }
 426  0
                         else if(parentElement != null){
 427  0
                                 parentElement.setClassName("error");
 428  
                         }
 429  
                         //When there is an error, don't use warning style
 430  0
                         setWarnState(false);
 431  
                 }
 432  
                 else{
 433  0
                         fieldTitle.removeStyleName("invalid");
 434  0
                         if(parentPanel != null){
 435  0
                                 parentPanel.removeStyleName("error");
 436  
                         }
 437  0
                         else if(parentElement != null){
 438  0
                                 parentElement.setClassName("");
 439  
                         }
 440  
                         //Reset earn state, in case there are warnings
 441  0
                         setWarnState(validationPanel.hasWarnings());
 442  
                 }
 443  0
         }
 444  
         
 445  
         /**
 446  
          * Turn on/off styling for warnings on field element
 447  
          * 
 448  
          * @param warn When true turns on warning styling, when false turns off warning styling
 449  
          */
 450  
         public void setWarnState(boolean warn){
 451  0
                 if(warn){
 452  
                         //fieldTitle.addStyleName("invalid");
 453  0
                         if(parentPanel != null){
 454  0
                                 parentPanel.addStyleName("warning");
 455  
                         }
 456  0
                         else if(parentElement != null){
 457  0
                                 parentElement.setClassName("warning");
 458  
                         }
 459  
 
 460  
                 }
 461  
                 else{
 462  
                         //fieldTitle.removeStyleName("invalid");
 463  0
                         if(parentPanel != null){
 464  0
                                 parentPanel.removeStyleName("warning");
 465  
                         }
 466  0
                         else if(parentElement != null){
 467  0
                                 parentElement.setClassName("");
 468  
                         }
 469  
                 }
 470  0
         }
 471  
         
 472  
 
 473  
         /**
 474  
          * Processes a validation result and adds an appropriate message, if needed
 475  
          * @param vr
 476  
          * @return
 477  
          */
 478  
         public ErrorLevel processValidationResult(ValidationResultInfo vr) {
 479  
                 //Check if this field is responsible for processing its own validation results
 480  0
                 if(getFieldWidget() instanceof ValidationProcessable){
 481  0
                         if(((ValidationProcessable)getFieldWidget()).shouldProcessValidationResult(vr)){
 482  0
                                 if (fieldName != null && fieldName.trim() != "")
 483  0
                                         return ((ValidationProcessable)getFieldWidget()).processValidationResult(vr, fieldName);
 484  
                                 else        
 485  0
                                         return ((ValidationProcessable)getFieldWidget()).processValidationResult(vr);
 486  
                         }
 487  
                 }
 488  
                 
 489  0
                 status = ErrorLevel.OK;
 490  
 
 491  0
                 if(vr.getLevel() == ErrorLevel.ERROR){
 492  0
                         String message = Application.getApplicationContext().getUILabel("validation", vr.getMessage());
 493  0
                         this.addValidationErrorMessage(message);
 494  
                         
 495  0
                         if(status.getLevel() < ErrorLevel.ERROR.getLevel()){
 496  0
                                 status = vr.getLevel();
 497  
                         }
 498  0
                 }
 499  0
                 else if(vr.getLevel() == ErrorLevel.WARN){
 500  0
                         String message = Application.getApplicationContext().getUILabel("validation", vr.getMessage());
 501  0
                         this.addValidationWarningMessage(message);
 502  
                         
 503  0
                         if(status.getLevel() < ErrorLevel.WARN.getLevel()){
 504  0
                                 status = vr.getLevel();                        
 505  
                         }
 506  
                 }
 507  
                 else{
 508  
                         //TODO does nothing on ok, ok is not currently used
 509  
                 }
 510  0
                 return status;
 511  
         }
 512  
 
 513  
         /**
 514  
          * Add a validation message to this fields validation panel as defined by setValidationPanel.
 515  
          * @param text
 516  
          */
 517  
         public void addValidationErrorMessage(String text){
 518  0
                 if(validationPanel != null){
 519  
                         KSLabel message;
 520  0
                         if(fieldName != null && !fieldName.trim().equals("")){
 521  0
                                 message = new KSLabel(fieldName + " - " + text);
 522  
                         }
 523  
                         else{
 524  0
                                 message = new KSLabel(text);
 525  
                         }
 526  0
                         message.setStyleName("ks-form-error-label");
 527  0
                         this.setErrorState(true);
 528  0
                         this.validationPanel.addErrorMessage(message);
 529  
                 }
 530  0
         }
 531  
 
 532  
         /**
 533  
          * Add a validation message to this fields validation panel as defined by setValidationPanel.
 534  
          * @param text
 535  
          */
 536  
         public void addValidationWarningMessage(String text){
 537  0
                 if(validationPanel != null){
 538  0
                         SpanPanel message = new SpanPanel();
 539  0
                         if(fieldName != null && !fieldName.trim().equals("")){
 540  0
                                 message.setHTML("<b> Warning </b> " + fieldName + " - " + text);
 541  
                         }
 542  
                         else{
 543  0
                                 message.setHTML("<b> Warning </b> " + text);
 544  
                         }
 545  0
                         message.setStyleName("ks-form-warn-label");
 546  
                         //Only set field styling to warn, when no errors
 547  0
                         this.setWarnState((status != ErrorLevel.ERROR));
 548  0
                         this.validationPanel.addWarnMessage(message);
 549  
                 }
 550  0
         }
 551  
 
 552  
         /**
 553  
          * Clears validation error and highlighting that may exist on this panel or widget
 554  
          */
 555  
         public void clearValidationErrors(){
 556  0
                 this.setErrorState(false);
 557  0
                 if(validationPanel != null){
 558  0
                         this.validationPanel.clearErrors();
 559  
                 }
 560  
                 
 561  
                 //Clear errors on widget if widget responsible for its own errors
 562  0
                 if(getFieldWidget() instanceof ValidationProcessable){
 563  0
                         ((ValidationProcessable)getFieldWidget()).clearValidationErrors();
 564  
                 }
 565  0
         }
 566  
 
 567  
         /**
 568  
          * Clears validation warnings and highlighting that may exist on this panel or widget
 569  
          */
 570  
         public void clearValidationWarnings(){
 571  0
                 this.setWarnState(false);
 572  0
                 if(validationPanel != null){
 573  0
                         this.validationPanel.clearWarnings();
 574  
                 }                                
 575  
                 
 576  
                 //Clear warnings on widget if widget responsible for its own warnings
 577  0
                 if(getFieldWidget() instanceof ValidationProcessable){
 578  0
                         ((ValidationProcessable)getFieldWidget()).clearValidationWarnings();
 579  
                 }
 580  0
         }
 581  
 
 582  
         @Override
 583  
         public String getKey() {
 584  0
                 return fieldKey;
 585  
         }
 586  
 
 587  
         @Override
 588  
         public void setKey(String key) {
 589  0
             if(key == null){
 590  
                         //TODO better way to generate unique id here?
 591  0
                         key = HTMLPanel.createUniqueId();
 592  
                 }
 593  0
                 this.fieldKey = key;
 594  0
         }
 595  
 
 596  
         /**
 597  
          * Sets the expected number of lines needed to space the vertical height of this field consistently
 598  
          * with fields next to it horizontally
 599  
          * @param margin
 600  
          */
 601  
         public void setTitleDescLineHeight(LineNum margin) {
 602  0
                 layout.removeStyleName("ks-form-module-single-line-margin");
 603  0
                 switch(margin){
 604  
                         case TRIPLE:
 605  0
                                 if(firstLineExists() && secondLineExists()){
 606  0
                                         layout.addStyleName("ks-form-module-single-line-margin");
 607  
                                 }
 608  0
                                 else if((firstLineExists() || secondLineExists())){
 609  0
                                         layout.addStyleName("ks-form-module-double-line-margin");
 610  
                                 }
 611  
                                 else{
 612  0
                                         layout.addStyleName("ks-form-module-triple-line-margin");
 613  
                                 }
 614  
 
 615  0
                                 break;
 616  
                         case DOUBLE:
 617  0
                                 if((firstLineExists() || secondLineExists())){
 618  0
                                         layout.addStyleName("ks-form-module-single-line-margin");
 619  
                                 }
 620  
                                 else{
 621  0
                                         layout.addStyleName("ks-form-module-double-line-margin");
 622  
                                 }
 623  0
                                 break;
 624  
                         case SINGLE:
 625  0
                                 layout.addStyleName("ks-form-module-single-line-margin");
 626  
                                 break;
 627  
                 }
 628  
 
 629  0
         }
 630  
 
 631  
         private boolean firstLineExists(){
 632  0
                 boolean exists = false;
 633  0
                 if((fieldName != null && !fieldName.equals("")) || required.isVisible() || help.isVisible()){
 634  0
                         exists = true;
 635  
                 }
 636  0
                 return exists;
 637  
         }
 638  
 
 639  
         private boolean secondLineExists(){
 640  0
                 boolean exists = false;
 641  0
                 if(instructions.isVisible()){
 642  0
                         exists = true;
 643  
                 }
 644  0
                 return exists;
 645  
         }
 646  
 
 647  
         /**
 648  
          * Hides the label of this field visually, but screen readers can still read it for accessibility
 649  
          */
 650  
         public void hideLabel() {
 651  0
                 layout.removeStyleName("ks-form-module-double-line-margin");
 652  0
                 layout.removeStyleName("ks-form-module-triple-line-margin");
 653  0
                 layout.addStyleName("ks-form-module-single-line-margin");
 654  0
                 fieldTitle.setStyleName("accessibility-hidden");
 655  0
                 instructions.setVisible(false);
 656  0
                 labelShown = false;
 657  0
         }
 658  
         
 659  
         public boolean isLabelShown(){
 660  0
                 return labelShown;
 661  
         }
 662  
 }