1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.vaadin.gwt.client.form.widget;
35
36 import info.magnolia.ui.vaadin.gwt.client.form.formsection.widget.InlineMessageWidget;
37
38 import com.google.gwt.dom.client.Element;
39 import com.google.gwt.dom.client.SpanElement;
40 import com.google.gwt.event.dom.client.BlurEvent;
41 import com.google.gwt.event.dom.client.BlurHandler;
42 import com.google.gwt.event.dom.client.ClickEvent;
43 import com.google.gwt.event.dom.client.ClickHandler;
44 import com.google.gwt.event.dom.client.FocusEvent;
45 import com.google.gwt.event.dom.client.FocusHandler;
46 import com.google.gwt.event.dom.client.HasBlurHandlers;
47 import com.google.gwt.event.dom.client.HasFocusHandlers;
48 import com.google.gwt.event.shared.HandlerRegistration;
49 import com.google.gwt.regexp.shared.MatchResult;
50 import com.google.gwt.regexp.shared.RegExp;
51 import com.google.gwt.user.client.DOM;
52 import com.google.gwt.user.client.ui.Button;
53 import com.google.gwt.user.client.ui.FlowPanel;
54 import com.google.gwt.user.client.ui.Widget;
55 import com.google.gwt.user.client.ui.impl.FocusImpl;
56 import com.vaadin.client.ui.aria.AriaHelper;
57
58
59
60
61 public class FormFieldWrapper extends FlowPanel implements HasFocusHandlers, HasBlurHandlers {
62
63 private final static RegExp localisedPropertyCaptionPattern = RegExp.compile("^(.+)\\s(\\([a-zA-Z]{2}\\))$");
64
65 private Element label = DOM.createDiv();
66
67 private Element fieldWrapper = DOM.createDiv();
68
69 private Element root;
70
71 private Element requirementAsterisk = null;
72
73 private final HelpIconWidget helpButton = new HelpIconWidget();
74
75 private Button errorAction = new Button();
76
77 private InlineMessageWidget errorSection = null;
78
79 private InlineMessageWidget helpSection = null;
80
81 private String helpDescription = null;
82
83 private Widget field = null;
84
85 public FormFieldWrapper() {
86 super();
87 addStyleName("v-form-field-section");
88 root = super.getElement();
89 construct();
90 setHelpEnabled(false);
91
92 helpButton.addDomHandler(new ClickHandler() {
93 @Override
94 public void onClick(ClickEvent event) {
95 if (helpSection == null) {
96 showHelp();
97 } else {
98 hideHelp();
99 }
100 }
101 }, ClickEvent.getType());
102
103 }
104
105 public void hideHelp() {
106 if (helpSection != null) {
107 remove(helpSection);
108 }
109 helpSection = null;
110 helpButton.setHighlighted(false);
111 }
112
113 public void showHelp() {
114 if (helpDescription == null || "".equals(helpDescription)) {
115 return;
116 }
117 helpSection = InlineMessageWidget.createHelpMessage();
118 helpSection.setMessage(helpDescription);
119 add(helpSection, root);
120 helpButton.setHighlighted(true);
121 }
122
123 private void construct() {
124 label.addClassName("v-form-field-label");
125 fieldWrapper.addClassName("v-form-field-container");
126 errorAction.addStyleName("action-validation");
127
128 root.appendChild(label);
129 root.appendChild(fieldWrapper);
130 add(helpButton, fieldWrapper);
131 add(errorAction, fieldWrapper);
132 }
133
134 public void showError(final String errorDescription) {
135 helpButton.setVisible(false);
136 errorAction.setVisible(true);
137 fieldWrapper.addClassName("validation-highlight");
138 if (errorSection == null) {
139 errorSection = InlineMessageWidget.createErrorMessage();
140 }
141 errorSection.setMessage(errorDescription);
142 add(errorSection, root);
143 }
144
145 public void setCaption(String caption) {
146 final MatchResult localisedPropertyMatcher = localisedPropertyCaptionPattern.exec(caption);
147 if (localisedPropertyMatcher != null && localisedPropertyMatcher.getGroupCount() > 2) {
148 caption = localisedPropertyMatcher.getGroup(1);
149 label.setInnerText(caption);
150
151 final Element localeLabel = SpanElement.as(DOM.createSpan());
152 localeLabel.setClassName("locale-label");
153 localeLabel.setInnerText(localisedPropertyMatcher.getGroup(2));
154
155 if (requirementAsterisk != null && label.isOrHasChild(requirementAsterisk)) {
156 label.insertAfter(localeLabel, requirementAsterisk);
157 } else {
158 label.insertFirst(localeLabel);
159 }
160 } else {
161 label.setInnerText(caption);
162 }
163
164 if (caption != null) {
165 label.setTitle(caption);
166 }
167 }
168
169 public void setRequired(boolean required) {
170 if (required) {
171 if (requirementAsterisk == null) {
172 requirementAsterisk = SpanElement.as(DOM.createSpan());
173 requirementAsterisk.setClassName("requiredfield");
174 requirementAsterisk.setInnerText("*");
175 }
176 label.insertFirst(requirementAsterisk);
177 } else if (requirementAsterisk != null && label.isOrHasChild(requirementAsterisk)) {
178 label.removeChild(requirementAsterisk);
179 }
180 }
181
182 @Override
183 public void add(Widget child) {
184 add(child, fieldWrapper);
185 }
186
187 public void setField(Widget child) {
188 if (this.field != null) {
189 remove(field);
190 }
191 this.field = child;
192 if (child != null) {
193 child.removeFromParent();
194 AriaHelper.bindCaption(child, label);
195 getChildren().add(child);
196 fieldWrapper.insertBefore(child.getElement(), helpButton.getElement());
197 adopt(child);
198 }
199 }
200
201 public boolean isDisplayingHelpSection() {
202 return helpSection != null;
203 }
204
205 public void clearError() {
206 if (errorSection != null) {
207 remove(errorSection);
208 errorSection = null;
209 }
210 fieldWrapper.removeClassName("validation-highlight");
211 errorAction.setVisible(false);
212 if (helpDescription != null && !"".equals(helpDescription)) {
213 helpButton.setVisible(true);
214 }
215 }
216
217 public void setHelpEnabled(boolean isHelpEnabled) {
218 helpButton.setVisible(helpDescription != null && !"".equals(helpDescription) && !errorAction.isVisible());
219 if (!isHelpEnabled && helpSection != null) {
220 hideHelp();
221 return;
222 }
223 if (isHelpEnabled && helpButton.isVisible() && helpSection == null) {
224 showHelp();
225 }
226 }
227
228 public void setHelpDescription(String description) {
229 this.helpDescription = description;
230 if (helpSection != null && getWidgetIndex(helpSection) >= 0) {
231 helpSection.setMessage(helpDescription);
232 }
233 if (description != null && !"".equals(description)) {
234 helpButton.setVisible(true);
235 } else {
236 helpButton.setVisible(false);
237 }
238 }
239
240 public void focusField() {
241 if (field != null) {
242 FocusImpl.getFocusImplForWidget().focus(field.getElement());
243 }
244 }
245
246 public Widget getField() {
247 return field;
248 }
249
250 @Override
251 public HandlerRegistration addFocusHandler(FocusHandler handler) {
252 return field.addDomHandler(handler, FocusEvent.getType());
253 }
254
255 @Override
256 public HandlerRegistration addBlurHandler(BlurHandler handler) {
257 return field.addDomHandler(handler, BlurEvent.getType());
258 }
259 }