1 24 package org.riotfamily.forms.element; 25 26 import org.riotfamily.forms.AbstractEditorBase; 27 import org.riotfamily.forms.BeanEditor; 28 import org.riotfamily.forms.Container; 29 import org.riotfamily.forms.ContainerElement; 30 import org.riotfamily.forms.Editor; 31 import org.riotfamily.forms.EditorBinder; 32 import org.riotfamily.forms.Element; 33 import org.riotfamily.forms.MessageUtils; 34 import org.riotfamily.forms.TemplateUtils; 35 import org.riotfamily.forms.event.Button; 36 import org.riotfamily.forms.event.JavaScriptEvent; 37 import org.riotfamily.forms.request.FormRequest; 38 import org.riotfamily.forms.support.MapOrBeanWrapper; 39 import org.springframework.util.Assert; 40 41 44 public class NestedForm extends TemplateElement implements 45 ContainerElement, Editor, BeanEditor { 46 47 private EditorBinder editorBinder; 48 49 private Container elements = new Container(); 50 51 private boolean present; 52 53 private boolean indent = true; 54 55 private String buttonLabelKeySet = "form.nestedForm.set"; 56 57 private String buttonLabelKeyRemove = "form.nestedForm.remove"; 58 59 public NestedForm() { 60 super("form"); 61 addComponent("elements", elements); 62 addComponent("toggleButton", new ToggleButton()); 63 } 64 65 public void setIndent(boolean indent) { 66 this.indent = indent; 67 setTemplate(TemplateUtils.getTemplatePath(NestedForm.class, 68 indent ? null : "_noindent")); 69 } 70 71 protected void setEditorBinder(EditorBinder editorBinder) { 72 this.editorBinder = editorBinder; 73 } 74 75 public void setBeanClass(Class beanClass) { 76 EditorBinder editorBinder = new EditorBinder(new MapOrBeanWrapper(beanClass)); 77 setEditorBinder(editorBinder); 78 } 79 80 84 protected void afterBindingSet() { 85 if (editorBinder == null) { 86 setBeanClass(getEditorBinding().getPropertyType()); 87 } 88 editorBinder.setParent(getEditorBinding()); 89 } 90 91 public Editor getEditor(String property) { 92 return editorBinder.getEditor(property); 93 } 94 95 protected void afterFormContextSet() { 96 editorBinder.registerPropertyEditors( 97 getFormContext().getPropertyEditorRegistrars()); 98 } 99 100 public String getLabel() { 101 return indent ? super.getLabel() : null; 102 } 103 104 public boolean isPresent() { 105 return present; 106 } 107 108 protected void toggle() { 109 present = !present; 110 if (getFormListener() != null) { 111 getFormListener().elementChanged(this); 112 } 113 } 114 115 public void processRequest(FormRequest request) { 116 if (present || isRequired()) { 117 super.processRequest(request); 118 } 119 } 120 121 127 public void setValue(Object value) { 128 this.present = isRequired() || value != null; 129 editorBinder.setBackingObject(value); 130 editorBinder.initEditors(); 131 } 132 133 139 public Object getValue() { 140 if (present || isRequired()) { 142 return editorBinder.populateBackingObject(); 143 } 144 return null; 145 } 146 147 public void bind(Editor editor, String property) { 148 Assert.notNull(editorBinder, "The NestedForm must either be bound " + 149 "to a property or setBeanClass() must be invoked before " + 150 "nested editors can be added."); 151 152 editorBinder.bind(editor, property); 153 } 154 155 public void addElement(Element element) { 156 elements.addElement(element); 157 } 158 159 public void addElement(Editor element, String property) { 160 addElement(element); 161 bind(element, property); 162 } 163 164 public void removeElement(Element element) { 165 elements.removeElement(element); 166 } 167 168 public String getProperty() { 169 if (getEditorBinding() == null) { 170 return null; 171 } 172 return getEditorBinding().getProperty(); 173 } 174 175 private class ToggleButton extends Button { 176 177 private ToggleButton() { 178 setCssClass("button button-toggle"); 179 setTabIndex(2); 180 } 181 182 public String getLabel() { 183 String key = present ? buttonLabelKeyRemove : buttonLabelKeySet; 184 String label = MessageUtils.getMessage(this, key); 185 if (label == null) { 186 label = present ? "Remove" : "Set"; 187 } 188 return label; 189 } 190 191 protected void onClick() { 192 toggle(); 193 } 194 195 public int getEventTypes() { 196 return JavaScriptEvent.ON_CLICK; 197 } 198 } 199 } | Popular Tags |