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?

melvnberd
la source

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

Tolo Palmer
la source
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
                    }
                })
            };
        }
    }
});
razorfish
la source
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"}
  ]
}
Ebad Ghafoory
la source
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",

         }
      }
   },

]
Dilip Hirapara
la source
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
        });
Chaudhry Waqas
la source
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) {
    ....
    }
testeur
la source
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.

Apit John Ismail
la source
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.

sudin
la source