選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

NativeSelectConnector.java 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright 2000-2018 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.client.ui.nativeselect;
  17. import com.google.gwt.event.shared.HandlerRegistration;
  18. import com.google.gwt.user.client.ui.ListBox;
  19. import com.vaadin.client.annotations.OnStateChange;
  20. import com.vaadin.client.connectors.AbstractSingleSelectConnector;
  21. import com.vaadin.client.data.DataSource;
  22. import com.vaadin.client.ui.VNativeSelect;
  23. import com.vaadin.shared.Range;
  24. import com.vaadin.shared.Registration;
  25. import com.vaadin.shared.data.selection.SelectionServerRpc;
  26. import com.vaadin.shared.ui.Connect;
  27. import com.vaadin.shared.ui.nativeselect.NativeSelectState;
  28. import elemental.json.JsonObject;
  29. /**
  30. * The client-side connector for the {@code NativeSelect} component.
  31. *
  32. * @author Vaadin Ltd.
  33. *
  34. * @see com.vaadin.ui.NativeSelect
  35. * @see com.vaadin.client.ui.VNativeSelect
  36. *
  37. * @since 8.0
  38. */
  39. @Connect(com.vaadin.ui.NativeSelect.class)
  40. public class NativeSelectConnector
  41. extends AbstractSingleSelectConnector<VNativeSelect> {
  42. private HandlerRegistration selectionChangeRegistration;
  43. private Registration dataChangeRegistration;
  44. private final SelectionServerRpc selectionRpc = getRpcProxy(
  45. SelectionServerRpc.class);
  46. @Override
  47. protected void init() {
  48. super.init();
  49. selectionChangeRegistration = getWidget().getListBox()
  50. .addChangeHandler(event -> selectionRpc
  51. .select(getWidget().getListBox().getSelectedValue()));
  52. }
  53. @Override
  54. public void onUnregister() {
  55. super.onUnregister();
  56. selectionChangeRegistration.removeHandler();
  57. selectionChangeRegistration = null;
  58. }
  59. @Override
  60. public void setDataSource(DataSource<JsonObject> dataSource) {
  61. if (dataChangeRegistration != null) {
  62. dataChangeRegistration.remove();
  63. }
  64. dataChangeRegistration = dataSource
  65. .addDataChangeHandler(this::onDataChange);
  66. super.setDataSource(dataSource);
  67. }
  68. @OnStateChange("readOnly")
  69. void updateWidgetReadOnly() {
  70. getWidget().getListBox().setEnabled(isEnabled() && !isReadOnly());
  71. }
  72. @OnStateChange("selectedItemKey")
  73. void updateSelectedItem() {
  74. getWidget().setSelectedItem(getState().selectedItemKey);
  75. }
  76. @OnStateChange("tabIndex")
  77. void updateTabIndex() {
  78. getWidget().setTabIndex(getState().tabIndex);
  79. }
  80. @OnStateChange({ "emptySelectionCaption", "emptySelectionAllowed" })
  81. private void onEmptySelectionCaptionChange() {
  82. ListBox listBox = getWidget().getListBox();
  83. boolean hasEmptyItem = listBox.getItemCount() > 0
  84. && listBox.getValue(0).isEmpty();
  85. if (hasEmptyItem && getState().emptySelectionAllowed) {
  86. listBox.setItemText(0, getState().emptySelectionCaption);
  87. } else if (hasEmptyItem && !getState().emptySelectionAllowed) {
  88. listBox.removeItem(0);
  89. } else if (!hasEmptyItem && getState().emptySelectionAllowed) {
  90. listBox.insertItem(getState().emptySelectionCaption, 0);
  91. listBox.setValue(0, "");
  92. }
  93. }
  94. @Override
  95. public NativeSelectState getState() {
  96. return (NativeSelectState) super.getState();
  97. }
  98. /**
  99. * A data change handler registered to the data source. Updates the data
  100. * items and selection status when the data source notifies of new changes
  101. * from the server side.
  102. *
  103. * @param range
  104. * the new range of data items
  105. */
  106. private void onDataChange(Range range) {
  107. assert range.getStart() == 0 && range.getEnd() == getDataSource()
  108. .size() : "NativeSelect only supports full updates, but got range "
  109. + range;
  110. final VNativeSelect select = getWidget();
  111. final int itemCount = select.getListBox().getItemCount();
  112. int increment = getState().emptySelectionAllowed ? 1 : 0;
  113. for (int i = range.getStart() + increment; i < range.getEnd()
  114. + increment; i++) {
  115. final JsonObject row = getDataSource().getRow(i - increment);
  116. if (i < itemCount) {
  117. // Reuse and update an existing item
  118. select.getListBox().setItemText(i, getRowData(row).asString());
  119. select.getListBox().setValue(i, getRowKey(row));
  120. } else {
  121. // Add new items if the new dataset is larger than the old
  122. select.getListBox().addItem(getRowData(row).asString(),
  123. getRowKey(row));
  124. }
  125. }
  126. for (int i = select.getListBox().getItemCount() - 1; i >= range.getEnd()
  127. + increment; i--) {
  128. // Remove extra items if the new dataset is smaller than the old
  129. select.getListBox().removeItem(i);
  130. }
  131. updateSelectedItem();
  132. }
  133. @Override
  134. public void setWidgetEnabled(boolean widgetEnabled) {
  135. // add or remove v-disabled style name from the widget
  136. super.setWidgetEnabled(widgetEnabled);
  137. if (widgetEnabled) {
  138. getWidget().getListBox().getElement().removeAttribute("disabled");
  139. } else {
  140. getWidget().getListBox().getElement().setAttribute("disabled",
  141. "disabled");
  142. }
  143. }
  144. }