← Back to all tutorials

How to create a tag input with Tailwind CSS and JavaScript

#_
Published on Jun 12 2024 by Michael Andreuzza

Recreating the tag input from the previous tutorial in with Alpine.js but with vainilla JavaScript.

How can we Utilize tag inputs in our UIs and why Are they important?

Tag inputs are a versatile feature used to enhance user interactions by allowing them to add tags to a list. These are frequently implemented in various applications, such as social media platforms, to enable users to tag posts effectively.

  • User Engagement: Enhance user interaction by enabling intuitive tag addition.
  • Versatility: Tailor tag inputs to align with specific application requirements.
  • Efficient Organization: Streamline content management through systematic tagging.
  • Enhanced Filtering: Facilitate content filtering based on tag attributes.
  • Streamlined Search: Enable users to locate content efficiently using tags.
  • Visual Representation: Create tag clouds for visualizing tag frequency and relevance.
  • Smart Suggestions: Offer tag suggestions to expedite the tagging process.
  • Autocompletion: Provide autocomplete functionality for quicker tag entry.

In summary, the incorporation of tag inputs enriches the user experience, promotes content organization, and fosters efficient navigation within applications.

Let’s write the markup

Understanding the code

  • id="tags-component" is the parent element of the tag input and tag list.
  • id="tags-input-wrapper" is the wrapper element for the input field and existing tags.
  • id="new-tag-input" is the input field for adding new tags.
  • id="tags-list" is the list element for displaying existing tags.

Note: The classes are removed for clarity.

<div id="tags-component">
  <!-- Tag Input -->
  <div id="tags-input-wrapper">
    <!-- Input Field -->
    <input id="new-tag-input" />
    <!-- Existing Tags -->
    <div id="tags-list"></div>
  </div>
</div>

Let’s write the JavaScript

Adding the event listener

  • newTagInput is the input field for adding new tags.
  • tagsList is the list element for displaying existing tags.
  • tags is an array to store the existing tags.

The new tag input event listener

  • newTagInput.addEventListener("keydown", function(event) { is the event listener for the keydown event.
  • event.key === "Enter" checks if the Enter key is pressed.
  • event.preventDefault(); prevents the default behavior of the Enter key.
  • const tag = newTagInput.value.trim(); gets the value of the newTagInput and removes any leading or trailing whitespace.
  • if (tag) { checks if the tag is not empty.
  • tags.push(tag.trim()); adds the tag to the tags array.
  • newTagInput.value = ""; clears the newTagInput value.
  • renderTags(); calls the renderTags function to update the tag list.

Rendering the tags

  • function renderTags() { is the function to render the tags.
  • tagsList.innerHTML = ""; clears the tagsList element.
  • tags.forEach((tag, index) => { loops through the tags array.
  • const tagElement = document.createElement("div"); creates a new div element for each tag.
  • tagElement.className = "inline-flex items-center gap-x-0.5 rounded-md bg-orange-50 px-2 py-1 text-xs font-medium text-orange-700 ring-1 ring-inset ring-orange-700/10"; sets the class attribute of the tagElement.
  • const tagText = document.createElement("span"); creates a new span element for the tag text.
  • tagText.textContent = tag; sets the textContent of the tagText element to the tag value.
  • const removeButton = document.createElement("button"); creates a new button element for the remove button.
  • removeButton.className = "ml-2"; sets the class attribute of the removeButton element.
  • removeButton.innerHTML = '<svg class="h-4 w-4 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>'; sets the innerHTML of the removeButton element to the SVG code for a close icon.
  • removeButton.addEventListener("click", function() { adds an event listener for the click event to the removeButton.
  • tags.splice(index, 1); removes the tag from the tags array.
  • renderTags(); calls the renderTags function to update the tag list.
  • tagElement.appendChild(tagText); appends the tagText element to the tagElement.
  • tagElement.appendChild(removeButton); appends the removeButton element to the tagElement.
  • tagsList.appendChild(tagElement); appends the tagElement to the tagsList element.
document.addEventListener("DOMContentLoaded", function() {
    const newTagInput = document.getElementById("new-tag-input");
    const tagsList = document.getElementById("tags-list");
    let tags = [];

    newTagInput.addEventListener("keydown", function(event) {
        if (event.key === "Enter") {
            event.preventDefault();
            const tag = newTagInput.value.trim();
            if (tag) {
                tags.push(tag);
                newTagInput.value = "";
                renderTags();
            }
        }
    });

    function renderTags() {
        tagsList.innerHTML = "";
        tags.forEach((tag, index) => {
            const tagElement = document.createElement("div");
            tagElement.className =
                "inline-flex items-center gap-x-0.5 rounded-md bg-orange-50 px-2 py-1 text-xs font-medium text-orange-700 ring-1 ring-inset ring-orange-700/10";

            const tagText = document.createElement("span");
            tagText.textContent = tag;

            const removeButton = document.createElement("button");
            removeButton.className = "ml-2";
            removeButton.innerHTML =
                '<svg class="h-4 w-4 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>';
            removeButton.addEventListener("click", function() {
                tags.splice(index, 1);
                renderTags();
            });

            tagElement.appendChild(tagText);
            tagElement.appendChild(removeButton);
            tagsList.appendChild(tagElement);
        });
    }
});

Conclusion

In this tutorial, we created a tag input using Tailwind CSS and JavaScript. We added an event listener to the newTagInput element to handle the keydown event and prevent the default behavior of the Enter key. We also created a function to render the tags and added an event listener to the removeButton element to remove the tag from the tags array. Finally, we updated the tagsList element with the new tag and removed the old tag.

Remember to customize it and adapt it to your specific use case and make it more user-friendly and accessible.

Hope you enjoyed this tutorial and have a good day!

/Michael Andreuzza

Did you like this tutorial? Please share it with your friends!

Reviews and opinions

  • "I bought a beautiful theme from Lexington a couple weeks ago. I didn't know Astro at the time, but Michael helped me get set up and really went above and beyond with his support. Now I'm happily redoing my site to look gorgeous with his template."

    Stuart

    Stuart

    Creator of saasydb.com

  • "Michael is one of the best designers on Twitter, would highly recommend his Lexington Themes if you want something in tailwind that doesn’t look the same as everyone else!"

    Alex Hughes

    Alex Hughes

    letsloopin.com

Get lifetime access to every theme available today for $199 and own them forever. Plus, new themes, lifetime updates, use on unlimited projects and enjoy lifetime support.

No subscription required!

Lexington

Beautifully designed HTML, Astro.js and Tailwind themes! Save months of time and build your startup landing page in minutes.