2222
2323import com .google .gwt .dom .client .Document ;
2424import com .google .gwt .event .dom .client .*;
25- import com .google .gwt .event .logical .shared .SelectionEvent ;
26- import com .google .gwt .event .logical .shared .SelectionHandler ;
27- import com .google .gwt .event .logical .shared .ValueChangeEvent ;
28- import com .google .gwt .event .logical .shared .ValueChangeHandler ;
25+ import com .google .gwt .event .logical .shared .*;
2926import com .google .gwt .event .shared .HandlerRegistration ;
3027import com .google .gwt .user .client .DOM ;
3128import com .google .gwt .user .client .ui .*;
6663 * {@code
6764 * <ma:autocomplete.MaterialAutoComplete ui:field="autocomplete" placeholder="States" />}
6865 * </pre>
69- *
66+ *
7067 * <h3>Java Usage:</h3>
71- *
68+ *
7269 * <p>
7370 * To use your domain object inside the MaterialAutoComplete, for example, an object
7471 * "User", you can subclass the {@link gwt.material.design.addins.client.autocomplete.base.MaterialSuggestionOracle} and {@link Suggestion}, like this:
7572 * </p>
7673 * <p><pre>
7774 * public class UserOracle extends MaterialSuggestionOracle {
7875 * private List<User> contacts = new LinkedList<>();
79- *
76+ *
8077 * public void addContacts(List<User> users){
8178 * contacts.addAll(users);
8279 * }
83- *
80+ *
8481 * {@literal @}Override
8582 * public void requestSuggestions(final Request request, final Callback callback) {
8683 * Response resp = new Response();
9087 * }
9188 * String text = request.getQuery();
9289 * text = text.toLowerCase();
93- *
90+ *
9491 * List<UserSuggestion> list = new ArrayList<>();
95- *
92+ *
9693 * /{@literal *}
9794 * {@literal *} Finds the contacts that meets the criteria. Note that since the
9895 * {@literal *} requestSuggestions method is asynchronous, you can fetch the
107104 * callback.onSuggestionsReady(request, resp);
108105 * }
109106 * }
110- *
107+ *
111108 * public class UserSuggestion implements SuggestOracle.Suggestion {
112- *
109+ *
113110 * private User user;
114- *
111+ *
115112 * public UserSuggestion(User user){
116113 * this.user = user;
117114 * }
118- *
115+ *
119116 * {@literal @}Override
120117 * public String getDisplayString() {
121118 * return getReplacementString();
122119 * }
123- *
120+ *
124121 * {@literal @}Override
125122 * public String getReplacementString() {
126123 * return user.getName();
127124 * }
128- *
125+ *
129126 * public User getUser() {
130127 * return user;
131128 * }
137134 * <p><pre>
138135 * //Constructor
139136 * MaterialAutoComplete userAutoComplete = new MaterialAutoComplete(new UserOracle());
140- *
137+ *
141138 * //How to get the selected User objects
142139 * public List<User> getSelectedUsers(){
143140 * List<? extends Suggestion> values = userAutoComplete.getValue();
159156 */
160157// @formatter:on
161158public class MaterialAutoComplete extends MaterialWidget implements HasError , HasPlaceholder ,
162- HasValue <List <? extends Suggestion >>, HasProgress , HasKeyUpHandlers , HasType <AutocompleteType > {
159+ HasValue <List <? extends Suggestion >>, HasProgress , HasKeyUpHandlers , HasType <AutocompleteType >, HasSelectionHandlers < Suggestion > {
163160
164161 static {
165162 if (MaterialResourceInjector .isDebug ()) {
@@ -185,7 +182,7 @@ public class MaterialAutoComplete extends MaterialWidget implements HasError, Ha
185182 private MaterialChipProvider chipProvider = new DefaultMaterialChipProvider ();
186183
187184 private final ErrorMixin <MaterialAutoComplete , MaterialLabel > errorMixin = new ErrorMixin <>(this ,
188- lblError , list );
185+ lblError , list );
189186 public final CssTypeMixin <AutocompleteType , MaterialAutoComplete > typeMixin = new CssTypeMixin <>(this );
190187
191188 /**
@@ -242,26 +239,46 @@ public void onKeyDown(KeyDownEvent event) {
242239 boolean itemsChanged = false ;
243240
244241 switch (event .getNativeKeyCode ()) {
245- case KeyCodes .KEY_ENTER :
246- if (directInputAllowed ) {
247- String value = itemBox .getValue ();
248- if (value != null && !(value = value .trim ()).isEmpty ()) {
249- gwt .material .design .client .base .Suggestion directInput = new gwt .material .design .client .base .Suggestion ();
250- directInput .setDisplay (value );
251- directInput .setSuggestion (value );
252- itemsChanged = addItem (directInput );
253- itemBox .setValue ("" );
254- itemBox .setFocus (true );
242+ case KeyCodes .KEY_ENTER :
243+ if (directInputAllowed ) {
244+ String value = itemBox .getValue ();
245+ if (value != null && !(value = value .trim ()).isEmpty ()) {
246+ gwt .material .design .client .base .Suggestion directInput = new gwt .material .design .client .base .Suggestion ();
247+ directInput .setDisplay (value );
248+ directInput .setSuggestion (value );
249+ itemsChanged = addItem (directInput );
250+ itemBox .setValue ("" );
251+ itemBox .setFocus (true );
252+ }
255253 }
256- }
257- break ;
254+ break ;
255+
256+ case KeyCodes .KEY_BACKSPACE :
257+ if (itemBox .getValue ().trim ().isEmpty ()) {
258+ if (itemsHighlighted .isEmpty ()) {
259+ if (suggestionMap .size () > 0 ) {
260+
261+ ListItem li = (ListItem ) list .getWidget (list .getWidgetCount () - 2 );
262+ MaterialChip p = (MaterialChip ) li .getWidget (0 );
263+
264+ Set <Entry <Suggestion , Widget >> entrySet = suggestionMap .entrySet ();
265+ for (Entry <Suggestion , Widget > entry : entrySet ) {
266+ if (p .equals (entry .getValue ())) {
267+ suggestionMap .remove (entry .getKey ());
268+ itemsChanged = true ;
269+ break ;
270+ }
271+ }
258272
259- case KeyCodes . KEY_BACKSPACE :
260- if ( itemBox . getValue (). trim (). isEmpty ()) {
261- if ( itemsHighlighted . isEmpty ()) {
262- if ( suggestionMap . size () > 0 ) {
273+ list . remove ( li );
274+ }
275+ }
276+ }
263277
264- ListItem li = (ListItem ) list .getWidget (list .getWidgetCount () - 2 );
278+ case KeyCodes .KEY_DELETE :
279+ if (itemBox .getValue ().trim ().isEmpty ()) {
280+ for (ListItem li : itemsHighlighted ) {
281+ li .removeFromParent ();
265282 MaterialChip p = (MaterialChip ) li .getWidget (0 );
266283
267284 Set <Entry <Suggestion , Widget >> entrySet = suggestionMap .entrySet ();
@@ -272,31 +289,11 @@ public void onKeyDown(KeyDownEvent event) {
272289 break ;
273290 }
274291 }
275-
276- list .remove (li );
277- }
278- }
279- }
280-
281- case KeyCodes .KEY_DELETE :
282- if (itemBox .getValue ().trim ().isEmpty ()) {
283- for (ListItem li : itemsHighlighted ) {
284- li .removeFromParent ();
285- MaterialChip p = (MaterialChip ) li .getWidget (0 );
286-
287- Set <Entry <Suggestion , Widget >> entrySet = suggestionMap .entrySet ();
288- for (Entry <Suggestion , Widget > entry : entrySet ) {
289- if (p .equals (entry .getValue ())) {
290- suggestionMap .remove (entry .getKey ());
291- itemsChanged = true ;
292- break ;
293- }
294292 }
293+ itemsHighlighted .clear ();
295294 }
296- itemsHighlighted .clear ();
297- }
298- itemBox .setFocus (true );
299- break ;
295+ itemBox .setFocus (true );
296+ break ;
300297 }
301298
302299 if (itemsChanged ) {
@@ -325,7 +322,7 @@ public void onSelection(SelectionEvent<Suggestion> selectionEvent) {
325322
326323 panel .add (list );
327324 panel .getElement ().setAttribute ("onclick" ,
328- "document.getElementById('" + autocompleteId + "').focus()" );
325+ "document.getElementById('" + autocompleteId + "').focus()" );
329326 panel .add (lblError );
330327 box .setFocus (true );
331328 }
@@ -334,6 +331,7 @@ public void onSelection(SelectionEvent<Suggestion> selectionEvent) {
334331 * Adding the item value using Material Chips added on auto complete box
335332 */
336333 protected boolean addItem (final Suggestion suggestion ) {
334+ SelectionEvent .fire (MaterialAutoComplete .this , suggestion );
337335 if (getLimit () > 0 ) {
338336 if (suggestionMap .size () >= getLimit ()) {
339337 return false ;
@@ -343,7 +341,7 @@ protected boolean addItem(final Suggestion suggestion) {
343341 if (suggestionMap .containsKey (suggestion )) {
344342 return false ;
345343 }
346-
344+
347345 final ListItem displayItem = new ListItem ();
348346 displayItem .setStyleName ("multiValueSuggestBox-token" );
349347
@@ -357,7 +355,7 @@ protected boolean addItem(final Suggestion suggestion) {
357355 if (chip == null ) {
358356 return false ;
359357 }
360-
358+
361359 chip .setIconType (IconType .CLOSE );
362360 chip .addClickHandler (new ClickHandler () {
363361 public void onClick (ClickEvent clickEvent ) {
@@ -370,7 +368,7 @@ public void onClick(ClickEvent clickEvent) {
370368 }
371369 }
372370 });
373-
371+
374372 chip .getIcon ().addClickHandler (new ClickHandler () {
375373 public void onClick (ClickEvent clickEvent ) {
376374 suggestionMap .remove (suggestion );
@@ -379,11 +377,11 @@ public void onClick(ClickEvent clickEvent) {
379377 box .showSuggestionList ();
380378 }
381379 });
382-
383- suggestionMap .put (suggestion , chip );
380+
381+ suggestionMap .put (suggestion , chip );
384382 displayItem .add (chip );
385383 }
386-
384+
387385 list .insert (displayItem , list .getWidgetCount () - 1 );
388386 return true ;
389387 }
@@ -576,6 +574,11 @@ public AutocompleteType getType() {
576574 return typeMixin .getType ();
577575 }
578576
577+ @ Override
578+ public HandlerRegistration addSelectionHandler (SelectionHandler <Suggestion > handler ) {
579+ return addHandler (handler , SelectionEvent .getType ());
580+ }
581+
579582 /**
580583 * Interface that defines how a {@link MaterialChip} is created, given a
581584 * {@link Suggestion}.
0 commit comments