Select2 - Ajax search - remember last results
Asked Answered
K

2

9

I am using Select2 3.5.1. With this plugin I can successfully load remote data. However I am here today to ask a question to improve this search. Here is the step-by-step to understand what I would like to do:

  1. Setup a Select2 with remote data loading (using ajax).
  2. Click on the Select2 input and search for something.
  3. The loading will appear and after some seconds you will see a list of results.
  4. Click on one of the results listed - the box of results will then disappear.
  5. If you click again on the search box, the list will be empty and you will need to type some new text again to have a list of results.

Is it possible that when we click again on the search box, that the list of results previously searched re-appear without any ajax call? Then if the user delete a character or change his search criteria it would then trigger the ajax search again.

If it is possible, how would we code that?

I hope my question is clear, please let me know if you have any questions. Thank you.

Here is a very simple code where we do a search that return a list of results. It doesn't really search, but it does return a list when you type something. I am not sure how to use the initSelection that is mentionned in one of the response.

<html>
<head>
    <title>
        Test page for ajax cache
    </title>
    <script type='text/javascript' src='../../resources/javascript/jquery/jquery-1.9.1.min.js'></script>
    <link type='text/css' href='../../resources/javascript/select2/select2.css' rel='stylesheet' />
    <script type='text/javascript' src='../../resources/javascript/select2/select2.js'></script>

    <script>
    $(document).ready(function(){
        $('#select').select2({
            ajax: {
                type: 'POST',
                url: 'ajax.php',
                dataType: 'json',
                data: function(term, page){
                    return {
                        autoc: 'country',
                        term: term
                    }
                },
                results: function(data, page){
                    console.log(data);

                    return( {results: data.results} );
                }
            },
            placeholder: 'Search something',
            minimumInputLength: 3,
            width: '333'
        });
    });
    </script>
</head>

<body>
    <input type='text' name='inputdata' id='select' />
</body>
</html>

The very simple ajax.php called:

<?php
$results2['more'] = false;
$results2['results'][0] = array('id'=> "1", 'text'=> "California");
$results2['results'][1] = array('id'=> "2", 'text'=> "Canada");
$results2['results'][2] = array('id'=> "2", 'text'=> "Someword");
$results2['results'][3] = array('id'=> "2", 'text'=> "Alberta");
$results2['results'][4] = array('id'=> "2", 'text'=> "New York");

echo json_encode($results2);
Khrushchev answered 20/10, 2014 at 13:25 Comment(0)
P
10

I did read your post once again. I misunderstood you last time.

The solution is here.

   $(document).ready(function () {
        $('#select').select2({
            // this part is responsible for data caching
            dataCache: [],
            query: function (q) {
                var obj = this,
                        key = q.term,
                        dataCache = obj.dataCache[key];

                //checking is result in cache
                if (dataCache) {
                    q.callback({results: dataCache.results});
                } else {
                    $.ajax({
                        url: 'ajax.php',
                        data: {q: q.term},
                        dataType: 'json',
                        type: 'POST',
                        success: function (data) {
                            //copy data to 'cache'
                            obj.dataCache[key] = data;
                            q.callback({results: data.results});
                        }
                    })
                }
            },
            placeholder: 'Search something',
            width: '333',
            minimumInputLength: 3,
        });
        // this part is responsible for setting last search when select2 is opening
        var last_search = '';
        $('#select').on('select2-open', function () {
            if (last_search) {
                $('.select2-search').find('input').val(last_search).trigger('paste');
            }
        });
        $('#select').on('select2-loaded', function () {
            last_search = $('.select2-search').find('input').val();
        });
    });
Phonograph answered 20/10, 2014 at 13:33 Comment(2)
I have added some example code. I am not sure to understand how to use initSelection with what I want to do. Thx.Khrushchev
Any chance to have this code for version 4.0? thanksHatbox
T
2

This will make another ajax call but with the same query string as before. Uses event select2:closing to save last query string and select2:open to insert the string into the search input and trigger input event.

var lastQueryString = '';

jQuery(".my-select2").select2({
    minimumInputLength: 2,
    placeholder: "Select an option",
    ajax: {
        url: "/example",
        data: function (params) {
            var query = {
                search: params.term
            }
            return query;
        },
        processResults: function (data) {
            return {
                results: JSON.parse(data)
            };
        }
    }
});

jQuery('.my-select2').on('select2:open', function () {
    if (lastQueryString) {
        jQuery('.select2-search').find('input').focus().val(lastQueryString).trigger('input');
    }
});

jQuery('.my-select2').on('select2:closing', function () {
    lastQueryString = jQuery('.select2-search').find('input').val();
});
Thinker answered 1/9, 2021 at 11:52 Comment(1)
Great, works well on version 4. Good solution.Bawdry

© 2022 - 2024 — McMap. All rights reserved.