org.apache.wicket.markup.html.form.SubmitLink.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.wicket.markup.html.form.SubmitLink.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket.markup.html.form;

import org.apache.wicket.IRequestListener;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.model.IModel;

/**
 * A link which can be used exactly like a Button to submit a Form. The onclick of the link will use
 * JavaScript to submit the form.
 * 
 * <p>
 * You can use this class 2 ways. First with the constructor without a Form object then this Link
 * must be inside a Form so that it knows what form to submit to. Second way is to use the Form
 * constructor then that form will be used to submit to.
 * </p>
 * <p>
 * 
 * <pre>
 * Form f = new Form(&quot;linkForm&quot;, new CompoundPropertyModel(mod));
 *     f.add(new TextField(&quot;value1&quot;));
 *     f.add(new SubmitLink(&quot;link1&quot;) {
 *         protected void onSubmit() {
 *             System.out.println(&quot;Link1 was clicked, value1 is: &quot;
 *                                 + mod.getValue1());
 *         };
 *      });
 *      add(new SubmitLink(&quot;link2&quot;,f) {
 *          protected void onSubmit() {
 *              System.out.println(&quot;Link2 was clicked, value1 is: &quot;
 *                                 + mod.getValue1());
 *           };
 *      });
 * 
 *      &lt;form wicket:id=&quot;linkForm&quot; &gt;
 *          &lt;input wicket:id=&quot;value1&quot; type=&quot;text&quot; size=&quot;30&quot;/&gt;
 *          &lt;a wicket:id=&quot;link1&quot;&gt;Press link1 to submit&lt;/a&gt;
 *          &lt;input type=&quot;submit&quot; value=&quot;Send&quot;/&gt;
 *      &lt;/form&gt;
 *      &lt;a wicket:id=&quot;link2&quot;&gt;Press link 2 to submit&lt;/a&gt;
 * </pre>
 * 
 * </p>
 * <p>
 * If this link is not placed in a form or given a form to cooperate with, it will fall back to a
 * normal link behavior, meaning that {@link #onSubmit()} will be called without any other
 * consequences.
 * </p>
 * <p>
 * To customize the JavaScript code used to submit the form we must override {@link #getTriggerJavaScript()}. 
 * This can be helpful to implement additional client side behaviors like disabling the link during form submission.
 * </p>
 * 
 * @author chris
 * @author jcompagner
 * @author Igor Vaynberg (ivaynberg)
 * @author Eelco Hillenius
 * 
 */
public class SubmitLink extends AbstractSubmitLink implements IRequestListener {
    private static final long serialVersionUID = 1L;

    /**
     * With this constructor the SubmitLink must be inside a Form.
     * 
     * @param id
     *            The id of the submitlink.
     */
    public SubmitLink(String id) {
        super(id);
    }

    /**
     * With this constructor the SubmitLink will submit the {@link Form} that is given when the link
     * is clicked on.
     * 
     * The SubmitLink doesn't have to be inside the {@link Form}. But currently if it is outside the
     * {@link Form} and the SubmitLink is rendered first, then the {@link Form} will have a
     * generated javascript/css id. The markup javascript/css id that can exist will be overridden.
     * 
     * @param id
     *            The id of the submitlink.
     * @param form
     *            The form which this submitlink must submit.
     */
    public SubmitLink(String id, Form<?> form) {
        super(id, form);
    }

    /**
     * With this constructor the SubmitLink must be inside a Form.
     * 
     * @param id
     *            The id of the submitlink.
     * @param model
     *            The model for this submitlink, It won't be used by the submit link itself, but it
     *            can be used for keeping state
     */
    public SubmitLink(String id, IModel<?> model) {
        super(id, model);
    }

    /**
     * With this constructor the SubmitLink will submit the {@link Form} that is given when the link
     * is clicked on.
     * 
     * The SubmitLink doesn't have to be in inside the {@link Form}. But currently if it is outside
     * the {@link Form} and the SubmitLink will be rendered first. Then the {@link Form} will have a
     * generated javascript/css id. The markup javascript/css id that can exist will be overridden.
     * 
     * @param id
     *            The id of the submitlink.
     * @param model
     *            The model for this submitlink, It won't be used by the submit link itself, but it
     *            can be used for keeping state
     * @param form
     *            The form which this submitlink must submit.
     */
    public SubmitLink(String id, IModel<?> model, Form<?> form) {
        super(id, model, form);
    }

    /**
     * This method is here as a means to fall back on normal link behavior when this link is not
     * nested in a form. Not intended to be called by clients directly.
     * 
     * @see org.apache.wicket.markup.html.link.ILinkListener#onLinkClicked()
     */
    public final void onLinkClicked() {
        onSubmit();
        onAfterSubmit();
    }

    /**
     * @see org.apache.wicket.Component#onComponentTag(org.apache.wicket.markup.ComponentTag)
     */
    @Override
    protected void onComponentTag(ComponentTag tag) {
        super.onComponentTag(tag);

        if (isEnabledInHierarchy()) {
            if (tag.getName().equalsIgnoreCase("a") || tag.getName().equalsIgnoreCase("link")
                    || tag.getName().equalsIgnoreCase("area")) {
                tag.put("href", "javascript:;");
            } else if (tag.getName().equalsIgnoreCase("button")) {
                // WICKET-5597 prevent default submit
                tag.put("type", "button");
            }

            tag.put("onclick", getTriggerJavaScript());
        } else {
            disableLink(tag);
        }
    }

    /**
     * Controls whether or not clicking on this link will invoke form's javascript onsubmit handler.
     * True by default.
     * 
     * @return true if form's javascript onsubmit handler should be invoked, false otherwise
     */
    protected boolean shouldInvokeJavaScriptFormOnsubmit() {
        return true;
    }

    /**
     * The JavaScript which triggers this link. Method is non-final so that subclasses can decorate
     * the provided script by wrapping their own JS around a call to super.getTriggerJavaScript().
     * 
     * @return The JavaScript to be executed when the link is clicked.
     */
    protected CharSequence getTriggerJavaScript() {
        if (getForm() != null) {
            // find the root form - the one we are really going to submit
            Form<?> root = getForm().getRootForm();

            StringBuilder script = new StringBuilder();
            if (shouldInvokeJavaScriptFormOnsubmit()) {
                script.append(String.format("var ff=document.getElementById('%s');", getForm().getMarkupId()));
                script.append("if (typeof ff.onsubmit === 'function' && ff.onsubmit() == false) return false;");
            }

            script.append(root.getJsForSubmitter(this));
            script.append("return false;");

            return script;
        } else {
            return null;
        }
    }

    /**
     * @deprecated do not override, will be removed in Wicket 9
     */
    @Deprecated
    @Override
    public void onRequest() {
        // with WICKET-6642 SubmitLink was reverted to use a request to the form once again,
        // see Form#getJsForSubmitter(IFormSubmittingComponent)
    }

    /**
     * @see org.apache.wicket.markup.html.form.IFormSubmittingComponent#onError()
     */
    @Override
    public void onError() {
    }

    /**
     * Override this method to provide special submit handling in a multi-button form. This method
     * will be called <em>after</em> the form's onSubmit method.
     */
    @Override
    public void onAfterSubmit() {
    }

    /**
     * Override this method to provide special submit handling in a multi-button form. This method
     * will be called <em>before</em> the form's onSubmit method.
     */
    @Override
    public void onSubmit() {
    }
}