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 015 package org.apache.tapestry.form; 016 017 import org.apache.tapestry.IMarkupWriter; 018 import org.apache.tapestry.IRequestCycle; 019 import org.apache.tapestry.valid.IValidationDelegate; 020 import org.apache.tapestry.valid.ValidatorException; 021 022 /** 023 * Implements a component that manages an HTML <input type=checkbox> form element. [ <a 024 * href="../../../../../ComponentReference/Checkbox.html">Component Reference </a>] 025 * <p> 026 * As of 4.0, this component can be validated. 027 * 028 * @author Howard Lewis Ship 029 * @author Paul Ferraro 030 */ 031 public abstract class Checkbox extends AbstractFormComponent implements ValidatableField 032 { 033 /** 034 * @see org.apache.tapestry.form.validator.AbstractRequirableField#renderRequirableFormComponent(org.apache.tapestry.IMarkupWriter, 035 * org.apache.tapestry.IRequestCycle) 036 */ 037 protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle) 038 { 039 renderDelegatePrefix(writer, cycle); 040 041 writer.beginEmpty("input"); 042 writer.attribute("type", "checkbox"); 043 044 writer.attribute("name", getName()); 045 046 if (isDisabled()) 047 writer.attribute("disabled", "disabled"); 048 049 // write out submitted input for case of validation errors 050 051 IValidationDelegate delegate = getForm().getDelegate(); 052 boolean checked = getValue(); 053 if (delegate != null && delegate.isInError()) { 054 055 checked = Boolean.valueOf(delegate.getFieldInputValue()).booleanValue(); 056 } 057 058 if (checked) { 059 writer.attribute("checked", "checked"); 060 } 061 062 renderIdAttribute(writer, cycle); 063 064 getValidatableFieldSupport().renderContributions(this, writer, cycle); 065 066 renderInformalParameters(writer, cycle); 067 068 writer.closeTag(); 069 070 renderDelegateSuffix(writer, cycle); 071 } 072 073 /** 074 * In traditional HTML, many checkboxes would have the same name but different values. Under 075 * Tapestry, it makes more sense to have different names and a fixed value. For a checkbox, we 076 * only care about whether the name appears as a request parameter. 077 */ 078 protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle) 079 { 080 String value = cycle.getParameter(getName()); 081 082 try 083 { 084 // This is atypical validation - since this component does not explicitly bind to an object 085 086 getValidatableFieldSupport().validate(this, writer, cycle, value); 087 088 setValue(value != null); 089 } 090 catch (ValidatorException e) 091 { 092 getForm().getDelegate().record(e); 093 getForm().getDelegate().recordFieldInputValue(Boolean.valueOf(value).toString()); 094 } 095 } 096 097 public abstract boolean getValue(); 098 099 public abstract void setValue(boolean selected); 100 101 /** 102 * Injected. 103 */ 104 public abstract ValidatableFieldSupport getValidatableFieldSupport(); 105 106 /** 107 * @see org.apache.tapestry.form.AbstractFormComponent#isRequired() 108 */ 109 public boolean isRequired() 110 { 111 return getValidatableFieldSupport().isRequired(this); 112 } 113 }