001/** 002 * Copyright 2005-2018 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 */ 016package org.kuali.rice.krad.uif.element; 017 018import java.util.List; 019 020import org.apache.commons.lang.StringUtils; 021import org.kuali.rice.krad.datadictionary.parse.BeanTag; 022import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute; 023import org.kuali.rice.krad.datadictionary.validator.ValidationTrace; 024import org.kuali.rice.krad.datadictionary.validator.Validator; 025import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 026import org.kuali.rice.krad.uif.UifConstants; 027import org.kuali.rice.krad.uif.component.Component; 028import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleRestriction; 029import org.kuali.rice.krad.uif.util.ComponentFactory; 030import org.kuali.rice.krad.uif.util.LifecycleElement; 031import org.kuali.rice.krad.util.KRADConstants; 032 033/** 034 * Content element that renders a label 035 * 036 * <p> 037 * Contains options for adding a colon to the label along with a required message 038 * </p> 039 * 040 * @author Kuali Rice Team (rice.collab@kuali.org) 041 */ 042@BeanTag(name = "label", parent = "Uif-Label") 043public class Label extends ContentElementBase { 044 private static final long serialVersionUID = -6491546893195180114L; 045 046 private String labelText; 047 private String labelForComponentId; 048 049 private boolean renderColon; 050 051 private String requiredIndicator; 052 private boolean renderRequiredIndicator; 053 054 private Message richLabelMessage; 055 private List<Component> inlineComponents; 056 057 public Label() { 058 renderColon = true; 059 } 060 061 /** 062 * Sets up rich message content for the label, if any exists 063 * 064 * {@inheritDoc} 065 */ 066 @Override 067 public void performApplyModel(Object model, LifecycleElement parent) { 068 super.performApplyModel(model, parent); 069 070 if (richLabelMessage == null && labelText != null && 071 labelText.contains(KRADConstants.MessageParsing.LEFT_TOKEN) && 072 labelText.contains(KRADConstants.MessageParsing.RIGHT_TOKEN)) { 073 Message message = ComponentFactory.getMessage(); 074 message.setMessageText(labelText); 075 message.setInlineComponents(inlineComponents); 076 message.setRenderWrapperTag(false); 077 078 this.setRichLabelMessage(message); 079 } 080 081 } 082 083 /** 084 * The following finalization is performed: 085 * 086 * <ul> 087 * <li>If label text is blank, set render to false for field</li> 088 * <li>Set the requiredIndicator</li> 089 * <li>Set the label text on the label field from the field's label property</li> 090 * <li>Set the render property on the label's required message field if this field is marked as required</li> 091 * <li>If the label is hidden then add CSS class to render off screen for accessibility</li> 092 * </ul> 093 * 094 * {@inheritDoc} 095 */ 096 @Override 097 public void performFinalize(Object model, LifecycleElement parent) { 098 super.performFinalize(model, parent); 099 100 if (StringUtils.isBlank(getLabelText())) { 101 setRender(false); 102 } 103 104 String defaultRequiredIndicator = (String) KRADServiceLocatorWeb.getDataDictionaryService().getDictionaryBean( 105 UifConstants.REQUIRED_INDICATOR_ID); 106 107 if (requiredIndicator != null && !requiredIndicator.equals(defaultRequiredIndicator)) { 108 this.addDataAttribute(UifConstants.DataAttributes.REQ_INDICATOR, requiredIndicator); 109 } else if (requiredIndicator == null) { 110 requiredIndicator = defaultRequiredIndicator; 111 } 112 113 if ((getRequired() != null) && getRequired().booleanValue()) { 114 setRenderRequiredIndicator(true); 115 } 116 117 // if hidden then add CSS class to render label off screen for accessibility 118 if (this.isHidden()) { 119 this.addStyleClass("sr-only"); 120 } 121 } 122 123 /** 124 * Indicates the id for the component the label applies to 125 * <p> 126 * Used for setting the labelFor attribute of the corresponding HTML 127 * element. Note this gets set automatically by the framework during the 128 * initialize phase 129 * </p> 130 * 131 * @return component id 132 */ 133 @BeanTagAttribute 134 public String getLabelForComponentId() { 135 return this.labelForComponentId; 136 } 137 138 /** 139 * Setter for the component id the label applies to 140 * 141 * @param labelForComponentId 142 */ 143 public void setLabelForComponentId(String labelForComponentId) { 144 this.labelForComponentId = labelForComponentId; 145 } 146 147 /** 148 * Text that will display as the label 149 * 150 * @return label text 151 */ 152 @BeanTagAttribute 153 public String getLabelText() { 154 return this.labelText; 155 } 156 157 /** 158 * Setter for the label text 159 * 160 * @param labelText 161 */ 162 public void setLabelText(String labelText) { 163 this.labelText = labelText; 164 } 165 166 /** 167 * Indicates whether a colon should be rendered after the label text, 168 * generally used when the label appears to the left of the field's control 169 * or value 170 * 171 * @return true if a colon should be rendered, false if it should not be 172 */ 173 @BeanTagAttribute 174 public boolean isRenderColon() { 175 return this.renderColon; 176 } 177 178 /** 179 * Setter for the render colon indicator 180 * 181 * @param renderColon 182 */ 183 public void setRenderColon(boolean renderColon) { 184 this.renderColon = renderColon; 185 } 186 187 /** 188 * True if the indicator will be displayed when this label is first render, false otherwise. 189 * 190 * <p>This is set by the framework based on required constraint state, and generally should NOT 191 * be set in most cases.</p> 192 * 193 * @return true if rendering, false otherwise 194 */ 195 public boolean isRenderRequiredIndicator() { 196 return renderRequiredIndicator; 197 } 198 199 /** 200 * @see org.kuali.rice.krad.uif.element.Label#isRenderRequiredIndicator() 201 * 202 * @param renderRequiredIndicator 203 */ 204 public void setRenderRequiredIndicator(boolean renderRequiredIndicator) { 205 this.renderRequiredIndicator = renderRequiredIndicator; 206 } 207 208 /** 209 * String indicator that will be displayed as a required indicator 210 * 211 * <p> 212 * To indicate a field must have a value (required input) the required 213 * indicator can be set to display an indicator or text along with 214 * the label. 215 * </p> 216 * 217 * @return the required indicator String to display 218 */ 219 @BeanTagAttribute 220 public String getRequiredIndicator() { 221 return requiredIndicator; 222 } 223 224 /** 225 * @see org.kuali.rice.krad.uif.element.Label#getRequiredIndicator() 226 * 227 * @param requiredIndicator 228 */ 229 public void setRequiredIndicator(String requiredIndicator) { 230 this.requiredIndicator = requiredIndicator; 231 } 232 233 /** 234 * Gets the Message that represents the rich message content of the label if labelText is using rich message tags. 235 * <b>DO NOT set this 236 * property directly unless you need full control over the message structure.</b> 237 * 238 * @return rich message structure, null if no rich message structure 239 */ 240 @BeanTagAttribute 241 public Message getRichLabelMessage() { 242 return richLabelMessage; 243 } 244 245 /** 246 * Sets the Message that represents the rich message content of the label if it is using rich message tags. <b>DO 247 * NOT set this 248 * property directly unless you need full control over the message structure.</b> 249 * 250 * @param richLabelMessage 251 */ 252 public void setRichLabelMessage(Message richLabelMessage) { 253 this.richLabelMessage = richLabelMessage; 254 } 255 256 /** 257 * Gets the inlineComponents used by index in a Label that has rich message component index tags in its labelText 258 * 259 * @return the Label's inlineComponents 260 */ 261 @ViewLifecycleRestriction 262 @BeanTagAttribute 263 public List<Component> getInlineComponents() { 264 return inlineComponents; 265 } 266 267 /** 268 * Sets the inlineComponents used by index in a Label that has rich message component index tags in its labelText 269 * 270 * @param inlineComponents 271 */ 272 public void setInlineComponents(List<Component> inlineComponents) { 273 this.inlineComponents = inlineComponents; 274 } 275 276 /** 277 * {@inheritDoc} 278 */ 279 @Override 280 public void completeValidation(ValidationTrace tracer){ 281 tracer.addBean(this); 282 283 if(tracer.getValidationStage()== ValidationTrace.BUILD){ 284 // Checks that text is set if the component is rendered 285 if(isRender() && getLabelText()==null){ 286 if(!Validator.checkExpressions(this, "labelText")) { 287 String currentValues [] = {"render = "+isRender(),"labelText ="+getLabelText()}; 288 tracer.createError("LabelText should be set if render is true",currentValues); 289 } 290 } 291 } 292 293 super.completeValidation(tracer.getCopy()); 294 } 295}