Lightweight, efficient Tags input component in Vanilla JS. Refer the offical library demo page for more options: https://yaireo.github.io/tagify/
Usage
In order to use Tagify on your page, It is required to include the following vendors css in the "Vendors CSS" area from the page's header:
<link rel="stylesheet" href="../../assets/vendor/libs/tagify/tagify.css"/>
Include the following vendors script in the "Vendors JS" area from the page's footer:
<script src="../../assets/vendor/libs/tagify/tagify.js"></script>
<script src="../../assets/js/forms-tagify.js"></script>
Basic
To create a basic tagify input by initialize tagify like this: new Tagify(YOUR_ELEment);
.
<div class="form-floating form-floating-outline">
<input id="TagifyBasic" class="form-control" name="TagifyBasic" value="Tag1, Tag2, Tag3" />
<label for="TagifyBasic">Basic</label>
</div>
const tagifyBasicEl = document.querySelector("#TagifyBasic");
const TagifyBasic = new Tagify(tagifyBasicEl);
Read Only
Use readonly
attribute with input and initialize it to create a readonly tagify.
<div class="form-floating form-floating-outline">
<input id="TagifyReadonly" class="form-control" readonly value="Tag1, Tag2, Tag3" />
<label for="TagifyReadonly">Readonly</label>
</div>
const tagifyReadonlyEl = document.querySelector("#TagifyReadonly");
const TagifyReadonly = new Tagify(tagifyReadonlyEl);
Custom Suggestion: Inline
Create inline tags input with multiple selection.
<div class="form-floating form-floating-outline">
<input id="TagifyCustomInlineSuggestion" name="TagifyCustomInlineSuggestion" class="form-control h-auto" placeholder="select technologies" value="css, html, javascript">
<label for="TagifyCustomInlineSuggestion">Custom Inline Suggestions</label>
</div>
<div class="form-floating form-floating-outline">
<input id="TagifyCustomInlineSuggestion" name="TagifyCustomInlineSuggestion" class="form-control h-auto" placeholder="select technologies" value="css, html, javascript">
<label for="TagifyCustomInlineSuggestion">Custom Inline Suggestions</label>
</div>
Custom Suggestion: List
Create list tags input with multiple selection.
<div class="form-floating form-floating-outline">
<input id="TagifyCustomListSuggestion" name="TagifyCustomListSuggestion" class="form-control h-auto" placeholder="select technologies" value="css, html, php">
<label for="TagifyCustomListSuggestion">Custom List Suggestions</label>
</div>
const TagifyCustomListSuggestionEl = document.querySelector("#TagifyCustomListSuggestion");
const whitelist = [
"A# .NET",
"A# (Axiom)",
"A-0 System",
"A+",
"A++",
"ABAP",
"ABC",
"ABC ALGOL",
"ABSET",
"ABSYS",
"ACC",
"Accent",
"Ace DASL",
"ACL2",
"Avicsoft",
"ACT-III",
"Action!",
"ActionScript",
"Ada",
"Adenine",
"Agda",
"Agilent VEE",
"Agora",
"AIMMS",
"Alef",
"ALF",
"ALGOL 58",
"ALGOL 60",
"ALGOL 68",
"ALGOL W",
"Alice",
"Alma-0",
"AmbientTalk",
"Amiga E",
"AMOS",
"AMPL",
"Apex (Salesforce.com)",
"APL",
"AppleScript",
"Arc",
"ARexx",
"Argus",
"AspectJ",
"Assembly language",
"ATS",
"Ateji PX",
"AutoHotkey",
"Autocoder",
"AutoIt",
"AutoLISP / Visual LISP",
"Averest",
"AWK",
"Axum",
"Active Server Pages",
"ASP.NET"
];
// List
let TagifyCustomListSuggestion = new Tagify(TagifyCustomListSuggestionEl, {
whitelist: whitelist,
maxTags: 10, // allows to select max items
dropdown: {
maxItems: 20, // display max items
classname: "", // Custom inline class
enabled: 0,
closeOnSelect: false
}
});
Users List
This example shows how to customize Tagify further. It also includes an 'Add all' option as the first item in the suggestions dropdown list.
<div class="form-floating form-floating-outline">
<input id="TagifyUserList" name="TagifyUserList" class="form-control h-auto" value="abatisse2@nih.gov, Justinian Hattersley" />
<label for="TagifyUserList">Users List</label>
</div>
const TagifyUserListEl = document.querySelector("#TagifyUserList");
const usersList = [
{
value: 1,
name: "Justinian Hattersley",
avatar: "https://i.pravatar.cc/80?img=1",
email: "jhattersley0@ucsd.edu"
},
{
value: 2,
name: "Antons Esson",
avatar: "https://i.pravatar.cc/80?img=2",
email: "aesson1@ning.com"
},
{
value: 3,
name: "Ardeen Batisse",
avatar: "https://i.pravatar.cc/80?img=3",
email: "abatisse2@nih.gov"
},
{
value: 4,
name: "Graeme Yellowley",
avatar: "https://i.pravatar.cc/80?img=4",
email: "gyellowley3@behance.net"
},
{
value: 5,
name: "Dido Wilford",
avatar: "https://i.pravatar.cc/80?img=5",
email: "dwilford4@jugem.jp"
},
{
value: 6,
name: "Celesta Orwin",
avatar: "https://i.pravatar.cc/80?img=6",
email: "corwin5@meetup.com"
},
{
value: 7,
name: "Sally Main",
avatar: "https://i.pravatar.cc/80?img=7",
email: "smain6@techcrunch.com"
},
{
value: 8,
name: "Grethel Haysman",
avatar: "https://i.pravatar.cc/80?img=8",
email: "ghaysman7@mashable.com"
},
{
value: 9,
name: "Marvin Mandrake",
avatar: "https://i.pravatar.cc/80?img=9",
email: "mmandrake8@sourceforge.net"
},
{
value: 10,
name: "Corrie Tidey",
avatar: "https://i.pravatar.cc/80?img=10",
email: "ctidey9@youtube.com"
}
];
function tagTemplate(tagData) {
return `
<tag title="${tagData.title || tagData.email}"
contenteditable='false'
spellcheck='false'
tabIndex="-1"
class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ''}"
${this.getAttributes(tagData)}
>
<x title='' class='tagify__tag__removeBtn' role='button' aria-label='remove tag'></x>
<div>
<div class='tagify__tag__avatar-wrap'>
<img onerror="this.style.visibility='hidden'" src="${tagData.avatar}">
</div>
<span class='tagify__tag-text'>${tagData.name}</span>
</div>
</tag>
`;
}
function suggestionItemTemplate(tagData) {
return `
<div ${this.getAttributes(tagData)}
class='tagify__dropdown__item align-items-center ${tagData.class ? tagData.class : ''}'
tabindex="0"
role="option"
>
${tagData.avatar ?
`<div class='tagify__dropdown__item__avatar-wrap'>
<img onerror="this.style.visibility='hidden'" src="${tagData.avatar}">
</div>`
: ''
}
<span class="fw-medium">${tagData.name}</span>
<span>${tagData.email}</span>
</div>
`;
}
// initialize Tagify on the above input node reference
let TagifyUserList = new Tagify(TagifyUserListEl, {
tagTextProp: "name", // very important since a custom template is used with this property as text. allows typing a "value" or a "name" to match input with whitelist
enforceWhitelist: true,
skipInvalid: true, // do not remporarily add invalid tags
dropdown: {
closeOnSelect: false,
enabled: 0,
classname: "users-list",
searchKeys: ["name", "email"] // very important to set by which keys to search for suggesttions when typing
},
templates: {
tag: tagTemplate,
dropdownItem: suggestionItemTemplate
},
whitelist: usersList
});
TagifyUserList.on("dropdown:show dropdown:updated", onDropdownShow);
TagifyUserList.on("dropdown:select", onSelectSuggestion);
let addAllSuggestionsEl;
function onDropdownShow(e) {
let dropdownContentEl = e.detail.tagify.DOM.dropdown.content;
if (TagifyUserList.suggestedListItems.length > 1) {
addAllSuggestionsEl = getAddAllSuggestionsEl();
// insert "addAllSuggestionsEl" as the first element in the suggestions list
dropdownContentEl.insertBefore(addAllSuggestionsEl, dropdownContentEl.firstChild);
}
}
function onSelectSuggestion(e) {
if (e.detail.elm == addAllSuggestionsEl) TagifyUserList.dropdown.selectAll.call(TagifyUserList);
}
// create an "add all" custom suggestion element every time the dropdown changes
function getAddAllSuggestionsEl() {
// suggestions items should be based on "dropdownItem" template
return TagifyUserList.parseTemplate("dropdownItem", [
{
class: "addAll",
name: "Add all",
email:
TagifyUserList.settings.whitelist.reduce(function(remainingSuggestions, item) {
return TagifyUserList.isTagDuplicate(item.value) ? remainingSuggestions : remainingSuggestions + 1;
}, 0) + " Members"
}
]);
}
This example shows how to customize Tagify further. It also includes an 'Add all' option as the first item in the suggestions dropdown list.
<div class="mb-3">
<label for="TagifyEmailList" class="form-label d-block">Email List</label>
<input id="TagifyEmailList" class="tagify-email-list" value="some56.name@website.com">
<button type="button" class="btn btn-sm rounded-pill btn-icon btn-outline-primary m-1"><span class="tf-icons ri-add-line"></span></button>
</div>
// generate random whitelist items (for the demo)
let randomStringsArr = Array.apply(null, Array(100)).map(function() {
return (
Array.apply(null, Array(~~(Math.random() * 10 + 3)))
.map(function() {
return String.fromCharCode(Math.random() * (123 - 97) + 97);
})
.join("") + "@gmail.com"
);
});
const TagifyEmailListEl = document.querySelector("#TagifyEmailList");
const TagifyEmailList = new Tagify(TagifyEmailListEl, {
// email address validation (https://stackoverflow.com/a/46181/104380)
pattern: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
whitelist: randomStringsArr,
callbacks: {
invalid: onInvalidTag
},
dropdown: {
position: "text",
enabled: 1 // show suggestions dropdown after 1 typed character
}
});
const button = TagifyEmailListEl.nextElementSibling; // "add new tag" action-button
button.addEventListener("click", onAddButtonClick);
function onAddButtonClick() {
TagifyEmailList.addEmptyTag();
}
function onInvalidTag(e) {
console.log("invalid", e.detail);
}