# Documentation v8.0.38

Preview Downloads Purchase

# Overview

Transforms an input field or a textarea into a Tags component, in an easy, customizable way, with great performance and small code footprint, exploded with features For full documentation please check the plugin's site.

# Usage

Tagify's CSS and Javascript files are bundled in the global plugin bundles and globally included in all pages:

    <link href="assets/plugins/global/plugins.bundle.css" rel="stylesheet" type="text/css"/>
    <script src="assets/plugins/global/plugins.bundle.js"></script>

# Initialization

- Tagify's CSS is highly customized in `sass/vendors/plugins/_tagify.scss`SCSS file in order to use it as native component within the design system. The SCSS code is compiled into `assets/plugins/global/plugins.bundle.css`and globally included in all pages.
- Tagify's Javascript is bundled in `assets/plugins/global/plugins.bundle.js`and globally included in all pages.

# Basic

Basic example of Tagify attached to an input element:
Default input style
Solid background style

    // The DOM elements you wish to replace with Tagify
    var input1 = document.querySelector("#kt_tagify_1");
    var input2 = document.querySelector("#kt_tagify_2");

    // Initialize Tagify components on the above inputs
    new Tagify(input1);
    new Tagify(input2);

    <div class="mb-10">
        <label class="form-label">Default input style</label>
        <input class="form-control" value="tag1, tag2, tag3" id="kt_tagify_1"/>
    </div>

    <div class="mb-0">
        <label class="form-label">Solid background style</label>
        <input class="form-control form-control-solid" value="tag1, tag2, tag3" id="kt_tagify_2"/>
    </div>

# Countries With Flags

Initialize Tagify programmatically and control the country flags via Javascript.
Country Tags

    var tagify = new Tagify(document.querySelector('#kt_tagify_country'), {
        delimiters: null,
        templates: {
            tag: function (tagData) {
                const countryPath = 'assets/media/flags/' + tagData.value.toLowerCase().replace(/\s+/g, '-') + '.svg';
                try {
                    // _ESCAPE_START_
                    return `<tag title='${tagData.value}' contenteditable='false' spellcheck="false"
                        class='tagify__tag ${tagData.class ? tagData.class : ""}' ${this.getAttributes(tagData)}>
                            <x title='remove tag' class='tagify__tag__removeBtn'></x>
                            <div class="d-flex align-items-center">
                                ${tagData.code ?
                            `<img onerror="this.style.visibility = 'hidden'" class="w-25px rounded-circle me-2" src='${countryPath}' />` : ''
                        }
                                <span class='tagify__tag-text'>${tagData.value}</span>
                            </div>
                        </tag>`
                    // _ESCAPE_END_
                }
                catch (err) { }
            },

            dropdownItem: function (tagData) {
                const countryPath = 'assets/media/flags/' + tagData.value.toLowerCase().replace(/\s+/g, '-') + '.svg';
                try {
                    // _ESCAPE_START_
                    return `<div class='tagify__dropdown__item ${tagData.class ? tagData.class : ""}'>
                                <img onerror="this.style.visibility = 'hidden'" class="w-25px rounded-circle me-2"
                                        src='${countryPath}' />
                                <span>${tagData.value}</span>
                            </div>`
                    // _ESCAPE_END_
                }
                catch (err) { }
            }
        },
        enforceWhitelist: true,
        whitelist: [
            { value: 'Afghanistan', code: 'AF' },
            { value: 'Aland Islands', code: 'AX' },
            { value: 'Albania', code: 'AL' },
            { value: 'Algeria', code: 'DZ' },
            { value: 'American Samoa', code: 'AS' },
            ...
        ],
        dropdown: {
            enabled: 1, // suggest tags after a single character input
            classname: 'extra-properties' // custom class for the suggestions dropdown
        } // map tags' values to this property name, so this property will be the actual value and not the printed value on the screen
    })

    // add the first 2 tags and makes them readonly
    var tagsToAdd = tagify.settings.whitelist.slice(0, 2);
    tagify.addTags(tagsToAdd);

    <label class="form-label">Country Tags</label>
    <input class="form-control d-flex align-items-center" value="" id="kt_tagify_country" />

# Users With Avatars

