Other

Multi-Select

05 Oct 2022

Multi Select - це селект, завдяки якому можно вибудовувати дерево різних опцій.
HTML
SCSS
JS
                            <div class="multi-select-item">
    <input type="text" class="multi-select" placeholder="Location" />
</div>
                        
                            input {
  position: relative;
  border-radius: 0;
  width: 100%;
  resize: none;
  color: #161626;
  font-size: 14px;
  border: 1px solid #161626;
  background: #ffffff;
  font-family: var(--font-main);

  &::placeholder {
    text-transform: uppercase;
    color: var(--black);
    font-size: 14px;
    font-weight: 600;
  }
}

span {
  display: block;
}

.comboTreeInputBox, .comboTreeDropDownContainer input{
  padding: 10px 20px;
}


.comboTreeDropDownContainer  {
  overflow: hidden;
  border-radius: 0 0 5px 5px;

  ul {
    color: #161626;
    background: #fff;
  }

  li {
    position: relative;
  }

  .comboTreeItemTitle {
    position: relative;
    padding-left: 20px;

    input {
      position: absolute;
      top: 50%;
      left: 4px;
      transform: translateY(-50%);
      opacity: 0;
      cursor: pointer;
    }

    &::before {
      content: '';
      position: absolute;
      width: 12px;
      height: 12px;
      border: 1px solid #161626;
      left: 4px;
      top: 0;
      bottom: 0;
      margin: auto;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 11px;
      color: #ffffff;
    }

    &.comboTreeItemHover {
      background-color: #EBEDEE !important;
      border-radius: 0 !important;
      color: #161626 !important;
    }

    &.selected {
      &::before {
        content: '\2713';
        background: #3cfbaf;
        border: 1px solid #3cfbaf;
      }
    }
  }
}

.comboTreeInputWrapper input{
  border: none;
}

.comboTreeInputBox {
  border-radius: 5px 5px 0 0;

  &:focus {
    border: none !important;
    & + .comboTreeArrowBtn {
      border: none !important;
    }
  }
}

.comboTreeParentPlus {
  cursor: pointer;
  top: 10px;
  left: 5px;
  position: absolute;
  z-index: 10;

  display: flex;
  align-items: center;
  justify-content: center;

  span {
    &::before {
      content: '';
      display: block;
      width: 8px;
      height: 8px;
      background: url("../images/arrow.svg") no-repeat center / contain;
    }
  }
}

.comboTreeArrowBtn {
  width: 12px;
  height: 12px;
  top: 50%;
  right: 45px;
  transform: translateY(-50%);
  border-radius: 0;
  border: none;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  display: none;

  &::after {
    content: '\2716';
    color: #161626;
    font-size: 15px;
  }

  &.show {
    display: flex;
  }
}
                        
                            // Locations
const locations = [
  {
    id: 0,
    title: "UK & Ireland",
    subs: [
      {
        id: 0,
        title: "Avon",
      },
      {
        id: 1,
        title: "Ireland",
      },
      {
        id: 2,
        title: "London",
      },
    ],
  },
  {
    id: 1,
    title: "Central Europe",
  },
  {
    id: 2,
    title: "Southern Europe",
  },
];

let locationParents = [];

locations.forEach((elem) => {
  if (elem.subs) {
    locationParents.push(elem.title);
  }
});

function limitInput(input) {
    const items = input.value.split(", ");

    return items.length > 1
        ? (input.value = `${items.length} selected`)
        : (input.value = `${items[0]}`);
}

function multiSelection(selectTree) {
    selectTree.onChange(() => {
        const mainInput = selectTree.elemInput;
        const inputHidden = selectTree._elemWrapper[0].nextElementSibling;

        let selectedItems = selectTree.getSelectedNames()
            ? selectTree.getSelectedNames()
            : [];

        if (selectedItems.length) {
            selectedItems = selectedItems.filter(function (el) {
                return locationParents.indexOf(el) < 0;
            });
        }

        // Change input value
        limitInput(mainInput);

        if (selectTree.getSelectedIds()) {
            inputHidden.value = selectTree
                .getSelectedIds()
                .filter((elem) => elem[0] !== "#");
        } else {
            inputHidden.value = "";
        }
    });
}

const multiSelect = $(".multi-select");
if (multiSelect) {
    // Select options
    const selectTree = multiSelect.comboTree({
        source: locations,
        isMultiple: true,
        cascadeSelect: true,
    });

    multiSelection(selectTree);
}
                        

Для реалізації використовується плагін ComboTree

Файли плагіну закріплені нижче :)

Для подальшої роботи на етапі бек-енду необхідно у кінці php файлу, де використовується селект, додавати масив даних.

Image

Image

treeSelectJS.zip

0