/* * Copyright (C) 2014 Civilian Framework. * * Licensed under the Civilian License (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.civilian-framework.org/license.txt * * 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.civilian.form; import org.civilian.Request; import org.civilian.template.HtmlUtil; import org.civilian.template.TemplateWriter; import org.civilian.type.TypeLib; import org.civilian.util.Check; /** * Button models the various HTML buttons: * {@code * <input value="..." type="submit"> * <input value="..." type="reset" > * <input value="..." type="button"> * <button>...</button> * <button type="submit">...</button> * <button type="reset">...</button> * } */ public class Button extends Control<String> { /** * Variant is an enum for the various HTML button variants. */ public enum Variant { /** * Printed as <input type="submit" value="..."> */ INPUT_SUBMIT(false, "submit"), /** * Printed as <input type="reset" value="..."> */ INPUT_RESET(false, "reset"), /** * Printed as <input type="button" value="..."> */ INPUT_BUTTON(false, "button"), /** * Printed as <button type="submit">{value}</button> */ BUTTON_SUBMIT(true, "submit"), /** * Printed as <button type="reset">{value}</button> */ BUTTON_RESET(true, "reset"), /** * Printed as <button>{value}</button> */ BUTTON(true, null); Variant(boolean buttonTag, String type) { this.buttonTag = buttonTag; this.type = type; } /** * Returns either "button" or "input". */ public final String tag() { return buttonTag ? "button" : "input"; } /** * Returns if the variant describes a submit button. */ public final boolean isSubmitVariant() { return "submit".equals(type); } public final boolean buttonTag; public final String type; } /** * Creates a Button for variant {@link Variant#BUTTON}. * @param label the button label */ public static Button button(String label) { return new Button(Variant.BUTTON, label); } /** * Creates a Button for variant {@link Variant#BUTTON_RESET}. * @param label the button label */ public static Button reset(String label) { return new Button(Variant.BUTTON_RESET, label); } /** * Creates a Button for variant {@link Variant#BUTTON_SUBMIT}. * @param label the button label */ public static Button submit(String label) { return new Button(Variant.BUTTON_SUBMIT, label); } /** * Creates a Button for variant {@link Variant#INPUT_BUTTON}. * @param label the button label */ public static Button inputButton(String label) { return new Button(Variant.INPUT_BUTTON, label); } /** * Creates a Button for variant {@link Variant#INPUT_RESET}. * @param label the button label */ public static Button inputReset(String label) { return new Button(Variant.INPUT_RESET, label); } /** * Creates a Button for variant {@link Variant#INPUT_SUBMIT}. * @param label the button label */ public static Button inputSubmit(String label) { return new Button(Variant.INPUT_SUBMIT, label); } /** * Creates a button. * @param variant the button variant * @param value the button label */ public Button(Variant variant, String value) { super(TypeLib.STRING); variant_ = Check.notNull(variant, "variant"); setValue(value); } /** * Returns Category.BUTTON. */ @Override public Category getCategory() { return Category.BUTTON; } /** * Sets the value of the "onclick" attribute. */ public Button setOnClick(String function) { setAttribute("onclick", function); return this; } /** * Sets the formnovalidate attribute of the button. * If set then HTML5 validations will not be performed when the button * is clicked and submitting the form. The use case are buttons with a * cancel or reset-function, which is implemented on the server-side. * When clicked, the form input should not be validated, but just submitted, * and the server-side logic will execute the cancel or reset functionality. */ public Button setNoValidate(boolean noValidate) { noValidate_ = noValidate; return this; } /** * Calls setNoValidate(true). */ public Button setNoValidate() { return setNoValidate(true); } /** * Returns the no-validate flag of the button. */ public boolean getNoValidate() { return noValidate_; } @Override protected void setForm(Form form) { super.setForm(form); if (getName() == null) setName(form.getName() + "_button"); if (variant_.isSubmitVariant() && form.getDefaultButton() == null) form.setDefaultButton(this); } /** * Does nothing. */ @Override protected void parse(Request request) { } /** * Returns if the form was submitted by clicking this button, or if the form * was submitted by pressing enter in a control and this button * was registered as default button. */ public boolean isClicked() { Form form = getForm(); if (form == null) return false; String param = form.getRequest().getParameter(getName()); if (param != null) return param.equals(getValue()); else return (form.getDefaultButton() == this) && form.isSubmitted(); } /** * Returns if the form was submitted by clicking this button. */ public boolean isDirectlyClicked() { Form form = getForm(); if (form == null) return false; else { String param = form.getRequest().getParameter(getName()); return (param != null) && param.equals(getValue()); } } /** * Prints the button markup. */ @Override public void print(TemplateWriter out, String... attrs) { start(out, attrs); if (variant_.buttonTag) { HtmlUtil.text(out, getValue()); end(out); } } public void start(TemplateWriter out) { start(out, (String[])null); } /** * Prints the button start tag. */ public void start(TemplateWriter out, String... attrs) { out.print("<"); out.print(variant_.tag()); if (variant_.type != null) HtmlUtil.attr(out, "type", variant_.type); if (getName() != null) HtmlUtil.attr(out, "name", getName()); if (isDisabled()) out.print(" disabled"); if (noValidate_) out.print(" formnovalidate"); // even if the button uses a <button> tag, we print // the value attribute, because we need the value as // parameter value if (!variant_.buttonTag || variant_.isSubmitVariant()) HtmlUtil.attr(out, "value", getValue()); printAttrs(out, attrs); out.print(">"); } /** * Prints the button end tag. */ public void end(TemplateWriter out) { if (variant_.buttonTag) { out.print("</"); out.print(variant_.tag()); out.print(">"); } } private Variant variant_; private boolean noValidate_; }