Comment utiliser Select2 avec JSON via une requête Ajax?


88

My Select2 3.4.5 ne fonctionne pas avec les données JSON.

Voici ma zone de saisie sur HTML:

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

… Et mon 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;
    }
});

J'ai créé une API avec Laravel 4 qui renvoie une valeur chaque fois que je tape quelque chose sur ma zone de texte.

Voici le résultat si je tape "test" dans ma zone de texte:

[{"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}]

Je ne peux pas ajouter le résultat à ma liste déroulante Select2. Je pense formatSelectionet formatResultcausent le problème parce que je ne sais pas quel paramètre devrait être placé dessus. Je ne sais pas où trouver ces paramètres tels que le conteneur, l'objet et la requête et les valeurs qu'il devrait renvoyer, ou ma réponse JSON est-elle erronée?

Réponses:


110

Ici vous avez un exemple

$("#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
                    }
                })
            };
        }
    }
});

C'est assez simple


2
Merci pour la suggestion à $ .map
tacos_tacos_tacos

Pouvez-vous expliquer le paramètre "slug"?
IcedDante

item est un objet avec les propriétés completeName, slug et id. Ceci est juste un exemple, copiez et collez.
Tolo Palmer

2
Slug c'est une propriété réelle de l'article, votre article, j'ai ajouté ceci car vous pouvez voir comment ajouter des paramètres supplémentaires;)
Tolo Palmer

4
Je reçois cette erreur jquery.min.js: 2 Uncaught TypeError: Impossible de lire la propriété 'length' de null lorsque mon serveur ne renvoie aucun résultat.
Soptareanu Alex

109

pour select2 v4.0.0 légèrement différent

$(".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
Impossible de faire fonctionner cela ...: (Aucun appel au serveur.
Simanas

Cela a fonctionné grâce, l'erreur je l' ai fait n'a pas été correctement dresser la carte idet les textvaleurs clés.
Ja8zyjits

18

Dans la version 4.0.2 légèrement différente Just in processResultset in result:

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

Vous devez ajouter data.itemsà result. itemsest le nom Json:

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

1
Si je supprime itemsde, data.itemsje n'ai pas besoin d'ajouter un itemsattribut sur la réponse, n'est-ce pas? ;)
Yana Agun Siswanto

1
@bekicot oui, vous ne spécifiez que $.map(data, function (item) si votre json est un tableau:[ {"id": 1,"text": "One"}, {"id": 2,"text": "Two"} ]
Tantowi Mustofa

2
J'ai cogné ma tête contre un mur et cela a clarifié les choses. Merci, la documentation de select2 fait cruellement défaut.
Neil B.

11

Ici, je vous donne mon exemple qui contient -> Drapeau du pays, Ville, État, Pays.

Voici ma sortie.

entrez la description de l'image ici

Attachez ces deux js ou liens Cdn.

<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>

script js

//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
                    }
                })
            };
        }

    }
});

Réponse JSON attendue.

[
   {
      "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",

         }
      }
   },

]

mais je suis déroutant dans `data: function (term) {return {term: term}; }, `
Vikas Katariya

6

C'est ainsi que j'ai résolu mon problème, j'obtiens des données dans la variable de données et en utilisant les solutions ci-dessus, j'obtenais une erreur could not load results. J'ai dû analyser les résultats différemment dans 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

Les problèmes peuvent être causés par un mappage incorrect. Êtes-vous sûr d'avoir votre jeu de résultats dans "données"? Dans mon exemple, le code backend renvoie les résultats sous la clé "items", le mappage devrait donc ressembler à:

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

et pas:

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

1

Mon ajax ne se fait jamais virer tant que je n'ai pas tout emballé

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

Je l'utilisais dans la section montée de Vue. il faut plus de temps.


0

Si la requête ajax n'est pas déclenchée, veuillez vérifier la classe select2 dans l'élément select. La suppression de la classe select2 résoudra ce problème.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.