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.field.factory;
35
36 import info.magnolia.i18nsystem.SimpleTranslator;
37 import info.magnolia.icons.MagnoliaIcons;
38
39 import java.util.ArrayList;
40 import java.util.Collection;
41 import java.util.List;
42 import java.util.stream.Collectors;
43 import java.util.stream.Stream;
44
45 import com.explicatis.ext_token_field.ExtTokenField;
46 import com.explicatis.ext_token_field.SimpleTokenizable;
47 import com.explicatis.ext_token_field.Tokenizable;
48 import com.vaadin.shared.Registration;
49 import com.vaadin.ui.Button;
50 import com.vaadin.ui.ComboBox;
51 import com.vaadin.ui.Component;
52 import com.vaadin.ui.CustomField;
53 import com.vaadin.ui.HorizontalLayout;
54
55 import lombok.RequiredArgsConstructor;
56
57
58
59
60
61
62
63 @RequiredArgsConstructor
64 public class TokenFieldWrapper<T> extends CustomField<Collection<String>> {
65
66 private final TokenField tokenField = new TokenField();
67 private final ComboBox<T> comboBox;
68 private final SimpleTranslator translator;
69 private Button removeAllTokensBtn;
70
71 @Override
72 public Collection<String> getValue() {
73 return tokenField.getValue().stream()
74 .map(Tokenizable::getStringValue)
75 .collect(Collectors.toList());
76 }
77
78
79 @Override
80 protected void doSetValue(Collection<String> strings) {
81 if (strings == null) {
82 tokenField.doSetValue(new ArrayList<>());
83 } else {
84 tokenField.doSetValue(toTokenizables(strings.stream()));
85 }
86 }
87
88 @Override
89 protected Component initContent() {
90 HorizontalLayout horizontalLayout = new HorizontalLayout();
91 horizontalLayout.setSpacing(false);
92 horizontalLayout.setStyleName("token-field-horizontal-layout");
93 comboBox.addValueChangeListener((ValueChangeListener<T>) event -> {
94 if (event.getValue() != null) {
95
96 tokenField.addTokenizable(new ToStringTokenizable(comboBox.getItemCaptionGenerator().apply(event.getValue())));
97 event.getSource().setValue(null);
98 }
99 });
100 tokenField.setTokenDragDropEnabled(true);
101 tokenField.setEnableDefaultDeleteTokenAction(true);
102 tokenField.setInputField(comboBox);
103 horizontalLayout.addComponent(tokenField);
104 removeAllTokensBtn = new Button(MagnoliaIcons.CLOSE);
105 removeAllTokensBtn.setDescription(translator.translate("fields.tokenField.remove.removeAllItems"));
106 removeAllTokensBtn.addStyleName("remove-all-tokens-button");
107 removeAllTokensBtn.addClickListener((event) -> {
108 tokenField.doSetValue(new ArrayList<>());
109 });
110 horizontalLayout.addComponent(removeAllTokensBtn);
111 return horizontalLayout;
112 }
113
114 @Override
115 public Registration addValueChangeListener(ValueChangeListener listener) {
116 tokenField.addValueChangeListener(listener);
117 return super.addValueChangeListener(listener);
118 }
119
120 @Override
121 public void setReadOnly(boolean readOnly) {
122 super.setReadOnly(readOnly);
123 tokenField.setReadOnly(readOnly);
124 }
125
126 private List<Tokenizable> toTokenizables(Stream<?> strings) {
127 return strings
128 .map(ToStringTokenizable::new)
129 .collect(Collectors.toList());
130 }
131
132 private static class ToStringTokenizable extends SimpleTokenizable {
133
134 private ToStringTokenizable(Object stringValue) {
135 super(stringValue.hashCode(), String.valueOf(stringValue));
136 }
137
138 @Override
139 public String toString() {
140 return getStringValue();
141 }
142 }
143
144 private static class TokenField extends ExtTokenField {
145
146 @Override
147 protected void doSetValue(List<Tokenizable> value) {
148 super.doSetValue(value);
149 }
150 }
151 }