diff options
author | elmot <elmot@vaadin.com> | 2016-09-14 17:48:50 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2016-09-16 13:35:05 +0000 |
commit | 05c051717401660a857ee7a314361a1735f376e6 (patch) | |
tree | 7e9f94925a0f3360ceb3833ec43a23d7c7b49fa0 /server | |
parent | 36ad322721e3548899cbca9516d91edabd252f2f (diff) | |
download | vaadin-framework-05c051717401660a857ee7a314361a1735f376e6.tar.gz vaadin-framework-05c051717401660a857ee7a314361a1735f376e6.zip |
Create a RadioButtonGroup that replaces the single select case of OptionGroup
Change-Id: I56b0f1dfa889e2eaa3db9b0b0aac860f1bb4dea8
Diffstat (limited to 'server')
3 files changed, 373 insertions, 0 deletions
diff --git a/server/src/main/java/com/vaadin/ui/RadioButtonGroup.java b/server/src/main/java/com/vaadin/ui/RadioButtonGroup.java new file mode 100644 index 0000000000..e3cc1892b0 --- /dev/null +++ b/server/src/main/java/com/vaadin/ui/RadioButtonGroup.java @@ -0,0 +1,236 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.ui; + +import com.vaadin.data.Listing; +import com.vaadin.server.Resource; +import com.vaadin.server.ResourceReference; +import com.vaadin.server.data.DataGenerator; +import com.vaadin.server.data.DataSource; +import com.vaadin.shared.ui.optiongroup.RadioButtonGroupConstants; +import com.vaadin.shared.ui.optiongroup.RadioButtonGroupState; +import elemental.json.JsonObject; + +import java.util.Collection; +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * A group of RadioButtons. Individual radiobuttons are made from items supplied by + * a {@link DataSource}. RadioButtons may have captions and icons. + * + * @param <T> + * item type + * @author Vaadin Ltd + * @since 8.0 + */ +public class RadioButtonGroup<T> extends AbstractSingleSelect<T> { + + private Function<T, Resource> itemIconProvider = item -> null; + + private Function<T, String> itemCaptionProvider = String::valueOf; + + private Predicate<T> itemEnabledProvider = item -> true; + + /** + * Constructs a new RadioButtonGroup with caption. + * + * @param caption + * caption text + * @see Listing#setDataSource(DataSource) + */ + public RadioButtonGroup(String caption) { + this(); + setCaption(caption); + } + + /** + * Constructs a new RadioButtonGroup with caption and DataSource. + * + * @param caption + * the caption text + * @param dataSource + * the data source, not null + * @see Listing#setDataSource(DataSource) + */ + public RadioButtonGroup(String caption, DataSource<T> dataSource) { + this(caption); + setDataSource(dataSource); + } + + /** + * Constructs a new RadioButtonGroup with caption and DataSource containing + * given items. + * + * @param caption + * the caption text + * @param items + * the data items to use, not null + * @see Listing#setDataSource(DataSource) + */ + public RadioButtonGroup(String caption, Collection<T> items) { + this(caption, DataSource.create(items)); + } + + /** + * Constructs a new RadioButtonGroup. + * + * @see Listing#setDataSource(DataSource) + */ + public RadioButtonGroup() { + setSelectionModel(new SimpleSingleSelection()); + + addDataGenerator(new DataGenerator<T>() { + @Override + public void generateData(T data, JsonObject jsonObject) { + jsonObject.put(RadioButtonGroupConstants.JSONKEY_ITEM_VALUE, + itemCaptionProvider.apply(data)); + Resource icon = itemIconProvider.apply(data); + if (icon != null) { + String iconUrl = ResourceReference + .create(icon, RadioButtonGroup.this, null).getURL(); + jsonObject.put(RadioButtonGroupConstants.JSONKEY_ITEM_ICON, + iconUrl); + } + if (!itemEnabledProvider.test(data)) { + jsonObject.put(RadioButtonGroupConstants.JSONKEY_ITEM_DISABLED, + true); + } + + if (getSelectionModel().isSelected(data)) { + jsonObject.put(RadioButtonGroupConstants.JSONKEY_ITEM_SELECTED, + true); + } + } + + @Override + public void destroyData(T data) { + } + }); + + } + + /** + * Sets whether html is allowed in the item captions. If set to true, the + * captions are passed to the browser as html and the developer is + * responsible for ensuring no harmful html is used. If set to false, the + * content is passed to the browser as plain text. + * + * @param htmlContentAllowed + * true if the captions are used as html, false if used as plain + * text + */ + public void setHtmlContentAllowed(boolean htmlContentAllowed) { + getState().htmlContentAllowed = htmlContentAllowed; + } + + /** + * Checks whether captions are interpreted as html or plain text. + * + * @return true if the captions are used as html, false if used as plain + * text + * @see #setHtmlContentAllowed(boolean) + */ + public boolean isHtmlContentAllowed() { + return getState(false).htmlContentAllowed; + } + + @Override + protected RadioButtonGroupState getState() { + return (RadioButtonGroupState) super.getState(); + } + + @Override + protected RadioButtonGroupState getState(boolean markAsDirty) { + return (RadioButtonGroupState) super.getState(markAsDirty); + } + + /** + * Returns the item icons provider. + * + * @return the icons provider for items + * @see #setItemIconProvider + */ + public Function<T, Resource> getItemIconProvider() { + return itemIconProvider; + } + + /** + * Sets the item icon provider for this radiobutton group. The icon provider is + * queried for each item to optionally display an icon next to the item + * caption. If the provider returns null for an item, no icon is displayed. + * The default provider always returns null (no icons). + * + * @param itemIconProvider + * icons provider, not null + */ + public void setItemIconProvider(Function<T, Resource> itemIconProvider) { + Objects.requireNonNull(itemIconProvider); + this.itemIconProvider = itemIconProvider; + } + + /** + * Returns the item caption provider. + * + * @return the captions provider + * @see #setItemCaptionProvider + */ + public Function<T, String> getItemCaptionProvider() { + return itemCaptionProvider; + } + + /** + * Sets the item caption provider for this radiobutton group. The caption + * provider is queried for each item to optionally display an item textual + * representation. The default provider returns + * {@code String.valueOf(item)}. + * + * @param itemCaptionProvider + * the item caption provider, not null + */ + public void setItemCaptionProvider( + Function<T, String> itemCaptionProvider) { + Objects.requireNonNull(itemCaptionProvider); + this.itemCaptionProvider = itemCaptionProvider; + } + + /** + * Returns the item enabled predicate. + * + * @return the item enabled predicate + * @see #setItemEnabledProvider + */ + public Predicate<T> getItemEnabledProvider() { + return itemEnabledProvider; + } + + /** + * Sets the item enabled predicate for this radiobutton group. The predicate is + * applied to each item to determine whether the item should be enabled + * (true) or disabled (false). Disabled items are displayed as grayed out + * and the user cannot select them. The default predicate always returns + * true (all the items are enabled). + * + * @param itemEnabledProvider + * the item enable predicate, not null + */ + public void setItemEnabledProvider(Predicate<T> itemEnabledProvider) { + Objects.requireNonNull(itemEnabledProvider); + this.itemEnabledProvider = itemEnabledProvider; + } +} diff --git a/server/src/test/java/com/vaadin/ui/RadioButtonGroupBoVTest.java b/server/src/test/java/com/vaadin/ui/RadioButtonGroupBoVTest.java new file mode 100644 index 0000000000..2ec2404515 --- /dev/null +++ b/server/src/test/java/com/vaadin/ui/RadioButtonGroupBoVTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.ui; + +import java.util.EnumSet; + +/** + * Option group test from Book of Vaadin + * + * @author Vaadin Ltd + * @since 8.0 + */ +public class RadioButtonGroupBoVTest +{ + public enum Status { + STATE_A, + STATE_B, + STATE_C, + STATE_D; + + public String getCaption() { + return "** " + toString(); + } + } + + + public void createOptionGroup() { + RadioButtonGroup<Status> s = new RadioButtonGroup<>(); + s.setItems(EnumSet.allOf(Status.class)); + s.setItemCaptionProvider(Status::getCaption); + } + +} diff --git a/server/src/test/java/com/vaadin/ui/RadioButtonGroupTest.java b/server/src/test/java/com/vaadin/ui/RadioButtonGroupTest.java new file mode 100644 index 0000000000..a03da685d8 --- /dev/null +++ b/server/src/test/java/com/vaadin/ui/RadioButtonGroupTest.java @@ -0,0 +1,91 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.ui; + +import com.vaadin.server.data.DataSource; +import com.vaadin.shared.data.selection.SelectionModel; +import com.vaadin.shared.data.selection.SelectionModel.Multi; +import com.vaadin.shared.data.selection.SelectionServerRpc; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicInteger; + +public class RadioButtonGroupTest { + private RadioButtonGroup<String> radioButtonGroup; + private SelectionModel.Single<String> selectionModel; + + @Before + public void setUp() { + radioButtonGroup = new RadioButtonGroup<>(); + // Intentional deviation from upcoming selection order + radioButtonGroup + .setDataSource(DataSource.create("Third", "Second", "First")); + selectionModel = radioButtonGroup.getSelectionModel(); + } + + + @Test + public void apiSelectionChange_notUserOriginated() { + AtomicInteger listenerCount = new AtomicInteger(0); + + radioButtonGroup.addSelectionListener(event -> { + listenerCount.incrementAndGet(); + Assert.assertFalse(event.isUserOriginated()); + }); + + radioButtonGroup.select("First"); + radioButtonGroup.select("Second"); + + radioButtonGroup.deselect("Second"); + radioButtonGroup.getSelectionModel().deselectAll(); + + Assert.assertEquals(3, listenerCount.get()); + } + + @Test + public void rpcSelectionChange_userOriginated() { + AtomicInteger listenerCount = new AtomicInteger(0); + + radioButtonGroup.addSelectionListener(event -> { + listenerCount.incrementAndGet(); + Assert.assertTrue(event.isUserOriginated()); + }); + + SelectionServerRpc rpc = ComponentTest.getRpcProxy(radioButtonGroup, + SelectionServerRpc.class); + + rpc.select(getItemKey("First")); + rpc.select(getItemKey("Second")); + rpc.deselect(getItemKey("Second")); + + Assert.assertEquals(3, listenerCount.get()); + } + + private String getItemKey(String dataObject) { + return radioButtonGroup.getDataCommunicator().getKeyMapper() + .key(dataObject); + } + + private static void assertSelectionOrder(Multi<String> selectionModel, + String... selectionOrder) { + Assert.assertEquals(Arrays.asList(selectionOrder), + new ArrayList<>(selectionModel.getSelectedItems())); + } +} |