Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

predefined options for ajax select2 #3828

Closed
Fivell opened this issue Oct 12, 2015 · 40 comments

Comments

@Fivell
Copy link

commented Oct 12, 2015

Hello, I have next html

<select class="change_item_dropdown_ajax form-control" id="item_id" name="item_id" onchange="updateData(this, this.value, 16)" >
<optgroup label="System Data">
  <option value="17">Test</option>
  <option selected="selected" value="18">System</option>
</optgroup>
</select>
    $(".change_item_dropdown_ajax").select2({
        ajax: {
            url: "get_user_items",
            dataType: 'json',
            delay: 250,
            theme: "classic",
            data: function (params) {
                return {
                    q: { name_contains: params.term } // search term
                };
            },
            processResults: function (data) {
                return {
                    results: data
                };
            },
            cache: true
        },
        allowClear: true,
        placeholder: '--- Please select item ---',
        minimumInputLength: 1
    });

I want to make possibility for customer to see some default system options with items <optgroup label="System Data">, but also add ability to make search ajax queries by his own items.

However after binding select2 it doesn't show <optgroup label="System Data">...</optgroup>,
select2 options are empty and it only displays hint "Please enter 1 or more characters".

It's not even clear if it is possible to do, thanks

SO Question http://stackoverflow.com/questions/33080739/select2-default-options-with-ajax

@Fivell

This comment has been minimized.

Copy link
Author

commented Oct 18, 2015

#684 and #2383, is quite similar but for older version,

@powderflask

This comment has been minimized.

Copy link

commented Oct 27, 2015

+1
My use case: the select initially lists "recently viewed" items - the user should be able to select from these items without searching (this will be about 50% of cases). If the desired item is not in this "recently viewed" list of options, the user starts typing a search term to trigger the AJAX call and load the search results.

However, as soon as I add the ajax option to select2, the initial data options provided in the underlying select widget are no longer displayed.

Displaying the initial / default list of select options makes sense when minimumInputLength > 0 -- the initial options can be displayed until the user types more than minimumInputLength search characters.

@powderflask

This comment has been minimized.

Copy link

commented Oct 27, 2015

Just noticed: the initial / default list of options are also not displayed when you explicitly specify minimumInputLength (even if the ajax option is not specified).

@govorov

This comment has been minimized.

Copy link

commented May 19, 2016

I created custom adapter extended from AjaxAdapter with defaultResults option, which will be used instead of ajax call results, if query length shorter than minimumInputLength.
Here it is: https://gist.github.com/govorov/3ee75f54170735153349b0a430581195
Hope it will help you.
@kevin-brown What about to incude this feature into basic AjaxAdapter?

@jamescgibson

This comment has been minimized.

Copy link

commented Jun 17, 2016

@govorov Could you provide an example of how to use your adapter?

@govorov

This comment has been minimized.

Copy link

commented Jun 18, 2016

I have a custom widget based on Select2, that allows user to select city (Russian and Ukraine in my case, so I'm sorry for only russian screenshots in advance, but hope it's still clear what's going on on them). Here is the gist with comments (coffeescript): https://gist.github.com/govorov/274a8aac5fb910472ff1d0022f32f53e
And some screenshots:
Default top-population cities, when there is no input:
screenshot_20160618_195033
Response result, when input is provided:
screenshot_20160618_195051

@exige81

This comment has been minimized.

Copy link

commented Jun 28, 2016

+1 Being able to display an initial default list rendered from unselected <options> would be very nice functionality to have.

@minlare

This comment has been minimized.

Copy link

commented Jun 30, 2016

+1

@andreyvolokitin

This comment has been minimized.

Copy link

commented Jul 14, 2016

It also strange as documentation states that you can provide default selections with ajax by putting actual options in the select:

If you need to provide default selections, you just need to include an option for each selection that contains the value and text that should be displayed.

@amnwebmaster

This comment has been minimized.

Copy link

commented Jul 26, 2016

+1

1 similar comment
@abdallahmaali

This comment has been minimized.

Copy link

commented Aug 14, 2016

+1

@ryandavs

This comment has been minimized.

Copy link

commented Oct 10, 2016

May I know the status of this issue or if there's already a plan where in the roadmap this issue will be addressed?

@decodekult

This comment has been minimized.

Copy link

commented Oct 17, 2016

I would also be interested on a native solution for this. As pointed out above, the docs suggest that initial values can be set with native HTML options, and that results untrue in case you use an AJAX data provider.

@demyan112rv

This comment has been minimized.

Copy link

commented Oct 23, 2016

+1

1 similar comment
@fredericoregateiro

This comment has been minimized.

Copy link

commented Oct 23, 2016

👍

@s0By

This comment has been minimized.

Copy link

commented Jan 20, 2017

I'm interested in solution as well

@abecks

This comment has been minimized.

Copy link

commented Mar 2, 2017

+1

@govorov

This comment has been minimized.

Copy link

commented Mar 2, 2017

@kevin-brown what about the issue? It is open more than a year :)

