org.dominokit.domino.ui.forms.RadioGroup Maven / Gradle / Ivy
package org.dominokit.domino.ui.forms;
import elemental2.dom.HTMLElement;
import elemental2.dom.HTMLLabelElement;
import elemental2.dom.Node;
import org.dominokit.domino.ui.grid.flex.FlexDirection;
import org.dominokit.domino.ui.grid.flex.FlexLayout;
import org.jboss.elemento.Elements;
import org.jboss.elemento.IsElement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static java.util.Objects.nonNull;
public class RadioGroup extends AbstractValueBox, HTMLElement, T> {
private List> radios = new ArrayList<>();
private String name;
private FlexLayout flexLayout;
public RadioGroup(String name) {
this(name, "");
}
public RadioGroup(String name, String label) {
super("RadioGroup", label);
init(this);
css("radio-group");
setLabel(label);
setName(name);
vertical();
}
public static RadioGroup create(String name) {
return new RadioGroup<>(name);
}
public static RadioGroup create(String name, String label) {
return new RadioGroup<>(name, label);
}
public RadioGroup appendChild(Radio extends T> radio) {
return appendChild(radio, (Node) null);
}
public RadioGroup appendChild(Radio extends T> radio, Node content) {
radio.setName(name);
radio.addChangeHandler(value -> onCheck(radio));
radio.setGroup(this);
if (radio.isChecked()) {
radios.forEach(r -> r.uncheck(true));
}
radios.add(radio);
if (nonNull(content)) {
radio.appendChild(content);
}
flexLayout.appendChild(radio);
return this;
}
public RadioGroup appendChild(Radio extends T> radio, IsElement> content) {
return appendChild(radio, content.element());
}
private void onCheck(Radio extends T> selectedRadio) {
for (ChangeHandler super T> changeHandler : changeHandlers) {
changeHandler.onValueChanged(selectedRadio.getValue());
}
}
public RadioGroup horizontal() {
flexLayout.setDirection(FlexDirection.LEFT_TO_RIGHT);
removeCss("horizontal");
css("horizontal");
return this;
}
public RadioGroup vertical() {
flexLayout.setDirection(FlexDirection.TOP_TO_BOTTOM);
removeCss("horizontal");
return this;
}
@Override
public RadioGroup invalidate(String errorMessage) {
invalidate(Collections.singletonList(errorMessage));
return this;
}
protected HTMLLabelElement makeErrorLabel(String message) {
return Elements.label().css("error").textContent(message).element();
}
public List> getRadios() {
return radios;
}
public boolean isSelected() {
return getValue() != null;
}
public T getValue() {
return radios.stream().filter(Radio::isChecked).map(Radio::getValue).findFirst().orElse(null);
}
@Override
public boolean isEmpty() {
return !isSelected();
}
@Override
public RadioGroup clear() {
radios.forEach(Radio::uncheck);
return this;
}
@Override
public RadioGroup groupBy(FieldsGrouping fieldsGrouping) {
fieldsGrouping.addFormElement(this);
return this;
}
@Override
public RadioGroup ungroup(FieldsGrouping fieldsGrouping) {
fieldsGrouping.removeFormElement(this);
return this;
}
@Override
public String getName() {
return name;
}
@Override
public RadioGroup setName(String name) {
this.name = name;
return this;
}
@Override
public RadioGroup enable() {
radios.forEach(Radio::enable);
return this;
}
@Override
public RadioGroup disable() {
radios.forEach(Radio::disable);
return this;
}
@Override
public boolean isEnabled() {
return radios.stream().allMatch(Radio::isEnabled);
}
public void setValue(Radio value) {
Radio radioToSelect = radios.stream().filter(radio -> radio.getValue().equals(value))
.findFirst().orElse(null);
if (nonNull(radioToSelect)) {
radioToSelect.check();
}
}
@Override
public void setValue(T value) {
Radio radioToSelect = radios.stream().filter(radio -> radio.getValue().equals(value))
.findFirst().orElse(null);
if (nonNull(radioToSelect)) {
radioToSelect.check();
}
}
public Radio getSelectedRadio() {
return (Radio) radios.stream()
.filter(Radio::isChecked)
.findFirst()
.orElse(null);
}
@Override
protected HTMLElement createInputElement(String type) {
flexLayout = FlexLayout.create();
return flexLayout.element();
}
@Override
protected AutoValidator createAutoValidator(AutoValidate autoValidate) {
return new RadioAutoValidator<>(this, autoValidate);
}
public RadioGroup condense() {
removeCss("condensed");
css("condensed");
return this;
}
public RadioGroup spread() {
removeCss("condensed");
return this;
}
public RadioGroup setCondensed(boolean condensed) {
if (condensed) {
return condense();
} else {
return spread();
}
}
@Override
protected void clearValue() {
}
@Override
protected void doSetValue(T value) {
}
private static class RadioAutoValidator extends AutoValidator {
private RadioGroup radioGroup;
private ChangeHandler changeHandler;
public RadioAutoValidator(RadioGroup radioGroup, AutoValidate autoValidate) {
super(autoValidate);
this.radioGroup = radioGroup;
}
@Override
public void attach() {
changeHandler = value -> autoValidate.apply();
radioGroup.getRadios()
.forEach(radio -> radio.addChangeHandler(changeHandler));
}
@Override
public void remove() {
radioGroup.getRadios()
.forEach(radio -> radio.removeChangeHandler(changeHandler));
}
}
}