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.form.field;
35
36 import info.magnolia.objectfactory.ComponentProvider;
37 import info.magnolia.objectfactory.Components;
38 import info.magnolia.ui.api.app.AppController;
39 import info.magnolia.ui.api.context.UiContext;
40 import info.magnolia.ui.form.field.component.ContentPreviewComponent;
41 import info.magnolia.ui.form.field.converter.IdentifierToPathConverter;
42 import info.magnolia.ui.form.field.definition.LinkFieldDefinition;
43
44 import org.apache.commons.lang3.StringUtils;
45
46 import com.vaadin.data.Property;
47 import com.vaadin.data.util.converter.Converter.ConversionException;
48 import com.vaadin.server.ErrorMessage;
49 import com.vaadin.server.UserError;
50 import com.vaadin.ui.Alignment;
51 import com.vaadin.ui.Button;
52 import com.vaadin.ui.Component;
53 import com.vaadin.ui.CustomField;
54 import com.vaadin.ui.HorizontalLayout;
55 import com.vaadin.ui.NativeButton;
56 import com.vaadin.ui.TextField;
57 import com.vaadin.ui.VerticalLayout;
58
59
60
61
62
63
64 public class LinkField extends CustomField<String> {
65
66
67
68
69 private final class LinkFieldTextBox extends TextField {
70 @Override
71 public void fireValueChange(boolean repaintIsNotNeeded) {
72 super.fireValueChange(repaintIsNotNeeded);
73 }
74 }
75
76
77 private final VerticalLayout rootLayout = new VerticalLayout();
78 private final HorizontalLayout linkLayout = new HorizontalLayout();
79 private final LinkFieldTextBox textField = new LinkFieldTextBox();
80 private final Button selectButton = new NativeButton();
81
82 private final IdentifierToPathConverter converter;
83 private final LinkFieldDefinition definition;
84 private String buttonCaptionNew;
85 private String buttonCaptionOther;
86
87 private final ComponentProvider componentProvider;
88
89 public LinkField(LinkFieldDefinition linkFieldDefinition, ComponentProvider componentProvider) {
90 this.definition = linkFieldDefinition;
91 this.converter = definition.getIdentifierToPathConverter();
92 if (this.converter != null) {
93 this.converter.setWorkspaceName(definition.getTargetWorkspace());
94 }
95 this.componentProvider = componentProvider;
96 setImmediate(true);
97 }
98
99 @Deprecated
100 public LinkField(LinkFieldDefinition linkFieldDefinition, AppController appController, UiContext uiContext, ComponentProvider componentProvider) {
101 this(linkFieldDefinition, componentProvider);
102 }
103
104 @Override
105 protected Component initContent() {
106 addStyleName("linkfield");
107
108 rootLayout.setSizeFull();
109 rootLayout.setSpacing(true);
110
111 textField.setImmediate(true);
112 textField.setWidth(100, Unit.PERCENTAGE);
113 textField.setNullRepresentation("");
114 textField.setNullSettingAllowed(true);
115
116 linkLayout.setSizeFull();
117 linkLayout.addComponent(textField);
118 linkLayout.setExpandRatio(textField, 1);
119 linkLayout.setComponentAlignment(textField, Alignment.MIDDLE_LEFT);
120
121 if (!textField.isReadOnly()) {
122 selectButton.addStyleName("magnoliabutton");
123 linkLayout.addComponent(selectButton);
124 linkLayout.setExpandRatio(selectButton, 0);
125 linkLayout.setComponentAlignment(selectButton, Alignment.MIDDLE_RIGHT);
126 }
127 setButtonCaption(StringUtils.EMPTY);
128 rootLayout.addComponent(linkLayout);
129
130
131 if (definition.getContentPreviewDefinition() != null && definition.getContentPreviewDefinition().getContentPreviewClass() != null) {
132 registerContentPreview();
133 }
134 return rootLayout;
135 }
136
137 public TextField getTextField() {
138 return this.textField;
139 }
140
141 public Button getSelectButton() {
142 return this.selectButton;
143 }
144
145 @Override
146 public String getValue() {
147 return textField.getValue();
148 }
149
150 @Override
151 public void setValue(String newValue) throws ReadOnlyException, ConversionException {
152 textField.setValue(newValue);
153 }
154
155
156
157
158
159
160 private void updateComponents(String currentValue) {
161 if (!definition.isFieldEditable() && StringUtils.isNotBlank(currentValue)) {
162 textField.setReadOnly(true);
163 if (linkLayout.getComponentIndex(selectButton) != -1) {
164 linkLayout.removeComponent(selectButton);
165 }
166 } else {
167 setButtonCaption(currentValue);
168 }
169 }
170
171
172
173
174
175 @Override
176 @SuppressWarnings("rawtypes")
177 public void setPropertyDataSource(Property newDataSource) {
178 if (converter != null) {
179 textField.setConverter(converter);
180 }
181 textField.setPropertyDataSource(newDataSource);
182 textField.addValueChangeListener(new ValueChangeListener() {
183 @Override
184 public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
185 String value = event.getProperty().getValue() != null ? event.getProperty().getValue().toString() : StringUtils.EMPTY;
186 updateComponents(value);
187 }
188 });
189
190 super.setPropertyDataSource(newDataSource);
191 }
192
193 @Override
194 @SuppressWarnings("rawtypes")
195 public Property getPropertyDataSource() {
196 return textField.getPropertyDataSource();
197 }
198
199 @Override
200 public Class<String> getType() {
201 return String.class;
202 }
203
204 private void setButtonCaption(String value) {
205 if (StringUtils.isNotBlank(value)) {
206 selectButton.setCaption(buttonCaptionOther);
207 selectButton.setDescription(buttonCaptionOther);
208 } else {
209 selectButton.setCaption(buttonCaptionNew);
210 selectButton.setDescription(buttonCaptionNew);
211 }
212 }
213
214 private void registerContentPreview() {
215 final ContentPreviewComponent<?> contentPreviewComponent = Components.newInstance(definition.getContentPreviewDefinition().getContentPreviewClass(), definition.getTargetWorkspace(), componentProvider);
216 textField.addValueChangeListener(new ValueChangeListener() {
217 @Override
218 public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
219 String itemReference = event.getProperty().getValue().toString();
220 contentPreviewComponent.onValueChange(itemReference);
221 }
222 });
223 rootLayout.addComponentAsFirst(contentPreviewComponent);
224 if (StringUtils.isNotBlank(textField.getValue())) {
225 textField.fireValueChange(false);
226 }
227 }
228
229
230
231
232 public void setButtonCaptionNew(String buttonCaptionNew) {
233 this.buttonCaptionNew = buttonCaptionNew;
234 }
235
236 public void setButtonCaptionOther(String buttonCaptionOther) {
237 this.buttonCaptionOther = buttonCaptionOther;
238 }
239
240 @Override
241 public boolean isValid() {
242 if (this.isRequired() && StringUtils.isBlank(getValue())) {
243 return false;
244 }
245 return true;
246 }
247
248 @Override
249 public ErrorMessage getErrorMessage() {
250 if (this.isRequired() && StringUtils.isBlank(getValue())) {
251 return new UserError(getRequiredError());
252 }
253 return null;
254 }
255
256 }