All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dominokit.domino.ui.forms.SuggestBox Maven / Gradle / Ivy

package org.dominokit.domino.ui.forms;

import elemental2.dom.DomGlobal;
import elemental2.dom.Element;
import elemental2.dom.HTMLDivElement;
import elemental2.dom.HTMLInputElement;
import org.dominokit.domino.ui.dropdown.DropDownMenu;
import org.dominokit.domino.ui.dropdown.DropdownAction;
import org.dominokit.domino.ui.loaders.Loader;
import org.dominokit.domino.ui.loaders.LoaderEffect;
import org.dominokit.domino.ui.utils.DelayedTextInput;
import org.dominokit.domino.ui.utils.HasSelectionHandler;
import org.jboss.gwt.elemento.core.Elements;

import java.util.ArrayList;
import java.util.List;

import static java.util.Objects.nonNull;
import static org.jboss.gwt.elemento.core.Elements.div;

public class SuggestBox extends AbstractValueBox implements HasSelectionHandler {

    private static final String TEXT = "text";
    private DropDownMenu suggestionsMenu;
    private List> selectionHandlers = new ArrayList<>();
    private SuggestBoxStore store;
    private HTMLDivElement loaderContainer = div().css("suggest-box-loader").asElement();
    private Loader loader;

    public SuggestBox() {
        this("");
    }

    public SuggestBox(String label) {
        this(label, null);
    }

    public SuggestBox(SuggestBoxStore store) {
        this("", store);
    }

    public SuggestBox(String label, SuggestBoxStore store) {
        this(TEXT, label, store);
    }

    public SuggestBox(String type, String label, SuggestBoxStore store) {
        super(type, label);
        this.store = store;
        suggestionsMenu = DropDownMenu.create(getInputElement());
        suggestionsMenu.addCloseHandler(this::focus);
        Element element = DomGlobal.document.querySelector(".content");
        element.addEventListener("transitionend", evt -> {
            suggestionsMenu.style().setWidth(asElement().offsetWidth + "px");
        });
        onAttached(mutationRecord -> {
            suggestionsMenu.style().setWidth(asElement().offsetWidth + "px");
        });
        getFieldContainer().insertFirst(loaderContainer);
        setLoaderEffect(LoaderEffect.IOS);

        DelayedTextInput.create(getInputElement(), 200)
                .setDelayedAction(() -> {
                    if (isEmpty()) {
                        suggestionsMenu.close();
                    } else {
                        search();
                    }
                });
    }

    private void search() {
        if (store != null) {
            loader.start();
            suggestionsMenu.clearActions();
            suggestionsMenu.close();
            store.filter(getValue(), suggestions -> {
                suggestionsMenu.clearActions();
                suggestions.forEach(suggestion -> {
                    suggestion.highlight(SuggestBox.this.getValue());
                    suggestionsMenu.appendChild(SuggestBox.this.dropdownAction(suggestion));
                });
                suggestionsMenu.open();
                loader.stop();
            });
        }
    }

    public static SuggestBox create(SuggestBoxStore store) {
        return new SuggestBox(store);
    }

    public static SuggestBox create(String label, SuggestBoxStore store) {
        return new SuggestBox(label, store);
    }

    @Override
    protected HTMLInputElement createInputElement(String type) {
        return Elements.input(type).css("form-control").asElement();
    }

    @Override
    protected void clearValue() {
        value("");
    }

    @Override
    protected void doSetValue(String value) {
        if (nonNull(value)) {
            getInputElement().asElement().value = value;
        } else {
            getInputElement().asElement().value = "";
        }
    }

    @Override
    public String getValue() {
        return getInputElement().asElement().value;
    }

    public SuggestBox setSuggestBoxStore(SuggestBoxStore store) {
        this.store = store;
        return this;
    }

    public SuggestBox setType(String type) {
        getInputElement().asElement().type = type;
        return this;
    }

    @Override
    public String getStringValue() {
        return getValue();
    }

    private DropdownAction dropdownAction(SuggestItem suggestItem) {
        DropdownAction suggestionAction = DropdownAction.create(suggestItem.getValue(), suggestItem.asElement());
        suggestionAction.addSelectionHandler(value -> {
            setValue(value);
            selectionHandlers.forEach(handler -> handler.onSelection(suggestItem));
            suggestionsMenu.close();
        });
        return suggestionAction;
    }

    @Override
    public SuggestBox addSelectionHandler(SelectionHandler selectionHandler) {
        selectionHandlers.add(selectionHandler);
        return this;
    }

    @Override
    public SuggestBox removeSelectionHandler(SelectionHandler selectionHandler) {
        selectionHandlers.remove(selectionHandler);
        return this;
    }

    public SuggestBox setLoaderEffect(LoaderEffect loaderEffect) {
        loader = Loader.create(loaderContainer, loaderEffect)
                .setSize("20px", "20px")
                .setRemoveLoadingText(true);
        return this;
    }

    public Loader getLoader() {
        return loader;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy