JSFiddle - React, Tailwind, and code Playground

by ckissi

HTML

<div class="multiselect-container">
  <div class="multiselect-tags"></div>
  <select id="multiselect" multiple>
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option value="option3">Option 3</option>
    <option value="option4">Option 4</option>
    <option value="option5">Option 5</option>
  </select>
</div>

CSS

.multiselect-container {
  position: relative;
}

#multiselect {
  position: absolute;
  left: -9999px;
}


.multiselect-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  padding: 4px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.multiselect-tag {
  display: inline-flex;
  align-items: center;
  padding: 2px 4px;
  margin: 2px;
  background-color: #eee;
  border-radius: 4px;
}

.multiselect-tag-text {
  margin-right: 4px;
}

#multiselect {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
}

JavaScript

const multiselect = document.getElementById("multiselect");
const multiselectTags = document.querySelector(".multiselect-tags");

multiselect.addEventListener("change", (event) => {
  multiselectTags.innerHTML = "";
  const selectedOptions = Array.from(event.target.selectedOptions).map((option) => option.value);
  selectedOptions.forEach((option) => {
    const tag = document.createElement("div");
    tag.classList.add("multiselect-tag");
    const tagText = document.createElement("span");
    tagText.classList.add("multiselect-tag-text");
    tagText.textContent = option;
    const removeButton = document.createElement("button");
    removeButton.classList.add("multiselect-remove-button");
    removeButton.textContent = "x";
    removeButton.addEventListener("click", () => {
      deselectOption(option);
    });
    tag.appendChild(tagText);
    tag.appendChild(removeButton);
    multiselectTags.appendChild(tag);
  });
});

function deselectOption(option) {