org.dominokit.domino.ui.forms.MultiSelect Maven / Gradle / Ivy
package org.dominokit.domino.ui.forms;
import org.dominokit.domino.ui.utils.ElementUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
public class MultiSelect extends AbstractSelect, T, MultiSelect> {
private static final String DEFAULT_SEPARATOR = ",";
private ValueRenderer valueRenderer = this::renderSelectedOptions;
private List> selectedOptions = new ArrayList<>();
private String selectedOptionsSeparator;
public static MultiSelect create() {
return new MultiSelect<>();
}
public static MultiSelect create(String label) {
return new MultiSelect<>(label);
}
public static MultiSelect create(String label, List> options) {
return new MultiSelect<>(label, options);
}
public static MultiSelect create(List> options) {
return new MultiSelect<>(options);
}
public static > MultiSelect ofEnum(String label, T[] values) {
MultiSelect select = create(label);
for (T value : values) {
select.appendChild(SelectOption.create(value, value.name(), value.toString()));
}
return select;
}
public MultiSelect() {
}
public MultiSelect(String label) {
super(label);
}
public MultiSelect(String label, List> options) {
super(label, options);
}
public MultiSelect(List> options) {
super(options);
}
@Override
public MultiSelect select(SelectOption option, boolean silent) {
floatLabel();
if (this.selectedOptions.contains(option)) {
option.deselect(silent);
selectedOptions.remove(option);
} else {
this.selectedOptions.add(option);
option.select();
}
valueRenderer.render();
if (!silent)
onSelection(option);
return this;
}
@Override
public MultiSelect setValue(List value, boolean silent) {
if (isNull(value))
return this;
for (SelectOption option : getOptions()) {
if (value.contains(option.getValue())) {
select(option, silent);
}
}
return this;
}
private void renderSelectedOptions() {
buttonValueContainer.setTextContent(getStringValue());
}
public List> getSelectedOptions() {
return selectedOptions;
}
@Override
public List getValue() {
return selectedOptions.stream()
.map(SelectOption::getValue)
.collect(Collectors.toList());
}
public String getSelectedOptionsSeparator() {
return selectedOptionsSeparator;
}
public void setSelectedOptionsSeparator(String selectedOptionsSeparator) {
this.selectedOptionsSeparator = selectedOptionsSeparator;
}
@Override
public String getStringValue() {
return selectedOptions.stream()
.map(SelectOption::getDisplayValue)
.collect(Collectors.joining(isNull(selectedOptionsSeparator) ? DEFAULT_SEPARATOR : selectedOptionsSeparator));
}
@Override
public MultiSelect clear() {
selectedOptions.clear();
return super.clear();
}
public List getSelectedIndex() {
return getSelectedOptions()
.stream()
.map(option -> options.indexOf(option))
.collect(Collectors.toList());
}
public void setValueRenderer(ValueRenderer valueRenderer) {
this.valueRenderer = valueRenderer;
}
@Override
protected void scrollToSelectedOption() {
List> selectedOptions = getSelectedOptions();
if(nonNull(selectedOptions) && !selectedOptions.isEmpty()){
ElementUtil.scrollIntoParent(selectedOptions.get(0).element(), getOptionsMenu().getMenuElement().element());
}
}
@FunctionalInterface
public interface ValueRenderer {
void render();
}
}