You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@click.apache.org by sa...@apache.org on 2009/04/17 18:37:21 UTC
svn commit: r766076 - in /incubator/click/trunk/click:
documentation/docs/roadmap-changes.html extras/src/extras-controls.xml
extras/src/org/apache/click/extras/control/SubmitLink.java
extras/src/org/apache/click/extras/control/extras-control.js
Author: sabob
Date: Fri Apr 17 16:37:20 2009
New Revision: 766076
URL: http://svn.apache.org/viewvc?rev=766076&view=rev
Log:
added SubmitLink control for submitting Forms. CLK-519
Added:
incubator/click/trunk/click/extras/src/org/apache/click/extras/control/SubmitLink.java
Modified:
incubator/click/trunk/click/documentation/docs/roadmap-changes.html
incubator/click/trunk/click/extras/src/extras-controls.xml
incubator/click/trunk/click/extras/src/org/apache/click/extras/control/extras-control.js
Modified: incubator/click/trunk/click/documentation/docs/roadmap-changes.html
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/docs/roadmap-changes.html?rev=766076&r1=766075&r2=766076&view=diff
==============================================================================
--- incubator/click/trunk/click/documentation/docs/roadmap-changes.html (original)
+++ incubator/click/trunk/click/documentation/docs/roadmap-changes.html Fri Apr 17 16:37:20 2009
@@ -149,6 +149,10 @@
and <a href="click-api/org/apache/click/Page.html#getHeadElements()">Page.getHeadElements()</a>.
</li>
<li class="change">
+ Added <a href="extras-api/org/apache/click/extras/control/SubmitLink.html">SubmitLink</a> control
+ that can submit a Form [<a target='_blank' href="https://issues.apache.org/jira/browse/CLK-519">519</a>].
+ </li>
+ <li class="change">
Added method,
<a href="click-api/org/apache/click/util/ClickUtils.html#createTemplateModel(org.apache.click.Page, org.apache.click.Context)">ClickUtils.createTemplateModel</a>,
which returns a template model containing objects such as the Context
Modified: incubator/click/trunk/click/extras/src/extras-controls.xml
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/extras/src/extras-controls.xml?rev=766076&r1=766075&r2=766076&view=diff
==============================================================================
--- incubator/click/trunk/click/extras/src/extras-controls.xml (original)
+++ incubator/click/trunk/click/extras/src/extras-controls.xml Fri Apr 17 16:37:20 2009
@@ -27,6 +27,7 @@
<control classname="org.apache.click.extras.control.PickList"/>
<control classname="org.apache.click.extras.control.Menu"/>
<control classname="org.apache.click.extras.control.RegexField"/>
+ <control classname="org.apache.click.extras.control.SubmitLink"/>
<control classname="org.apache.click.extras.control.TabbedForm"/>
<control classname="org.apache.click.extras.control.VirtualKeyboard"/>
<control classname="org.apache.click.extras.panel.ListPanel"/>
Added: incubator/click/trunk/click/extras/src/org/apache/click/extras/control/SubmitLink.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/extras/src/org/apache/click/extras/control/SubmitLink.java?rev=766076&view=auto
==============================================================================
--- incubator/click/trunk/click/extras/src/org/apache/click/extras/control/SubmitLink.java (added)
+++ incubator/click/trunk/click/extras/src/org/apache/click/extras/control/SubmitLink.java Fri Apr 17 16:37:20 2009
@@ -0,0 +1,519 @@
+/*
+ * 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.click.extras.control;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.click.Context;
+import org.apache.click.control.ActionLink;
+import org.apache.click.control.Form;
+import org.apache.click.element.JsImport;
+import org.apache.click.util.ClickUtils;
+import org.apache.click.util.ContainerUtils;
+import org.apache.click.util.HtmlStringBuffer;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Provides a Submit Link control, <a href=""></a>, that can
+ * submit a {@link org.apache.click.control.Form Form}.
+ * <p/>
+ * SubmitLink can be added to a Form and it will submit the Form when clicked.
+ * All SubmitLink parameters will be submitted to the server as hidden fields.
+ * <p/>
+ * <b>Please note:</b> SubmitLink uses a <tt>JavaScript</tt> function to submit
+ * the Form. This JavaScript function also creates <tt>hidden fields</tt>
+ * for each SubmitLink parameter, to ensure the link's parameters are
+ * submitted.
+ * <p/>
+ * <b>Also note:</b> if SubmitLink is <tt>not</tt> added to a Form, it behaves
+ * like an {@link org.apache.click.control.ActionLink ActionLink} control.
+ * <p/>
+ * Here is an example:
+ * <pre class="prettyprint">
+ * public class MyPage extends Page {
+ *
+ * public void onInit() {
+ *
+ * // Create a Form control
+ * Form form = new Form("form");
+ * addControl(form);
+ *
+ * // Add a SubmitLink to the Form
+ * SubmitLink link = new SubmitLink("link");
+ * form.add(link);
+ * }
+ * } </pre>
+ *
+ * <h3>JavaScript and CSS Dependencies</h3>
+ *
+ * When SubmitLink is added to a Form it will include the following resources:
+ * <ul>
+ * <li>/click/extras-control.js</li>
+ * </ul>
+ *
+ * @author Bob Schellink
+ */
+public class SubmitLink extends ActionLink {
+
+ // -------------------------------------------------------------- Variables
+
+ /** The SubmitLink parent Form. */
+ private Form form;
+
+ /**
+ * A parameter prefix to differentiate the link parameters from
+ * From parameters.
+ */
+ private String parameterPrefix;
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * Create an SubmitLink for the given name.
+ * <p/>
+ * Please note the name 'actionLink' is reserved as a control request
+ * parameter name and cannot be used as the name of the control.
+ *
+ * @param name the action link name
+ * @throws IllegalArgumentException if the name is null
+ */
+ public SubmitLink(String name) {
+ setName(name);
+ }
+
+ /**
+ * Create an SubmitLink for the given name and label.
+ * <p/>
+ * Please note the name 'actionLink' is reserved as a control request
+ * parameter name and cannot be used as the name of the control.
+ *
+ * @param name the action link name
+ * @param label the action link label
+ * @throws IllegalArgumentException if the name is null
+ */
+ public SubmitLink(String name, String label) {
+ setName(name);
+ setLabel(label);
+ }
+
+ /**
+ * Create an SubmitLink for the given listener object and listener
+ * method.
+ *
+ * @param listener the listener target object
+ * @param method the listener method to call
+ * @throws IllegalArgumentException if the name, listener or method is null
+ * or if the method is blank
+ */
+ public SubmitLink(Object listener, String method) {
+ if (listener == null) {
+ throw new IllegalArgumentException("Null listener parameter");
+ }
+ if (StringUtils.isBlank(method)) {
+ throw new IllegalArgumentException("Blank listener method");
+ }
+ setListener(listener, method);
+ }
+
+ /**
+ * Create an SubmitLink for the given name, listener object and listener
+ * method.
+ * <p/>
+ * Please note the name 'actionLink' is reserved as a control request
+ * parameter name and cannot be used as the name of the control.
+ *
+ * @param name the action link name
+ * @param listener the listener target object
+ * @param method the listener method to call
+ * @throws IllegalArgumentException if the name, listener or method is null
+ * or if the method is blank
+ */
+ public SubmitLink(String name, Object listener, String method) {
+ setName(name);
+ if (listener == null) {
+ throw new IllegalArgumentException("Null listener parameter");
+ }
+ if (StringUtils.isBlank(method)) {
+ throw new IllegalArgumentException("Blank listener method");
+ }
+ setListener(listener, method);
+ }
+
+ /**
+ * Create an SubmitLink for the given name, label, listener object and
+ * listener method.
+ * <p/>
+ * Please note the name 'actionLink' is reserved as a control request
+ * parameter name and cannot be used as the name of the control.
+ *
+ * @param name the action link name
+ * @param label the action link label
+ * @param listener the listener target object
+ * @param method the listener method to call
+ * @throws IllegalArgumentException if the name, listener or method is null
+ * or if the method is blank
+ */
+ public SubmitLink(String name, String label, Object listener,
+ String method) {
+
+ setName(name);
+ setLabel(label);
+ if (listener == null) {
+ throw new IllegalArgumentException("Null listener parameter");
+ }
+ if (StringUtils.isBlank(method)) {
+ throw new IllegalArgumentException("Blank listener method");
+ }
+ setListener(listener, method);
+ }
+
+ /**
+ * Create an SubmitLink with no name defined. <b>Please note</b> the
+ * control's name must be defined before it is valid.
+ */
+ public SubmitLink() {
+ }
+
+ // ------------------------------------------------------ Public Attributes
+
+ /**
+ * Return the parent Form or null if no Form is available.
+ *
+ * @return the parent Form or null if no Form is available
+ */
+ public Form getForm() {
+ if (form == null) {
+ form = ContainerUtils.findForm(this);
+ }
+ return form;
+ }
+
+ /**
+ * Set the SubmitLink Form.
+ *
+ * @param form the SubmitLink Form
+ */
+ public void setForm(Form form) {
+ this.form = form;
+ }
+
+ /**
+ * Returns the button onclick attribute value, or null if not defined.
+ *
+ * @return the button onclick attribute value, or null if not defined.
+ */
+ public String getOnClick() {
+ if (attributes != null) {
+ return (String) attributes.get("onclick");
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Sets the button onclick attribute value.
+ *
+ * @param value the onclick attribute value.
+ */
+ public void setOnClick(String value) {
+ setAttribute("onclick", value);
+ }
+
+ /**
+ * @see org.apache.click.control.AbstractLink#getParameter(java.lang.String)
+ *
+ * @param name the name of request parameter
+ * @return the link request parameter value
+ */
+ public String getParameter(String name) {
+ Object value = getParameters().get(name);
+
+ if (value instanceof String) {
+ return (String) value;
+ }
+
+ if (value instanceof String[]) {
+ String[] array = (String[]) value;
+ if (array.length >= 1) {
+ return array[0];
+ } else {
+ return null;
+ }
+ }
+
+ return (value == null ? null : value.toString());
+ }
+
+ /**
+ * Return the link request parameter values for the given name, or null if
+ * the parameter values does not exist.
+ *
+ * @param name the name of request parameter
+ * @return the link request parameter values
+ */
+ public String[] getParameterValues(String name) {
+ Object values = getParameters().get(name);
+ if (values instanceof String) {
+ return new String[] { values.toString() };
+ }
+ if (values instanceof String[]) {
+ return (String[]) values;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @see org.apache.click.control.AbstractLink#setParameter(java.lang.String, java.lang.String)
+ *
+ * @param name the attribute name
+ * @param values the attribute values
+ * @throws IllegalArgumentException if name parameter is null
+ */
+ public void setParameters(String name, String[] values) {
+ if (name == null) {
+ throw new IllegalArgumentException("Null name parameter");
+ }
+
+ if (values != null) {
+ getParameters().put(name, values);
+ } else {
+ getParameters().remove(name);
+ }
+ }
+
+ /**
+ * Set the paramter prefix that is applied to the SubmitLink parameters.
+ *
+ * @param prefix the parameter prefix
+ */
+ public void setParameterPrefix(String prefix) {
+ this.parameterPrefix = prefix;
+ }
+
+ /**
+ * Return the paramter prefix that is applied to the SubmitLink parameters.
+ *
+ * @return the paramter prefix that is applied to the SubmitLink parameters.
+ */
+ public String getParameterPrefix() {
+ if (!hasParentForm()) {
+ return "";
+ }
+ if (parameterPrefix == null) {
+ parameterPrefix = getName() + '_';
+ }
+ return parameterPrefix;
+ }
+
+ /**
+ * Return true if SubmitLink has a parent Form control, false otherwise.
+ *
+ * @return true if SubmitLink has a parent Form control, false otherwise.
+ */
+ public boolean hasParentForm() {
+ return getForm() != null;
+ }
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Return the SubmitLink anchor <a> tag href attribute for the
+ * given value. This method will encode the URL with the session ID
+ * if required using <tt>HttpServletResponse.encodeURL()</tt>.
+ *
+ * @param value the SubmitLink value parameter
+ * @return the SubmitLink HTML href attribute
+ */
+ public String getHref(Object value) {
+ Context context = getContext();
+ String uri = ClickUtils.getRequestURI(context.getRequest());
+
+ HtmlStringBuffer buffer =
+ new HtmlStringBuffer(uri.length() + getName().length() + 40);
+
+ String prefix = getParameterPrefix();
+
+ buffer.append(uri);
+ buffer.append("?");
+ buffer.append(ACTION_LINK);
+ buffer.append("=");
+ buffer.append(getName());
+ if (value != null) {
+ buffer.append("&");
+ if (hasParentForm()) {
+ // Value parameter is prefixed when SubmitLink is included
+ // inside a Form
+ buffer.append(prefix);
+ }
+ buffer.append(VALUE);
+ buffer.append("=");
+ buffer.append(ClickUtils.encodeUrl(value, context));
+ }
+
+ if (hasParameters()) {
+ Iterator i = getParameters().keySet().iterator();
+ while (i.hasNext()) {
+ String name = i.next().toString();
+ if (!name.equals(ACTION_LINK) && !name.equals(VALUE)) {
+ Object paramValue = getParameters().get(name);
+ if (paramValue instanceof String[]) {
+ String[] paramValues = (String[]) paramValue;
+ for (int j = 0; j < paramValues.length; j++) {
+ renderParameter(name, paramValues[j], buffer, context);
+ }
+ } else {
+ renderParameter(name, paramValue, buffer, context);
+ }
+ }
+ }
+ }
+
+ return context.getResponse().encodeURL(buffer.toString());
+ }
+
+ /**
+ * This method binds the submitted request value to the SubmitLink's
+ * value.
+ */
+ public void bindRequestValue() {
+ Context context = getContext();
+
+ clicked = getName().equals(context.getRequestParameter(ACTION_LINK));
+
+ if (clicked) {
+ // SubmitLink parameters are prefixed when included inside a Form
+ String prefix = getParameterPrefix();
+
+ HttpServletRequest request = context.getRequest();
+ Enumeration paramNames = request.getParameterNames();
+
+ boolean hasParentForm = hasParentForm();
+
+ while (paramNames.hasMoreElements()) {
+ String param = paramNames.nextElement().toString();
+ String[] values = request.getParameterValues(param);
+
+ if (hasParentForm) {
+ // Only bind parameters that start with the prefix
+ if (param.startsWith(prefix)) {
+
+ // Remove prefix from parameters
+ String key = param.substring(prefix.length());
+ if (values != null && values.length == 1) {
+ getParameters().put(key, values[0]);
+ } else {
+ getParameters().put(key, values);
+ }
+ }
+
+ } else {
+ if (values != null && values.length == 1) {
+ getParameters().put(param, values[0]);
+ } else {
+ getParameters().put(param, values);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Return the list of HEAD {@link org.apache.click.element.Element elements}
+ * to be included in the page.
+ * <p/>
+ * The list of resources returned are:
+ * <ul>
+ * <li>the template "/click/extras-control.js"</li>
+ * </ul>
+ *
+ * @return the list of HEAD elements to be included in the page
+ */
+ public List getHeadElements() {
+ if (getForm() == null) {
+ return super.getHeadElements();
+ }
+
+ if (headElements == null) {
+ headElements = super.getHeadElements();
+ JsImport jsImport = new JsImport("/click/extras-control.js");
+ headElements.add(jsImport);
+ }
+ return headElements;
+ }
+
+ /**
+ * Render the HTML representation of the SubmitLink.
+ *
+ * @param buffer the specified buffer to render the control's output to
+ */
+ public void render(HtmlStringBuffer buffer) {
+
+ // Check that the link is attached to a Form and the onClick attribute
+ // has not been set
+ Form form = getForm();
+ if (form != null && getOnClick() == null) {
+ setOnClick("return Click.submitLinkAction(this, '" + form.getName() + "');");
+ }
+
+ super.render(buffer);
+ }
+
+ /**
+ * Deploy the <tt>extras-control.js</tt> file to the <tt>click</tt> web
+ * directory when the application is initialized.
+ *
+ * @see org.apache.click.Control#onDeploy(ServletContext)
+ *
+ * @param servletContext the servlet context
+ */
+ public void onDeploy(ServletContext servletContext) {
+ ClickUtils.deployFile(servletContext,
+ "/org/apache/click/extras/control/extras-control.js",
+ "click");
+ }
+
+ // -------------------------------------------------------- Private Methods
+
+ /**
+ * Render the specified name and value pair to the buffer.
+ *
+ * @param name the parameter name
+ * @param value the parameter value
+ * @param buffer the buffer to render the parameter to
+ * @param context the request context
+ */
+ private void renderParameter(String name, Object value,
+ HtmlStringBuffer buffer, Context context) {
+
+ String encodedValue = ClickUtils.encodeUrl(value, context);
+ buffer.append("&");
+ if (hasParentForm()) {
+ // Parameters are prefixed when SubmitLink is included
+ // inside a Form
+ buffer.append(getParameterPrefix());
+ }
+ buffer.append(name);
+ buffer.append("=");
+ buffer.append(encodedValue);
+ }
+}
Modified: incubator/click/trunk/click/extras/src/org/apache/click/extras/control/extras-control.js
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/extras/src/org/apache/click/extras/control/extras-control.js?rev=766076&r1=766075&r2=766076&view=diff
==============================================================================
--- incubator/click/trunk/click/extras/src/org/apache/click/extras/control/extras-control.js (original)
+++ incubator/click/trunk/click/extras/src/org/apache/click/extras/control/extras-control.js Fri Apr 17 16:37:20 2009
@@ -18,7 +18,11 @@
/*
* This file is dependend upon /click/control.js functions.
*/
-
+
+ /* Ensure Click namespace exists */
+if ( typeof Click == 'undefined' )
+ Click = {};
+
/* Validate Functions */
function validateCreditCardField(id, typeId, required, minLength, maxLength, msgs){
@@ -248,3 +252,56 @@
}
}
}
+
+/**
+ * Define the SubmitLink action. This function creates hidden fields for
+ * each SubmitLink parameter and submits the form.
+ */
+Click.submitLinkAction = function(link, formName) {
+ var params=Click.getUrlParams(link.href);
+ if (params == null) {
+ return false;
+ }
+ var form = document.getElementById(formName);
+ if(form == null) {
+ return false;
+ }
+ for(var i=0; i<params.length; i++){
+ var param=params[i];
+ var input = document.createElement("input");
+ input.setAttribute("type", "hidden");
+ input.setAttribute("name", param.name);
+ input.setAttribute("value", param.value);
+ form.appendChild(input);
+ }
+ form.submit();
+ return false;
+}
+
+/**
+ * Return the url parameters as an array of key/value pairs or null
+ * if no parameters can be extracted.
+ */
+Click.getUrlParams = function(url) {
+ if (url == null || url == '' || url == 'undefined') {
+ return null;
+ }
+ url = unescape(url);
+ var start = url.indexOf('?')
+ if (start == -1) {
+ return null;
+ }
+ url=url.substring(start + 1);
+ var pairs=url.split("&");
+ var params = new Array();
+ for (var i=0;i<pairs.length;i++) {
+ var param = new Object();
+ var pos = pairs[i].indexOf('=');
+ if (pos >= 0) {
+ param.name = pairs[i].substring(0,pos);
+ param.value = pairs[i].substring(pos+1);
+ params.push(param);
+ }
+ }
+ return params;
+};
\ No newline at end of file