4

I'm trying to use the newest version of Select2 to query my site's API and return a multiple-select. It's fetching the right data and it's even formatting the dropdown properly, combining two keys in the returned objects as "(A-123) John Johnson", but the dropdown's not responding to mouseover or clicks.

I'm using the select2.full.min.js and select2.min.css files. For the purposes of the project, I'm including them in the directory and accessing them through Bundles in cshtml, instead of accessing them via a CDN.

HTML:

<div>
    <select class="user-list" multiple="multiple" style="width: 100%">
    </select>
</div>

At the moment, it's looking like this, which is how I want it: properly-formatted dropdown

Not sure if this is relevant, but when I browse the generated source code while searching, the input looks fine, but the dropdown's code is greyed out as though it were hidden.

solid/opaque input code

greyed out dropdown code

Per other suggestions I've found on here and elsewhere, I've tried a few different solutions. I eventually found out how templateResult and templateSelection are supposed to work (not particularly thanks to the documentation), and tried returning the ID as well, but I still can't seem to actually select anything, or even get a response when I hover over the options.

Here's what I wound up with, including some debugging to make sure the returned object is valid.

JS:

        // Setup autocomplete/select for User filter
        $(".user-list").select2({
            ajax: {
                url: "[api url]",
                type: "GET",
                dataType: "json",
                data: function (params) {
                    return {
                        search: params.term, // search term
                        page: params.page
                    };
                },
                processResults: function (data) {
                    console.log(JSON.stringify(data));
                    return {
                        results: data
                    };
                },
            },
            escapeMarkup: function (markup) { return markup; },
            id: function (data) { return data.Id.toString(); },
            minimumInputLength: 1,
            templateResult: function (data, page) {
                return "(" + data.User + ") " + data.Name;
            },
            templateSelection: function (data, page) {
                return "(" + data.User + ") " + data.Name;
            }
        })

The ID is a GUID, and there are two other fields, which I'll call Name and User.

Data Sample:

[
    {
        "Id":"a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1",
        "Name":"John Johnson",
        "User":"A-123"
    },
    {
        "Id":"b2b2b2b2-b2b2-b2b2-b2b2-b2b2b2b2b2b2",
        "Name":"Tom Thompson",
        "User":"B-456"
    }
]

I hate to add to the pile of questions that seem to be about this, but most results I've found have been for the older version with significantly different options, and they just haven't worked for me yet.

MikeOShay
  • 522
  • 1
  • 7
  • 17
  • 1
    Perhaps a bit irregular to comment on my own question, but I'm wondering why I'm being downvoted without any actual feedback. I've seen little in the way of help threads or troubleshooting documentation on the new version of this plugin, and I think the question is general enough to help anyone, while I gave as much detail as I could on my own issues here. – MikeOShay Jul 13 '15 at 16:50
  • 1
    Look here: http://stackoverflow.com/questions/29035717/select2-load-data-using-ajax-cannot-select-any-option Note that you have `Id` property - not `id` and that probably causes the problem. – akn Jul 21 '15 at 12:53
  • That was part of it. Don't like to keep hating on the documentation, but to me it didn't make that requirement clear, nor how to process the data or how to use templateResult or templateSelection. To really learn that, you actually have to look into the source HTML and JS on the documentation site itself, which is a pretty lousy way to teach people to use the plugin. Either way, I figured out which of the options were relevant to the new version and got it returning "id" instead of "Id" and it's working. – MikeOShay Jul 21 '15 at 19:59
  • You're right. I've reported it today, and they told it will be described soon. Current select2 doc is one of the worst I've ever seen :) – akn Jul 21 '15 at 21:12

2 Answers2

9

The way select2 operates is that it uses the "id" values of each data object and puts those into the original Select element as the selected option(s). This is case-sensitive.

By default, it displays the dropdown options and the selected element by whatever the "text" value is of the data object. This does not allow for custom formatting.

If (like me) you want to return different data options, you still need to return a field as "id", or re-map a field to "id" in an object returned in the processResults option under ajax. Then use the templateResult and templateSelection settings with your other returned data to display what you want.

If you return and parse everything correctly except for the id, you may wind up with an otherwise functional list, but be unable to select any options.

The requirements for the dropdown changed a bit with my project, but here's where I wound up. It works fine the multiple="multiple" attribute added to to make it a multi-select, too.

<select class="select2" style="width:100%; height: 100%;">
    <option></option>
</select>

$(".select2").select2({
    ajax: {
        url: "[api url]",
        method: "get",
        data: function (params) {
            return {
                search: params.term
            };
        },
        processResults: function (data) {
            return {
                results: data
            };
        },
        cache: true
    },
    placeholder: "Enter a User ID or Name",
    templateResult: function(data) {
            return "(" + data.user + ") " + data.name;
    },
    templateSelection: function(data) {
        return "(" + data.user + ") " + data.name;
    }
}).ready(function () {
    $(".select2-selection__placeholder").text("Enter a User ID or Name")
})

It's possible part of my initial issue was all the attempts at implementing fixes for older versions of Select2, which had a completely different set of options/settings available.

Additionally, a bit of a side-note, the "placeholder" attribute doesn't currently work with custom templating. It tries to force the placeholder text into the Result format, which shows "(undefined) undefined" with this code. To fix it requires an empty option and to replace the text on select2.ready.

MikeOShay
  • 522
  • 1
  • 7
  • 17
1

I had the same problem. Solution: added this part :

_.each(data.ResultObject, function (item) { item.id = item.K_CONTACT; });

(used underscore)

for my init

$(".js-data-example-ajax").select2({
    ajax: {
        url: "api/MyApi/MyApi",
        method: "POST",
        dataType: 'json',
        delay: 250,
        data: function (params) {
            return {
                SearchPart: params.term, // search term
                page: params.page
            };
        },
        processResults: function (data, params) {

            params.page = params.page || 1;
            _.each(data.ResultObject, function (item) { item.id = item.K_CONTACT; });

            return {
                results: data.ResultObject,
                pagination: {
                    more: (params.page * 30) < data.total_count
                }
            };
        },
        cache: true
    },
    multiple: true,
    escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
    minimumInputLength: 3,
    tags: true,
    templateResult: self.Select2FormatData, // omitted for brevity, see the source of this page
    templateSelection: self.Select2FormatDataSelection // omitted for brevity, see the source of this page
});