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