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.field;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.krad.uif.UifConstants;
020import org.kuali.rice.krad.uif.component.Component;
021import org.kuali.rice.krad.uif.view.View;
022
023/**
024 * Action field that performs an Ajax request and will result in updating of the page or a component
025 *
026 * @author Kuali Rice Team (rice.collab@kuali.org)
027 */
028public class AjaxActionField extends ActionField {
029    private static final long serialVersionUID = -2831173647391138870L;
030
031    private String refreshId;
032    private String refreshPropertyName;
033
034    public AjaxActionField() {
035        super();
036    }
037
038    /**
039     * The following finalization is performed:
040     *
041     * <ul>
042     * <li>Add methodToCall action parameter if set and setup event code for
043     * setting action parameters</li>
044     * </ul>
045     *
046     * @see org.kuali.rice.krad.uif.component.ComponentBase#performFinalize(org.kuali.rice.krad.uif.view.View,
047     *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
048     */
049    @Override
050    public void performFinalize(View view, Object model, Component parent) {
051        Component refreshComponent = null;
052
053        // if refresh property name is given, adjust the binding and then attempt to find the
054        // component in the view index
055        if (StringUtils.isNotBlank(refreshPropertyName)) {
056            // TODO: does this support all binding prefixes?
057            if (refreshPropertyName.startsWith(UifConstants.NO_BIND_ADJUST_PREFIX)) {
058                refreshPropertyName = StringUtils.removeStart(refreshPropertyName, UifConstants.NO_BIND_ADJUST_PREFIX);
059            } else if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
060                refreshPropertyName = view.getDefaultBindingObjectPath() + "." + refreshPropertyName;
061            }
062
063            DataField dataField = view.getViewIndex().getDataFieldByPath(refreshPropertyName);
064            if (dataField != null) {
065               refreshComponent = dataField;
066            }
067        }
068        else if (StringUtils.isNotBlank(refreshId)) {
069            Component component = view.getViewIndex().getComponentById(refreshId);
070            if (component != null) {
071                refreshComponent = component;
072            }
073        }
074
075        String actionScript = "";
076        if (refreshComponent != null) {
077            refreshComponent.setRefreshedByAction(true);
078            // update initial state
079            Component initialComponent = view.getViewIndex().getInitialComponentStates().get(
080                    refreshComponent.getFactoryId());
081            if (initialComponent != null) {
082                initialComponent.setRefreshedByAction(true);
083                view.getViewIndex().getInitialComponentStates().put(refreshComponent.getFactoryId(), initialComponent);
084            }
085
086            // refresh component for action
087            actionScript = "retrieveComponent('" + refreshComponent.getId() + "','" + refreshComponent.getFactoryId()
088                    + "','" + getMethodToCall() + "');";
089        }
090        else {
091            // refresh page
092            actionScript = "submitForm();";
093        }
094
095        // add action script to client JS
096        if (StringUtils.isNotBlank(getClientSideJs())) {
097            actionScript = getClientSideJs() + actionScript;
098        }
099        setClientSideJs(actionScript);
100
101        super.performFinalize(view, model, parent);
102    }
103
104    /**
105     * Id for the component that should be refreshed after the action completes
106     *
107     * <p>
108     * Either refresh id or refresh property name can be set to configure the component that should
109     * be refreshed after the action completes. If both are blank, the page will be refreshed
110     * </p>
111     *
112     * @return String valid component id
113     */
114    public String getRefreshId() {
115        return refreshId;
116    }
117
118    /**
119     * Setter for the component refresh id
120     *
121     * @param refreshId
122     */
123    public void setRefreshId(String refreshId) {
124        this.refreshId = refreshId;
125    }
126
127    /**
128     * Property name for the {@link DataField} that should be refreshed after the action completes
129     *
130     * <p>
131     * Either refresh id or refresh property name can be set to configure the component that should
132     * be refreshed after the action completes. If both are blank, the page will be refreshed
133     * </p>
134     *
135     * <p>
136     * Property name will be adjusted to use the default binding path unless it contains the form prefix
137     *
138     * @return String valid property name with an associated DataField
139     * @see org.kuali.rice.krad.uif.UifConstants#NO_BIND_ADJUST_PREFIX
140     *      </p>
141     */
142    public String getRefreshPropertyName() {
143        return refreshPropertyName;
144    }
145
146    /**
147     * Setter for the property name of the DataField that should be refreshed
148     *
149     * @param refreshPropertyName
150     */
151    public void setRefreshPropertyName(String refreshPropertyName) {
152        this.refreshPropertyName = refreshPropertyName;
153    }
154}