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.element;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.exception.RiceRuntimeException;
20 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
21 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
22 import org.kuali.rice.krad.datadictionary.parse.BeanTags;
23 import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
24 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
25 import org.kuali.rice.krad.uif.UifConstants;
26 import org.kuali.rice.krad.uif.UifParameters;
27 import org.kuali.rice.krad.uif.UifPropertyPaths;
28 import org.kuali.rice.krad.uif.component.Component;
29 import org.kuali.rice.krad.uif.component.ComponentSecurity;
30 import org.kuali.rice.krad.uif.container.DialogGroup;
31 import org.kuali.rice.krad.uif.container.Group;
32 import org.kuali.rice.krad.uif.field.DataField;
33 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
34 import org.kuali.rice.krad.uif.util.ComponentFactory;
35 import org.kuali.rice.krad.uif.util.LifecycleElement;
36 import org.kuali.rice.krad.uif.util.ScriptUtils;
37 import org.kuali.rice.krad.uif.util.UrlInfo;
38 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
39 import org.kuali.rice.krad.uif.view.FormView;
40 import org.kuali.rice.krad.uif.view.View;
41 import org.kuali.rice.krad.util.KRADUtils;
42
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.List;
46 import java.util.Map;
47
48 /**
49 * Field that presents an action that can be taken on the UI such as submitting the form or invoking a script.
50 *
51 * @author Kuali Rice Team (rice.collab@kuali.org)
52 */
53 @BeanTags({@BeanTag(name = "action", parent = "Uif-Action"),
54 @BeanTag(name = "actionImage", parent = "Uif-ActionImage"),
55 @BeanTag(name = "button", parent = "Uif-PrimaryActionButton"),
56 @BeanTag(name = "secondaryButton", parent = "Uif-SecondaryActionButton"),
57 @BeanTag(name = "buttonLarge", parent = "Uif-PrimaryActionButton-Large"),
58 @BeanTag(name = "secondaryButtonLarge", parent = "Uif-SecondaryActionButton-Large"),
59 @BeanTag(name = "buttonSmall", parent = "Uif-PrimaryActionButton-Small"),
60 @BeanTag(name = "secondaryButtonSmall", parent = "Uif-SecondaryActionButton-Small"),
61 @BeanTag(name = "buttonMini", parent = "Uif-PrimaryActionButton-Mini"),
62 @BeanTag(name = "secondaryButtonMini", parent = "Uif-SecondaryActionButton-Mini"),
63 @BeanTag(name = "actionLink", parent = "Uif-ActionLink"),
64 @BeanTag(name = "navigationActionLink", parent = "Uif-NavigationActionLink"),
65 @BeanTag(name = "navigationButton", parent = "Uif-NavigationActionButton"),
66 @BeanTag(name = "secondaryNavigationActionButton", parent = "Uif-SecondaryNavigationActionButton")})
67 public class Action extends ContentElementBase {
68 private static final long serialVersionUID = 1025672792657238829L;
69
70 private String methodToCall;
71 private String actionEvent;
72 private String navigateToPageId;
73 private List<String> fieldsToSend;
74
75 private String actionScript;
76 private UrlInfo actionUrl;
77
78 private String actionLabel;
79 private boolean renderInnerTextSpan;
80
81 private Image actionImage;
82 private String actionImagePlacement;
83
84 private String iconClass;
85 private String actionIconPlacement;
86
87 private String jumpToIdAfterSubmit;
88 private String jumpToNameAfterSubmit;
89 private String focusOnIdAfterSubmit;
90
91 private boolean performClientSideValidation;
92 private boolean performDirtyValidation;
93 private boolean clearDirtyOnAction;
94 private boolean dirtyOnAction;
95
96 private String preSubmitCall;
97 private String confirmationPromptText;
98 private DialogGroup confirmationDialog;
99
100 private String dialogDismissOption;
101 private String dialogResponse;
102
103 private boolean ajaxSubmit;
104 private String ajaxReturnType;
105 private String refreshId;
106 private String refreshPropertyName;
107
108 private String successCallback;
109 private String errorCallback;
110
111 private String loadingMessageText;
112 private boolean disableBlocking;
113
114 private Map<String, String> additionalSubmitData;
115 private Map<String, String> actionParameters;
116
117 private boolean evaluateDisabledOnKeyUp;
118
119 private boolean defaultEnterKeyAction;
120
121 private boolean disabled;
122 private String disabledReason;
123 private String disabledExpression;
124 private String disabledConditionJs;
125 private List<String> disabledConditionControlNames;
126
127 private List<String> disabledWhenChangedPropertyNames;
128 private List<String> enabledWhenChangedPropertyNames;
129
130 /**
131 * Sets initial field values and initializes collections.
132 */
133 public Action() {
134 super();
135
136 actionImagePlacement = UifConstants.Position.LEFT.name();
137 actionIconPlacement = UifConstants.Position.LEFT.name();
138
139 ajaxSubmit = true;
140
141 successCallback = "";
142 errorCallback = "";
143 preSubmitCall = "";
144
145 additionalSubmitData = new HashMap<String, String>();
146 actionParameters = new HashMap<String, String>();
147
148 disabled = false;
149 disabledWhenChangedPropertyNames = new ArrayList<String>();
150 enabledWhenChangedPropertyNames = new ArrayList<String>();
151 }
152
153 /**
154 * Sets the disabledExpression, if any, evaluates it and sets the disabled property.
155 *
156 * @param model top level object containing the data (could be the form or a
157 * @param parent parent component
158 */
159 public void performApplyModel(Object model, LifecycleElement parent) {
160 super.performApplyModel(model, parent);
161
162 disabledExpression = this.getPropertyExpression("disabled");
163 if (disabledExpression != null) {
164 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
165
166 disabledExpression = expressionEvaluator.replaceBindingPrefixes(ViewLifecycle.getView(), this,
167 disabledExpression);
168 disabled = (Boolean) expressionEvaluator.evaluateExpression(this.getContext(), disabledExpression);
169 }
170
171 if (actionUrl != null) {
172 ViewLifecycle.getExpressionEvaluator().populatePropertyExpressionsFromGraph(actionUrl, false);
173 ViewLifecycle.getExpressionEvaluator().evaluateExpressionsOnConfigurable(ViewLifecycle.getView(),
174 actionUrl, this.getContext());
175 }
176
177 if (StringUtils.isNotBlank(confirmationPromptText) && (confirmationDialog != null) && StringUtils.isBlank(
178 confirmationDialog.getPromptText())) {
179 confirmationDialog.setPromptText(confirmationPromptText);
180 }
181
182 addConfirmDialogToView();
183 }
184
185 /**
186 * For confirm text without a dialog, add instance of yes no dialog to view so it is already available
187 * on the client for dynamic dialog creation.
188 */
189 protected void addConfirmDialogToView() {
190 if (StringUtils.isBlank(confirmationPromptText) || (confirmationDialog != null)) {
191 return;
192 }
193
194 boolean containsYesNoDialog = false;
195
196 List<Group> viewDialogs = ViewLifecycle.getView().getDialogs();
197 if (viewDialogs == null) {
198 viewDialogs = new ArrayList<Group>();
199 } else {
200 for (Group dialogGroup : viewDialogs) {
201 if (StringUtils.equals(ComponentFactory.YES_NO_DIALOG, dialogGroup.getId())) {
202 containsYesNoDialog = true;
203 }
204 }
205 }
206
207 if (!containsYesNoDialog) {
208 Group confirmDialog = ComponentFactory.getYesNoDialog();
209 confirmDialog.setId(ComponentFactory.YES_NO_DIALOG);
210
211 viewDialogs.add(confirmDialog);
212 }
213 }
214
215 /**
216 * The following finalization is performed:
217 *
218 * <ul>
219 * <li>Add methodToCall action parameter if set and setup event code for
220 * setting action parameters</li>
221 * <li>Invoke method to build the data attributes and submit data for the action</li>
222 * <li>Compose the final onclick script for the action</li>
223 * <li>Parses the disabled expressions, if any, to equivalent javascript and evaluates the disable/enable when
224 * changed property names</li>
225 * </ul>
226 *
227 * {@inheritDoc}
228 */
229 @Override
230 public void performFinalize(Object model, LifecycleElement parent) {
231 super.performFinalize(model, parent);
232
233 View view = ViewLifecycle.getView();
234 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
235
236 if (StringUtils.isNotEmpty(disabledExpression)
237 && !disabledExpression.equalsIgnoreCase("true")
238 && !disabledExpression.equalsIgnoreCase("false")) {
239 disabledConditionControlNames = new ArrayList<String>();
240 disabledConditionJs = ViewLifecycle.getExpressionEvaluator().parseExpression(disabledExpression,
241 disabledConditionControlNames, this.getContext());
242 }
243
244 List<String> adjustedDisablePropertyNames = new ArrayList<String>();
245 for (String propertyName : disabledWhenChangedPropertyNames) {
246 adjustedDisablePropertyNames.add(expressionEvaluator.replaceBindingPrefixes(view, this, propertyName));
247 }
248 disabledWhenChangedPropertyNames = adjustedDisablePropertyNames;
249
250 List<String> adjustedEnablePropertyNames = new ArrayList<String>();
251 for (String propertyName : enabledWhenChangedPropertyNames) {
252 adjustedEnablePropertyNames.add(expressionEvaluator.replaceBindingPrefixes(view, this, propertyName));
253 }
254 enabledWhenChangedPropertyNames = adjustedEnablePropertyNames;
255
256 // clear alt text to avoid screen reader confusion when using image in button with text
257 if (actionImage != null && StringUtils.isNotBlank(actionImagePlacement) && StringUtils.isNotBlank(actionLabel)) {
258 actionImage.setAltText("");
259 }
260
261 // when icon only is set, add the icon class to the action
262 if (StringUtils.isNotBlank(iconClass) && (UifConstants.ICON_ONLY_PLACEMENT.equals(actionIconPlacement)
263 || StringUtils.isBlank(actionLabel))) {
264 getCssClasses().add(iconClass);
265
266 // force icon only placement
267 actionIconPlacement = UifConstants.ICON_ONLY_PLACEMENT;
268 }
269
270 if (!actionParameters.containsKey(UifConstants.UrlParams.ACTION_EVENT) && StringUtils.isNotBlank(actionEvent)) {
271 actionParameters.put(UifConstants.UrlParams.ACTION_EVENT, actionEvent);
272 }
273
274 if (StringUtils.isNotBlank(navigateToPageId)) {
275 actionParameters.put(UifParameters.NAVIGATE_TO_PAGE_ID, navigateToPageId);
276 if (StringUtils.isBlank(methodToCall)) {
277 this.methodToCall = UifConstants.MethodToCallNames.NAVIGATE;
278 }
279 }
280
281 if (!actionParameters.containsKey(UifConstants.CONTROLLER_METHOD_DISPATCH_PARAMETER_NAME) && StringUtils
282 .isNotBlank(methodToCall)) {
283 actionParameters.put(UifConstants.CONTROLLER_METHOD_DISPATCH_PARAMETER_NAME, methodToCall);
284 }
285
286 setupRefreshAction(view);
287
288 // Apply dirty check if it is enabled for the view and the action requires it
289 if (view instanceof FormView) {
290 performDirtyValidation = performDirtyValidation && ((FormView) view).isApplyDirtyCheck();
291 }
292
293 if (StringUtils.isBlank(getActionScript()) && (actionUrl != null) && actionUrl.isFullyConfigured()) {
294 String actionScript = ScriptUtils.buildFunctionCall(UifConstants.JsFunctions.REDIRECT, actionUrl.getHref());
295 setActionScript(actionScript);
296 }
297
298 // add the method to call as an available method
299 if (StringUtils.isNotBlank(methodToCall)) {
300 ViewLifecycle.getViewPostMetadata().addAvailableMethodToCall(methodToCall);
301 }
302
303 // add additional submit data as accessible binding paths, and method to call as accessible method
304 if (isRender()) {
305 for (String additionalSubmitPath : additionalSubmitData.keySet()) {
306 ViewLifecycle.getViewPostMetadata().addAccessibleBindingPath(additionalSubmitPath);
307 }
308
309 if (StringUtils.isNotBlank(methodToCall)) {
310 ViewLifecycle.getViewPostMetadata().addAccessibleMethodToCall(methodToCall);
311 }
312 }
313
314 buildActionData(view, model, parent);
315 }
316
317 /**
318 * When the action is updating a component sets up the refresh script for the component (found by the
319 * given refresh id or refresh property name.
320 *
321 * @param view view instance the action belongs to
322 */
323 protected void setupRefreshAction(View view) {
324 // if refresh property or id is given, make return type update component
325 // TODO: what if the refresh id is the page id? we should set the return type as update page
326 if (StringUtils.isNotBlank(refreshPropertyName) || StringUtils.isNotBlank(refreshId)) {
327 ajaxReturnType = UifConstants.AjaxReturnTypes.UPDATECOMPONENT.getKey();
328 }
329
330 // if refresh property name is given, adjust the binding and then attempt to find the
331 // component in the view index
332 Component refreshComponent = null;
333 if (StringUtils.isNotBlank(refreshPropertyName)) {
334 // TODO: does this support all binding prefixes?
335 if (refreshPropertyName.startsWith(UifConstants.NO_BIND_ADJUST_PREFIX)) {
336 refreshPropertyName = StringUtils.removeStart(refreshPropertyName, UifConstants.NO_BIND_ADJUST_PREFIX);
337 } else if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
338 refreshPropertyName = view.getDefaultBindingObjectPath() + "." + refreshPropertyName;
339 }
340
341 DataField dataField = view.getViewIndex().getDataFieldByPath(refreshPropertyName);
342 if (dataField != null) {
343 refreshComponent = dataField;
344 refreshId = refreshComponent.getId();
345 }
346 } else if (StringUtils.isNotBlank(refreshId)) {
347 Component component = view.getViewIndex().getComponentById(refreshId);
348 if (component != null) {
349 refreshComponent = component;
350 }
351 }
352
353 if (refreshComponent != null) {
354 refreshComponent.setRefreshedByAction(true);
355 }
356 }
357
358 /**
359 * Builds the data attributes that will be read client side to determine how to
360 * handle the action and the additional data that should be submitted with the action
361 *
362 * <p>
363 * Note these data attributes will be exposed as a data map client side. The simple attributes (non object
364 * value) are also written out as attributes on the action element.
365 * </p>
366 *
367 * @param view view instance the action belongs to
368 * @param model model object containing the view data
369 * @param parent component the holds the action
370 */
371 protected void buildActionData(View view, Object model, LifecycleElement parent) {
372 HashMap<String, String> actionDataAttributes = new HashMap<String, String>();
373
374 Map<String, String> dataDefaults =
375 (Map<String, String>) (KRADServiceLocatorWeb.getDataDictionaryService().getDictionaryBean(
376 UifConstants.ACTION_DEFAULTS_MAP_ID));
377
378 // map properties to data attributes
379 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.ActionDataAttributes.AJAX_SUBMIT,
380 Boolean.toString(ajaxSubmit));
381 addActionDataSettingsValue(actionDataAttributes, dataDefaults,
382 UifConstants.ActionDataAttributes.SUCCESS_CALLBACK, this.successCallback);
383 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.ActionDataAttributes.ERROR_CALLBACK,
384 this.errorCallback);
385 addActionDataSettingsValue(actionDataAttributes, dataDefaults,
386 UifConstants.ActionDataAttributes.PRE_SUBMIT_CALL, this.preSubmitCall);
387 addActionDataSettingsValue(actionDataAttributes, dataDefaults,
388 UifConstants.ActionDataAttributes.LOADING_MESSAGE, this.loadingMessageText);
389 addActionDataSettingsValue(actionDataAttributes, dataDefaults,
390 UifConstants.ActionDataAttributes.DISABLE_BLOCKING, Boolean.toString(this.disableBlocking));
391 addActionDataSettingsValue(actionDataAttributes, dataDefaults,
392 UifConstants.ActionDataAttributes.AJAX_RETURN_TYPE, this.ajaxReturnType);
393 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.ActionDataAttributes.REFRESH_ID,
394 this.refreshId);
395 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.ActionDataAttributes.VALIDATE,
396 Boolean.toString(this.performClientSideValidation));
397 addActionDataSettingsValue(actionDataAttributes, dataDefaults,
398 UifConstants.ActionDataAttributes.DIRTY_ON_ACTION, Boolean.toString(this.dirtyOnAction));
399 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.ActionDataAttributes.CLEAR_DIRTY,
400 Boolean.toString(this.clearDirtyOnAction));
401 addActionDataSettingsValue(actionDataAttributes, dataDefaults,
402 UifConstants.ActionDataAttributes.PERFORM_DIRTY_VALIDATION, Boolean.toString(
403 this.performDirtyValidation));
404 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.ActionDataAttributes.FIELDS_TO_SEND,
405 ScriptUtils.translateValue(this.fieldsToSend));
406
407 if (confirmationDialog != null) {
408 addDataAttribute(UifConstants.ActionDataAttributes.CONFIRM_DIALOG_ID, confirmationDialog.getId());
409 } else if (StringUtils.isNotBlank(confirmationPromptText)) {
410 addDataAttribute(UifConstants.ActionDataAttributes.CONFIRM_PROMPT_TEXT, confirmationPromptText);
411 }
412
413 if (StringUtils.isNotBlank(dialogDismissOption)) {
414 addDataAttribute(UifConstants.DataAttributes.DISMISS_DIALOG_OPTION, dialogDismissOption);
415 }
416
417 if (StringUtils.isNotBlank(dialogResponse)) {
418 addDataAttribute(UifConstants.DataAttributes.DISMISS_RESPONSE, dialogResponse);
419 }
420
421 // all action parameters should be submitted with action
422 Map<String, String> submitData = new HashMap<String, String>();
423 for (String key : actionParameters.keySet()) {
424 String parameterPath = key;
425 if (!key.equals(UifConstants.CONTROLLER_METHOD_DISPATCH_PARAMETER_NAME)) {
426 parameterPath = UifPropertyPaths.ACTION_PARAMETERS + "[" + key + "]";
427 }
428 submitData.put(parameterPath, actionParameters.get(key));
429 }
430
431 for (String key : additionalSubmitData.keySet()) {
432 submitData.put(key, additionalSubmitData.get(key));
433 }
434
435 // if focus id not set default to focus on action
436 if (focusOnIdAfterSubmit.equalsIgnoreCase(UifConstants.Order.NEXT_INPUT.toString())) {
437 focusOnIdAfterSubmit = UifConstants.Order.NEXT_INPUT.toString() + ":" + this.getId();
438 }
439
440 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.ActionDataAttributes.FOCUS_ID,
441 focusOnIdAfterSubmit);
442
443 if (StringUtils.isNotBlank(jumpToIdAfterSubmit)) {
444 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.ActionDataAttributes.JUMP_TO_ID,
445 jumpToIdAfterSubmit);
446 } else if (StringUtils.isNotBlank(jumpToNameAfterSubmit)) {
447 addActionDataSettingsValue(actionDataAttributes, dataDefaults,
448 UifConstants.ActionDataAttributes.JUMP_TO_NAME, jumpToNameAfterSubmit);
449 }
450
451 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.DataAttributes.SUBMIT_DATA,
452 ScriptUtils.toJSON(submitData));
453
454 // build final onclick script
455 String onClickScript = this.getOnClickScript();
456 if (StringUtils.isNotBlank(actionScript)) {
457 onClickScript = ScriptUtils.appendScript(onClickScript, actionScript);
458 } else {
459 onClickScript = ScriptUtils.appendScript(onClickScript, "actionInvokeHandler(this);");
460 }
461
462 //stop action if the action is disabled
463 if (disabled) {
464 this.addStyleClass("disabled");
465 this.setSkipInTabOrder(true);
466 }
467
468 // on click script becomes a data attribute for use in a global handler on the client
469 addActionDataSettingsValue(actionDataAttributes, dataDefaults, UifConstants.DataAttributes.ONCLICK,
470 KRADUtils.convertToHTMLAttributeSafeString(onClickScript));
471
472 if (!actionDataAttributes.isEmpty()) {
473 this.getDataAttributes().putAll(actionDataAttributes);
474 }
475
476 this.addDataAttribute(UifConstants.DataAttributes.ROLE, UifConstants.RoleTypes.ACTION);
477
478 // add data attribute if this is the primary action
479 if (this.isDefaultEnterKeyAction()) {
480 this.addDataAttribute(UifConstants.DataAttributes.DEFAULT_ENTER_KEY_ACTION,
481 Boolean.toString(this.isDefaultEnterKeyAction()));
482 }
483 }
484
485 /**
486 * Adds the value passed to the valueMap with the key specified, if the value does not match the
487 * value which already exists in defaults (to avoid having to write out extra data that can later
488 * be derived from the defaults in the js client-side).
489 *
490 * @param valueMap the data map being constructed
491 * @param defaults defaults for validation messages
492 * @param key the variable name being added
493 * @param value the value set on this object as a String equivalent
494 */
495 protected void addActionDataSettingsValue(Map<String, String> valueMap, Map<String, String> defaults, String key,
496 String value) {
497 if (StringUtils.isBlank(value)) {
498 return;
499 }
500
501 String defaultValue = defaults.get(key);
502 if (defaultValue == null || !value.equals(defaultValue)) {
503 valueMap.put(key, value);
504 }
505 }
506
507 /**
508 * Name of the method that should be called when the action is selected
509 *
510 * <p>
511 * For a server side call (clientSideCall is false), gives the name of the
512 * method in the mapped controller that should be invoked when the action is
513 * selected. For client side calls gives the name of the script function
514 * that should be invoked when the action is selected
515 * </p>
516 *
517 * @return name of method to call
518 */
519 @BeanTagAttribute
520 public String getMethodToCall() {
521 return this.methodToCall;
522 }
523
524 /**
525 * Setter for the actions method to call.
526 *
527 * @param methodToCall method to call
528 */
529 public void setMethodToCall(String methodToCall) {
530 this.methodToCall = methodToCall;
531 }
532
533 /**
534 * Label text for the action
535 *
536 * <p>
537 * The label text is used by the template renderers to give a human readable
538 * label for the action. For buttons this generally is the button text,
539 * while for an action link it would be the links displayed text
540 * </p>
541 *
542 * @return label for action
543 */
544 @BeanTagAttribute
545 public String getActionLabel() {
546 return this.actionLabel;
547 }
548
549 /**
550 * Setter for the actions label.
551 *
552 * @param actionLabel action label
553 */
554 public void setActionLabel(String actionLabel) {
555 this.actionLabel = actionLabel;
556 }
557
558 /**
559 * When true, a span will be rendered around the actionLabel text.
560 *
561 * @return true if rendering a span around actionLabel, false otherwise
562 */
563 @BeanTagAttribute
564 public boolean isRenderInnerTextSpan() {
565 return renderInnerTextSpan;
566 }
567
568 /**
569 * Setter for {@link org.kuali.rice.krad.uif.element.Action#isRenderInnerTextSpan()}.
570 *
571 * @param renderInnerTextSpan property value
572 */
573 public void setRenderInnerTextSpan(boolean renderInnerTextSpan) {
574 this.renderInnerTextSpan = renderInnerTextSpan;
575 }
576
577 /**
578 * Image to use for the action
579 *
580 * <p>
581 * When the action image component is set (and render is true) the image will be
582 * used to present the action as opposed to the default (input submit). For
583 * action link templates the image is used for the link instead of the
584 * action link text
585 * </p>
586 *
587 * @return action image
588 */
589 @BeanTagAttribute
590 public Image getActionImage() {
591 return this.actionImage;
592 }
593
594 /**
595 * Setter for the action image field.
596 *
597 * @param actionImage action image
598 */
599 public void setActionImage(Image actionImage) {
600 this.actionImage = actionImage;
601 }
602
603 /**
604 * The css class (some which exist in bootstrap css) to use to render an icon for this action.
605 *
606 * @return the icon css class
607 */
608 @BeanTagAttribute
609 public String getIconClass() {
610 return iconClass;
611 }
612
613 /**
614 * Setter for {@link org.kuali.rice.krad.uif.element.Action#getIconClass()}.
615 *
616 * @param iconClass property value
617 */
618 public void setIconClass(String iconClass) {
619 this.iconClass = iconClass;
620 }
621
622 /**
623 * For an <code>Action</code> that is part of a
624 * <code>NavigationGroup</code>, the navigate to page id can be set to
625 * configure the page that should be navigated to when the action is
626 * selected.
627 *
628 * <p>
629 * Support exists in the <code>UifControllerBase</code> for handling
630 * navigation between pages.
631 * </p>
632 *
633 * @return id of page that should be rendered when the action item is
634 * selected
635 */
636 @BeanTagAttribute
637 public String getNavigateToPageId() {
638 return this.navigateToPageId;
639 }
640
641 /**
642 * Setter for {@link #getNavigateToPageId()}.
643 *
644 * @param navigateToPageId property value
645 */
646 public void setNavigateToPageId(String navigateToPageId) {
647 this.navigateToPageId = navigateToPageId;
648 }
649
650 /**
651 * Limits the field data to send on a refresh methodToCall server call to the names/group id/field id
652 * specified in this list.
653 *
654 * <p>The names in the list should be the propertyNames of the fields sent with this request. A wildcard("*")
655 * can be used at the END of a name to specify all fields with names that begin with the string
656 * before the wildcard. If the array contains 1 item with the keyword "NONE", then no form fields are sent.
657 * In addition, A group id or field id with the "#" id selector prefix can be used to send all inputs which
658 * are nested within them. Note that this only limits the fields which exist on the form and data required
659 * by the KRAD framework is still sent (eg, methodToCall, formKey, sessionId, etc.)</p>
660 *
661 * @return the only input fields to send by name with the action request
662 */
663 @BeanTagAttribute
664 public List<String> getFieldsToSend() {
665 return fieldsToSend;
666 }
667
668 /**
669 * @see Action#fieldsToSend
670 */
671 public void setFieldsToSend(List<String> fieldsToSend) {
672 this.fieldsToSend = fieldsToSend;
673 }
674
675 /**
676 * Name of the event that will be set when the action is invoked
677 *
678 * <p>
679 * Action events can be looked at by the view or components in order to render differently depending on
680 * the action requested.
681 * </p>
682 *
683 * @return action event name
684 * @see org.kuali.rice.krad.uif.UifConstants.ActionEvents
685 */
686 @BeanTagAttribute
687 public String getActionEvent() {
688 return actionEvent;
689 }
690
691 /**
692 * Setter for {@link #getActionEvent()}.
693 *
694 * @param actionEvent property value
695 */
696 public void setActionEvent(String actionEvent) {
697 this.actionEvent = actionEvent;
698 }
699
700 /**
701 * Map of additional data that will be posted when the action is invoked.
702 *
703 * <p>
704 * Each entry in this map will be sent as a request parameter when the action is chosen. Note this in
705 * addition to the form data that is sent. For example, suppose the model contained a property named
706 * number and a boolean named showActive, we can send values for this properties by adding the following
707 * entries to this map:
708 * {'number':'a13', 'showActive', 'true'}
709 * </p>
710 *
711 * <p>
712 * The additionalSubmitData map is different from the actionParameters map. All name/value pairs given as
713 * actionParameters populated the form map actionParameters. While name/value pair given in additionalSubmitData
714 * populate different form (model) properties.
715 * </p>
716 *
717 * @return additional key/value pairs to submit
718 */
719 @BeanTagAttribute
720 public Map<String, String> getAdditionalSubmitData() {
721 return additionalSubmitData;
722 }
723
724 /**
725 * Setter for map holding additional data to post.
726 *
727 * @param additionalSubmitData property value
728 */
729 public void setAdditionalSubmitData(Map<String, String> additionalSubmitData) {
730 this.additionalSubmitData = additionalSubmitData;
731 }
732
733 /**
734 * Parameters that should be sent when the action is invoked
735 *
736 * <p>
737 * Action renderer will decide how the parameters are sent for the action
738 * (via script generated hiddens, or script parameters, ...)
739 * </p>
740 *
741 * <p>
742 * Can be set by other components such as the <code>CollectionGroup</code>
743 * to provide the context the action is in (such as the collection name and
744 * line the action applies to)
745 * </p>
746 *
747 * @return action parameters
748 */
749 @BeanTagAttribute
750 public Map<String, String> getActionParameters() {
751 return this.actionParameters;
752 }
753
754 /**
755 * Setter for {@link #getActionParameters()}.
756 *
757 * @param actionParameters property value
758 */
759 public void setActionParameters(Map<String, String> actionParameters) {
760 this.actionParameters = actionParameters;
761 }
762
763 /**
764 * Convenience method to add a parameter to the action parameters Map.
765 *
766 * @param parameterName name of parameter to add
767 * @param parameterValue value of parameter to add
768 */
769 public void addActionParameter(String parameterName, String parameterValue) {
770 if (actionParameters == null) {
771 this.actionParameters = new HashMap<String, String>();
772 }
773
774 this.actionParameters.put(parameterName, parameterValue);
775 }
776
777 /**
778 * Gets an action parameter by name.
779 *
780 * @param parameterName parameter name
781 * @return action parameter
782 */
783 public String getActionParameter(String parameterName) {
784 return this.actionParameters.get(parameterName);
785 }
786
787 /**
788 * Action Security object that indicates what authorization (permissions) exist for the action.
789 *
790 * @return ActionSecurity instance
791 */
792 public ActionSecurity getActionSecurity() {
793 return (ActionSecurity) super.getComponentSecurity();
794 }
795
796 /**
797 * Override to assert a {@link ActionSecurity} instance is set.
798 *
799 * @param componentSecurity instance of ActionSecurity
800 */
801 @Override
802 public void setComponentSecurity(ComponentSecurity componentSecurity) {
803 if ((componentSecurity != null) && !(componentSecurity instanceof ActionSecurity)) {
804 throw new RiceRuntimeException("Component security for Action should be instance of ActionSecurity");
805 }
806
807 super.setComponentSecurity(componentSecurity);
808 }
809
810 /**
811 * {@inheritDoc}
812 */
813 @Override
814 protected void initializeComponentSecurity() {
815 if (getComponentSecurity() == null) {
816 setComponentSecurity(KRADUtils.createNewObjectFromClass(ActionSecurity.class));
817 }
818 }
819
820 /**
821 * Indicates whether or not to perform action auth.
822 *
823 * @return true to perform action auth
824 */
825 @BeanTagAttribute
826 public boolean isPerformActionAuthz() {
827 initializeComponentSecurity();
828
829 return getActionSecurity().isPerformActionAuthz();
830 }
831
832 /**
833 * Setter for {@link #isPerformActionAuthz()}.
834 *
835 * @param performActionAuthz property value
836 */
837 public void setPerformActionAuthz(boolean performActionAuthz) {
838 initializeComponentSecurity();
839
840 getActionSecurity().setPerformActionAuthz(performActionAuthz);
841 }
842
843 /**
844 * Indicates whether or not to perform line action auth.
845 *
846 * @return true to perform line action auth
847 */
848 @BeanTagAttribute
849 public boolean isPerformLineActionAuthz() {
850 initializeComponentSecurity();
851
852 return getActionSecurity().isPerformLineActionAuthz();
853 }
854
855 /**
856 * Setter for {@link #isPerformActionAuthz()}.
857 *
858 * @param performLineActionAuthz property value
859 */
860 public void setPerformLineActionAuthz(boolean performLineActionAuthz) {
861 initializeComponentSecurity();
862
863 getActionSecurity().setPerformLineActionAuthz(performLineActionAuthz);
864 }
865
866 /**
867 * Gets the id to jump to after submit.
868 *
869 * @return the jumpToIdAfterSubmit
870 */
871 @BeanTagAttribute
872 public String getJumpToIdAfterSubmit() {
873 return this.jumpToIdAfterSubmit;
874 }
875
876 /**
877 * The id to jump to in the next page, the element with this id will be
878 * jumped to automatically when the new page is retrieved after a submit.
879 * Using "TOP" or "BOTTOM" will jump to the top or the bottom of the
880 * resulting page. Passing in nothing for both jumpToIdAfterSubmit and
881 * jumpToNameAfterSubmit will result in this Action being jumped to by
882 * default if it is present on the new page. WARNING: jumpToIdAfterSubmit
883 * always takes precedence over jumpToNameAfterSubmit, if set.
884 *
885 * @param jumpToIdAfterSubmit the jumpToIdAfterSubmit to set
886 */
887 public void setJumpToIdAfterSubmit(String jumpToIdAfterSubmit) {
888 this.jumpToIdAfterSubmit = jumpToIdAfterSubmit;
889 }
890
891 /**
892 * The name to jump to in the next page, the element with this name will be
893 * jumped to automatically when the new page is retrieved after a submit.
894 * Passing in nothing for both jumpToIdAfterSubmit and jumpToNameAfterSubmit
895 * will result in this Action being jumped to by default if it is
896 * present on the new page. WARNING: jumpToIdAfterSubmit always takes
897 * precedence over jumpToNameAfterSubmit, if set.
898 *
899 * @return the jumpToNameAfterSubmit
900 */
901 @BeanTagAttribute
902 public String getJumpToNameAfterSubmit() {
903 return this.jumpToNameAfterSubmit;
904 }
905
906 /**
907 * Setter for {@link #getJumpToIdAfterSubmit()}.
908 *
909 * @param jumpToNameAfterSubmit the jumpToNameAfterSubmit to set
910 */
911 public void setJumpToNameAfterSubmit(String jumpToNameAfterSubmit) {
912 this.jumpToNameAfterSubmit = jumpToNameAfterSubmit;
913 }
914
915 /**
916 * The element to place focus on in the new page after the new page
917 * is retrieved.
918 *
919 * <p>The following are allowed:
920 * <ul>
921 * <li>A valid element id</li>
922 * <li>"FIRST" will focus on the first visible input element on the form</li>
923 * <li>"SELF" will result in this Action being focused (action bean defaults to "SELF")</li>
924 * <li>"LINE_FIRST" will result in the first input of the collection line to be focused (if available)</li>
925 * <li>"NEXT_INPUT" will result in the next available input that exists after this Action to be focused
926 * (only if this action still exists on the page)</li>
927 * </ul>
928 * </p>
929 *
930 * @return the focusOnAfterSubmit
931 */
932 @BeanTagAttribute
933 public String getFocusOnIdAfterSubmit() {
934 return this.focusOnIdAfterSubmit;
935 }
936
937 /**
938 * Setter for {@link #getFocusOnIdAfterSubmit()}.
939 *
940 * @param focusOnIdAfterSubmit the focusOnAfterSubmit to set
941 */
942 public void setFocusOnIdAfterSubmit(String focusOnIdAfterSubmit) {
943 this.focusOnIdAfterSubmit = focusOnIdAfterSubmit;
944 }
945
946 /**
947 * Indicates whether the form data should be validated on the client side.
948 *
949 * @return true if validation should occur, false otherwise
950 */
951 @BeanTagAttribute
952 public boolean isPerformClientSideValidation() {
953 return this.performClientSideValidation;
954 }
955
956 /**
957 * Setter for the client side validation flag.
958 *
959 * @param performClientSideValidation property value
960 */
961 public void setPerformClientSideValidation(boolean performClientSideValidation) {
962 this.performClientSideValidation = performClientSideValidation;
963 }
964
965 /**
966 * Client side javascript to be executed when this actionField is clicked.
967 *
968 * <p>
969 * This overrides the default action for this Action so the method
970 * called must explicitly submit, navigate, etc. through js, if necessary.
971 * In addition, this js occurs AFTER onClickScripts set on this field, it
972 * will be the last script executed by the click event. Sidenote: This js is
973 * always called after hidden actionParameters and methodToCall methods are
974 * written by the js to the html form.
975 * </p>
976 *
977 * @return the actionScript
978 */
979 @BeanTagAttribute
980 public String getActionScript() {
981 return this.actionScript;
982 }
983
984 /**
985 * Setter for {@link #getActionScript()}.
986 *
987 * @param actionScript the actionScript to set
988 */
989 public void setActionScript(String actionScript) {
990 if (StringUtils.isNotBlank(actionScript) && !StringUtils.endsWith(actionScript, ";")) {
991 actionScript = actionScript + ";";
992 }
993
994 this.actionScript = actionScript;
995 }
996
997 /**
998 * Url to open when the action item is selected
999 *
1000 * <p>
1001 * This makes the action behave like a standard link. Instead of posting the form, the configured URL will
1002 * simply be opened (using window.open). For using standard post actions these does not need to be configured.
1003 * </p>
1004 *
1005 * @return Url info instance for the configuration action link
1006 */
1007 @BeanTagAttribute
1008 public UrlInfo getActionUrl() {
1009 return actionUrl;
1010 }
1011
1012 /**
1013 * Setter for {@link #getActionUrl()}.
1014 *
1015 * @param actionUrl property value
1016 */
1017 public void setActionUrl(UrlInfo actionUrl) {
1018 this.actionUrl = actionUrl;
1019 }
1020
1021 /**
1022 * Setter for {@link #isPerformDirtyValidation()}.
1023 *
1024 * @param performDirtyValidation the blockValidateDirty to set
1025 */
1026 public void setPerformDirtyValidation(boolean performDirtyValidation) {
1027 this.performDirtyValidation = performDirtyValidation;
1028 }
1029
1030 /**
1031 * Indicates whether or not to perform dirty validation.
1032 *
1033 * @return true to perform dirty validation
1034 */
1035 @BeanTagAttribute
1036 public boolean isPerformDirtyValidation() {
1037 return performDirtyValidation;
1038 }
1039
1040 /**
1041 * True to make this action clear the dirty flag before submitting.
1042 *
1043 * <p>This will clear both the dirtyForm flag on the form and the count of fields considered dirty on the
1044 * client-side. This will only be performed if this action is a request based action.</p>
1045 *
1046 * @return true if the dirty
1047 */
1048 @BeanTagAttribute
1049 public boolean isClearDirtyOnAction() {
1050 return clearDirtyOnAction;
1051 }
1052
1053 /**
1054 * Setter for {@link #isClearDirtyOnAction()}.
1055 *
1056 * @param clearDirtyOnAction property value
1057 */
1058 public void setClearDirtyOnAction(boolean clearDirtyOnAction) {
1059 this.clearDirtyOnAction = clearDirtyOnAction;
1060 }
1061
1062 /**
1063 * When true, this action will mark the form dirty by incrementing the dirty field count, but if this action
1064 * refreshes the entire view this will be lost (most actions only refresh the page)
1065 *
1066 * <p>This will increase count of fields considered dirty on the
1067 * client-side by 1. This will only be performed if this action is a request based action.</p>
1068 *
1069 * @return true if this action is considered dirty, false otherwise
1070 */
1071 @BeanTagAttribute
1072 public boolean isDirtyOnAction() {
1073 return dirtyOnAction;
1074 }
1075
1076 /**
1077 * Set to true, if this action is considered one that changes the form's data (makes the form dirty).
1078 *
1079 * @param dirtyOnAction property value
1080 */
1081 public void setDirtyOnAction(boolean dirtyOnAction) {
1082 this.dirtyOnAction = dirtyOnAction;
1083 }
1084
1085 /**
1086 * Indicates whether the action (input or button) is disabled (doesn't allow interaction).
1087 *
1088 * @return true if the action field is disabled, false if not
1089 */
1090 @BeanTagAttribute
1091 public boolean isDisabled() {
1092 return disabled;
1093 }
1094
1095 /**
1096 * Setter for the disabled indicator.
1097 *
1098 * @param disabled property value
1099 */
1100 public void setDisabled(boolean disabled) {
1101 this.disabled = disabled;
1102 }
1103
1104 /**
1105 * If the action field is disabled, gives a reason for why which will be displayed as a tooltip
1106 * on the action field (button).
1107 *
1108 * @return disabled reason text
1109 * @see #isDisabled()
1110 */
1111 @BeanTagAttribute
1112 public String getDisabledReason() {
1113 return disabledReason;
1114 }
1115
1116 /**
1117 * Setter for the disabled reason text.
1118 *
1119 * @param disabledReason property value
1120 */
1121 public void setDisabledReason(String disabledReason) {
1122 this.disabledReason = disabledReason;
1123 }
1124
1125 /**
1126 * Gets the action image placement.
1127 *
1128 * @return action image placement
1129 */
1130 @BeanTagAttribute
1131 public String getActionImagePlacement() {
1132 return actionImagePlacement;
1133 }
1134
1135 /**
1136 * Set to TOP, BOTTOM, LEFT, RIGHT to position image at that location within the button.
1137 * For the subclass ActionLinkField only LEFT and RIGHT are allowed. When set to blank/null/IMAGE_ONLY, the image
1138 * itself will be the Action, if no value is set the default is ALWAYS LEFT, you must explicitly set
1139 * blank/null/IMAGE_ONLY to use ONLY the image as the Action.
1140 *
1141 * @param actionImagePlacement action image placement indicator
1142 */
1143 public void setActionImagePlacement(String actionImagePlacement) {
1144 this.actionImagePlacement = actionImagePlacement;
1145 }
1146
1147 /**
1148 * Gets the action icon placement.
1149 *
1150 * @return action icon placement
1151 */
1152 @BeanTagAttribute
1153 public String getActionIconPlacement() {
1154 return actionIconPlacement;
1155 }
1156
1157 /**
1158 * Setter for {@link #getActionIconPlacement()}.
1159 *
1160 * @param actionIconPlacement property value
1161 */
1162 public void setActionIconPlacement(String actionIconPlacement) {
1163 this.actionIconPlacement = actionIconPlacement;
1164 }
1165
1166 /**
1167 * Gets the script which needs to be invoked before the form is submitted
1168 *
1169 * <p>
1170 * The preSubmitCall can carry out custom logic for the action before the submit occurs. The value should
1171 * be given as one or more lines of script and should return a boolean. If false is returned from the call,
1172 * the submit is not carried out. Furthermore, the preSubmitCall can refer to the request object through the
1173 * variable 'kradRequest' or 'this'. This gives full access over the request for doing such things as
1174 * adding additional data
1175 * </p>
1176 *
1177 * <p>
1178 * Examples 'return doFunction(kradRequest);', 'var valid=true;return valid;'
1179 * </p>
1180 *
1181 * <p>
1182 * The preSubmit call will be invoked both for ajax and non-ajax submits
1183 * </p>
1184 *
1185 * @return script text that will be invoked before form submission
1186 */
1187 @BeanTagAttribute
1188 public String getPreSubmitCall() {
1189 return preSubmitCall;
1190 }
1191
1192 /**
1193 * Setter for {@link #getPreSubmitCall()}.
1194 *
1195 * @param preSubmitCall property value
1196 */
1197 public void setPreSubmitCall(String preSubmitCall) {
1198 this.preSubmitCall = preSubmitCall;
1199 }
1200
1201 /**
1202 * Text to display as a confirmation of the action.
1203 *
1204 * <p>When this text is displayed the user will receive a confirmation when the action is taken. The user
1205 * can then cancel the action, or continue. If set, {@link Action#getConfirmationDialog()} will be used
1206 * to build the dialog. Otherwise, the dialog is created dynamically on the client.</p>
1207 *
1208 * @return text to display in a confirmation for the action
1209 */
1210 public String getConfirmationPromptText() {
1211 return confirmationPromptText;
1212 }
1213
1214 /**
1215 * @see Action#getConfirmationPromptText()
1216 */
1217 public void setConfirmationPromptText(String confirmationPromptText) {
1218 this.confirmationPromptText = confirmationPromptText;
1219 }
1220
1221 /**
1222 * Dialog to use an a confirmation for the action.
1223 *
1224 * <p>For custom confirmation dialogs this can be set to any valid dialog group. It is expected that the
1225 * dialog have at least one action with the dialog response of 'true' to continue the action.</p>
1226 *
1227 * @return dialog group instance to use an a confirmation
1228 */
1229 public DialogGroup getConfirmationDialog() {
1230 return confirmationDialog;
1231 }
1232
1233 /**
1234 * @see Action#getConfirmationDialog()
1235 */
1236 public void setConfirmationDialog(DialogGroup confirmationDialog) {
1237 this.confirmationDialog = confirmationDialog;
1238 }
1239
1240 /**
1241 * If the action is within a {@link org.kuali.rice.krad.uif.container.DialogGroup} it can be configured to
1242 * dismiss the dialog using this property.
1243 *
1244 * <p>A dialog can be dismissed at various points of the action using the values:
1245 * IMMEDIATE - dismiss dialog right away (and do nothig further)
1246 * PRESUBMIT - run the action presubmit (which can include validation), if successful close the dialog and
1247 * do nothing further
1248 * REQUEST - carry out the action request as usual and dismiss the dialog when the server request is made
1249 * </p>
1250 *
1251 * <p>Note the id for the dialog that will be dismissed is automatically associated with the action when
1252 * the dialog is shown.</p>
1253 *
1254 * @return String option for dismissing a dialog
1255 */
1256 public String getDialogDismissOption() {
1257 return dialogDismissOption;
1258 }
1259
1260 /**
1261 * @see Action#getDialogDismissOption()
1262 */
1263 public void setDialogDismissOption(String dialogDismissOption) {
1264 this.dialogDismissOption = dialogDismissOption;
1265 }
1266
1267 /**
1268 * If the action is within a {@link org.kuali.rice.krad.uif.container.DialogGroup} it can be configured to
1269 * return a response using this property.
1270 *
1271 * <p>Dialogs can be used to get a response from a user, either a simple confirmation (true or false), or to
1272 * choice from a list of options. The responses for the dialog are created with action components. The property
1273 * specifies the action value that should be returned (when chosen) to the dialog response handlers. For example,
1274 * in a simple confirmation one action will have a dialog response 'false', and the other will have a dialog
1275 * response 'true'.</p>
1276 *
1277 * @return String dialog response value
1278 */
1279 public String getDialogResponse() {
1280 return dialogResponse;
1281 }
1282
1283 /**
1284 * @see Action#getDialogResponse()
1285 */
1286 public void setDialogResponse(String dialogResponse) {
1287 this.dialogResponse = dialogResponse;
1288 }
1289
1290 /**
1291 * When this property is set to true it will submit the form using Ajax instead of the browser submit. Will default
1292 * to updating the page contents
1293 *
1294 * @return boolean
1295 */
1296 @BeanTagAttribute
1297 public boolean isAjaxSubmit() {
1298 return ajaxSubmit;
1299 }
1300
1301 /**
1302 * Setter for {@link #isAjaxSubmit()}.
1303 *
1304 * @param ajaxSubmit property value
1305 */
1306 public void setAjaxSubmit(boolean ajaxSubmit) {
1307 this.ajaxSubmit = ajaxSubmit;
1308 }
1309
1310 /**
1311 * Gets the return type for the ajax call
1312 *
1313 * <p>
1314 * The ajax return type indicates how the response content will be handled in the client. Typical
1315 * examples include updating a component, the page, or doing a redirect.
1316 * </p>
1317 *
1318 * @return return type
1319 * @see org.kuali.rice.krad.uif.UifConstants.AjaxReturnTypes
1320 */
1321 @BeanTagAttribute
1322 public String getAjaxReturnType() {
1323 return this.ajaxReturnType;
1324 }
1325
1326 /**
1327 * Setter for the type of ajax return.
1328 *
1329 * @param ajaxReturnType property value
1330 */
1331 public void setAjaxReturnType(String ajaxReturnType) {
1332 this.ajaxReturnType = ajaxReturnType;
1333 }
1334
1335 /**
1336 * Indicates if the action response should be displayed in a lightbox.
1337 *
1338 * @return true if response should be rendered in a lightbox, false if not
1339 */
1340 @BeanTagAttribute
1341 public boolean isDisplayResponseInLightBox() {
1342 return StringUtils.equals(this.ajaxReturnType, UifConstants.AjaxReturnTypes.DISPLAYLIGHTBOX.getKey());
1343 }
1344
1345 /**
1346 * Setter for indicating the response should be rendered in a lightbox.
1347 *
1348 * @param displayResponseInLightBox property value
1349 */
1350 public void setDisplayResponseInLightBox(boolean displayResponseInLightBox) {
1351 if (displayResponseInLightBox) {
1352 this.ajaxReturnType = UifConstants.AjaxReturnTypes.DISPLAYLIGHTBOX.getKey();
1353 }
1354 // if display lightbox is false and it was previously true, set to default of update page
1355 else if (StringUtils.equals(this.ajaxReturnType, UifConstants.AjaxReturnTypes.DISPLAYLIGHTBOX.getKey())) {
1356 this.ajaxReturnType = UifConstants.AjaxReturnTypes.UPDATEPAGE.getKey();
1357 }
1358 }
1359
1360 /**
1361 * Gets the script which will be invoked on a successful ajax call
1362 *
1363 * <p>
1364 * The successCallback can carry out custom logic after a successful ajax submission has been made. The
1365 * value can contain one or more script statements. In addition, the response contents can be accessed
1366 * through the variable 'responseContents'
1367 * </p>
1368 *
1369 * <p>
1370 * Examples 'handleSuccessfulUpdate(responseContents);'
1371 * </p>
1372 *
1373 * <p>
1374 * The successCallback may only be specified when {@link #isAjaxSubmit()} is true
1375 * </p>
1376 *
1377 * @return script to be executed when the action is successful
1378 */
1379 @BeanTagAttribute
1380 public String getSuccessCallback() {
1381 return successCallback;
1382 }
1383
1384 /**
1385 * Setter for successCallback.
1386 *
1387 * @param successCallback property value
1388 */
1389 public void setSuccessCallback(String successCallback) {
1390 this.successCallback = successCallback;
1391 }
1392
1393 /**
1394 * Gets the script which will be invoked when the action fails due to problems in the ajax call or
1395 * the return of an incident report
1396 *
1397 * <p>
1398 * The errorCallback can carry out custom logic after a failed ajax submission. The
1399 * value can contain one or more script statements. In addition, the response contents can be accessed
1400 * through the variable 'responseContents'
1401 * </p>
1402 *
1403 * <p>
1404 * Examples 'handleFailedUpdate(responseContents);'
1405 * </p>
1406 *
1407 * <p>
1408 * The errorCallback may only be specified when {@link #isAjaxSubmit()} is true
1409 * </p>
1410 *
1411 * @return script to be executed when the action is successful
1412 */
1413 @BeanTagAttribute
1414 public String getErrorCallback() {
1415 return errorCallback;
1416 }
1417
1418 /**
1419 * Setter for {@link #getErrorCallback()}.
1420 *
1421 * @param errorCallback property value
1422 */
1423 public void setErrorCallback(String errorCallback) {
1424 this.errorCallback = errorCallback;
1425 }
1426
1427 /**
1428 * Id for the component that should be refreshed after the action completes
1429 *
1430 * <p>
1431 * Either refresh id or refresh property name can be set to configure the component that should
1432 * be refreshed after the action completes. If both are blank, the page will be refreshed
1433 * </p>
1434 *
1435 * @return valid component id
1436 */
1437 @BeanTagAttribute
1438 public String getRefreshId() {
1439 return refreshId;
1440 }
1441
1442 /**
1443 * Setter for the {@link #getRefreshId()}.
1444 *
1445 * @param refreshId property value
1446 */
1447 public void setRefreshId(String refreshId) {
1448 this.refreshId = refreshId;
1449 }
1450
1451 /**
1452 * Property name for the {@link org.kuali.rice.krad.uif.field.DataField} that should be refreshed after the action
1453 * completes
1454 *
1455 * <p>
1456 * Either refresh id or refresh property name can be set to configure the component that should
1457 * be refreshed after the action completes. If both are blank, the page will be refreshed
1458 * </p>
1459 *
1460 * <p>
1461 * Property name will be adjusted to use the default binding path unless it contains the form prefix
1462 * </p>
1463 *
1464 * @return valid property name with an associated DataField
1465 * @see org.kuali.rice.krad.uif.UifConstants#NO_BIND_ADJUST_PREFIX
1466 */
1467 @BeanTagAttribute
1468 public String getRefreshPropertyName() {
1469 return refreshPropertyName;
1470 }
1471
1472 /**
1473 * Setter for the property name of the DataField that should be refreshed.
1474 *
1475 * @param refreshPropertyName property value
1476 */
1477 public void setRefreshPropertyName(String refreshPropertyName) {
1478 this.refreshPropertyName = refreshPropertyName;
1479 }
1480
1481 /**
1482 * Gets the loading message used by action's blockUI.
1483 *
1484 * @return String if String is not null, used in place of loading message
1485 */
1486 @BeanTagAttribute
1487 public String getLoadingMessageText() {
1488 return loadingMessageText;
1489 }
1490
1491 /**
1492 * When this property is set, it is used in place of the loading message text used by the blockUI.
1493 *
1494 * @param loadingMessageText property value
1495 */
1496 public void setLoadingMessageText(String loadingMessageText) {
1497 this.loadingMessageText = loadingMessageText;
1498 }
1499
1500 /**
1501 * Indicates whether blocking for the action should be disabled
1502 *
1503 * <p>
1504 * By default when an action is invoked part of the page or the entire window is blocked until
1505 * the action completes. If this property is set to true the blocking will not be displayed.
1506 * </p>
1507 *
1508 * <p>
1509 * Currently if an action returns a file download, this property should be set to true. If not, the blocking
1510 * will never get unblocked (because the page does not get notification a file was downloaded)
1511 * </p>
1512 *
1513 * @return true if blocking should be disabled, false if not
1514 */
1515 @BeanTagAttribute
1516 public boolean isDisableBlocking() {
1517 return disableBlocking;
1518 }
1519
1520 /**
1521 * Setter for disabling blocking when the action is invoked.
1522 *
1523 * @param disableBlocking property value
1524 */
1525 public void setDisableBlocking(boolean disableBlocking) {
1526 this.disableBlocking = disableBlocking;
1527 }
1528
1529 /**
1530 * Evaluate the disable condition on controls which disable it on each key up event.
1531 *
1532 * @return true if evaluate on key up, false otherwise
1533 */
1534 @BeanTagAttribute
1535 public boolean isEvaluateDisabledOnKeyUp() {
1536 return evaluateDisabledOnKeyUp;
1537 }
1538
1539 /**
1540 * Setter for {@link #isEvaluateDisabledOnKeyUp()}.
1541 *
1542 * @param evaluateDisabledOnKeyUp property value
1543 */
1544 public void setEvaluateDisabledOnKeyUp(boolean evaluateDisabledOnKeyUp) {
1545 this.evaluateDisabledOnKeyUp = evaluateDisabledOnKeyUp;
1546 }
1547
1548 /**
1549 * Evaluate if this action is the default action for a page, view, group, or section.
1550 *
1551 * @return true if this action is default, false otherwise
1552 */
1553 @BeanTagAttribute(name = "defaultEnterKeyAction")
1554 public boolean isDefaultEnterKeyAction() {
1555 return this.defaultEnterKeyAction;
1556 }
1557
1558 /**
1559 * @see #isDefaultEnterKeyAction()
1560 */
1561 public void setDefaultEnterKeyAction(boolean defaultEnterKeyAction) {
1562 this.defaultEnterKeyAction = defaultEnterKeyAction;
1563 }
1564
1565 /**
1566 * Get the disable condition js derived from the springEL, cannot be set.
1567 *
1568 * @return the disableConditionJs javascript to be evaluated
1569 */
1570 public String getDisabledConditionJs() {
1571 return disabledConditionJs;
1572 }
1573
1574 /**
1575 * Sets the disabled condition javascript.
1576 *
1577 * @param disabledConditionJs property value
1578 */
1579 protected void setDisabledConditionJs(String disabledConditionJs) {
1580 this.disabledConditionJs = disabledConditionJs;
1581 }
1582
1583 /**
1584 * Gets a list of control names to add handlers to for disable functionality, cannot be set.
1585 *
1586 * @return control names to add handlers to for disable
1587 */
1588 public List<String> getDisabledConditionControlNames() {
1589 return disabledConditionControlNames;
1590 }
1591
1592 /**
1593 * Set disabled condition control names.
1594 *
1595 * @param disabledConditionControlNames property value
1596 */
1597 public void setDisabledConditionControlNames(List<String> disabledConditionControlNames) {
1598 this.disabledConditionControlNames = disabledConditionControlNames;
1599 }
1600
1601 /**
1602 * Gets the property names of fields that when changed, will disable this component.
1603 *
1604 * @return the property names to monitor for change to disable this component
1605 */
1606 @BeanTagAttribute
1607 public List<String> getDisabledWhenChangedPropertyNames() {
1608 return disabledWhenChangedPropertyNames;
1609 }
1610
1611 /**
1612 * Sets the property names of fields that when changed, will disable this component.
1613 *
1614 * @param disabledWhenChangedPropertyNames property value
1615 */
1616 public void setDisabledWhenChangedPropertyNames(List<String> disabledWhenChangedPropertyNames) {
1617 this.disabledWhenChangedPropertyNames = disabledWhenChangedPropertyNames;
1618 }
1619
1620 /**
1621 * Gets the property names of fields that when changed, will enable this component.
1622 *
1623 * @return the property names to monitor for change to enable this component
1624 */
1625 @BeanTagAttribute
1626 public List<String> getEnabledWhenChangedPropertyNames() {
1627 return enabledWhenChangedPropertyNames;
1628 }
1629
1630 /**
1631 * Sets the property names of fields that when changed, will enable this component.
1632 *
1633 * @param enabledWhenChangedPropertyNames property value
1634 */
1635 public void setEnabledWhenChangedPropertyNames(List<String> enabledWhenChangedPropertyNames) {
1636 this.enabledWhenChangedPropertyNames = enabledWhenChangedPropertyNames;
1637 }
1638
1639 /**
1640 * Sets the disabled expression.
1641 *
1642 * @param disabledExpression property value
1643 */
1644 protected void setDisabledExpression(String disabledExpression) {
1645 this.disabledExpression = disabledExpression;
1646 }
1647
1648 /**
1649 * {@inheritDoc}
1650 */
1651 @Override
1652 public void completeValidation(ValidationTrace tracer) {
1653 tracer.addBean(this);
1654
1655 // Checks that an action is set
1656 if (getJumpToIdAfterSubmit() != null && getJumpToNameAfterSubmit() != null) {
1657 String currentValues[] = {"jumpToIdAfterSubmit =" + getJumpToIdAfterSubmit(),
1658 "jumpToNameAfterSubmit =" + getJumpToNameAfterSubmit()};
1659 tracer.createWarning("Only 1 jumpTo property should be set", currentValues);
1660 }
1661 super.completeValidation(tracer.getCopy());
1662 }
1663 }