简体   繁体   中英

Using initSelection in select2 3.5.2 for custom filtering

I have a text field which uses select2. Here is the initialization:

        $("#foo").select2({
            createSearchChoice:function(term, data) { 
                if ($(data).filter(function() { 
                    return this.text.localeCompare(term)===0; 
                }).length===0) 
                {return {id:term, text:term};} 
            },
            initSelection : function (element, callback) {
                var data = {id: element.val(), text: element.val()};
                callback(data);
            },
            tags:[],
            tokenSeparators: [","], 
            data: [...data goes here...]
        }); 

In this field, the user is supposed to put in a number, or select items from a list. If an item that the user puts in doesn't appear on the list, it ought be created as a simple tag (id and text identical). This works.

What doesn't work is when I set the value programmatically:

myvar.find('.placeholder lorem-ipsum').val(number).trigger("change");

The way it works now, is that when I set it to any value, it takes it without complaint, making a new simple tag. However, if I were to remove the initSelection parameter completely, it would ignore unknown values, and use known values as taken from the list (where tags are complex - id and text are different).

How do I make it so that if the value I set to the field is found on the list, it will use the item, and otherwise make a simple tag? The way it works now (simple tags only) is sort-of acceptable, but I'd prefer it worked ideally.

EDIT: I've made examples for how it works with and without the initSelection parameter.

http://jppk.byethost12.com/with.html

http://jppk.byethost12.com/without.html

In short, I want it to work like with.html when I push "Add New Item" and I want it to work like without.html when I push "Add Existing Item".

Here is my best interpretation of what you want.

JSFiddle

The trick is to append the element to the select field.

 var array = ['foo', 'bar', 'baz'] $.each(array, function(key, value) { appendSelect(value); }); $("#foo").select2(); $('#submit').click(function() { var val = $('#name').val(); $('#name').val(''); array.push(val); appendSelect(val); }); function appendSelect(value) { $('#foo').append($("<option></option>").text(value)); } 
 <link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0-rc.1/css/select2.min.css" rel="stylesheet" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0-rc.1/js/select2.min.js"></script> <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> <div class='container'> <select id='foo' multiple="multiple" class='form-control'></select> <label>Input</label> <input id='name' /> <button id='submit'>submit</button> </div> 

Much, much later, I found a solution that works right:

    initSelection : function (element, callback) {
        var eArr = element.val().split(",");
        var data = [];
        for (var i=0;i<eArr.length;i++) {
            for (var j=0;j<preExistingData.length;j++) {
                if (preExistingData[j]["id"] === eArr[i]) {
                    data.push(preExistingData[j]);
                    continue;
                }
            }
            data.push({id: eArr[i], text: eArr[i]});
        }
        callback(data);
    },

This not only checks if the value is among the pre-existing values (in which case it uses that item), but also if the value is a comma-separated list of values (in which case it properly encapsulates them as JS objects).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM