001/** 002 * Copyright 2005-2016 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.ArrayList; 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.ErrorReport; 024import org.kuali.rice.krad.datadictionary.validator.ValidationTrace; 025import org.kuali.rice.krad.datadictionary.validator.Validator; 026import org.kuali.rice.krad.messages.MessageService; 027import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 028import org.kuali.rice.krad.uif.UifConstants; 029import org.kuali.rice.krad.uif.util.ComponentFactory; 030import org.kuali.rice.krad.uif.util.LifecycleElement; 031import org.kuali.rice.krad.uif.widget.LightBox; 032 033/** 034 * Content element that renders a link 035 * 036 * @author Kuali Rice Team (rice.collab@kuali.org) 037 */ 038@BeanTag(name = "link", parent="Uif-Link") 039public class Link extends ContentElementBase { 040 private static final long serialVersionUID = 8989868231938336068L; 041 042 private String linkText; 043 private String target; 044 private String href; 045 046 private String iconClass; 047 private String linkIconPlacement; 048 049 private String linkDialogId; 050 private boolean openInDialog; 051 052 public Link() { 053 super(); 054 linkIconPlacement = UifConstants.Position.LEFT.name(); 055 linkDialogId = ""; 056 } 057 058 /** 059 * The following updates are done here: 060 * 061 * <ul> 062 * <li>Initialize the nested lightBox widget if open in lightbox is true</li> 063 * </ul> 064 * 065 * {@inheritDoc} 066 */ 067 @Override 068 public void performApplyModel(Object model, LifecycleElement parent) { 069 super.performApplyModel(model, parent); 070 } 071 072 /** 073 * Special handling for lightbox links to add and onclick data attribute to be handled by a global handler 074 */ 075 @Override 076 public void performFinalize(Object model, LifecycleElement parent) { 077 super.performFinalize(model, parent); 078 079 MessageService messageService = KRADServiceLocatorWeb.getMessageService(); 080 081 if (openInDialog){ 082 this.addDataAttribute(UifConstants.DataAttributes.ONCLICK, "e.preventDefault(); " 083 + "openLinkInDialog(jQuery(this), \"" 084 + linkDialogId + "\");"); 085 this.addDataAttribute(UifConstants.DataAttributes.ROLE, UifConstants.RoleTypes.ACTION); 086 } 087 088 // when icon only is set, add the icon class to the action 089 if (StringUtils.isNotBlank(iconClass) && (UifConstants.ICON_ONLY_PLACEMENT.equals(linkIconPlacement) 090 || StringUtils.isBlank(linkText))) { 091 getCssClasses().add(iconClass); 092 093 // force icon only placement 094 linkIconPlacement = UifConstants.ICON_ONLY_PLACEMENT; 095 } 096 097 if (target.equals(UifConstants.HtmlAttributeValues.TARGET_BLANK)) { 098 String title = this.getTitle(); 099 if (StringUtils.isNotBlank(title)) { 100 this.setTitle(title + " - " + messageService.getMessageText("accessibility.link.opensTab")); 101 } 102 else{ 103 this.setTitle(messageService.getMessageText("accessibility.link.opensTab")); 104 } 105 } 106 } 107 108 /** 109 * Returns the label of the link 110 * 111 * @return The link label 112 */ 113 @BeanTagAttribute 114 public String getLinkText() { 115 return linkText; 116 } 117 118 /** 119 * Setter for the link label 120 * 121 * @param linkText 122 */ 123 public void setLinkText(String linkText) { 124 this.linkText = linkText; 125 } 126 127 /** 128 * Returns the target that will be used to specify where to open the href 129 * 130 * @return The target 131 */ 132 @BeanTagAttribute 133 public String getTarget() { 134 return target; 135 } 136 137 /** 138 * Setter for the link target 139 * 140 * @param target 141 */ 142 public void setTarget(String target) { 143 this.target = target; 144 } 145 146 /** 147 * Returns the href text 148 * 149 * @return The href text 150 */ 151 @BeanTagAttribute 152 public String getHref() { 153 return href; 154 } 155 156 /** 157 * Setter for the hrefText 158 * 159 * @param href 160 */ 161 public void setHref(String href) { 162 this.href = href; 163 } 164 165 /** 166 * The id of the DialogGroup to use when the openInDialog property is true. 167 * 168 * <p>The DialogGroup should only contain an iframe for its items. When not set, a default dialog 169 * will be used.</p> 170 * 171 * @return the id of the dialog to use for this link 172 */ 173 @BeanTagAttribute 174 public String getLinkDialogId() { 175 return linkDialogId; 176 } 177 178 /** 179 * @see org.kuali.rice.krad.uif.element.Link#getLinkDialogId() 180 */ 181 public void setLinkDialogId(String linkDialogId) { 182 this.linkDialogId = linkDialogId; 183 } 184 185 /** 186 * Indicates whether the link URL should be opened in a dialog. 187 * 188 * <p> 189 * If set the target attribute is ignored and the URL is opened in a dialog instead. 190 * </p> 191 * 192 * @return true to open link in a dialog, false if not (follow standard target attribute) 193 */ 194 @BeanTagAttribute 195 public boolean isOpenInDialog() { 196 return openInDialog; 197 } 198 199 /** 200 * @see org.kuali.rice.krad.uif.element.Link#isOpenInDialog() 201 */ 202 public void setOpenInDialog(boolean openInDialog) { 203 this.openInDialog = openInDialog; 204 } 205 206 /** 207 * Icon Class for the link 208 * 209 * <p> 210 * Bootstrap Icon Class to be rendered on this Link 211 * </p> 212 * 213 * @return label for action 214 */ 215 @BeanTagAttribute 216 public String getIconClass() { 217 return iconClass; 218 } 219 220 /** 221 * Setter for the Icon Class 222 * 223 * @param iconClass 224 */ 225 public void setIconClass(String iconClass) { 226 this.iconClass = iconClass; 227 } 228 229 /** 230 * Set to LEFT, RIGHT to position image at that location within the button. When set to blank/null/ICON_ONLY, the icon 231 * itself will be the Action, if no value is set the default is ALWAYS LEFT, you must explicitly set 232 * blank/null/ICON_ONLY to use ONLY the image as the Action. 233 * 234 * @return Action Icon Placement 235 */ 236 @BeanTagAttribute 237 public String getLinkIconPlacement() { 238 return linkIconPlacement; 239 } 240 241 /** 242 * Setter for the Link Icon Placement 243 * 244 * @param linkIconPlacement 245 */ 246 public void setLinkIconPlacement(String linkIconPlacement) { 247 this.linkIconPlacement = linkIconPlacement; 248 } 249 250 /** 251 * {@inheritDoc} 252 */ 253 @Override 254 public void completeValidation(ValidationTrace tracer){ 255 ArrayList<ErrorReport> reports=new ArrayList<ErrorReport>(); 256 tracer.addBean(this); 257 258 if(tracer.getValidationStage()== ValidationTrace.BUILD){ 259 260 // Checks that href is set 261 if(getHref()==null){ 262 if(!Validator.checkExpressions(this, "href")){ 263 String currentValues [] = {"href ="+getHref()}; 264 tracer.createError("Href must be set",currentValues); 265 } 266 } 267 268 // Checks that the text is set 269 if(getLinkText()==null){ 270 if(!Validator.checkExpressions(this, "linkText")){ 271 String currentValues [] = {"linkText = "+getLinkText()}; 272 tracer.createError("LinkText must be set",currentValues); 273 } 274 } 275 276 } 277 278 super.completeValidation(tracer.getCopy()); 279 } 280}