Initialize Tagify programmatically and control the user portraits and names via Javascript.
User Tags

    var inputElm = document.querySelector('#kt_tagify_users');

    const usersList = [
        { value: 1, name: 'Emma Smith', avatar: 'avatars/300-6.jpg', email: 'e.smith@kpmg.com.au' },
        { value: 2, name: 'Max Smith', avatar: 'avatars/300-1.jpg', email: 'max@kt.com' },
        { value: 3, name: 'Sean Bean', avatar: 'avatars/300-5.jpg', email: 'sean@dellito.com' },
        { value: 4, name: 'Brian Cox', avatar: 'avatars/300-25.jpg', email: 'brian@exchange.com' },
        { value: 5, name: 'Francis Mitcham', avatar: 'avatars/300-9.jpg', email: 'f.mitcham@kpmg.com.au' },
        { value: 6, name: 'Dan Wilson', avatar: 'avatars/300-23.jpg', email: 'dam@consilting.com' },
        { value: 7, name: 'Ana Crown', avatar: 'avatars/300-12.jpg', email: 'ana.cf@limtel.com' },
        { value: 8, name: 'John Miller', avatar: 'avatars/300-13.jpg', email: 'miller@mapple.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 class="d-flex align-items-center">
                    <div class='tagify__tag__avatar-wrap ps-0'>
                        <img onerror="this.style.visibility='hidden'" class="rounded-circle w-25px me-2" src="assets/media/${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 d-flex align-items-center ${tagData.class ? tagData.class : ""}'
                tabindex="0"
                role="option">

                ${tagData.avatar ? `
                        <div class='tagify__dropdown__item__avatar-wrap me-2'>
                            <img onerror="this.style.visibility='hidden'"  class="rounded-circle w-50px me-2" src="assets/media/${tagData.avatar}">
                        </div>` : ''
                    }

                <div class="d-flex flex-column">
                    <strong>${tagData.name}</strong>
                    <span>${tagData.email}</span>
                </div>
            </div>
        `
    }

    // initialize Tagify on the above input node reference
    var tagify = new Tagify(inputElm, {
        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
    })

    tagify.on('dropdown:show dropdown:updated', onDropdownShow)
    tagify.on('dropdown:select', onSelectSuggestion)

    var addAllSuggestionsElm;

    function onDropdownShow(e) {
        var dropdownContentElm = e.detail.tagify.DOM.dropdown.content;

        if (tagify.suggestedListItems.length > 1) {
            addAllSuggestionsElm = getAddAllSuggestionsElm();

            // insert "addAllSuggestionsElm" as the first element in the suggestions list
            dropdownContentElm.insertBefore(addAllSuggestionsElm, dropdownContentElm.firstChild)
        }
    }

    function onSelectSuggestion(e) {
        if (e.detail.elm == addAllSuggestionsElm)
            tagify.dropdown.selectAll.call(tagify);
    }

    // create a "add all" custom suggestion element every time the dropdown changes
    function getAddAllSuggestionsElm() {
        // suggestions items should be based on "dropdownItem" template
        return tagify.parseTemplate('dropdownItem', [{
            class: "addAll",
            name: "Add all",
            email: tagify.settings.whitelist.reduce(function (remainingSuggestions, item) {
                return tagify.isTagDuplicate(item.value) ? remainingSuggestions : remainingSuggestions + 1
            }, 0) + " Members"
        }]
        )
    }

    <label class="form-label">User Tags</label>
    <input class="form-control d-flex align-items-center" value="" id="kt_tagify_users" />

# Sizes

Apply the standard Bootstrap input sizes `.form-control-sm`and `.form-control-lg`:
Small size
Default size
Large size

    // The DOM elements you wish to replace with Tagify
    var input1 = document.querySelector("#kt_tagify_3");
    var input2 = document.querySelector("#kt_tagify_4");
    var input2 = document.querySelector("#kt_tagify_5");

    // Initialize Tagify components on the above inputs
    new Tagify(input1);
    new Tagify(input2);
    new Tagify(input3);

    <input class="form-control form-control-sm form-control-solid" value="tag1, tag2, tag3" id="kt_tagify_3"/>
    <input class="form-control form-control-solid" value="tag1, tag2, tag3" id="kt_tagify_4"/>
    <input class="form-control form-control-lg form-control-solid" value="tag1, tag2, tag3" id="kt_tagify_5"/>

# Suggestions

A dropdown with suggestions will appear immediately when Tagify has focus.
Inline Suggestions
List Suggestions

    // The DOM elements you wish to replace with Tagify
    var input = document.querySelector("#kt_tagify_6");
    var input = document.querySelector("#kt_tagify_7");

    // Initialize Tagify script on the above inputs
    new Tagify(input, {
        whitelist: ["Ada", "Adenine", "Agda", "Agilent VEE"],
        maxTags: 10,
        dropdown: {
            maxItems: 20,           // <- mixumum allowed rendered suggestions
            classname: "tagify__inline__suggestions", // <- custom classname for this dropdown, so it could be targeted
            enabled: 0,             // <- show suggestions on focus
            closeOnSelect: false    // <- do not hide the suggestions dropdown once an item has been selected
        }
    });

    new Tagify(input, {
        whitelist: ["Ada", "Adenine", "Agda", "Agilent VEE"],
        maxTags: 10,
        dropdown: {
            maxItems: 20,           // <- mixumum allowed rendered suggestions
            classname: "", // <- custom classname for this dropdown, so it could be targeted
            enabled: 0,             // <- show suggestions on focus
            closeOnSelect: false    // <- do not hide the suggestions dropdown once an item has been selected
        }
    });

    <input class="form-control form-control-solid" value="css, html, javascript" id="kt_tagify_6"/>

    <input class="form-control form-control-solid" value="css, html, javascript" id="kt_tagify_7"/>

# External Suggestions

Allows to select suggestions from an external container.
External Suggestions
Suggested: Bootstrap, Angular, React, Vue

    var input = document.querySelector('#kt_tagify_custom'),

    // Init Tagify script on the above inputs
    tagify = new Tagify(input, {
        whitelist: ["Bootstrap", "Angular", "React", "Vue"],
        placeholder: "Type something",
        enforceWhitelist: true
    });

    // Suggestions
    var suggestions = document.querySelector('#kt_tagify_custom_suggestions');

    // Suggestion item click
    KTUtil.on(suggestions,  '[data-kt-suggestion="true"]', 'click', function(e) {
        tagify.addTags([this.innerText]);
    });

    <div class="mb-0">
        <label class="form-label">External Suggestions</label>
        <input class="form-control form-control-solid" value="Bootstrap" id="kt_tagify_custom"/>
        <div class="pt-3">
            <span class="text-gray-700">Suggested:</span>

            <span class="text-danger" id="kt_tagify_custom_suggestions">
                <span class="cursor-pointer" data-kt-suggestion="true">Bootstrap</span>,
                <span class="cursor-pointer" data-kt-suggestion="true">Angular</span>,
                <span class="cursor-pointer" data-kt-suggestion="true">React</span>,
                <span class="cursor-pointer" data-kt-suggestion="true">Vue</span>
            </span>
        </div>
    </div>

# Readonly Mode

If the original input field has a readonly attribute, then, via CSS, there will be no way of manually adding tags because the inline contenteditable element will be hidden.
Example

    // The DOM elements you wish to replace with Tagify
    var input1 = document.querySelector("#kt_tagify_8");

    // Initialize Tagify components on the above inputs
    new Tagify(input1);

    <input class="form-control form-control-solid" value="css, html, javascript" readonly id="kt_tagify_8"/>

### Explore

### Metronic Licenses

License FAQs
Regular License
For single end product used by you or one client
$ 39
Extended License
For single SaaS app with paying users
$ 969
Custom License
Reach us for custom license offers.
Contact Us
Buy Now

### Metronic Demos

Demo 1
Demo 2
Demo 3
Demo 4
Demo 5
Demo 6
Demo 7
Demo 8
Demo 9
Demo 10
Demo 11
Demo 12
Demo 13
Demo 14
Demo 15
Demo 16
Demo 17
Demo 18
Demo 19
Demo 20
Demo 21
Demo 22
Coming soon
Coming soon

##### Learn & Get Inspired

## Support at devs.keenthemes.com

Join our developers community to find answer to your question and help others. FAQs
Get Support
Documentation & Videos
From guides and video tutorials, to live demos and code examples to get started.
Plugins & Components
Check out our 300+ in-house components and customized 3rd-party plugins.
Layout Builder
Build your layout, preview it and export the HTML for server side integration.
Metronic Downloads
Download your prefered framework and demo with one click.
What's New
Latest features and improvements added with our users feedback in mind.
Buy now