Skip to content

Commit e24c2e9

Browse files
committed
Add option to allow wrapping MultiSelect selected options and show selected options counter
fix #1020
1 parent 314db71 commit e24c2e9

File tree

5 files changed

+72
-8
lines changed

5 files changed

+72
-8
lines changed

domino-ui/src/main/java/org/dominokit/domino/ui/config/FormsFieldsConfig.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ default boolean isFormFieldFloatLabelLeft() {
146146
return false;
147147
}
148148

149+
default String multiSelectSelectionCountFormatExpression(int count) {
150+
return count + " Selected";
151+
}
152+
149153
interface NumberParsers {
150154
default Function<String, BigDecimal> bigDecimalParser(BigDecimalBox field) {
151155
return value -> BigDecimal.valueOf(field.parseDouble(value));

domino-ui/src/main/java/org/dominokit/domino/ui/forms/suggest/AbstractSelect.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public AbstractSelect() {
9494
.appendChild(
9595
fieldInput =
9696
div()
97-
.addCss(dui_field_input)
97+
.addCss(dui_field_input, dui_flex_nowrap)
9898
.appendChild(placeHolderElement.addCss(dui_field_placeholder)))
9999
.appendChild(inputElement = input(getType()).addCss(dui_hidden_input))
100100
.appendChild(

domino-ui/src/main/java/org/dominokit/domino/ui/forms/suggest/CheckOption.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
*/
3838
public class CheckOption<V> extends SelectOption<V> {
3939

40+
private CheckBox checkbox;
41+
4042
/**
4143
* Creates a new CheckOption with the provided key, value, and text.
4244
*
@@ -156,7 +158,7 @@ private void initCheckBox() {
156158
(option, self) -> {
157159
self.withPrefixElement(
158160
(menuItem, pre) -> {
159-
CheckBox checkbox = CheckBox.create().addCss(dui_minified);
161+
checkbox = CheckBox.create().addCss(dui_minified);
160162
pre.appendChild(checkbox);
161163
checkbox.addChangeListener(
162164
(oldValue, newValue) -> {
@@ -166,13 +168,19 @@ private void initCheckBox() {
166168
menuItem.deselect();
167169
}
168170
});
169-
170-
menuItem.addSelectionHandler(
171-
menuItemValue -> checkbox.withValue(menuItem.isSelected(), true));
172-
173-
menuItem.addDeselectionHandler(
174-
() -> checkbox.withValue(menuItem.isSelected(), true));
175171
});
176172
});
177173
}
174+
175+
@Override
176+
public SelectOption<V> onSelected() {
177+
checkbox.withValue(true, true);
178+
return super.onSelected();
179+
}
180+
181+
@Override
182+
public SelectOption<V> onDeselected() {
183+
checkbox.withValue(false, true);
184+
return super.onDeselected();
185+
}
178186
}

domino-ui/src/main/java/org/dominokit/domino/ui/forms/suggest/MultiSelect.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,20 @@
1717

1818
import static java.util.Objects.isNull;
1919
import static java.util.Objects.nonNull;
20+
import static org.dominokit.domino.ui.style.DisplayCss.dui_hidden;
21+
import static org.dominokit.domino.ui.style.SpacingCss.dui_flex_nowrap;
2022

2123
import java.util.Arrays;
2224
import java.util.HashSet;
2325
import java.util.List;
2426
import java.util.Optional;
2527
import java.util.Set;
2628
import java.util.stream.Collectors;
29+
import org.dominokit.domino.ui.badges.Badge;
2730
import org.dominokit.domino.ui.elements.DivElement;
31+
import org.dominokit.domino.ui.style.BooleanCssClass;
2832
import org.dominokit.domino.ui.utils.BaseDominoElement;
33+
import org.dominokit.domino.ui.utils.PrimaryAddOn;
2934

3035
/**
3136
* Represents a multi-selection dropdown menu UI component, allowing users to select multiple
@@ -45,6 +50,7 @@ public class MultiSelect<V>
4550
extends AbstractSelect<V, List<V>, DivElement, SelectOption<V>, MultiSelect<V>> {
4651

4752
private Set<SelectOption<V>> selectedOptions = new HashSet<>();
53+
private Badge selectionCountBadge;
4854

4955
/**
5056
* Creates a new instance of {@link MultiSelect} without any predefined label.
@@ -71,6 +77,9 @@ public static <V> MultiSelect<V> create(String label) {
7177
public MultiSelect() {
7278
optionsMenu.setMultiSelect(true);
7379
setAutoCloseOnSelect(false);
80+
selectionCountBadge =
81+
Badge.create(getConfig().multiSelectSelectionCountFormatExpression(0)).addCss(dui_hidden);
82+
appendChild(PrimaryAddOn.of(selectionCountBadge));
7483
}
7584

7685
/**
@@ -163,6 +172,9 @@ protected void onOptionSelected(SelectOption<V> option, boolean silent) {
163172
fieldInput.appendChild(option);
164173
selectedOptions.add(option);
165174
getInputElement().element().focus();
175+
selectionCountBadge.setText(
176+
getConfig().multiSelectSelectionCountFormatExpression(selectedOptions.size()));
177+
option.onSelected();
166178
}
167179

168180
/**
@@ -199,6 +211,9 @@ protected void onOptionDeselected(SelectOption<V> option, boolean silent) {
199211
if (!silent) {
200212
triggerChangeListeners(oldValue, getValue());
201213
}
214+
selectionCountBadge.setText(
215+
getConfig().multiSelectSelectionCountFormatExpression(selectedOptions.size()));
216+
option.onDeselected();
202217
}
203218
}
204219

@@ -243,4 +258,33 @@ protected void onTypingEnd() {
243258
protected void onOptionRemoved(SelectOption<V> option) {
244259
selectedOptions.remove(option);
245260
}
261+
262+
/**
263+
* Sets whether the selection should wrap or not.
264+
*
265+
* <p>If {@code wrapSelection} is {@code true}, the selection will wrap. Otherwise, it will be
266+
* forced to stay on a single line using a no-wrap CSS class.
267+
*
268+
* @param wrapSelection {@code true} to allow wrapping, {@code false} to prevent wrapping
269+
* @return this {@code MultiSelect} instance for method chaining
270+
*/
271+
public MultiSelect<V> setWrapSelection(boolean wrapSelection) {
272+
fieldInput.addCss(BooleanCssClass.of(dui_flex_nowrap, !wrapSelection));
273+
return this;
274+
}
275+
276+
/**
277+
* Sets whether the selection count badge should be visible.
278+
*
279+
* <p>If {@code showSelectionCount} is {@code true}, the selection count badge will be shown.
280+
* Otherwise, it will be hidden using the appropriate CSS class.
281+
*
282+
* @param showSelectionCount {@code true} to display the selection count badge, {@code false} to
283+
* hide it
284+
* @return this {@code MultiSelect} instance for method chaining
285+
*/
286+
public MultiSelect<V> setShowSelectionCount(boolean showSelectionCount) {
287+
selectionCountBadge.addCss(BooleanCssClass.of(dui_hidden, !showSelectionCount));
288+
return this;
289+
}
246290
}

domino-ui/src/main/java/org/dominokit/domino/ui/forms/suggest/Option.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,14 @@ private void cleanHighlight(Node node) {
257257
}
258258
}
259259

260+
public O onSelected() {
261+
return (O) this;
262+
}
263+
264+
public O onDeselected() {
265+
return (O) this;
266+
}
267+
260268
/**
261269
* Functional interface for supplying an instance of a type {@code T} based on a key and a value.
262270
*

0 commit comments

Comments
 (0)