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.extension;
35
36 import com.google.gwt.dom.client.Element;
37 import com.google.gwt.dom.client.Style;
38 import com.google.gwt.event.dom.client.KeyUpEvent;
39 import com.google.gwt.event.shared.HandlerRegistration;
40 import com.google.gwt.user.client.DOM;
41 import com.google.gwt.user.client.ui.HasValue;
42 import com.google.gwt.user.client.ui.Widget;
43 import com.vaadin.client.ServerConnector;
44 import com.vaadin.client.communication.StateChangeEvent;
45 import com.vaadin.client.extensions.AbstractExtensionConnector;
46 import com.vaadin.client.ui.AbstractComponentConnector;
47
48
49
50
51
52
53 public abstract class AbstractMaxLengthIndicatorExtensionConnector<T extends AbstractComponentConnector> extends AbstractExtensionConnector {
54
55 public static final String MAXLENGTH_INDICATOR_STYLE_NAME = "maxlength-indicator";
56
57 protected T textConnector;
58 private Widget textWidget;
59 private final Element indicatorElem = DOM.createDiv();
60 private int maxLength = 0;
61 private HandlerRegistration keyUpHandlerRegistration;
62 private com.google.web.bindery.event.shared.HandlerRegistration parentStateChangeHandlerRegistration;
63
64 abstract protected int getConnectorStateMaxLength();
65 abstract protected String getConnectorStateText();
66
67 @Override
68 protected void extend(ServerConnector target) {
69 textConnector = (T) target;
70 textWidget = textConnector.getWidget();
71
72 addHandlers();
73 updateIndicatorFromParentState();
74
75 textWidget.addAttachHandler(event -> {
76 if (event.isAttached()) {
77 assembleAndAttach();
78 }
79 });
80 }
81
82 @Override
83 public void onUnregister() {
84 super.onUnregister();
85 cleanUp();
86 }
87
88 private void cleanUp() {
89 if (keyUpHandlerRegistration != null) {
90 keyUpHandlerRegistration.removeHandler();
91 }
92 if (parentStateChangeHandlerRegistration != null) {
93 parentStateChangeHandlerRegistration.removeHandler();
94 }
95 if (indicatorElem.hasParentElement()) {
96 indicatorElem.removeFromParent();
97 }
98 }
99
100 private void assembleAndAttach() {
101
102 indicatorElem.addClassName(MAXLENGTH_INDICATOR_STYLE_NAME);
103 textWidget.getElement().getParentElement().appendChild(indicatorElem);
104 }
105
106 private void addHandlers() {
107
108
109
110 keyUpHandlerRegistration = textWidget.addDomHandler(event -> updateIndicatorValue(getInputValueLength()), KeyUpEvent.getType());
111
112
113 parentStateChangeHandlerRegistration = textConnector.addStateChangeHandler((StateChangeEvent.StateChangeHandler) stateChangeEvent -> {
114 if (stateChangeEvent.hasPropertyChanged("maxLength") || stateChangeEvent.hasPropertyChanged("text")) {
115 updateIndicatorFromParentState();
116 }
117 });
118 }
119
120 private void updateIndicatorFromParentState() {
121 maxLength = getConnectorStateMaxLength();
122 String text = getConnectorStateText();
123 updateIndicatorValue(text == null ? 0 : text.length());
124 setIndicatorVisible(maxLength >= 0);
125 }
126
127 private void setIndicatorVisible(boolean isVisible) {
128 if (isVisible) {
129 indicatorElem.getStyle().clearDisplay();
130 } else {
131 indicatorElem.getStyle().setDisplay(Style.Display.NONE);
132 }
133 }
134
135 private void updateIndicatorValue(int currentlyDisplayedCharactersAmount) {
136 indicatorElem.setInnerHTML(currentlyDisplayedCharactersAmount + "/" + maxLength);
137 }
138
139 private int getInputValueLength() {
140 return ((String)((HasValue)textWidget).getValue()).length();
141 }
142
143
144 }