admin管理员组

文章数量:1353303

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

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

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.

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

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

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.

Share Improve this question edited Mar 28, 2013 at 21:41 j0k 22.8k28 gold badges81 silver badges90 bronze badges asked Feb 4, 2013 at 4:38 HailwoodHailwood 92.8k112 gold badges273 silver badges425 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

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.

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("");
    }
});

A solution including the marking of matches is the following:

...
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 (result, container, query, escapeMarkup) {
    var markup=[];
    window.Select2.util.markMatch(this.text(result), query.term, markup, escapeMarkup);
    var text = markup.join("");
    if (result.isNew) {
        text = '<span class="label label-important">NEW</span> ' + text;
    }
    return text;
},
...

本文标签: javascriptMark new tag in select2Stack Overflow