001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.markup.html.form; 018 019import org.apache.wicket.WicketRuntimeException; 020import org.apache.wicket.markup.ComponentTag; 021import org.apache.wicket.markup.html.WebMarkupContainer; 022import org.apache.wicket.model.IModel; 023import org.apache.wicket.util.convert.ConversionException; 024import org.apache.wicket.util.visit.IVisit; 025import org.apache.wicket.util.visit.IVisitor; 026 027/** 028 * Component used to connect instances of Radio components into a group. Instances of Radio have to 029 * be in the component hierarchy somewhere below the group component. The model object of the group 030 * is set to the model object of the selected radio component or null if none selected. 031 * 032 * ie 033 * 034 * <pre> 035 * <span wicket:id="radiochoicegroup"> 036 * ... 037 * <input type="radio" wicket:id="singleradiochoice1"/>choice 1 038 * ... 039 * <input type="radio" wicket:id="singleradiochoice2"/>choice 2 040 * ... 041 * </span> 042 * </pre> 043 * 044 * @author Igor Vaynberg 045 * @author Sven Meier (svenmeier) 046 * 047 * @param <T> 048 * The model object type 049 */ 050public class RadioGroup<T> extends FormComponent<T> 051{ 052 private static final long serialVersionUID = 1L; 053 054 /** 055 * @see WebMarkupContainer#WebMarkupContainer(String) 056 */ 057 public RadioGroup(String id) 058 { 059 super(id); 060 setRenderBodyOnly(true); 061 } 062 063 /** 064 * @param id 065 * @param model 066 * @see WebMarkupContainer#WebMarkupContainer(String, IModel) 067 */ 068 public RadioGroup(String id, IModel<T> model) 069 { 070 super(id, model); 071 setRenderBodyOnly(true); 072 } 073 074 @Override 075 protected String getModelValue() 076 { 077 String radioValue = visitChildren(Radio.class, new IVisitor<Radio<T>, String>() 078 { 079 @Override 080 public void component(Radio<T> radio, IVisit<String> visit) 081 { 082 if (getModelComparator().compare(RadioGroup.this, radio.getDefaultModelObject())) 083 { 084 visit.stop(radio.getValue()); 085 } 086 } 087 }); 088 089 return radioValue; 090 } 091 092 /** 093 * @see org.apache.wicket.markup.html.form.FormComponent#convertValue(String[]) 094 */ 095 @Override 096 protected T convertValue(String[] input) throws ConversionException 097 { 098 if (input != null && input.length > 0) 099 { 100 final String value = input[0]; 101 102 // retrieve the selected single radio choice component 103 Radio<T> choice = visitChildren(Radio.class, 104 new org.apache.wicket.util.visit.IVisitor<Radio<T>, Radio<T>>() 105 { 106 107 @Override 108 public void component(final Radio<T> radio, final IVisit<Radio<T>> visit) 109 { 110 if (radio.getValue().equals(value)) 111 { 112 visit.stop(radio); 113 } 114 } 115 116 }); 117 118 if (choice == null) 119 { 120 throw new WicketRuntimeException( 121 "submitted http post value [" + 122 value + 123 "] for RadioGroup component [" + 124 getPath() + 125 "] is illegal because it does not point to a Radio component. " + 126 "Due to this the RadioGroup component cannot resolve the selected Radio component pointed to by the illegal value. A possible reason is that component hierarchy changed between rendering and form submission."); 127 } 128 129 130 // assign the value of the group's model 131 return choice.getModelObject(); 132 } 133 return null; 134 } 135 136 /** 137 * @see org.apache.wicket.markup.html.form.FormComponent#onComponentTag(org.apache.wicket.markup.ComponentTag) 138 */ 139 @Override 140 protected void onComponentTag(ComponentTag tag) 141 { 142 super.onComponentTag(tag); 143 // No longer applicable, breaks XHTML validation. 144 tag.remove("disabled"); 145 tag.remove("name"); 146 } 147}