@podorozhny

This comment has been minimized.

Copy link

commented Mar 2, 2017

+1

1 similar comment
@vadlat

This comment has been minimized.

Copy link

commented Mar 20, 2017

+1

@Fivell Fivell closed this Mar 20, 2017

@baronvertigovongrahamthesecondofsealand

This comment has been minimized.

Copy link

commented Mar 23, 2017

So, this was closed... was it implemented? Any resolution at all? What?

@Fivell Fivell reopened this Mar 23, 2017

@abecks

This comment has been minimized.

Copy link

commented Mar 27, 2017

I've heard selectize can do this properly.

@Alagaesia93

This comment has been minimized.

Copy link

commented Apr 3, 2017

+1

1 similar comment
@sarahkemp

This comment has been minimized.

Copy link

commented Apr 4, 2017

+1

@fsteinbauer

This comment has been minimized.

Copy link

commented Jul 20, 2017

+1

2 similar comments
@jfcsantos

This comment has been minimized.

Copy link

commented Jul 25, 2017

+1

@nuryagdym

This comment has been minimized.

Copy link

commented Jul 26, 2017

+1

@ghost

This comment has been minimized.

Copy link

commented Aug 3, 2017

It works. Documentation:

If you need to provide default selections, you just need to include an option for each selection that contains the value and text that should be displayed.

This is important: selected="selected" for each option you want to preload.

Here is my working code:

HTML:

<select class="form-control select2-multiple" style="width: 100%;" name="test[]" multiple="multiple">
    <option value="1" selected="selected">Option 1</option>
    <option value="2" selected="selected">Option 2</option>
</select>

JS:

