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}