Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select2 - Pass back additional data via ajax call

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.

like image 818
Captain Hypertext Avatar asked Feb 22 '16 14:02

Captain Hypertext


2 Answers

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);
like image 122
Ric.H Avatar answered Oct 20 '22 12:10

Ric.H


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
            }
        ]
    }
]
like image 25
Captain Hypertext Avatar answered Oct 20 '22 13:10

Captain Hypertext