Come utilizzare Select2 con JSON tramite richiesta Ajax?


88

My Select2 3.4.5 non funziona con i dati JSON.

Ecco la mia casella di input su HTML:

<input class='form-control col-lg-5 itemSearch' type='text' placeholder='select item' />

... e il mio JavaScript

$(".itemSearch").select2({
    placeholder: "Search for an Item",
    minimumInputLength: 2,
    ajax: {
        url: "/api/productSearch",
        dataType: 'json',
        quietMillis: 100,
        data: function (term, page) {
            return {
                option: term
            };
        },
        results: function (data, page) {
            var more = (page * 10) < data.total;
            return {
                results: data.itemName,
                more: more
            };
        }
    },
    formatResult: function (data, term) {
        return data;
    },
    formatSelection: function (data) {
        return data;
    },
    dropdownCssClass: "bigdrop",
    escapeMarkup: function (m) {
        return m;
    }
});

Ho creato un'API con Laravel 4 che restituisce un valore ogni volta che digito qualcosa nella mia casella di testo.

Ecco il risultato se digito "test" nella mia casella di testo:

[{"itemName":"Test item no. 1","id":5},
{"itemName":"Test item no. 2","id":6},
{"itemName":"Test item no. 3","id":7},
{"itemName":"Test item no. 4","id":8},
{"itemName":"Test item no. 5","id":9},
{"itemName":"Test item no. 6","id":10},
{"itemName":"Test item no. 7","id":11}]

Non riesco ad aggiungere il risultato al mio menu a tendina Select2. Penso formatSelectione formatResultstanno causando il problema perché non so quale parametro dovrebbe essere inserito su di esso. Non so dove trovare quei parametri come container, object e query e i valori che dovrebbero restituire, o la mia risposta JSON è sbagliata?

Risposte:


110

Ecco un esempio

$("#profiles-thread").select2({
    minimumInputLength: 2,
    tags: [],
    ajax: {
        url: URL,
        dataType: 'json',
        type: "GET",
        quietMillis: 50,
        data: function (term) {
            return {
                term: term
            };
        },
        results: function (data) {
            return {
                results: $.map(data, function (item) {
                    return {
                        text: item.completeName,
                        slug: item.slug,
                        id: item.id
                    }
                })
            };
        }
    }
});

È abbastanza facile


2
Grazie per il suggerimento a $ .map
tacos_tacos_tacos

Puoi spiegare il parametro "slug"?
IcedDante

item è un oggetto con proprietà completeName, slug e id. Questo è solo un esempio, copia e incolla.
Tolo Palmer

2
Slug è una proprietà effettiva dell'oggetto, il tuo articolo, l'ho aggiunto come puoi vedere come aggiungere parametri extra;)
Tolo Palmer

4
Ricevo questo errore jquery.min.js: 2 Uncaught TypeError: Impossibile leggere la proprietà "length" di null quando il mio server non restituisce alcun risultato.
Soptareanu Alex

109

per select2 v4.0.0 leggermente diverso

$(".itemSearch").select2({
    tags: true,
    multiple: true,
    tokenSeparators: [',', ' '],
    minimumInputLength: 2,
    minimumResultsForSearch: 10,
    ajax: {
        url: URL,
        dataType: "json",
        type: "GET",
        data: function (params) {

            var queryParameters = {
                term: params.term
            }
            return queryParameters;
        },
        processResults: function (data) {
            return {
                results: $.map(data, function (item) {
                    return {
                        text: item.tag_value,
                        id: item.tag_id
                    }
                })
            };
        }
    }
});

