Select2 - Pass back additional data via ajax call
Asked Answered
S

2

15

Ok, I feel like I'm going crazy here. I'm using the select2 jquery plugin (version 4), and retrieving data via ajax. So you can type in a name, and it will return that contact information. But I also want to return what organization that contact is a part of.

Here is my select2 initialization:

$('#contact_id').select2({
    ajax: {
        url: 'example.com/contacts/select',
        dataType: 'json',
        delay: 250,
        data: function (params) {
            return {
                q: params.term,
                page: params.page
            };
        },
        processResults: function (data) {
            return {
                results: data
            };
        },
        cache: true
    },
    minimumInputLength: 3,
    maximumSelectionLength: 1
});

And here is the data I'm returning (laravel framework):

foreach($contacts as $con) {
    $results[] = [
        'id'    => $con->contact_id,
        'text'  => $con->full_name,
        'org'   => [
            'org_id'        => $con->organization_id,
            'org_name'      => $con->org_name
        ]
    ];
}

return response()->json($results);

So isn't 'org' supposed to be attached to either the created option or select element by select2? So I could do something like $('#contact_id').select2().find(':selected').data('data').org or $('#contact_id').select2().data('data').org or something like that?

Idealistically, this would look like:

<select>
    <option value="43" data-org="{org_id:377, org_name:'Galactic Empire'}">Darth Vader</option>
</select>

I swear I confirmed this worked last week, but now it's completely ignoring that org property. I have confirmed that the json data being returned does include org with the proper org_id and org_name. I haven't been able to dig anything up online, only this snippet of documentation:

The id and text properties are required on each object, and these are the properties that Select2 uses for the internal data objects. Any additional paramters passed in with data objects will be included on the data objects that Select2 exposes.

So can anyone help me with this? I've already wasted a couple hours on this.

EDIT: Since I haven't gotten any responses, my current plan is to use the processResults callback to spawn hidden input fields or JSON blocks that I will reference later in my code. I feel like this is a hacky solution given the situation, but if there's no other way, that's what I'll do. I'd rather that than do another ajax call to get the organization. When I get around to implementing it, I'll post my solution.

Semiquaver answered 22/2, 2016 at 14:55 Comment(3)
Hi, I am facing right now the same problem. I need to pass additional data (not only id and text) using data attributes ideally. Did you solve the problem?Otoplasty
Did you ever get a working solution for this?Alaric
I added my solution.Semiquaver
S
8

Can't remember what I was doing wrong, but with processResults(data), data contains the full response. In my implementation below, I access this info when an item is selected:

$('#select2-box').select2({
    placeholder: 'Search Existing Contacts',
    ajax: {
        url: '/contacts/typeahead',
        dataType: 'json',
        delay: 250,
        data: function(params){
            return {
                q: params.term,
                type: '',
                suggestions: 1
            };
        },
        processResults: function(data, params){
            //Send the data back
            return {
                results: data
            };
        }
    },
    minimumInputLength: 2
}).on('select2:select', function(event) {
    // This is how I got ahold of the data
    var contact = event.params.data;

    // contact.suggestions ...
    // contact.organization_id ...
});



// Data I was returning
[
    {
        "id":36167, // ID USED IN SELECT2
        "avatar":null,
        "organization_id":28037,
        "text":"John Cena - WWE", // TEXT SHOWN IN SELECT2
        "suggestions":[
            {
                "id":28037,
                "text":"WWE",
                "avatar":null
            },
            {
                "id":21509,
                "text":"Kurt Angle",
                "avatar":null
            },
            {
                "id":126,
                "text":"Mark Calaway",
                "avatar":null
            },
            {
                "id":129,
                "text":"Ricky Steamboat",
                "avatar":null
            },
            {
                "id":131,
                "text":"Brock Lesnar",
                "avatar":null
            }
        ]
    }
]
Semiquaver answered 15/12, 2017 at 19:45 Comment(0)
J
25

Can't comment for now (low reputation).. so... answering to slick:

Including additional data (v4.0):

processResults: function (data) {
    data = data.map(function (item) {
        return {
            id: item.id_field,
            text: item.text_field,
            otherfield: item.otherfield
        };
    });
    return { results: data };
}

Reading the data:

var data=$('#contact_id').select2('data')[0];
console.log(data.otherfield);
Jedthus answered 15/6, 2016 at 4:7 Comment(1)
thanks, your solution above solved my problem and save my timeWelldone
S
8

Can't remember what I was doing wrong, but with processResults(data), data contains the full response. In my implementation below, I access this info when an item is selected:

$('#select2-box').select2({
    placeholder: 'Search Existing Contacts',
    ajax: {
        url: '/contacts/typeahead',
        dataType: 'json',
        delay: 250,
        data: function(params){
            return {
                q: params.term,
                type: '',
                suggestions: 1
            };
        },
        processResults: function(data, params){
            //Send the data back
            return {
                results: data
            };
        }
    },
    minimumInputLength: 2
}).on('select2:select', function(event) {
    // This is how I got ahold of the data
    var contact = event.params.data;

    // contact.suggestions ...
    // contact.organization_id ...
});



// Data I was returning
[
    {
        "id":36167, // ID USED IN SELECT2
        "avatar":null,
        "organization_id":28037,
        "text":"John Cena - WWE", // TEXT SHOWN IN SELECT2
        "suggestions":[
            {
                "id":28037,
                "text":"WWE",
                "avatar":null
            },
            {
                "id":21509,
                "text":"Kurt Angle",
                "avatar":null
            },
            {
                "id":126,
                "text":"Mark Calaway",
                "avatar":null
            },
            {
                "id":129,
                "text":"Ricky Steamboat",
                "avatar":null
            },
            {
                "id":131,
                "text":"Brock Lesnar",
                "avatar":null
            }
        ]
    }
]
Semiquaver answered 15/12, 2017 at 19:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.