/* * Copyright 2004-2005 Revolution Systems Inc. * * Licensed 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 com.revolsys.ui.html.form; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.springframework.web.util.UrlPathHelper; import com.revolsys.record.io.format.xml.XmlWriter; import com.revolsys.ui.html.fields.Field; import com.revolsys.ui.html.view.ElementContainer; import com.revolsys.util.HtmlAttr; import com.revolsys.util.HtmlElem; import com.revolsys.util.HtmlUtil; import com.revolsys.util.Property; import com.revolsys.util.UrlUtil; public class Form extends ElementContainer { public static final String FORM_TASK_PARAM = "rs_form_task"; public static final String GET_METHOD = "get"; public static final String MULTIPART_FORM_DATA = "multipart/form-data"; public static final String POST_METHOD = "post"; private static final UrlPathHelper URL_HELPER = new UrlPathHelper(); private String acceptCharset = "UTF-8"; private String action = ""; private String cssClass = "form"; private String defaultFormTask; private String encType = "application/x-www-form-urlencoded"; private String formTask; private String method = POST_METHOD; private String name; private final List<String> onSubmit = new ArrayList<>(); private boolean posted = false; private final Map<String, Object> savedParameters = new HashMap<>(); private String title; private boolean valid = true; public Form() { } /** * @param name */ public Form(final String name) { this(name, null, null); } public Form(final String name, final String action) { this(name, action, null); } public Form(final String name, final String action, final String title) { this.name = name; if (action != null) { this.action = action; } this.title = title; this.defaultFormTask = name; addCssClass(name); } public void addCssClass(final String cssClass) { this.cssClass += " " + cssClass; } public void addOnSubmit(final String script) { this.onSubmit.add(script); } public void addSavedParameter(final String name, final Object value) { this.savedParameters.put(name, value); } public String getAcceptCharset() { return this.acceptCharset; } /** * @return Returns the action. */ public String getAction() { return this.action; } protected Map<String, String[]> getActionParameters(final HttpServletRequest request) { final Set<String> fieldNames = getFields().keySet(); final Map<String, String[]> parameters = new HashMap<>(); for (final Enumeration<String> paramNames = request.getParameterNames(); paramNames .hasMoreElements();) { final String fieldName = paramNames.nextElement(); if (!fieldNames.contains(fieldName) && !FORM_TASK_PARAM.equals(fieldName)) { final String[] values = request.getParameterValues(fieldName); parameters.put(fieldName, values); } } return parameters; } public String getEncType() { return this.encType; } @Override public Form getForm() { return this; } @Override public <T> T getInitialValue(final Field field, final HttpServletRequest request) { return null; } public String getMethod() { return this.method; } public String getName() { return this.name; } public String getTask() { return this.formTask; } public String getTitle() { return this.title; } @SuppressWarnings("unchecked") public <T> T getValue(final String fieldName) { final Field field = getField(fieldName); if (field != null) { return (T)field.getValue(); } else { return null; } } public boolean hasTask() { return this.formTask != null; } public boolean hasValue(final String fieldName) { final Field field = getField(fieldName); if (field != null) { return field.hasValue(); } else { return false; } } @Override public void initialize(final HttpServletRequest request) { if (this.action == null || this.action.trim().length() == 0) { this.action = URL_HELPER.getOriginatingRequestUri(request); } // ensure the formTaskField is initialized first so that it can be used // by the other fields this.formTask = request.getParameter(FORM_TASK_PARAM); final String method = request.getMethod(); this.posted = method.equalsIgnoreCase(POST_METHOD); preInit(request); super.initialize(request); final Map<String, Field> fieldMap = getFields(); final Collection<Field> fields = fieldMap.values(); for (final Field field : fields) { field.initialize(this, request); } for (final Field field : fields) { field.postInit(request); } final Map<String, String[]> parameters = getActionParameters(request); this.action = UrlUtil.getUrl(this.action, parameters); } public boolean isMainFormTask() { return hasTask() && this.formTask.equals(this.name); } public boolean isPosted() { return this.posted; } public boolean isValid() { boolean success = true; for (final Field field : getFields().values()) { success &= field.isValid(); } success &= validate(); this.valid = success; return success; } protected void preInit(final HttpServletRequest request) { } @Override public void serializeElement(final XmlWriter out) { serializeStartTag(out); if (this.defaultFormTask != null) { HtmlUtil.serializeHiddenInput(out, FORM_TASK_PARAM, this.defaultFormTask); } for (final Entry<String, Object> savedParam : this.savedParameters.entrySet()) { final Object value = savedParam.getValue(); if (value != null) { HtmlUtil.serializeHiddenInput(out, savedParam.getKey(), value); } } super.serializeElement(out); serializeEndTag(out); } /** * @param out * @throws IOException */ public void serializeEndTag(final XmlWriter out) { out.endTag(HtmlElem.FORM); out.endTag(HtmlElem.DIV); } /** * @param out * @throws IOException */ public void serializeStartTag(final XmlWriter out) { out.startTag(HtmlElem.DIV); String cssClass = this.cssClass; if (!this.valid) { if (Property.hasValue(cssClass)) { cssClass += " formInvalid"; } else { cssClass = "formInvalid"; } } out.attribute(HtmlAttr.CLASS, cssClass); final String title = getTitle(); if (title != null) { out.startTag(HtmlElem.DIV); out.attribute(HtmlAttr.CLASS, "title"); out.text(title); out.endTag(HtmlElem.DIV); } out.startTag(HtmlElem.DIV); out.attribute(HtmlAttr.CLASS, "errorContainer"); out.startTag(HtmlElem.DIV); out.attribute(HtmlAttr.CLASS, "title"); out.text("The form contains errors, please update the highlighted fields to fix the errors."); out.endTag(HtmlElem.DIV); out.startTag(HtmlElem.UL); out.endTag(HtmlElem.UL); out.endTag(HtmlElem.DIV); out.startTag(HtmlElem.FORM); if (this.onSubmit.size() > 0) { final StringBuilder submitScripts = new StringBuilder(); for (final String script : this.onSubmit) { submitScripts.append(script).append(';'); } out.attribute(HtmlAttr.ON_SUBMIT, submitScripts.toString()); } out.attribute(HtmlAttr.ID, getName()); out.attribute(HtmlAttr.NAME, getName()); out.attribute(HtmlAttr.ROLE, "form"); out.attribute(HtmlAttr.CLASS, "form-horizontal"); out.attribute(HtmlAttr.ACTION, getAction()); out.attribute(HtmlAttr.METHOD, getMethod()); out.attribute(HtmlAttr.ENCTYPE, getEncType()); out.attribute(HtmlAttr.ACCEPT_CHARSET, getAcceptCharset()); } public void setAcceptCharset(final String acceptCharset) { this.acceptCharset = acceptCharset; } /** * @param action The action to set. */ public void setAction(final String action) { this.action = action; } public void setEncType(final String encType) { this.encType = encType; } /** * @param method The method to set. */ public void setMethod(final String method) { this.method = method; } public void setName(final String name) { this.name = name; } /** * @param title The title to set. */ public void setTitle(final String title) { this.title = title; } public void setValue(final String fieldName, final Object value) { final Field field = getField(fieldName); if (field != null) { field.setValue(value); } else { throw new IllegalArgumentException("No Such Field " + fieldName); } } }