twinColumn
twinColumn lets users select items by moving them between available and selected columns.
XML Element |
|
|---|---|
Java Class |
|
Basics
The component puts two columns side by side. The left column contains items that the user can select from. The right column displays currently selected items. Users can select one or more items and click buttons to move them between columns, adding or removing them from the selection.
To create the component, use twinColumn XML element and set its itemsContainer attribute to a collection container. The items within this container will appear in the columns.
The following example demonstrates how a basic twin column is created:
<data readOnly="true">
<instance id="productDc"
class="io.jmix.uisamples.entity.Product"
fetchPlan="_local">
</instance>
<collection id="productTagsDc"
class="io.jmix.uisamples.entity.ProductTag"
fetchPlan="_local">
<loader id="productTagsDl" readOnly="true">
<query>
<![CDATA[select e from ProductTag e order by e.name]]>
</query>
</loader>
</collection>
</data>
<facets>
<dataLoadCoordinator auto="true"/>
</facets>
<twinColumn id="twinColumn" label="Tags" itemsColumnLabel="Available tags"
selectedItemsColumnLabel="Selected tags" itemsContainer="productTagsDc"
dataContainer="productDc" property="tags"/>
Data-aware twinColumn
Data binding refers to linking a visual component to a data container. Changes in the visual component or corresponding data container can trigger updates to one another. See Using Data Components for more details.
To create twinColumn connected to data, use the dataContainer and property attributes. The itemsContainer attribute is used to create a list of items.
<data readOnly="true">
<instance id="productDc"
class="io.jmix.uisamples.entity.Product"
fetchPlan="_local">
</instance>
<collection id="productTagsDc"
class="io.jmix.uisamples.entity.ProductTag"
fetchPlan="_local">
<loader id="productTagsDl" readOnly="true">
<query>
<![CDATA[select e from ProductTag e order by e.name]]>
</query>
</loader>
</collection>
</data>
<facets>
<dataLoadCoordinator auto="true"/>
</facets>
<twinColumn id="twinColumn" label="Tags" itemsColumnLabel="Available tags"
selectedItemsColumnLabel="Selected tags" itemsContainer="productTagsDc"
dataContainer="productDc" property="tags"/>
@ViewComponent
protected InstanceContainer<Product> productDc;
@ViewComponent
protected Span spanValue;
@Autowired
protected Metadata metadata;
@Subscribe
protected void onInit(InitEvent event) {
Product product = metadata.create(Product.class);
productDc.setItem(product);
}
@Subscribe("twinColumn")
protected void onTwinColumnValueChange(ComponentValueChangeEvent<TwinColumn<Product>, Product> event) {
if (productDc.getItem().getTags() == null) {
return;
}
spanValue.setText(getSelectedTagsInstanceName());
}
protected String getSelectedTagsInstanceName() {
return productDc.getItem().getTags()
.stream()
.map(ProductTag::getInstanceName)
.collect(Collectors.joining(", "));
}
Multi Select
The twinColumn component is always in multi-select mode, allowing users to select and move multiple items. You can also provide the ability to move all items at once by setting the selectAllButtonsVisible attribute:
@ViewComponent
protected TwinColumn<String> twinColumn;
@Subscribe("selectAllButtonsCheckbox")
public void onSelectAllButtonsCheckboxValueChange(ComponentValueChangeEvent<JmixCheckbox, Boolean> event) {
twinColumn.setSelectAllButtonsVisible(event.getValue());
}
Column Labels
You can provide descriptive labels for each column with the itemsColumnLabel and selectedItemsColumnLabel attributes:
<twinColumn id="twinColumn" label="Shopping list" itemsColumnLabel="Need to buy"
selectedItemsColumnLabel="Purchased"/>
Items Order
By default, items do not maintain their original position in the list. Each time an item is moved to another column, it is added to the bottom of the list. You can choose to preserve the original order of items at all times by setting reorderable = "true".
@ViewComponent
protected TwinColumn<String> twinColumn;
@Subscribe("reorderableCheckbox")
public void onReorderableCheckboxValueChange(ComponentValueChangeEvent<JmixCheckbox, Boolean> event) {
twinColumn.setReorderable(event.getValue());
}
Custom Items
Populate twinColumn programmatically from a list, a value-to-label map, or an enumeration.
<twinColumn id="twinColumnWithList"
label="Items List"/>
<twinColumn id="twinColumnWithMap"
label="Items Map"/>
<twinColumn id="twinColumnWithEnum"
label="Items Enum"/>
@ViewComponent
protected TwinColumn<Integer> twinColumnWithList;
@ViewComponent
protected TwinColumn<Integer> twinColumnWithMap;
@ViewComponent
protected TwinColumn<CustomerGrade> twinColumnWithEnum;
@Subscribe
protected void onInit(InitEvent event) {
twinColumnWithList.setItems(getItemsList());
ComponentUtils.setItemsMap(twinColumnWithMap, getItemsMap());
twinColumnWithEnum.setItems(CustomerGrade.class);
}
protected List<Integer> getItemsList() {
return List.of(2, 4, 5, 7);
}
protected Map<Integer, String> getItemsMap() {
Map<Integer, String> itemsMap = new LinkedHashMap<>();
itemsMap.put(2, "Two");
itemsMap.put(4, "Four");
itemsMap.put(5, "Five");
itemsMap.put(7, "Seven");
return itemsMap;
}
Theme Variants
Use the themeNames attribute to apply one or more theme variants.
| Variant | Description | Supported By |
|---|---|---|
|
Removes the outer border of the component. |
Aura, Lumo |
|
Removes the separators between rows. |
Lumo |
|
Uses checkmarks to indicate selected items instead of changing the row background color. |
Lumo |
|
Removes the space between action buttons. |
Aura, Lumo |
Attributes
The following attributes are specific to twinColumn:
| Name | Description | Default |
|---|---|---|
Sets the items column label. See Column Labels. |
— |
|
Sets the items container. See Basics. |
— |
|
Controls whether users can reorder items in the component. See Items Order. |
— |
|
Controls whether buttons for selecting and clearing all items are displayed. See Multi Select. |
— |
|
Sets the selected items column label. See Column Labels. |
— |
The following shared attributes are supported by twinColumn:
id - alignSelf - ariaLabel - ariaLabelledBy - classNames - colspan - css - dataContainer - enabled - height - helperText - label - maxHeight - maxWidth - minHeight - minWidth - property - readOnly - required - requiredMessage - themeNames - visible - width
Handlers
The following handlers are specific to twinColumn:
| Name | Description |
|---|---|
Validates the component value. |
The following shared handlers are supported by twinColumn:
Elements
A twinColumn can include validator as its nested elements.