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

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

There is a newer version: 2.0.4
Show newest version
/*
 * Copyright © 2019 Dominokit
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.dominokit.domino.ui.forms;

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;

import elemental2.dom.HTMLDivElement;
import elemental2.dom.HTMLElement;
import java.util.List;
import java.util.Objects;
import org.dominokit.domino.ui.dropdown.DropDownMenu;
import org.dominokit.domino.ui.grid.flex.FlexItem;
import org.dominokit.domino.ui.icons.Icon;
import org.dominokit.domino.ui.icons.Icons;
import org.dominokit.domino.ui.style.Styles;
import org.dominokit.domino.ui.utils.ElementUtil;

/**
 * A component that allow selecting a single option from a DropDownMenu
 *
 * @param  The type of a single option value
 */
public class Select extends AbstractSelect> {

  private SelectOption selectedOption;

  /**
   * Creates an instance without a label
   *
   * @param  Type the select options value
   * @return new Select instance
   */
  public static  Select create() {
    return new Select<>();
  }

  /**
   * Creates an instance with a label
   *
   * @param label String
   * @param  Type the select options value
   * @return new Select instance
   */
  public static  Select create(String label) {
    return new Select<>(label);
  }

  /**
   * Creates an instance with a label and initialized with a list of options
   *
   * @param label String
   * @param options List of {@link SelectOption}
   * @param  Type the select options value
   * @return new Select instance
   */
  public static  Select create(String label, List> options) {
    return new Select<>(label, options);
  }

  /**
   * Creates an instance without a label and initialized with a list of options
   *
   * @param options List of {@link SelectOption}
   * @param  Type the select options value
   * @return new Select instance
   */
  public static  Select create(List> options) {
    return new Select<>(options);
  }

  public static > Select ofEnum(String label, T[] values) {
    Select select = create(label);
    for (T value : values) {
      select.appendChild(SelectOption.create(value, value.name(), value.toString()));
    }
    return select;
  }

  /** Creates an instance without a label */
  public Select() {
    setOptionRenderer(new SingleOptionRenderer());
  }

  /**
   * Creates an instance with a label
   *
   * @param label String
   */
  public Select(String label) {
    super(label);
    setOptionRenderer(new SingleOptionRenderer());
  }

  /**
   * Creates an instance without a label and initialized with a list of options
   *
   * @param options List of {@link SelectOption}
   */
  public Select(List> options) {
    super(options);
    setOptionRenderer(new SingleOptionRenderer());
  }

  /**
   * Creates an instance with a label and initialized with a list of options
   *
   * @param label String
   * @param options List of {@link SelectOption}
   */
  public Select(String label, List> options) {
    super(label, options);
    setOptionRenderer(new SingleOptionRenderer());
  }

  /** {@inheritDoc} */
  @Override
  public DropDownMenu getOptionsMenu() {
    return super.getOptionsMenu();
  }

  /** {@inheritDoc} */
  @Override
  public Select select(SelectOption option, boolean silent) {
    if (nonNull(selectedOption) && !option.isEqualNode(selectedOption.element())) {
      selectedOption.deselect();
    }
    floatLabel();
    this.selectedOption = option;
    option.select();
    valuesContainer.setTextContent(option.getDisplayValue());
    hidePlaceholder();
    if (!silent) onSelection(option);
    return this;
  }

  /** @return The currently Select {@link SelectOption} */
  public SelectOption getSelectedOption() {
    return selectedOption;
  }

  /** {@inheritDoc} */
  @Override
  public Select setValue(T value, boolean silent) {
    for (SelectOption option : getOptions()) {
      if (Objects.equals(option.getValue(), value)) {
        select(option, silent);
        return this;
      }
    }

    // if not found, then same as clear & doClear but pass silent to deselect
    if (nonNull(selectedOption)) {
      unfloatLabel();
      selectedOption.deselect(silent);
      selectedOption = null;
      valuesContainer.setTextContent("");
      showPlaceholder();
    }

    return this;
  }

  /** {@inheritDoc} */
  @Override
  public T getValue() {
    return isSelected() ? getSelectedOption().getValue() : null;
  }

  /** {@inheritDoc} */
  @Override
  public String getStringValue() {
    SelectOption selectedOption = getSelectedOption();
    if (nonNull(selectedOption)) {
      return selectedOption.getDisplayValue();
    }
    return null;
  }

  /** {@inheritDoc} */
  @Override
  protected void clearValue(boolean silent) {
    if (nonNull(selectedOption)) {
      selectedOption.deselect(silent);
      selectedOption = null;
    }
  }

  /** @return int index of selected {@link SelectOption} */
  public int getSelectedIndex() {
    return options.indexOf(getSelectedOption());
  }

  /** {@inheritDoc} */
  @Override
  protected void scrollToSelectedOption() {
    if (nonNull(selectedOption)) {
      ElementUtil.scrollIntoParent(
          selectedOption.element(), getOptionsMenu().getMenuElement().element());
    }
  }

  @Override
  public boolean isEmpty() {
    return isNull(getValue());
  }

  @Override
  public boolean isEmptyIgnoreSpaces() {
    return isEmpty();
  }

  @Override
  public boolean isSelected() {
    return nonNull(selectedOption);
  }

  private class SingleOptionRenderer implements OptionRenderer {

    @Override
    public HTMLElement element(SelectOption option) {
      Icon checkMark =
          Icons.ALL.check().addCss(Styles.pull_right).addCss("select-option-check-mark");
      FlexItem checkMarkFlexItem = FlexItem.create();
      checkMarkFlexItem.appendChild(checkMark);
      option.getOptionLayoutElement().appendChild(checkMarkFlexItem);

      checkMark.toggleDisplay(option.isSelected());
      option.addSelectionHandler(selectable -> checkMark.toggleDisplay(selectable.isSelected()));
      return option.element();
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy