yairEO / tagify

🔖 lightweight, efficient Tags input component in Vanilla JS / React / Angular / Vue
https://yaireo.github.io/tagify/
Other
3.56k stars 436 forks source link

Multiple init Tagify #1336

Closed Kossin7 closed 6 months ago

Kossin7 commented 6 months ago

Hi, is best of the best component) There are two questions.

1. Multiple init Tagify. There are many Tagify elements on the page, also dynamic ones. Writing initialization code for each is not very good. Wrote and sampled the function:

function initTagify(el, data = {}){

    let opt = {
        delimiters: '?'
    }

    // example
    if(el.getAttribute('data-one') == '1'){
        opt.mode = 'select';
    }

    // set some option 
    if(el.getAttribute('data-bla_bla') == '1'){
        opt.some_prop = 'some_value';
    }

    // init
    let tagifyItem = new Tagify(el, opt);

    if(el.getAttribute('data-suggest') != ''){
        tagifyItem.on('input', function (e){
            tagifyItem.whitelist = null;
            requestTagifySuggest(tagifyItem,{'e' : e, 'type' : 'getProducts' })
        });
    }

}

then on dom load

document.addEventListener('DOMContentLoaded', () => {
    if(document.querySelector('.productFiltersList .productFilterListItem')){
        document.querySelectorAll('.productFiltersList .productFilterListItem').forEach((el) => {
            initTagify(el.querySelector('input'))
        })
    }
}

If write to input have error in console image

I probably approached the problem incorrectly or wrote the code incorrectly, please tell me how to organize such an idea correctly?

2. Second question , reinit Tagify

yairEO commented 6 months ago

To detect dynamically added DOM nodes, please read my answer here: https://stackoverflow.com/a/14570614/104380

I assume you have no idea when are those inputs which are supposed to be Tagified are added, because you would have had them Tagified right after that.

Regarding your initTagify function, it is strange to put the input event callback inside it, as it might be garbage-collected. And on top of that, you are creating a new callback function every time instead of using the same one for all of your Tagify inputs..

You do not need to access the tagifyItem variable inside the input event callback because you should have multiple Tagify instances using the same callback, and so you can access the instance (in the callback function) like so:

function initTagify(el, data = {}){

    let opt = {
        delimiters: '?'
    }

    // example
    if(el.getAttribute('data-one') == '1'){
        opt.mode = 'select';
    }

    // set some option 
    if(el.getAttribute('data-bla_bla') == '1'){
        opt.some_prop = 'some_value';
    }

    // init
    let tagifyItem = new Tagify(el, opt);

    if(el.getAttribute('data-suggest'))
        tagifyItem.on('input', onTagifyInput);
}

function onTagifyInput(e) {
    tagify = e.detail.tagify
    tagify.whitelist = null
    requestTagifySuggest(tagify, {'e' : e, 'type' : 'getProducts' })
}