8
Non riesco a farlo funzionare ... :( Nessuna chiamata al server.
Simanas

Ha funzionato grazie, l'errore che ho fatto non era la mappatura corretta ide texti valori chiave.
Ja8zyjits

18

Nella versione 4.0.2 leggermente diverso Just in processResultse in result:

    processResults: function (data) {
        return {
            results: $.map(data.items, function (item) {
                return {
                    text: item.tag_value,
                    id: item.tag_id
                }
            })
        };
    }

È necessario aggiungere data.itemsa result. itemsè il nome di Json:

{
  "items": [
    {"id": 1,"name": "Tetris","full_name": "s9xie/hed"},
    {"id": 2,"name": "Tetrisf","full_name": "s9xie/hed"}
  ]
}

1
Se rimuovo itemsda data.itemsnon avrei bisogno di aggiungere l' itemsattributo sulla risposta, giusto? ;)
Yana Agun Siswanto

1
@bekicot sì, devi solo specificare $.map(data, function (item) se il tuo json è un array:[ {"id": 1,"text": "One"}, {"id": 2,"text": "Two"} ]
Tantowi Mustofa

2
Ho sbattuto la testa contro un muro e questo ha chiarito le cose. Grazie, la documentazione per select2 è gravemente carente.
Neil B.

11

Qui ti do il mio esempio che contiene -> Bandiera Paese, Città, Stato, Paese.

Ecco la mia uscita.

inserisci qui la descrizione dell'immagine

Allega questi due Cdn js o link.

<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/js/select2.min.js"></script>

js script

//for apend flag of country.

function formatState (state) {
    console.log(state);
    if (!state.id) {
      return state.text;
    }
    var baseUrl = "admin/images/flags";
    var $state = $(
      '<span><img src="'+baseUrl+ '/' + state.contryflage.toLowerCase() + '.png"  class="img-flag" /> ' +state.text+ '</span>'
    );
    return $state;
  };


$(function(){
    $("#itemSearch").select2({
    minimumInputLength: 2,
    templateResult: formatState, //this is for append country flag.
    ajax: {
        url: URL,
        dataType: 'json',
        type: "POST",
        data: function (term) {
            return {
                term: term
            };
        },
        processResults: function (data) {
            return {
                results: $.map(data, function (item) {
                    return {
                        text: item.name+', '+item.state.name+', '+item.state.coutry.name,
                        id: item.id,
                        contryflage:item.state.coutry.sortname
                    }
                })
            };
        }

    }
});

Risposta JSON prevista.

[
   {
      "id":7570,
      "name":"Brussels",
      "state":{
         "name":"Brabant",
         "coutry":{
            "sortname":"BE",
            "name":"Belgium",

         }
      }
   },
   {
      "id":7575,
      "name":"Brussels",
      "state":{
         "name":"Brabant Wallon",
         "coutry":{
            "sortname":"BE",
            "name":"Belgium",

         }
      }
   },
   {
      "id":7578,
      "name":"Brussel",
      "state":{
         "name":"Brussel",
         "coutry":{
            "sortname":"BE",
            "name":"Belgium",

         }
      }
   },

]

ma mi confondo in `data: function (term) {return {term: term}; }, `
Vikas Katariya,

6

È così che ho risolto il mio problema, ricevo i dati nella variabile di dati e utilizzando le soluzioni di cui sopra ho ricevuto un errore could not load results. Ho dovuto analizzare i risultati in modo diverso in processResults.

searchBar.select2({
            ajax: {
                url: "/search/live/results/",
                dataType: 'json',
                headers : {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
                delay: 250,
                type: 'GET',
                data: function (params) {
                    return {
                        q: params.term, // search term
                    };
                },
                processResults: function (data) {
                    var arr = []
                    $.each(data, function (index, value) {
                        arr.push({
                            id: index,
                            text: value
                        })
                    })
                    return {
                        results: arr
                    };
                },
                cache: true
            },
            escapeMarkup: function (markup) { return markup; },
            minimumInputLength: 1
        });

1

I problemi possono essere causati da una mappatura errata. Sei sicuro di avere il tuo risultato impostato in "dati"? Nel mio esempio, il codice di backend restituisce i risultati nella chiave "items", quindi la mappatura dovrebbe essere simile a:

results: $.map(data.items, function (item) {
....
}

e non:

 results: $.map(data, function (item) {
    ....
    }

1

Il mio ajax non viene mai licenziato fino a quando non ho avvolto il tutto

setTimeout(function(){ .... }, 3000);

Lo stavo usando nella sezione montata di Vue. ha bisogno di più tempo.


0

Se la richiesta ajax non viene attivata, controlla la classe select2 nell'elemento select. La rimozione della classe select2 risolverà il problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.