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.tab.widget.FormTabWidget;
37 import info.magnolia.ui.vaadin.gwt.client.jquerywrapper.JQueryWrapper;
38 import info.magnolia.ui.vaadin.gwt.client.tabsheet.event.ActiveTabChangedEvent;
39 import info.magnolia.ui.vaadin.gwt.client.tabsheet.event.TabSetChangedEvent;
40 import info.magnolia.ui.vaadin.gwt.client.tabsheet.tab.widget.MagnoliaTabWidget;
41 import info.magnolia.ui.vaadin.gwt.client.tabsheet.widget.MagnoliaTabSheetView;
42
43 import java.util.ArrayList;
44 import java.util.List;
45
46 import com.google.gwt.event.dom.client.ClickEvent;
47 import com.google.gwt.event.dom.client.ClickHandler;
48 import com.google.gwt.event.dom.client.FocusEvent;
49 import com.google.gwt.event.dom.client.FocusHandler;
50 import com.google.gwt.user.client.DOM;
51 import com.google.gwt.user.client.Element;
52 import com.google.gwt.user.client.Event;
53 import com.google.gwt.user.client.ui.FlowPanel;
54 import com.google.gwt.user.client.ui.HTML;
55 import com.google.gwt.user.client.ui.Widget;
56 import com.vaadin.client.Util;
57
58
59
60
61
62 public class FormViewImpl extends FlowPanel implements FormView {
63
64 private static final String CLASSNAME = "form-panel";
65
66 private static final String CLASSNAME_CONTENT = "form-content";
67
68 private static final String ClASSNAME_ERROR = "form-error";
69
70 private final List<FormTabWidget> formTabs = new ArrayList<FormTabWidget>();
71
72 private final Element contentEl = DOM.createDiv();
73
74 private FormFieldWrapper lastFocused = null;
75
76 private MagnoliaTabSheetView tabSheet;
77
78 private Presenter presenter;
79
80 private boolean hasErrors = false;
81
82 private FlowPanel errorPanel = new FlowPanel();
83
84 private String errorsLabel;
85
86 private String nextErrorLabel;
87
88 public FormViewImpl() {
89 super();
90 setStylePrimaryName(CLASSNAME);
91
92 errorPanel.addStyleName(ClASSNAME_ERROR);
93 errorPanel.setVisible(false);
94 add(errorPanel);
95
96 contentEl.addClassName(CLASSNAME_CONTENT);
97 getElement().appendChild(contentEl);
98 }
99
100 @Override
101 public void setContent(Widget contentWidget) {
102 if (contentWidget instanceof MagnoliaTabSheetView) {
103 if (tabSheet != null) {
104 remove(tabSheet);
105 }
106
107 this.tabSheet = (MagnoliaTabSheetView) contentWidget;
108 tabSheet.addTabSetChangedHandler(new TabSetChangedEvent.Handler() {
109 @Override
110 public void onTabSetChanged(TabSetChangedEvent event) {
111 final List<MagnoliaTabWidget> tabs = event.getTabSheet().getTabs();
112 formTabs.clear();
113 for (final MagnoliaTabWidget tab : tabs) {
114 if (tab instanceof FormTabWidget) {
115 formTabs.add((FormTabWidget) tab);
116 }
117 }
118 }
119 });
120
121 tabSheet.addActiveTabChangedHandler(new ActiveTabChangedEvent.Handler() {
122 @Override
123 public void onActiveTabChanged(ActiveTabChangedEvent event) {
124
125 if (!hasErrors) {
126 if (!event.isShowingAllTabs()) {
127 focusFirstFieldInTab((FormTabWidget) event.getTab());
128 } else {
129 focusFirstFieldInTab(formTabs.get(0));
130 }
131 }
132
133
134 lastFocused = null;
135 if (!event.isShowingAllTabs()) {
136 setFieldFocusHandler((FormTabWidget) event.getTab());
137 } else {
138 for (FormTabWidget tab : formTabs) {
139 setFieldFocusHandler(tab);
140 }
141 }
142 }
143
144 private void focusFirstFieldInTab(FormTabWidget tab) {
145 if (tab.getFields().isEmpty()) {
146 return;
147 }
148 FormFieldWrapper firstField = tab.getFields().get(0);
149 firstField.focusField();
150 }
151
152 private void setFieldFocusHandler(FormTabWidget tab) {
153 final List<FormFieldWrapper> fields = tab.getFields();
154 for (final FormFieldWrapper field : fields) {
155 field.addFocusHandler(new FocusHandler() {
156 @Override
157 public void onFocus(FocusEvent event) {
158 final Element target = event.getRelativeElement().cast();
159 lastFocused = Util.findWidget(target, FormFieldWrapper.class);
160 }
161 });
162 }
163 }
164 });
165 add(tabSheet.asWidget(), contentEl);
166 }
167 }
168
169 @Override
170 public void setErrorsLabel(String errorsLabel) {
171 this.errorsLabel = errorsLabel;
172 }
173
174 @Override
175 public void setNextErrorLabel(String nextErrorLabel) {
176 this.nextErrorLabel = nextErrorLabel;
177 }
178
179 @Override
180 public void setErrorAmount(int totalProblematicFields) {
181 hasErrors = (totalProblematicFields > 0);
182
183 errorPanel.setVisible(totalProblematicFields > 0);
184 if (totalProblematicFields > 0) {
185 String formattedTotal = String.valueOf(totalProblematicFields);
186 errorPanel.getElement().setInnerHTML("<span>" + errorsLabel.replaceFirst("#", formattedTotal) + "</span>");
187 final HTML errorButton = new HTML("[" + nextErrorLabel + "]");
188 errorButton.setStyleName("action-jump-to-next-error");
189 DOM.sinkEvents(errorButton.getElement(), Event.MOUSEEVENTS);
190 errorButton.addDomHandler(new ClickHandler() {
191 @Override
192 public void onClick(ClickEvent event) {
193 jumpToNextError();
194 }
195 }, ClickEvent.getType());
196 errorPanel.add(errorButton);
197 presenter.onErrorsDisplayed();
198 }
199 }
200
201 @Override
202 public void setPresenter(final Presenter presenter) {
203 this.presenter = presenter;
204 }
205
206 @Override
207 public void setDescriptionVisible(boolean isVisible) {
208 for (final FormTabWidget tab : formTabs) {
209 tab.setDescriptionVisible(isVisible);
210 }
211 }
212
213 public void jumpToNextError() {
214 presenter.jumpToNextError(lastFocused);
215 }
216
217 @Override
218 public void setMaxHeight(int height) {
219 if (this.hasErrors) {
220 height -= JQueryWrapper.select(errorPanel).marginHeight();
221 }
222 if (this.tabSheet != null) {
223 this.tabSheet.setMaxHeight(height);
224 }
225 }
226 }