Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mark new tag in select2?

I am using select2,

I have set it up so I can add a new tag if it does not exist,

I am also using twitter bootstrap, If a tag does not exist I want to mark it as a new tag, to do so I prepend the text with '<span class="label label-important">New</span> ' this as my select2 initializer.

$('#newVideoCategory').select2({
        placeholder: 'Select a category...',
        data: categories,
        createSearchChoice: function (term, data) {
            if ($(data).filter(function () {
                return this.text.localeCompare(term) === 0;
            }).length === 0) {
                return {id: term, text: '<span class="label label-important">New</span> ' + term};
            }
        },
        initSelection: function (element, callback) {
            $(categories).each(function () {
                if (this.id == element.val()) {
                    callback(this);
                    return;
                }
            })
        }
    })

Now this works great

Marked as new tag

Unless what I have entered for the tag exists as part of the markup for that label Error marked as new tag

From what I have gathered I need to overwrite either the formatResult, formatSelection, or matcher.

That's what I got from the documentation, but I don't understand how I need to alter it.

like image 373
Hailwood Avatar asked Feb 04 '13 04:02

Hailwood


People also ask

How do you add new option if not exist in the list using Select2?

New options can be added to a Select2 control programmatically by creating a new Javascript Option object and appending it to the control: var data = { id: 1, text: 'Barn owl' }; var newOption = new Option(data.text, data.id, false, false); $('#mySelect2').append(newOption).trigger('change');

How do I create a Select2 dynamically?

HTML. Create a <select class="select2_el" > element to initialize select2 on page load and create <div id="elements" > container to store <select > element on button click using jQuery AJAX.

What is Select2 tag?

Select2 gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options.

How do I change the height of my Select 2?

Adding the following is enough: . select2-container . select2-choice { height: 200px; } To have it apply only after an object is selected, add/modify the corresponding css on a change event or similar. This changes the height of the select2 input field, which is not what was asked for.


2 Answers

Thanks for posting (and answering) the question! I think I've found a simpler way to solve this:

...
createSearchChoice:function(term, data) {
    if ($(data).filter(function() {
        return this.text.localeCompare(term) === 0;
    }).length === 0) {
        return {id:term, text: term, isNew: true};
    }
},
formatResult: function(term) {
    if (term.isNew) {
        return '<span class="label label-important">New</span> ' + term.text;
    }
    else {
        return term.text;
    }
},
...

You can return any object from the createSearchChoice() function, so just add in a field telling formatResult() that it's a new item.

This way, the text of the returned item is just the text you want, and formatResult() is a lot simpler.

like image 112
Eric Anderle Avatar answered Oct 25 '22 19:10

Eric Anderle


Ah, Got it by overwriting the formatResult function.

Basically what we do is check if the first characters are our newTagMark if it is, then we strip that off, apply the matching logic, then prepend it again to spit it out.

The bulk of the logic is actually just a copy and paste of select2's internal markMatch function.

var newTagMark = '<span class="label label-important">New</span> ';

$('#newVideoCategory').select2({
    placeholder: 'Select a category...',
    data: categories,
    createSearchChoice: function (term, data) {
        if ($(data).filter(function () {
            return this.text.localeCompare(term) === 0;
        }).length === 0) {
            return {id: term, text: newTagMark + term};
        }
    },
    initSelection: function (element, callback) {
        $(categories).each(function () {
            if (this.id == element.val()) {
                callback(this);
                return;
            }
        })
    },
    formatResult: function(result, container, query) {
        var text = result.text;
        var term = query.term;
        var markup=[];
        var marked = false;
        if(text.substr(0, newTagMark.length) == newTagMark){
            text = text.substr(newTagMark.length);
            markup.push(newTagMark);
        }

        var match=text.toUpperCase().indexOf(term.toUpperCase()),
                tl=term.length;
        if (match<0) {
            markup.push(text);
            return;
        }

        markup.push(text.substring(0, match));
        markup.push("<span class='select2-match'>");
        markup.push(text.substring(match, match + tl));
        markup.push("</span>");
        markup.push(text.substring(match + tl, text.length));
        return markup.join("");
    }
});
like image 1
Hailwood Avatar answered Oct 25 '22 20:10

Hailwood