Jak korzystać z Select2 z JSON za pośrednictwem żądania Ajax?

88

Mój Select2 3.4.5 nie działa z danymi JSON.

Oto moje pole wprowadzania w HTML:

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

… I mój 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;
    }
});

Stworzyłem API z Laravel 4, które zwraca wartość za każdym razem, gdy piszę cokolwiek w moim polu tekstowym.

Oto wynik, jeśli wpiszę „test” w moim polu tekstowym:

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

Nie mogę dodać wyniku do listy rozwijanej Select2. Myślę formatSelectioni formatResultpowodują problem, ponieważ nie wiem, jaki parametr powinien być na nim umieszczony. Nie wiem, skąd wziąć te parametry, takie jak kontener, obiekt i zapytanie oraz wartości, które powinny zwracać, czy też moja odpowiedź JSON jest nieprawidłowa?

melvnberd
źródło

Odpowiedzi:

110

Tutaj masz przykład

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

To całkiem proste

Tolo Palmer
źródło
2
Dzięki za sugestię do $ .map
tacos_tacos_tacos,
Czy możesz wyjaśnić parametr „slug”?
IcedDante
item jest obiektem z właściwościami completeName, slug i id. To tylko przykład, kopiuj i wklej.
Tolo Palmer
2
Ślimak to aktualna własność przedmiotu, twojego przedmiotu, dodałem to jak widać jak dodać dodatkowe parametry;)
Tolo Palmer
4
Otrzymuję ten błąd jquery.min.js: 2 Uncaught TypeError: Nie można odczytać właściwości „length” o wartości null, gdy mój serwer nie zwraca żadnego wyniku.
Soptareanu Alex
109

dla select2 v4.0.0 nieco inaczej

$(".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
                    }
                })
            };
        }
    }
});
brzytwa
źródło
8
Nie mogę tego uruchomić ... :( Brak połączeń z serwerem.
Simanas
Zadziałało dzięki, błąd, który popełniłem, polegał na nieprawidłowym mapowaniu idi textkluczowych wartościach.
Ja8zyjits
18

W wersji 4.0.2 nieco inaczej Just in processResultsi in result:

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

Należy dodać data.itemsw result. itemsto nazwa Json:

{
  "items": [
    {"id": 1,"name": "Tetris","full_name": "s9xie/hed"},
    {"id": 2,"name": "Tetrisf","full_name": "s9xie/hed"}
  ]
}
Ebad ghafoory
źródło
1
Jeśli usunę itemsz pola, data.itemsnie będę musiał dodawać itemsatrybutu w odpowiedzi, prawda? ;)
Yana Agun Siswanto
1
@bekicot tak, po prostu określ tylko, $.map(data, function (item) czy twój json jest tablicą:[ {"id": 1,"text": "One"}, {"id": 2,"text": "Two"} ]
Tantowi Mustofa
2
Waliłem głową o ścianę i to wyjaśniło sprawę. Dziękuję, bardzo brakuje dokumentacji dla select2.
Neil B.
11

Oto mój przykład, który zawiera -> Flaga kraju, miasto, stan, kraj.

Oto mój wynik.

wprowadź opis obrazu tutaj

Dołącz te dwa pliki Cdn js lub łącza.

<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

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

    }
});

Oczekiwana odpowiedź JSON.

[
   {
      "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
źródło
ale mylę się w `data: function (term) {return {term: term}; }, `
Vikas Katariya
6

W ten sposób naprawiłem swój problem, otrzymuję dane w zmiennej data i używając powyższych rozwiązań otrzymałem błąd could not load results. Musiałem inaczej przeanalizować wyniki w 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
źródło
1

Problemy mogą być spowodowane nieprawidłowym mapowaniem. Czy na pewno masz zestaw wyników w „danych”? W moim przykładzie kod zaplecza zwraca wyniki pod kluczem „items”, więc mapowanie powinno wyglądać następująco:

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

i nie:

 results: $.map(data, function (item) {
    ....
    }
próbnik
źródło
1

Mój Ajax nigdy nie zostaje zwolniony, dopóki nie zapakuję całej rzeczy

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

Używałem go w zamontowanej sekcji Vue. potrzebuje więcej czasu.

Apit John Ismail
źródło
0

Jeśli żądanie AJAX nie zostanie uruchomione, sprawdź klasę select2 w elemencie select. Usunięcie klasy select2 rozwiąże ten problem.

sudin
źródło