001// Copyright 2004, 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry.form;
016
017import org.apache.tapestry.IMarkupWriter;
018import org.apache.tapestry.IRequestCycle;
019import org.apache.tapestry.valid.ValidatorException;
020
021/**
022 * Implements a component that manages an HTML &lt;input type=checkbox&gt; form element. [ <a
023 * href="../../../../../ComponentReference/Checkbox.html">Component Reference </a>]
024 * <p>
025 * As of 4.0, this component can be validated.
026 * 
027 * @author Howard Lewis Ship
028 * @author Paul Ferraro
029 */
030public abstract class Checkbox extends AbstractFormComponent implements ValidatableField
031{
032    /**
033     * @see org.apache.tapestry.form.validator.AbstractRequirableField#renderRequirableFormComponent(org.apache.tapestry.IMarkupWriter,
034     *      org.apache.tapestry.IRequestCycle)
035     */
036    protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle)
037    {
038        writer.beginEmpty("input");
039        writer.attribute("type", "checkbox");
040
041        writer.attribute("name", getName());
042
043        if (isDisabled())
044            writer.attribute("disabled", "disabled");
045
046        if (getValue())
047            writer.attribute("checked", "checked");
048
049        renderIdAttribute(writer, cycle);
050
051        renderInformalParameters(writer, cycle);
052
053        writer.closeTag();
054    }
055
056    /**
057     * In traditional HTML, many checkboxes would have the same name but different values. Under
058     * Tapestry, it makes more sense to have different names and a fixed value. For a checkbox, we
059     * only care about whether the name appears as a request parameter.
060     */
061    protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle)
062    {
063        String value = cycle.getParameter(getName());
064        
065        try
066        {
067            // This is atypical validation - since this component does not explicitly bind to an object
068            getValidatableFieldSupport().validate(this, writer, cycle, value);
069
070            setValue(value != null);
071        }
072        catch (ValidatorException e)
073        {
074            getForm().getDelegate().record(e);
075        }
076    }
077
078    public abstract boolean getValue();
079
080    public abstract void setValue(boolean selected);
081
082    /**
083     * Injected.
084     */
085    public abstract ValidatableFieldSupport getValidatableFieldSupport();
086
087    /**
088     * @see org.apache.tapestry.form.AbstractFormComponent#isRequired()
089     */
090    public boolean isRequired()
091    {
092        return getValidatableFieldSupport().isRequired(this);
093    }
094}