001/* 002 * #%L 003 * GwtMaterial 004 * %% 005 * Copyright (C) 2015 - 2017 GwtMaterialDesign 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package gwt.material.design.client.ui; 021 022import com.google.gwt.core.client.GWT; 023import com.google.gwt.dom.client.Document; 024import com.google.gwt.dom.client.OptionElement; 025import com.google.gwt.dom.client.SelectElement; 026import com.google.gwt.event.logical.shared.ValueChangeEvent; 027import com.google.gwt.i18n.client.HasDirection.Direction; 028import com.google.gwt.user.client.ui.FormPanel; 029import com.google.gwt.user.client.ui.HasConstrainedValue; 030import com.google.gwt.user.client.ui.ListBox; 031import gwt.material.design.client.base.*; 032import gwt.material.design.client.base.helper.UiHelper; 033import gwt.material.design.client.base.mixin.ErrorMixin; 034import gwt.material.design.client.base.mixin.ReadOnlyMixin; 035import gwt.material.design.client.base.mixin.ToggleStyleMixin; 036import gwt.material.design.client.constants.CssName; 037import gwt.material.design.client.js.JsMaterialElement; 038import gwt.material.design.client.ui.html.Label; 039import gwt.material.design.jquery.client.api.JQuery; 040import gwt.material.design.jquery.client.api.JQueryElement; 041 042import java.util.ArrayList; 043import java.util.Collection; 044import java.util.LinkedList; 045import java.util.List; 046 047import static gwt.material.design.client.js.JsMaterialElement.$; 048//@formatter:off 049 050/** 051 * <p>Material ListBox is another dropdown component that will set / get the value depends on the selected index 052 * <h3>UiBinder Usage:</h3> 053 * <p> 054 * <pre> 055 * {@code 056 * <m:MaterialListBox ui:field="lstBox" /> 057 * } 058 * </pre> 059 * <h3>Java Usage:</h3> 060 * <p> 061 * <pre> 062 * {@code 063 * // functions 064 * lstBox.setSelectedIndex(2); 065 * lstBox.getSelectedIndex(); 066 * lstBox.addValueChangeHandler(handler); 067 * } 068 * </pre> 069 * </p> 070 * 071 * @author kevzlou7979 072 * @author Ben Dol 073 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#forms">Material ListBox</a> 074 * @see <a href="https://material.io/guidelines/components/menus.html">Material Design Specification</a> 075 */ 076//@formatter:on 077public class MaterialListValueBox<T> extends AbstractValueWidget<T> implements JsLoader, HasPlaceholder, 078 HasConstrainedValue<T>, HasReadOnly { 079 080 private final ListBox listBox = new ListBox(); 081 private final Label label = new Label(); 082 protected final List<T> values = new ArrayList<>(); 083 private KeyFactory<T, String> keyFactory = Object::toString; 084 private MaterialLabel errorLabel = new MaterialLabel(); 085 086 private ToggleStyleMixin<ListBox> toggleOldMixin; 087 private ReadOnlyMixin<MaterialListValueBox<T>, ListBox> readOnlyMixin; 088 private ErrorMixin<AbstractValueWidget, MaterialLabel> errorMixin; 089 090 public MaterialListValueBox() { 091 super(Document.get().createDivElement(), CssName.INPUT_FIELD); 092 } 093 094 @Override 095 protected void onLoad() { 096 super.onLoad(); 097 098 add(listBox); 099 add(label); 100 add(errorLabel); 101 102 registerHandler(addValueChangeHandler(valueChangeEvent -> { 103 if (isToggleReadOnly()) { 104 setReadOnly(true); 105 } 106 })); 107 108 load(); 109 } 110 111 @Override 112 public void load() { 113 JQueryElement listBoxElement = $(listBox.getElement()); 114 JsMaterialElement.$(listBox.getElement()).material_select( 115 () -> $("input.select-dropdown").trigger("close", true)); 116 listBoxElement.change((e, param) -> { 117 try { 118 ValueChangeEvent.fire(this, getValue()); 119 } catch (IndexOutOfBoundsException ex) { 120 GWT.log("ListBox value change handler threw an exception.", ex); 121 } 122 return true; 123 }); 124 125 // Fixed IE browser for select dropdown scrolling 126 // Related materialize issue https://github.com/Dogfalo/materialize/issues/901 127 listBoxElement.siblings("input.select-dropdown").mousedown((event, o) -> { 128 $("input[data-activates!='" + listBoxElement.attr("data-activates") + "'].select-dropdown").trigger("close", true); 129 if (!UiHelper.isTouchScreenDevice()) { 130 event.preventDefault(); 131 } 132 return true; 133 }); 134 } 135 136 @Override 137 protected void onUnload() { 138 super.onUnload(); 139 140 unload(); 141 } 142 143 @Override 144 public void unload() { 145 if (listBox != null && listBox.isAttached()) { 146 $(listBox.getElement()).siblings("input.select-dropdown").off("mousedown"); 147 $(listBox.getElement()).off("change"); 148 $(listBox.getElement()).material_select("destroy"); 149 } 150 } 151 152 @Override 153 public void reload() { 154 if (isAttached()) { 155 unload(); 156 load(); 157 } 158 } 159 160 public void add(T value) { 161 addItem(value); 162 } 163 164 /** 165 * Adds an item to the list box, specifying its direction. This method has 166 * the same effect as 167 * <pre>addItem(value, dir, item)</pre> 168 * 169 * @param value the item's value, to be submitted if it is part of a 170 * {@link FormPanel}; cannot be <code>null</code> 171 * @param dir the item's direction 172 */ 173 public void addItem(T value, Direction dir) { 174 addItem(value, dir, true); 175 } 176 177 /** 178 * Adds an item to the list box, specifying its direction. This method has 179 * the same effect as 180 * <pre>addItem(value, dir, item)</pre> 181 * 182 * @param value the item's value, to be submitted if it is part of a 183 * {@link FormPanel}; cannot be <code>null</code> 184 * @param dir the item's direction 185 * @param reload perform a 'material select' reload to update the DOM. 186 */ 187 public void addItem(T value, Direction dir, boolean reload) { 188 values.add(value); 189 listBox.addItem(keyFactory.generateKey(value), dir); 190 191 if (reload) { 192 reload(); 193 } 194 } 195 196 /** 197 * Adds an item to the list box. This method has the same effect as 198 * <pre>addItem(value, item)</pre> 199 * 200 * @param value the item's value, to be submitted if it is part of a 201 * {@link FormPanel}; cannot be <code>null</code> 202 */ 203 public void addItem(T value) { 204 addItem(value, true); 205 } 206 207 /** 208 * Adds an item to the list box. This method has the same effect as 209 * <pre>addItem(value, item)</pre> 210 * 211 * @param value the item's value, to be submitted if it is part of a 212 * {@link FormPanel}; cannot be <code>null</code> 213 * @param reload perform a 'material select' reload to update the DOM. 214 */ 215 public void addItem(T value, boolean reload) { 216 values.add(value); 217 listBox.addItem(keyFactory.generateKey(value)); 218 219 if (reload) { 220 reload(); 221 } 222 } 223 224 /** 225 * Adds an item to the list box, specifying an initial value for the item. 226 * 227 * @param value the item's value, to be submitted if it is part of a 228 * {@link FormPanel}; cannot be <code>null</code> 229 * @param text the text of the item to be added 230 */ 231 public void addItem(T value, String text) { 232 addItem(value, text, true); 233 } 234 235 /** 236 * Adds an item to the list box, specifying an initial value for the item. 237 * 238 * @param value the item's value, to be submitted if it is part of a 239 * {@link FormPanel}; cannot be <code>null</code> 240 * @param text the text of the item to be added 241 * @param reload perform a 'material select' reload to update the DOM. 242 */ 243 public void addItem(T value, String text, boolean reload) { 244 values.add(value); 245 listBox.addItem(text, keyFactory.generateKey(value)); 246 247 if (reload) { 248 reload(); 249 } 250 } 251 252 /** 253 * Adds an item to the list box, specifying its direction and an initial 254 * value for the item. 255 * 256 * @param value the item's value, to be submitted if it is part of a 257 * {@link FormPanel}; cannot be <code>null</code> 258 * @param dir the item's direction 259 * @param text the text of the item to be added 260 */ 261 public void addItem(T value, Direction dir, String text) { 262 addItem(value, dir, text, true); 263 } 264 265 /** 266 * Adds an item to the list box, specifying its direction and an initial 267 * value for the item. 268 * 269 * @param value the item's value, to be submitted if it is part of a 270 * {@link FormPanel}; cannot be <code>null</code> 271 * @param dir the item's direction 272 * @param text the text of the item to be added 273 * @param reload perform a 'material select' reload to update the DOM. 274 */ 275 public void addItem(T value, Direction dir, String text, boolean reload) { 276 values.add(value); 277 listBox.addItem(text, dir, keyFactory.generateKey(value)); 278 279 if (reload) { 280 reload(); 281 } 282 } 283 284 /** 285 * Inserts an item into the list box. Has the same effect as 286 * <pre>insertItem(value, item, index)</pre> 287 * 288 * @param value the item's value, to be submitted if it is part of a 289 * {@link FormPanel}. 290 * @param index the index at which to insert it 291 */ 292 public void insertItem(T value, int index) { 293 insertItem(value, index, true); 294 } 295 296 /** 297 * Inserts an item into the list box. Has the same effect as 298 * <pre>insertItem(value, item, index)</pre> 299 * 300 * @param value the item's value, to be submitted if it is part of a 301 * {@link FormPanel}. 302 * @param index the index at which to insert it 303 * @param reload perform a 'material select' reload to update the DOM. 304 */ 305 public void insertItem(T value, int index, boolean reload) { 306 values.add(index, value); 307 listBox.insertItem(keyFactory.generateKey(value), index); 308 309 if (reload) { 310 reload(); 311 } 312 } 313 314 /** 315 * Inserts an item into the list box, specifying its direction. Has the same 316 * effect as 317 * <pre>insertItem(value, dir, item, index)</pre> 318 * 319 * @param value the item's value, to be submitted if it is part of a 320 * {@link FormPanel}. 321 * @param dir the item's direction 322 * @param index the index at which to insert it 323 */ 324 public void insertItem(T value, Direction dir, int index) { 325 insertItem(value, dir, index, true); 326 } 327 328 /** 329 * Inserts an item into the list box, specifying its direction. Has the same 330 * effect as 331 * <pre>insertItem(value, dir, item, index)</pre> 332 * 333 * @param value the item's value, to be submitted if it is part of a 334 * {@link FormPanel}. 335 * @param dir the item's direction 336 * @param index the index at which to insert it 337 * @param reload perform a 'material select' reload to update the DOM. 338 */ 339 public void insertItem(T value, Direction dir, int index, boolean reload) { 340 values.add(index, value); 341 listBox.insertItem(keyFactory.generateKey(value), dir, index); 342 343 if (reload) { 344 reload(); 345 } 346 } 347 348 /** 349 * Inserts an item into the list box, specifying an initial value for the 350 * item. Has the same effect as 351 * <pre>insertItem(value, null, item, index)</pre> 352 * 353 * @param value the item's value, to be submitted if it is part of a 354 * {@link FormPanel}. 355 * @param text the text of the item to be inserted 356 * @param index the index at which to insert it 357 */ 358 public void insertItem(T value, String text, int index) { 359 insertItem(value, text, index, true); 360 } 361 362 /** 363 * Inserts an item into the list box, specifying an initial value for the 364 * item. Has the same effect as 365 * <pre>insertItem(value, null, item, index)</pre> 366 * 367 * @param value the item's value, to be submitted if it is part of a 368 * {@link FormPanel}. 369 * @param text the text of the item to be inserted 370 * @param index the index at which to insert it 371 * @param reload perform a 'material select' reload to update the DOM. 372 */ 373 public void insertItem(T value, String text, int index, boolean reload) { 374 values.add(index, value); 375 listBox.insertItem(text, keyFactory.generateKey(value), index); 376 377 if (reload) { 378 reload(); 379 } 380 } 381 382 /** 383 * Inserts an item into the list box, specifying its direction and an 384 * initial value for the item. If the index is less than zero, or greater 385 * than or equal to the length of the list, then the item will be appended 386 * to the end of the list. 387 * 388 * @param value the item's value, to be submitted if it is part of a 389 * {@link FormPanel}. 390 * @param dir the item's direction. If {@code null}, the item is displayed 391 * in the widget's overall direction, or, if a direction 392 * estimator has been set, in the item's estimated direction. 393 * @param text the text of the item to be inserted 394 * @param index the index at which to insert it 395 */ 396 public void insertItem(T value, Direction dir, String text, int index) { 397 insertItem(value, dir, text, index, true); 398 } 399 400 /** 401 * Inserts an item into the list box, specifying its direction and an 402 * initial value for the item. If the index is less than zero, or greater 403 * than or equal to the length of the list, then the item will be appended 404 * to the end of the list. 405 * 406 * @param value the item's value, to be submitted if it is part of a 407 * {@link FormPanel}. 408 * @param dir the item's direction. If {@code null}, the item is displayed 409 * in the widget's overall direction, or, if a direction 410 * estimator has been set, in the item's estimated direction. 411 * @param text the text of the item to be inserted 412 * @param index the index at which to insert it 413 * @param reload perform a 'material select' reload to update the DOM. 414 */ 415 public void insertItem(T value, Direction dir, String text, int index, boolean reload) { 416 values.add(index, value); 417 listBox.insertItem(keyFactory.generateKey(value), dir, text, index); 418 419 if (reload) { 420 reload(); 421 } 422 } 423 424 /** 425 * Removes the item at the specified index. 426 * 427 * @param index the index of the item to be removed 428 * @throws IndexOutOfBoundsException if the index is out of range 429 */ 430 public void removeItem(int index) { 431 removeItem(index, true); 432 } 433 434 /** 435 * Removes the item at the specified index. 436 * 437 * @param index the index of the item to be removed 438 * @param reload perform a 'material select' reload to update the DOM. 439 * @throws IndexOutOfBoundsException if the index is out of range 440 */ 441 public void removeItem(int index, boolean reload) { 442 values.remove(index); 443 listBox.removeItem(index); 444 445 if (reload) { 446 reload(); 447 } 448 } 449 450 /** 451 * Removes a value from the list box. Nothing is done if the value isn't on 452 * the list box. 453 * 454 * @param value the value to be removed from the list 455 */ 456 public void removeValue(String value) { 457 removeValue(value, true); 458 } 459 460 /** 461 * Removes a value from the list box. Nothing is done if the value isn't on 462 * the list box. 463 * 464 * @param value the value to be removed from the list 465 * @param reload perform a 'material select' reload to update the DOM. 466 */ 467 public void removeValue(String value, boolean reload) { 468 int idx = getIndex(value); 469 if (idx >= 0) { 470 removeItem(idx, reload); 471 } 472 } 473 474 @Override 475 public void reset() { 476 super.reset(); 477 clear(); 478 } 479 480 /** 481 * Removes all items from the list box. 482 */ 483 @Override 484 public void clear() { 485 values.clear(); 486 listBox.clear(); 487 reload(); 488 } 489 490 @Override 491 public void setPlaceholder(String placeholder) { 492 label.setText(placeholder); 493 } 494 495 @Override 496 public String getPlaceholder() { 497 return label.getText(); 498 } 499 500 public OptionElement getOptionElement(int index) { 501 return getSelectElement().getOptions().getItem(index); 502 } 503 504 protected SelectElement getSelectElement() { 505 return listBox.getElement().cast(); 506 } 507 508 /** 509 * Sets whether this list allows multiple selections. 510 * 511 * @param multipleSelect <code>true</code> to allow multiple selections 512 */ 513 public void setMultipleSelect(boolean multipleSelect) { 514 listBox.setMultipleSelect(multipleSelect); 515 } 516 517 /** 518 * Gets whether this list allows multiple selection. 519 * 520 * @return <code>true</code> if multiple selection is allowed 521 */ 522 public boolean isMultipleSelect() { 523 return listBox.isMultipleSelect(); 524 } 525 526 public void setEmptyPlaceHolder(String value) { 527 listBox.insertItem(value, 0); 528 529 getOptionElement(0).setDisabled(true); 530 } 531 532 @Override 533 public void setAcceptableValues(Collection<T> values) { 534 this.values.clear(); 535 clear(); 536 values.forEach(this::addItem); 537 } 538 539 540 @Override 541 public T getValue() { 542 if (getSelectedIndex() != -1) { 543 return values.get(getSelectedIndex()); 544 } 545 return null; 546 } 547 548 @Override 549 public void setValue(T value) { 550 setValue(value, false); 551 } 552 553 @Override 554 public void setValue(T value, boolean fireEvents) { 555 int index = values.indexOf(value); 556 if (index >= 0) { 557 T before = getValue(); 558 setSelectedIndex(index); 559 560 if (fireEvents) { 561 ValueChangeEvent.fireIfNotEqual(this, before, value); 562 } 563 } 564 } 565 566 public boolean isOld() { 567 return getToggleOldMixin().isOn(); 568 } 569 570 public void setOld(boolean old) { 571 getToggleOldMixin().setOn(old); 572 } 573 574 /** 575 * Sets the value associated with the item at a given index. This value can 576 * be used for any purpose, but is also what is passed to the server when 577 * the list box is submitted as part of a {@link FormPanel}. 578 * 579 * @param index the index of the item to be set 580 * @param value the item's new value; cannot be <code>null</code> 581 * @throws IndexOutOfBoundsException if the index is out of range 582 */ 583 public void setValue(int index, String value) { 584 listBox.setValue(index, value); 585 reload(); 586 } 587 588 @Override 589 public void setTitle(String title) { 590 listBox.setTitle(title); 591 } 592 593 /** 594 * Sets whether an individual list item is selected. 595 * 596 * @param index the index of the item to be selected or unselected 597 * @param selected <code>true</code> to select the item 598 * @throws IndexOutOfBoundsException if the index is out of range 599 */ 600 public void setItemSelected(int index, boolean selected) { 601 listBox.setItemSelected(index, selected); 602 reload(); 603 } 604 605 /** 606 * Sets the text associated with the item at a given index. 607 * 608 * @param index the index of the item to be set 609 * @param text the item's new text 610 * @throws IndexOutOfBoundsException if the index is out of range 611 */ 612 public void setItemText(int index, String text) { 613 listBox.setItemText(index, text); 614 reload(); 615 } 616 617 /** 618 * Sets the text associated with the item at a given index. 619 * 620 * @param index the index of the item to be set 621 * @param text the item's new text 622 * @param dir the item's direction. 623 * @throws IndexOutOfBoundsException if the index is out of range 624 */ 625 public void setItemText(int index, String text, Direction dir) { 626 listBox.setItemText(index, text, dir); 627 reload(); 628 } 629 630 public void setName(String name) { 631 listBox.setName(name); 632 } 633 634 /** 635 * Sets the currently selected index. 636 * <p> 637 * After calling this method, only the specified item in the list will 638 * remain selected. For a ListBox with multiple selection enabled, see 639 * {@link #setItemSelected(int, boolean)} to select multiple items at a 640 * time. 641 * 642 * @param index the index of the item to be selected 643 */ 644 public void setSelectedIndex(int index) { 645 listBox.setSelectedIndex(index); 646 reload(); 647 } 648 649 /** 650 * Sets the number of items that are visible. If only one item is visible, 651 * then the box will be displayed as a drop-down list. 652 * 653 * @param visibleItems the visible item count 654 */ 655 public void setVisibleItemCount(int visibleItems) { 656 listBox.setVisibleItemCount(visibleItems); 657 } 658 659 /** 660 * Gets the number of items present in the list box. 661 * 662 * @return the number of items 663 */ 664 public int getItemCount() { 665 return listBox.getItemCount(); 666 } 667 668 /** 669 * Gets the text associated with the item at the specified index. 670 * 671 * @param index the index of the item whose text is to be retrieved 672 * @return the text associated with the item 673 * @throws IndexOutOfBoundsException if the index is out of range 674 */ 675 public String getItemText(int index) { 676 return listBox.getItemText(index); 677 } 678 679 /** 680 * Gets the text for currently selected item. If multiple items are 681 * selected, this method will return the text of the first selected item. 682 * 683 * @return the text for selected item, or {@code null} if none is selected 684 */ 685 public String getSelectedItemText() { 686 return listBox.getSelectedItemText(); 687 } 688 689 public String getName() { 690 return listBox.getName(); 691 } 692 693 /** 694 * Gets the currently-selected item. If multiple items are selected, this 695 * method will return the first selected item ({@link #isItemSelected(int)} 696 * can be used to query individual items). 697 * 698 * @return the selected index, or <code>-1</code> if none is selected 699 */ 700 public int getSelectedIndex() { 701 return listBox.getSelectedIndex(); 702 } 703 704 /** 705 * Gets the value associated with the item at a given index. 706 * 707 * @param index the index of the item to be retrieved 708 * @return the item's associated value 709 * @throws IndexOutOfBoundsException if the index is out of range 710 */ 711 public T getValue(int index) { 712 return values.get(index); 713 } 714 715 /** 716 * Gets the value for currently selected item. If multiple items are 717 * selected, this method will return the value of the first selected item. 718 * 719 * @return the value for selected item, or {@code null} if none is selected 720 */ 721 public T getSelectedValue() { 722 try { 723 return values.get(getSelectedIndex()); 724 } catch (IndexOutOfBoundsException ex) { 725 return null; 726 } 727 } 728 729 /** 730 * Gets the number of items that are visible. If only one item is visible, 731 * then the box will be displayed as a drop-down list. 732 * 733 * @return the visible item count 734 */ 735 public int getVisibleItemCount() { 736 return listBox.getVisibleItemCount(); 737 } 738 739 /** 740 * Determines whether an individual list item is selected. 741 * 742 * @param index the index of the item to be tested 743 * @return <code>true</code> if the item is selected 744 * @throws IndexOutOfBoundsException if the index is out of range 745 */ 746 public boolean isItemSelected(int index) { 747 return listBox.isItemSelected(index); 748 } 749 750 751 @Override 752 public void setEnabled(boolean enabled) { 753 listBox.setEnabled(enabled); 754 reload(); 755 } 756 757 @Override 758 public boolean isEnabled() { 759 return listBox.isEnabled(); 760 } 761 762 /** 763 * Use your own key factory for value keys. 764 */ 765 public void setKeyFactory(KeyFactory<T, String> keyFactory) { 766 this.keyFactory = keyFactory; 767 } 768 769 @Override 770 public void setReadOnly(boolean value) { 771 getReadOnlyMixin().setReadOnly(value); 772 if (!value) { 773 $(listBox.getElement()).material_select("destroy"); 774 $(listBox.getElement()).material_select(); 775 } 776 } 777 778 @Override 779 public boolean isReadOnly() { 780 return getReadOnlyMixin().isReadOnly(); 781 } 782 783 @Override 784 public void setToggleReadOnly(boolean toggle) { 785 getReadOnlyMixin().setToggleReadOnly(toggle); 786 } 787 788 @Override 789 public boolean isToggleReadOnly() { 790 return getReadOnlyMixin().isToggleReadOnly(); 791 } 792 793 public ListBox getListBox() { 794 return listBox; 795 } 796 797 @Override 798 public ErrorMixin<AbstractValueWidget, MaterialLabel> getErrorMixin() { 799 if (errorMixin == null) { 800 errorMixin = new ErrorMixin<>(this, errorLabel, listBox, label); 801 } 802 return errorMixin; 803 } 804 805 public Label getLabel() { 806 return label; 807 } 808 809 public MaterialLabel getErrorLabel() { 810 return errorLabel; 811 } 812 813 /** 814 * Returns all selected values of the list box, or empty array if none. 815 * 816 * @return the selected values of the list box 817 */ 818 public String[] getItemsSelected() { 819 List<String> selected = new LinkedList<>(); 820 for (int i = 0; i < listBox.getItemCount(); i++) { 821 if (listBox.isItemSelected(i)) { 822 selected.add(listBox.getValue(i)); 823 } 824 } 825 return selected.toArray(new String[selected.size()]); 826 } 827 828 /** 829 * Sets the currently selected value. 830 * <p> 831 * After calling this method, only the specified item in the list will 832 * remain selected. For a ListBox with multiple selection enabled, see 833 * {@link #setValueSelected(String, boolean)} to select multiple items at a 834 * time. 835 * 836 * @param value the value of the item to be selected 837 */ 838 public void setSelectedValue(String value) { 839 int idx = getIndex(value); 840 if (idx >= 0) { 841 setSelectedIndex(idx); 842 } 843 } 844 845 /** 846 * Sets whether an individual list value is selected. 847 * 848 * @param value the value of the item to be selected or unselected 849 * @param selected <code>true</code> to select the item 850 */ 851 public void setValueSelected(String value, boolean selected) { 852 int idx = getIndex(value); 853 if (idx >= 0) { 854 setItemSelected(idx, selected); 855 } 856 } 857 858 /** 859 * Gets the index of the specified value. 860 * 861 * @param value the value of the item to be found 862 * @return the index of the value 863 */ 864 public int getIndex(String value) { 865 int count = getItemCount(); 866 for (int i = 0; i < count; i++) { 867 if (getValue(i).equals(value)) { 868 return i; 869 } 870 } 871 return -1; 872 } 873 874 public ReadOnlyMixin<MaterialListValueBox<T>, ListBox> getReadOnlyMixin() { 875 if (readOnlyMixin == null) { 876 readOnlyMixin = new ReadOnlyMixin<>(this, listBox); 877 } 878 return readOnlyMixin; 879 } 880 881 protected ToggleStyleMixin<ListBox> getToggleOldMixin() { 882 if (toggleOldMixin == null) { 883 toggleOldMixin = new ToggleStyleMixin<>(listBox, "browser-default"); 884 } 885 return toggleOldMixin; 886 } 887}