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.form.field;
35
36 import info.magnolia.icons.MagnoliaIcons;
37 import info.magnolia.ui.vaadin.gwt.client.form.field.FieldLayoutState;
38
39 import java.util.function.Consumer;
40
41 import org.apache.commons.lang3.StringUtils;
42 import org.vaadin.jonatan.contexthelp.ContextHelp;
43
44 import com.google.common.base.Preconditions;
45 import com.vaadin.shared.ui.ContentMode;
46 import com.vaadin.ui.AbstractField;
47 import com.vaadin.ui.Button;
48 import com.vaadin.ui.Component;
49 import com.vaadin.ui.HorizontalLayout;
50 import com.vaadin.ui.Label;
51 import com.vaadin.ui.TabSheet;
52 import com.vaadin.ui.UI;
53 import com.vaadin.ui.VerticalLayout;
54
55
56
57
58 public class FieldLayout extends VerticalLayout implements Component.Focusable {
59
60 private final ContextHelp contextHelp;
61
62 private Label statusLabel;
63 private final Component field;
64 private final String description;
65
66 public static FieldLayout of(Component field, String description) {
67 return new FieldLayout(field, description);
68 }
69
70 private FieldLayout(Component field, String description) {
71 Preconditions.checkNotNull(field);
72 this.field = field;
73 this.description = description;
74 this.contextHelp = UI.getCurrent().getExtensions().stream()
75 .filter(ContextHelp.class::isInstance)
76 .findFirst()
77 .map(ContextHelp.class::cast)
78 .orElse(null);
79 initContent();
80 }
81
82 private void initContent() {
83 setMargin(false);
84 setVisible(field.isVisible());
85
86 statusLabel = new Label(null, ContentMode.HTML);
87 statusLabel.setVisible(false);
88 statusLabel.addStyleName("validation-display");
89
90 Component horizontalLayout = field;
91 if (contextHelp != null && hasTranslatedDescription()) {
92 final Button helpButton = new Button(MagnoliaIcons.HELP_MARK);
93 helpButton.addStyleName("help-button v-button-icon icon-button");
94
95 contextHelp.extend(UI.getCurrent());
96 contextHelp.addHelpForComponent(helpButton, description);
97
98 helpButton.addClickListener(event -> {
99 contextHelp.showHelpFor(helpButton);
100 });
101 HorizontalLayout descriptionLayout = new HorizontalLayout(field, helpButton);
102 descriptionLayout.addStyleName("help-button-field-layout");
103 descriptionLayout.setSizeFull();
104 descriptionLayout.setExpandRatio(field, 1);
105 descriptionLayout.setExpandRatio(helpButton, 0);
106 descriptionLayout.setSpacing(false);
107 horizontalLayout = descriptionLayout;
108 }
109 addComponents(horizontalLayout, statusLabel);
110 }
111
112 @Override
113 public void setCaption(String caption) {
114 super.setCaption(caption);
115 }
116
117 @Override
118 public void setRequiredIndicatorVisible(boolean visible) {
119 if (field instanceof AbstractField) {
120 ((AbstractField) field).setRequiredIndicatorVisible(false);
121 }
122 getState().required = visible;
123 }
124
125 @Override
126 protected boolean isRequiredIndicatorVisible() {
127 return getState().required;
128 }
129
130 @Override
131 protected FieldLayoutState getState() {
132 return (FieldLayoutState) super.getState();
133 }
134
135 @Override
136 public void focus() {
137 performTabSelection(field);
138 if (field instanceof Focusable) {
139 ((Focusable) field).focus();
140 }
141 }
142
143 @Override
144 public int getTabIndex() {
145 return 0;
146 }
147
148 @Override
149 public void setTabIndex(int tabIndex) {
150 }
151
152 public Consumer<String> getValidationStatusHandler() {
153 return errorMessage -> {
154 statusLabel.setValue(errorMessage);
155 if (errorMessage.isEmpty()) {
156 field.removeStyleName("error");
157 statusLabel.setVisible(false);
158 } else {
159 field.addStyleName("error");
160
161 statusLabel.setVisible(true);
162 }
163 };
164 }
165
166 public Component getField() {
167 return field;
168 }
169
170 private boolean hasTranslatedDescription() {
171 return StringUtils.isNotEmpty(description) && (StringUtils.endsWith(description, ".") || !StringUtils.contains(description, ".") || StringUtils.contains(description, " "));
172 }
173
174
175
176
177 private void performTabSelection(Component f) {
178 Component t = f;
179 do {
180 f = t;
181 t = f.getParent();
182 } while (!(t == null || t instanceof TabSheet));
183 if (t != null) {
184 ((TabSheet) t).setSelectedTab(f);
185 }
186 }
187 }