View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.uif.widget;
17  
18  import java.text.MessageFormat;
19  
20  import org.apache.commons.lang.StringUtils;
21  import org.kuali.rice.core.api.CoreApiServiceLocator;
22  import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
23  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
24  import org.kuali.rice.krad.datadictionary.HelpDefinition;
25  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
26  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
27  import org.kuali.rice.krad.uif.CssConstants;
28  import org.kuali.rice.krad.uif.UifConstants;
29  import org.kuali.rice.krad.uif.element.Action;
30  import org.kuali.rice.krad.uif.field.InputField;
31  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
32  import org.kuali.rice.krad.uif.util.ComponentFactory;
33  import org.kuali.rice.krad.uif.util.LifecycleElement;
34  
35  /**
36   * Widget that renders help on a component
37   *
38   * <p>
39   * If help URL is specified then display help icon and/or if help summary is specified then display help tooltip.
40   * </p>
41   *
42   * @author Kuali Rice Team (rice.collab@kuali.org)
43   */
44  @BeanTag(name = "help", parent = "Uif-Help")
45  public class Help extends WidgetBase {
46  	private static final long serialVersionUID = -1514436681476297241L;
47  
48      private Action helpAction;
49      private HelpDefinition helpDefinition;
50      private String externalHelpUrl;
51  
52      private String tooltipHelpContent;
53  
54      /**
55       * The following initialization is performed:
56       *
57       * <ul>
58       * <li>If help action not initialized and external help is configured, get the default
59       * help action component</li>
60       * </ul>
61       *
62       * {@inheritDoc}
63       */
64      @Override
65      public void performInitialization(Object model) {
66          super.performInitialization(model);
67  
68          if (helpAction == null) {
69              // TODO: check for expressions on helpDefinition?
70              if ((StringUtils.isNotBlank(externalHelpUrl) || (getPropertyExpression("externalHelpUrl") != null))
71                      || ((helpDefinition != null) && StringUtils.isNotBlank(helpDefinition.getParameterName()))
72                      && StringUtils.isNotBlank(helpDefinition.getParameterDetailType())) {
73                  helpAction = ComponentFactory.getHelpAction();
74                  helpAction.addDataAttribute(UifConstants.DataAttributes.ROLE, "help");
75              }
76          }
77          else{
78              helpAction.addDataAttribute(UifConstants.DataAttributes.ROLE, "help");
79          }
80      }
81  
82      /**
83       * Finalize the help widget for usage
84       *
85       * <p>
86       * In addition to the standard finalization the following tasks are performed:
87       * <li>Build the external help Url</li>
88       * <li>Set the javascript action which opens the external help in window</li>
89       * <li>Set render to false if help not configured</li>
90       * </p>
91       *
92       * {@inheritDoc}
93       */
94      @Override
95      public void performFinalize(Object model, LifecycleElement parent) {
96          super.performFinalize(model, parent);
97  
98          buildExternalHelp(parent);
99          buildTooltipHelp(parent);
100 
101         // if help is not configured don't render the component
102         if (StringUtils.isBlank(this.externalHelpUrl) && StringUtils.isBlank(this.tooltipHelpContent)) {
103             setRender(false);
104         }
105 
106         // Change to icon only look and feel if not associated with an input
107         if (parent != null && !(parent instanceof InputField) && helpAction != null) {
108             helpAction.getLibraryCssClasses().remove(CssConstants.Classes.BTN);
109             helpAction.getLibraryCssClasses().remove(CssConstants.Classes.BTN_DEFAULT);
110             helpAction.getLibraryCssClasses().add(CssConstants.Classes.ICON_ONLY_BUTTON);
111         }
112     }
113 
114     /**
115      * Build the external help
116      *
117      * <p>
118      * When the externalHelpUrl is blank and the helpDefinition is specified then the external help URL is
119      * looked up via the helpDefinition from the system parameters.  The namespace in the helpDefinition
120      * does not need to be specified and will default to the namespace of the view.
121      * </p>
122      *
123      * <p>
124      * Set the javascript action to open the external help in a window.
125      * </p>
126      *
127      * <p>
128      * Set the html title attribute of the help icon.
129      * </p>
130      *
131      * @param parent used to get the help title text used in the html title attribute of the help icon
132      */
133     protected void buildExternalHelp(LifecycleElement parent) {
134         if (StringUtils.isBlank(externalHelpUrl) && (helpDefinition != null)) {
135             if (StringUtils.isBlank(helpDefinition.getParameterNamespace())) {
136                 helpDefinition.setParameterNamespace(ViewLifecycle.getView().getNamespaceCode());
137             }
138 
139             String parameterNamespace = helpDefinition.getParameterNamespace();
140             String parameterDetailType = helpDefinition.getParameterDetailType();
141             String parameterName = helpDefinition.getParameterName();
142 
143             if (StringUtils.isNotBlank(parameterNamespace)
144                     && StringUtils.isNotBlank(parameterDetailType)
145                     && StringUtils.isNotBlank(parameterName)) {
146                 externalHelpUrl = getParameterService().getParameterValueAsFilteredString(
147                         parameterNamespace, parameterDetailType, parameterName);
148             }
149         }
150 
151         if (StringUtils.isNotBlank(externalHelpUrl)) {
152             // set the javascript action for the external help
153             getHelpAction().setActionScript("openHelpWindow('" + externalHelpUrl + "')");
154 
155             // set the alt and title attribute of the image
156             String helpTitle;
157 
158             // make sure that we are the component's native help and not a misconfigured standalone help bean.
159             if ((parent instanceof Helpable) && (((Helpable) parent).getHelp() == this)) {
160                 helpTitle = MessageFormat.format(
161                         CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
162                                 "help.icon.title.tag.with.field.label"), ((Helpable) parent).getHelpTitle());
163             } else {
164                 helpTitle = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
165                         "help.icon.title.tag");
166             }
167 
168             getHelpAction().setTitle(helpTitle);
169         }
170     }
171 
172     /**
173      * Build the tooltip help
174      *
175      * <p>
176      * The help tooltip is set on the component.  To use the help tooltip bean definition, the help's tooltip is used
177      * as and intermediary for setting up the tooltip widget and then copied to the component.
178      * </p>
179      *
180      * @param parent used for checking misconfigurations
181      */
182     protected void buildTooltipHelp(LifecycleElement parent) {
183         if (StringUtils.isNotBlank(tooltipHelpContent) && this.isRender()) {
184             // make sure that we are the component's native help and not a misconfigured standalone help bean.
185             if (this.getToolTip() != null && (parent instanceof Helpable) 
186                     && (((Helpable) parent).getHelp() == this)) {
187                 this.getToolTip().setTooltipContent(tooltipHelpContent);
188                 ((Helpable) parent).setTooltipOfComponent(this.getToolTip());
189             }
190         }
191     }
192 
193     /**
194      * HelpActionField is used for rendering external help
195      *
196      * @return Action for external help
197      */
198     @BeanTagAttribute
199     public Action getHelpAction() {
200         return helpAction;
201     }
202 
203     /**
204      * Setter for helpAction
205      *
206      * @param helpAction
207      */
208     public void setHelpAction(Action helpAction) {
209         this.helpAction = helpAction;
210     }
211 
212     /**
213      * The help definition is used as the key to retrieve the external help Url from the parameter table of
214      * the database
215      *
216      * @return HelpDefinition
217      */
218     @BeanTagAttribute(type= BeanTagAttribute.AttributeType.DIRECTORBYTYPE)
219     public HelpDefinition getHelpDefinition() {
220         return helpDefinition;
221     }
222 
223     /**
224      * Setter for the help definition of the database.
225      *
226      * @param helpDefinition
227      */
228     public void setHelpDefinition(HelpDefinition helpDefinition) {
229         this.helpDefinition = helpDefinition;
230     }
231 
232     /**
233      * The external help Url
234      *
235      * <p>
236      * This should contain a valid URL.  When specified this URL takes precedence over the external help URL from
237      * the system parameters.
238      * </p>
239      *
240      * @return Url of the external help
241      */
242     @BeanTagAttribute
243     public String getExternalHelpUrl() {
244         return this.externalHelpUrl;
245     }
246 
247     /**
248      * Setter for externalHelpUrl
249      *
250      * @param externalHelpUrl
251      */
252     public void setExternalHelpUrl(String externalHelpUrl) {
253         this.externalHelpUrl = externalHelpUrl;
254     }
255 
256     /**
257      * TooltipHelpContent
258      *
259      * @return TooltipHelpContent
260      */
261     @BeanTagAttribute
262     public String getTooltipHelpContent() {
263         return this.tooltipHelpContent;
264     }
265 
266     /**
267      * Setter for tooltipHelpContent
268      *
269      * @param tooltipHelpContent
270      */
271     public void setTooltipHelpContent(String tooltipHelpContent) {
272         this.tooltipHelpContent = tooltipHelpContent;
273     }
274 
275     /**
276      * Retrieve the parameter service
277      *
278      * @return ParameterService
279      */
280     protected ParameterService getParameterService() {
281         return CoreFrameworkServiceLocator.getParameterService();
282     }
283 }