$input.select2({'theme':'bootstrap','ajax':{ .... });

Result:
screen shot 2017-08-03 at 15 32 45

@fsteinbauer

This comment has been minimized.

Copy link

commented Aug 4, 2017

@merik Thank you for your effort, but in this issue, a method to prefill options before the first ajax call is searched.

@Rockstar04

This comment has been minimized.

Copy link

commented Nov 15, 2017

That does not address the intial issue, which is to allow a list of selected AND un-selected options the user can select from before using the AJAX search to find their selection.

@alexweissman

This comment has been minimized.

Copy link
Contributor

commented Nov 19, 2017

Alright, well, the original issue did not make that very clear. This issue comes across as a "fix mah codez" type of issue, rather than a formal feature request or bug fix with a minimal, complete, and verifiable example.

So you're saying that this issue boils down to the ability to have preselected options? I believe there are several issues/PRs specifically about this already.

@Rockstar04

This comment has been minimized.

Copy link

commented Nov 19, 2017

That's fine, and maybe I was just seeing that in the initial issue because that's what I was trying to accomplish. Could you reference them or point me to the other issues requesting this sort of thing?

@alexweissman

This comment has been minimized.

Copy link
Contributor

commented Nov 19, 2017

allow a list of selected AND un-selected options the user can select from before using the AJAX search to find their selection.

I'm doing exactly this in my own application that uses Select2, without any problems and as described in the documentation. I populate the selected options initially in my server-rendered DOM:

<select name="institutions[]" class="form-control select2" type="text" multiple="multiple" data-placeholder="Please select an institution">
{% for institution in student.institutions %}
    <option value="{{institution.id}}" selected>{{institution.slug}}</option>
{% endfor %}
</select>

and then initialize Select2 on this control, with an AJAX data source:

// Institution select
form.find("select[name='institutions[]']").select2({
    ajax: {
        url: site.uri.public + "/api/institutions",
        dataType: "json",
        delay: 250,
        data: function (params) {
            return {
                filters: {
                    name : params.term
                },
                page: params.page || 0,
                size: params.size || 10
            };
        },
        processResults: function (data, params) {
            var suggestions = [];
            // Process the data into dropdown options
            if (data && data.rows) {
                jQuery.each(data.rows, function(idx, row) {
                    row.text = row.slug;
                    suggestions.push(row);
                });
            }

            params.page = params.page || 0;
            params.size = params.size || 10;

            return {
                results: suggestions,
                pagination: {
                    more: (params.page * params.size) < data.count_filtered
                }
            };
        }
    },
    width: '100%',
    templateResult: function(item) {
        // Display institution name as tag option
        return $("<div>" + item.name + "</div>");
    },
    cache: true
});

Is this the same as your use case? If so, could you please post your code to the forums, and we can discuss it there?

@Rockstar04

This comment has been minimized.

Copy link

commented Nov 20, 2017

Disclaimer: This is the functionality that I am asking for, I am unable to confirm if this is what the original issue is specifically asking for.

    <div class="form-group">
        <label for="book">Book *</label>
        <select id="book" class="select2-books form-control" name="book" required>
            <optionx></option>
            <option value="1">Recent Book #1</option>
            <option value="2">Recent Book #2</option>
            <option value="3">Recent Book #3</option>
            <option value="4">Recent Book #4</option>
        </select>
    </div>
$(".select2-books").select2({
    ajax: {
        url: public_url + "/api/book/search",
        dataType: 'json',
        delay: 250,
        data: function(params) {
            return {
                q: params.term,
                page: params.page
            };
        },
        processResults: function(data, params) {
            params.page = params.page || 1;
            return {
                results: data.items,
                pagination: {
                    more: (params.page * 30) < data.total_count
                }
            };
        },
        cache: true
    },
    escapeMarkup: function(markup) {
        return markup;
    },
    minimumInputLength: 3,
    placeholder: 'Select a Book...',
    instructions: 'To find a book, search the <strong>Book\'s Title</strong>, <strong>ISBN</strong>, or <strong>Authors</strong>',
});

Result

Recent Book #1 is preselected (even though there is a blank option first that should be selected by default)
select2collapsed

Preset options to not display when element is selected
select2expanded

Desired

When selected the preset options are displayed first. These would be what we expect the user will select, followed by a search box in case we didnt provide the correct preset options. (I messed up the image below in Photoshop, options obviously should be 1, 2, 3, 4)

select2desired

@fsanderson

This comment has been minimized.

Copy link

commented Aug 17, 2018

+1

@geoff-maddock

This comment has been minimized.

Copy link

commented Sep 20, 2018

Did you ever come up with an adequate solution @Rockstar04 ? I'm looking to do the same thing.

@Rockstar04

This comment has been minimized.

Copy link

commented Sep 20, 2018

@geoff-maddock I do not believe I did. We also had to stop using Select2 entirely because of accessibility issues.

@ajjn

This comment has been minimized.

Copy link

commented Feb 12, 2019

Hey @geoff-maddock, I was looking also looking for a solution and actually you can do it if you can access the backend.
You need, however, to remove the minimumInputLength: 3 option so that the query is made to backend right away with empty string. Make the check at backend and send empty list back if query term's length is less than three. Then at processResults add after the first line:

if (params.page == 1) {
  $(".select2-books").find('option').each(function (i, e) {
     var object = {id: e.value, text: e.text};
     if ($.inArray(object, data.items) == -1)
       data.items.push(object);
     });
}

This will then add the initial options to the data list. At least worked for me and solved the problem. You have to think harder if you don't have the access to the backend and want to limit the first query to be sent only after typing three characters.

@mpryvkin

This comment has been minimized.

Copy link

commented May 1, 2019

Wrote a post titled Predefined options for Select2 control using remote data source that demonstrates solution suggested by @govorov above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.