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/204
0%
0/98
2.282
FieldElement$1
0%
0/1
N/A
2.282
FieldElement$LineNum
0%
0/1
N/A
2.282
 
 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.ui.client.application.Application;
 19  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.ValidationMessagePanel;
 20  
 import org.kuali.student.common.ui.client.widgets.HasInputWidget;
 21  
 import org.kuali.student.common.ui.client.widgets.HasWatermark;
 22  
 import org.kuali.student.common.ui.client.widgets.KSLabel;
 23  
 import org.kuali.student.common.ui.client.widgets.KSTitleDescPanel;
 24  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.AbbrButton.AbbrButtonType;
 25  
 import org.kuali.student.common.ui.client.widgets.field.layout.layouts.FieldLayoutComponent;
 26  
 import org.kuali.student.common.validation.dto.ValidationResultInfo;
 27  
 import org.kuali.student.common.validation.dto.ValidationResultInfo.ErrorLevel;
 28  
 
 29  
 import com.google.gwt.user.client.Element;
 30  
 import com.google.gwt.user.client.ui.Composite;
 31  
 import com.google.gwt.user.client.ui.FlowPanel;
 32  
 import com.google.gwt.user.client.ui.HTMLPanel;
 33  
 import com.google.gwt.user.client.ui.Panel;
 34  
 import com.google.gwt.user.client.ui.Widget;
 35  
 
 36  
 /**
 37  
  * A ui field element.  Areas which contain a field for user data entry should use
 38  
  * this class for visual and behavior consistency.  Used by FieldDescriptor for its layout.
 39  
  * 
 40  
  * General layout of a field element, all elements are conditional based on the field's
 41  
  * configuration through set methods on this class: <br>
 42  
  * <b>[label][requiredness indicator][help]<br>
 43  
  * [input widget]<br>
 44  
  * [constraint text]<br></b>
 45  
  * <br>
 46  
  * 
 47  
  * The messageKeyInfo passed in is used to generate the messages needed for a field these include:<br>
 48  
  * Field Label<br>
 49  
  * Help text<br>
 50  
  * Instructions<br>
 51  
  * Constraint text<br>
 52  
  * Watermark text - only if the widget one that accepts text input<br><br>
 53  
  * These are generated by the single key, the additional text is determined by special suffixes on keys within
 54  
  * the messages data - example - you pass in "sampleField" for the message key - it is automatically determined
 55  
  * that if there is a message in the messages data named "sampleField-instruct", instructions will be added to the field
 56  
  * in the appropriate location.<br>
 57  
  * List of the appended keys for use in messages data:<br>
 58  
  * "-help" for help text<br>
 59  
  * "-instruct" for instructions<br>
 60  
  * "-constraints" for constraint text<br>
 61  
  * "-watermark" for watermark text<br>
 62  
  * 
 63  
  * @author Kuali Student Team
 64  
  * @see FieldDescriptor
 65  
  * @see FieldLayout
 66  
  */
 67  
 public class FieldElement extends Composite implements FieldLayoutComponent{
 68  
 
 69  
         //Layout
 70  0
         private KSTitleDescPanel titlePanel = new KSTitleDescPanel();
 71  0
         private FlowPanel layout = new FlowPanel();
 72  
         private FieldTitle fieldTitle;
 73  0
         private SpanPanel instructions = new SpanPanel();
 74  0
         private SpanPanel constraints = new SpanPanel();
 75  0
         private AbbrPanel required = new AbbrPanel("Required", "ks-form-module-elements-required", " * ");
 76  0
         private AbbrButton help = new AbbrButton(AbbrButtonType.HELP);
 77  
         private Widget fieldWidget;
 78  0
         private SpanPanel widgetSpan = new SpanPanel();
 79  
         private String fieldHTMLId;
 80  
         private LineNum margin;
 81  0
         private String watermarkText = null;
 82  0
         public static enum LineNum{SINGLE, DOUBLE, TRIPLE}
 83  
 
 84  
         private ValidationMessagePanel validationPanel;
 85  
         private String fieldKey;
 86  0
         private boolean labelShown = true;
 87  
         
 88  
         private Panel parentPanel;
 89  
         private Element parentElement;
 90  
 
 91  
         /**
 92  
          * Sets this field's validation panel, note that this does not add it to the ui.  Attaching must be done
 93  
          * elsewhere.  Most FieldLayout implementations handle this attachment.
 94  
          * @param validationPanel
 95  
          */
 96  
         public void setValidationPanel(ValidationMessagePanel validationPanel) {
 97  0
                 this.validationPanel = validationPanel;
 98  0
         }
 99  
 
 100  
 
 101  
         public Panel getParentPanel() {
 102  0
                 return parentPanel;
 103  
         }
 104  
 
 105  
         public void setParentPanel(Panel parentPanel) {
 106  0
                 this.parentPanel = parentPanel;
 107  0
                 this.parentElement = parentPanel.getElement();
 108  0
         }
 109  
 
 110  
         public void setParentElement(Element element){
 111  0
                 parentElement = element;
 112  0
         }
 113  
 
 114  
         private String fieldName;
 115  
         private String instructionText;
 116  
 
 117  
     public String getInstructionText() {
 118  0
                 return instructionText;
 119  
         }
 120  
 
 121  0
         public FieldElement(String title, Widget widget) {
 122  0
             generateLayout(title, title, null, null, null, widget);
 123  
 
 124  0
     }
 125  
 
 126  0
     public FieldElement(String key, String title, Widget widget){
 127  0
             generateLayout(key, title, null, null, null, widget);
 128  0
     }
 129  
 
 130  
     /**
 131  
      * Standard constructor for FieldElement
 132  
      * @param key unique key to identify this field
 133  
      * @param info key for the messages used in this field element - see class description
 134  
      */
 135  0
     public FieldElement(String key, MessageKeyInfo info){
 136  0
             init(key, info, null);
 137  0
     }
 138  
 
 139  
     /**
 140  
      * Standard constructor for FieldElement
 141  
      * @param key unique key to identify this field
 142  
      * @param info key for the messages used in this field element - see class description
 143  
      * @param widget widget used for input/display on this field
 144  
      */
 145  0
     public FieldElement(String key, MessageKeyInfo info, Widget widget){
 146  0
             init(key, info, widget);
 147  
 
 148  0
     }
 149  
     
 150  
     private void init(String key, MessageKeyInfo info, Widget widget){
 151  0
             String title = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(), info.getId());
 152  
             
 153  0
             String help = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(),
 154  
                             info.getId() + HELP_MESSAGE_KEY);
 155  0
             if(help.equals(info.getId() + HELP_MESSAGE_KEY)){
 156  0
                     help = null;
 157  
             }
 158  
             
 159  0
             String instructions = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(),
 160  
                             info.getId() + INSTRUCT_MESSAGE_KEY);
 161  0
             if(instructions.equals(info.getId() + INSTRUCT_MESSAGE_KEY)){
 162  0
                     instructions = null;
 163  
             }
 164  
             
 165  0
             String constraints = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(),
 166  
                             info.getId() + CONSTRAINT_MESSAGE_KEY);
 167  0
             if(constraints.equals(info.getId() + CONSTRAINT_MESSAGE_KEY)){
 168  0
                     constraints = null;
 169  
             }
 170  
             
 171  0
             watermarkText = Application.getApplicationContext().getUILabel(info.getGroup(), info.getType(), info.getState(),
 172  
                             info.getId() + WATERMARK_MESSAGE_KEY);
 173  0
             if(watermarkText.equals(info.getId() + WATERMARK_MESSAGE_KEY)){
 174  0
                     watermarkText = null;
 175  
             }
 176  
             
 177  0
             generateLayout(key, title, help, instructions, constraints, widget);
 178  0
     }
 179  
 
 180  
     private void generateLayout(String key, String title, String helpText, String instructText, String constraintText, Widget widget){
 181  0
             this.setKey(key);
 182  0
                 fieldName = title;
 183  
 
 184  0
                 fieldHTMLId = HTMLPanel.createUniqueId();
 185  0
                 fieldTitle = new LabelPanel(title, fieldHTMLId);
 186  
 
 187  0
                 required.setVisible(false);
 188  0
                 fieldTitle.add(required);
 189  0
                 if(helpText != null){
 190  0
                         this.setHelp(helpText);
 191  
                 }
 192  
                 else{
 193  0
                         help.setVisible(false);
 194  
                 }
 195  
 
 196  0
                 fieldTitle.add(help);
 197  0
                 layout.add(fieldTitle);
 198  0
                 if(instructText != null){
 199  0
                         this.setInstructions(instructText);
 200  
                 }
 201  
                 else{
 202  0
                         instructions.setVisible(false);
 203  
                 }
 204  
                 
 205  0
                 if(constraintText != null){
 206  0
                         this.setConstraintText(constraintText);
 207  
                 }
 208  
                 else{
 209  0
                         constraints.setVisible(false);
 210  
                 }
 211  0
                 instructions.setStyleName("ks-form-module-elements-instruction");
 212  0
                 layout.add(instructions);
 213  0
                 layout.add(widgetSpan);
 214  0
                 if(widget != null){
 215  0
                         this.setWidget(widget);
 216  
                 }
 217  0
                 constraints.setStyleName("ks-form-module-elements-help-text");
 218  0
                 layout.add(constraints);
 219  
 
 220  
 
 221  0
         initWidget(layout);
 222  0
         layout.addStyleName("ks-form-module-elements");
 223  0
         layout.addStyleName("ks-form-module-single-line-margin");
 224  0
     }
 225  
 
 226  
     /**
 227  
      * Sets the widget for this field, automatically adds an id which will match this field's label-for tag in
 228  
      * its label
 229  
      * @see com.google.gwt.user.client.ui.Composite#setWidget(com.google.gwt.user.client.ui.Widget)
 230  
      */
 231  
     public void setWidget(Widget w){
 232  0
             if(fieldWidget != null){
 233  0
                     widgetSpan.remove(fieldWidget);
 234  
             }
 235  0
             fieldWidget = w;
 236  
             //TODO Do a check here to change the type of label based on widget type eventually
 237  0
             if(fieldWidget != null){
 238  
                     
 239  
                     //Checks for input widgets that may be incased in a more complex widget layout
 240  0
                     if(fieldWidget instanceof HasInputWidget){
 241  0
                             Widget input = ((HasInputWidget)fieldWidget).getInputWidget();
 242  0
                             if(input != null){
 243  0
                                     if(input instanceof HasWatermark && watermarkText != null){
 244  0
                                             ((HasWatermark)input).setWatermarkText(watermarkText);
 245  
                                     }
 246  0
                                     input.getElement().setAttribute("id", fieldHTMLId);
 247  
                             }
 248  
                             else{
 249  0
                                     fieldWidget.getElement().setAttribute("id", fieldHTMLId);
 250  
                             }
 251  0
                     }
 252  
                     else{
 253  0
                         if(fieldWidget instanceof HasWatermark && watermarkText != null){
 254  0
                                 ((HasWatermark)fieldWidget).setWatermarkText(watermarkText);
 255  
                         }
 256  0
                             fieldWidget.getElement().setAttribute("id", fieldHTMLId);
 257  
                     }
 258  
                     
 259  0
                     widgetSpan.add(fieldWidget);
 260  
             }
 261  0
     }
 262  
     
 263  
     /**
 264  
      * Sets the required string key to be used for when a field is required.  For example, in most cases this
 265  
      * key maps to a "*"
 266  
      * 
 267  
      * @param requiredKey
 268  
      */
 269  
     public void setRequiredString(String requiredKey){
 270  0
             String requiredText = Application.getApplicationContext().getMessage(requiredKey);
 271  0
             required.setText(requiredText);
 272  0
             required.setVisible(true);
 273  0
     }
 274  
     
 275  
     public void setRequiredString(String requiredKey, String style){
 276  0
             String requiredText = Application.getApplicationContext().getMessage(requiredKey);
 277  0
             required.setText(requiredText);
 278  0
             required.setStyleName(style);
 279  0
             required.setVisible(true);
 280  0
     }
 281  
 
 282  
     public AbbrPanel getRequiredPanel(){
 283  0
             return required;
 284  
     }
 285  
     
 286  
     public void clearRequiredText(){
 287  0
         required.setText("");
 288  0
     }
 289  
 
 290  
     public Widget getFieldWidget(){
 291  0
             return fieldWidget;
 292  
     }
 293  
 
 294  
     public FlowPanel getFieldDetailsLayout(){
 295  0
             FlowPanel div = new FlowPanel();
 296  0
                 div.add(fieldTitle);
 297  0
                 div.add(instructions);
 298  0
                 div.addStyleName("ks-form-module-elements");
 299  0
                 return div;
 300  
     }
 301  
 
 302  
     public FlowPanel getFieldWidgetAreaLayout(){
 303  0
             FlowPanel div = new FlowPanel();
 304  0
             div.add(fieldWidget);
 305  0
             div.add(constraints);
 306  0
             div.addStyleName("ks-form-module-elements");
 307  0
             return div;
 308  
     }
 309  
     
 310  
     public boolean isRequired() {
 311  0
         return required.isVisible();
 312  
     }
 313  
 
 314  
     public void setRequired(boolean isRequired){
 315  0
             required.setVisible(isRequired);
 316  0
     }
 317  
 
 318  
     public void setInstructions(String text){
 319  0
             instructionText = text;
 320  0
             if(instructionText != null && !instructionText.trim().equals("")){
 321  0
                     instructions.setHTML(text);
 322  0
                     instructions.setVisible(true);
 323  
             }
 324  0
     }
 325  
 
 326  
     public void setConstraintText(String text){
 327  0
             if(text != null && !text.trim().equals("")){
 328  0
                     constraints.setHTML(text);
 329  0
                     constraints.setVisible(true);
 330  
             }
 331  0
     }
 332  
 
 333  
     public void setHelp(final String html){
 334  0
             if(html != null && !html.trim().equals("")){
 335  0
                     help.setVisible(true);
 336  0
                     help.setHoverHTML(html);
 337  
                     /*help.addClickHandler(new ClickHandler(){
 338  
 
 339  
                                 @Override
 340  
                                 public void onClick(ClickEvent event) {
 341  
                                         //TODO show actual help window
 342  
                                         Window.alert(html);
 343  
 
 344  
                                 }
 345  
                         });*/
 346  
             }
 347  
             else{
 348  0
                     help.setVisible(false);
 349  
             }
 350  0
     }
 351  
 
 352  
         public Widget getTitleWidget() {
 353  0
             return titlePanel.getTitleWidget();
 354  
         }
 355  
 
 356  
         public ValidationMessagePanel getValidationPanel() {
 357  0
                 return validationPanel;
 358  
         }
 359  
 
 360  
         public Panel getEncapsulatingPanel() {
 361  0
                 return parentPanel;
 362  
         }
 363  
 
 364  
         public String getFieldName() {
 365  0
                 return fieldName;
 366  
         }
 367  
 
 368  
         public void setErrorState(boolean error){
 369  0
                 if(error){
 370  0
                         fieldTitle.addStyleName("invalid");
 371  0
                         if(parentPanel != null){
 372  0
                                 parentPanel.addStyleName("error");
 373  
                         }
 374  0
                         else if(parentElement != null){
 375  0
                                 parentElement.setClassName("error");
 376  
                         }
 377  
 
 378  
                 }
 379  
                 else{
 380  0
                         fieldTitle.removeStyleName("invalid");
 381  0
                         if(parentPanel != null){
 382  0
                                 parentPanel.removeStyleName("error");
 383  
                         }
 384  0
                         else if(parentElement != null){
 385  0
                                 parentElement.setClassName("");
 386  
                         }
 387  
                 }
 388  
 
 389  0
         }
 390  
 
 391  
         /**
 392  
          * Processes a validation result and adds an appropriate message, if needed
 393  
          * @param vr
 394  
          * @return
 395  
          */
 396  
         public ErrorLevel processValidationResult(ValidationResultInfo vr) {
 397  0
                 ErrorLevel status = ErrorLevel.OK;
 398  
 
 399  0
                 if(vr.getLevel() == ErrorLevel.ERROR){
 400  0
                         String message = Application.getApplicationContext().getUILabel("validation", vr.getMessage());
 401  0
                         this.addValidationErrorMessage(message);
 402  
                         
 403  0
                         if(status.getLevel() < ErrorLevel.ERROR.getLevel()){
 404  0
                                 status = vr.getLevel();
 405  
                         }
 406  0
                 }
 407  0
                 else if(vr.getLevel() == ErrorLevel.WARN){
 408  0
                         if(status.getLevel() < ErrorLevel.WARN.getLevel()){
 409  0
                                 status = vr.getLevel();
 410  
                         }
 411  
                         //TODO does nothing on warn, warn is not currently used
 412  
                 }
 413  
                 else{
 414  
                         //TODO does nothing on ok, ok is not currently used
 415  
                 }
 416  0
                 return status;
 417  
         }
 418  
 
 419  
         /**
 420  
          * Add a validation message to this fields validation panel as defined by setValidationPanel.
 421  
          * @param text
 422  
          */
 423  
         public void addValidationErrorMessage(String text){
 424  0
                 if(validationPanel != null){
 425  
                         KSLabel message;
 426  0
                         if(fieldName != null && !fieldName.trim().equals("")){
 427  0
                                 message = new KSLabel(fieldName + " - " + text);
 428  
                         }
 429  
                         else{
 430  0
                                 message = new KSLabel(text);
 431  
                         }
 432  0
                         message.setStyleName("ks-form-validation-label");
 433  0
                         this.setErrorState(true);
 434  0
                         this.validationPanel.addMessage(message);
 435  
                 }
 436  0
         }
 437  
 
 438  
         public void clearValidationPanel(){
 439  0
                 this.setErrorState(false);
 440  0
                 if(validationPanel != null){
 441  0
                         this.validationPanel.clear();
 442  
                 }
 443  0
         }
 444  
 
 445  
         @Override
 446  
         public String getKey() {
 447  0
                 return fieldKey;
 448  
         }
 449  
 
 450  
         @Override
 451  
         public void setKey(String key) {
 452  0
             if(key == null){
 453  
                         //TODO better way to generate unique id here?
 454  0
                         key = HTMLPanel.createUniqueId();
 455  
                 }
 456  0
                 this.fieldKey = key;
 457  0
         }
 458  
 
 459  
         /**
 460  
          * Sets the expected number of lines needed to space the vertical height of this field consistently
 461  
          * with fields next to it horizontally
 462  
          * @param margin
 463  
          */
 464  
         public void setTitleDescLineHeight(LineNum margin) {
 465  0
                 layout.removeStyleName("ks-form-module-single-line-margin");
 466  0
                 switch(margin){
 467  
                         case TRIPLE:
 468  0
                                 if(firstLineExists() && secondLineExists()){
 469  0
                                         layout.addStyleName("ks-form-module-single-line-margin");
 470  
                                 }
 471  0
                                 else if((firstLineExists() || secondLineExists())){
 472  0
                                         layout.addStyleName("ks-form-module-double-line-margin");
 473  
                                 }
 474  
                                 else{
 475  0
                                         layout.addStyleName("ks-form-module-triple-line-margin");
 476  
                                 }
 477  
 
 478  0
                                 break;
 479  
                         case DOUBLE:
 480  0
                                 if((firstLineExists() || secondLineExists())){
 481  0
                                         layout.addStyleName("ks-form-module-single-line-margin");
 482  
                                 }
 483  
                                 else{
 484  0
                                         layout.addStyleName("ks-form-module-double-line-margin");
 485  
                                 }
 486  0
                                 break;
 487  
                         case SINGLE:
 488  0
                                 layout.addStyleName("ks-form-module-single-line-margin");
 489  
                                 break;
 490  
                 }
 491  
 
 492  0
         }
 493  
 
 494  
         private boolean firstLineExists(){
 495  0
                 boolean exists = false;
 496  0
                 if((fieldName != null && !fieldName.equals("")) || required.isVisible() || help.isVisible()){
 497  0
                         exists = true;
 498  
                 }
 499  0
                 return exists;
 500  
         }
 501  
 
 502  
         private boolean secondLineExists(){
 503  0
                 boolean exists = false;
 504  0
                 if(instructions.isVisible()){
 505  0
                         exists = true;
 506  
                 }
 507  0
                 return exists;
 508  
         }
 509  
 
 510  
         /**
 511  
          * Hides the label of this field visually, but screen readers can still read it for accessibility
 512  
          */
 513  
         public void hideLabel() {
 514  0
                 layout.removeStyleName("ks-form-module-double-line-margin");
 515  0
                 layout.removeStyleName("ks-form-module-triple-line-margin");
 516  0
                 layout.addStyleName("ks-form-module-single-line-margin");
 517  0
                 fieldTitle.setStyleName("accessibility-hidden");
 518  0
                 instructions.setVisible(false);
 519  0
                 labelShown = false;
 520  0
         }
 521  
         
 522  
         public boolean isLabelShown(){
 523  0
                 return labelShown;
 524  
         }
 525  
 }