Select2 Ajax-Methode nicht ausgewählt

72

Ok, ich bin mir sicher, dass hier etwas Einfaches falsch ist, aber ich bin nicht 100% was es ist.

Daher versuche ich, die Select2 AJAX-Methode zu verwenden, damit Benutzer eine Datenbank durchsuchen und ein Ergebnis auswählen können. Der Anruf selbst kommt mit Ergebnissen zurück, erlaubt mir jedoch nicht, die Antwort aus der Liste auszuwählen. Es scheint Ihnen auch nicht zu erlauben, es beim Schweben oder Aufwärts- / Abwärtspfeil "auszuwählen". Also ohne weiteres, hier ist mein Code:

index.html

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
        <link rel="stylesheet" type="text/css" href="select2/select2.css" media="screen" />
        <script src="select2/select2.js"></script>
        <script src="select.js"></script>
    </head>
    <body>
        <input type="text" style="width: 500px" class="select2">
    </body>
</html>

select.js

jQuery(function() {

  var formatSelection = function(bond) {
    console.log(bond)
    return bond.name
  }

  var formatResult = function(bond) {
    return '<div class="select2-user-result">' + bond.name + '</div>'
  }

  var initSelection = function(elem, cb) {
    console.log(elem)
    return elem
  }

    $('.select2').select2({
      placeholder: "Policy Name",
      minimumInputLength: 3,
      multiple: false,
      quietMillis: 100,
      ajax: {
        url: "http://localhost:3000/search",
        dataType: 'json',
        type: 'POST',
        data: function(term, page) {
          return {
            search: term,
            page: page || 1
          }
        },
        results: function(bond, page) {
          return {results: bond.results, more: (bond.results && bond.results.length == 10 ? true: false)}
        }
      },
      formatResult: formatResult,
      formatSelection: formatSelection,
      initSelection: initSelection
    })
})

JSON-Antwort

{
  error: null,
  results: [
    {
      name: 'Some Name',
      _id: 'Some Id'
    },
    {
      name: 'Some Name',
      _id: 'Some Id'
    }
  ]
}

Alles scheint korrekt zu sein, aber ich kann die Antwort nicht auswählen und in das Feld eingeben. Gibt es irgendwo in meinem Code ein Problem?

AlbertEngelB
quelle
2
Bei weiteren Untersuchungen scheint alles korrekt zu funktionieren, wenn ich die Dropdown-Klasse von select2-result-unselectable auf select2-result-selectable ändere.
AlbertEngelB
Ich würde es vermeiden, Ihren Abfrage-Aufruf mit einer Klasse durchzuführen, und stattdessen eine ID verwenden. $ ('# thisSelect'). select2 ({......
ganders
@ganders Ich weiß nicht, wie das überhaupt wichtig wäre.
AlbertEngelB
Wenn Sie zufällig zwei dieser select2-Implementierungen auf demselben Formular / derselben Seite verwenden und dann eine eingeben, werden die Ergebnisse in beiden platziert. Klassen sind so konzipiert, dass sie wiederverwendet werden können, während IDs nur für einen bestimmten Zweck verwendet werden sollten.
Ganders

Antworten:

141

Nachdem ich mir eine andere Antwort angesehen habe, muss ich anscheinend bei jedem Anruf auch das ID-Feld übergeben, da sonst die Eingabe deaktiviert wird.

Beispielcode, der das Problem behoben hat:

$('.select2').select2({
  placeholder: "Policy Name",
  minimumInputLength: 3,
  multiple: false,
  quietMillis: 100,
  id: function(bond){ return bond._id; },
  ajax: {
    url: "http://localhost:3000/search",
    dataType: 'json',
    type: 'POST',
    data: function(term, page) {
      return {
        search: term,
        page: page || 1
      }
    },
    results: function(bond, page) {
      return {results: bond.results, more: (bond.results && bond.results.length == 10 ? true: false)}
    }
  },
  formatResult: formatResult,
  formatSelection: formatSelection,
  initSelection: initSelection
})

Bearbeiten

Da dies immer wieder positiv bewertet wird, werde ich etwas näher darauf eingehen. Die .select2 () -Methode erwartet idfür alle Ergebnisse ein eindeutiges Feld. Zum Glück gibt es eine Problemumgehung. Die idOption akzeptiert eine Funktion wie diese:

function( <INDIVIDUAL_RESULT> ) {
  // Expects you to return a unique identifier.
  // Ideally this should be from the results of the $.ajax() call. 
}

Da meine eindeutige Kennung war <RESULT>._id, habe ich einfachreturn <RESULT>._id;

AlbertEngelB
quelle
2
Vielen Dank für diese Antwort! Riesige, große Hilfe! Ich bekam keine Fehler und alles, was ich durchging, zeigte an, dass es funktionieren sollte.
Mike Homol
@ MikeHomol Kein Problem, ich bin froh, dass diese Frage so vielen Menschen in der Community geholfen hat. Überrascht ist dies ein so häufiges Problem!
AlbertEngelB
1
Danke dafür. Kleiner Hinweis: Wenn das Formular gesendet wird, ist der Feldwert die Zeichenfolge "Objekt [Objekt]". "Return {id: bond._id}" wurde durch "return bond._id" ersetzt und alles ist wieder sonnig ...
medowlock
@ BogdanG Ohhh, das ist in der Tat richtig. Ich wusste nicht, dass ich in dieser Antwort falsch lag. Ich werde aktualisieren!
AlbertEngelB
15
Dies funktioniert in Select2 4.0 leider nicht mehr. Sie benötigen den Code hier , damit er funktioniert.
Awidgery
13

Die Sache ist, dass die JSON-Daten eine Eigenschaft namens "id" benötigen. Es besteht keine Notwendigkeit für

id: function (bond) {return bond._id; }}

Wenn die Daten keine eigene ID haben, können Sie sie mit einer Funktion für processResults wie hier hinzufügen .

        $(YOUR FIELD).select2({
            placeholder: "Start typing...",
            ajax: {
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "YOUR API ENDPOINT",
                dataType: 'json',
                data: 
                    function (params) {
                        return JSON.stringify({ username: params.term });
                },
                processResults: function (data, page) {

                    var results = [];

                    $.each(JSON.parse(data.d), function (i, v) {
                        var o = {};
                        o.id = v.key;
                        o.name = v.displayName;
                        o.value = v.key;
                        results.push(o);
                    })

                    return {
                        results: results
                    };
                },
                cache: true
            },
            escapeMarkup: function (markup) { return markup;},
            minimumInputLength: 1,
            templateResult: function (people) {
                if (people.loading)
                    return people.text;

                var markup = '<option value="' + people.value + '">' + people.name + '</option>';

                return markup;
            },
            templateSelection: function (people) { return people.value || people.text }

        });    
Andres Gonzalez
quelle
Die ID-Option in select2 scheint in der neueren Version nicht zu funktionieren. Befolgen Sie diese Lösung, wenn Sie die neueste Version vom 16. Mai verwenden.
Vihari Piratla
5

Seien Sie auch vorsichtig mit dem Fall. Ich habe verwendet, Idaber select2 erwartet id. Könnte jemandem Zeit sparen.

Eugene
quelle
5

Wie Dropped.on.Caprica sagte: Jedes Ergebniselement benötigt eine eindeutige ID.

Weisen Sie einfach jedem Ergebnis ideine eindeutige Nummer zu:

$('#searchDriver').select2({
    ajax: {
       dataType: 'json',
       delay: 250,
       cache: true,
       url: '/users/search',
       processResults: function (data, params) {
           //data is an array of results
           data.forEach(function (d, i) {
               //Just assign a unique number or your own unique id
               d.id = i; // or e.id = e.userId;
           })

           return {
               results: data
           };
       },
    },
    escapeMarkup: function (markup) { return markup; },
    minimumInputLength: 1,
    templateResult: formatRepo,
    templateSelection: formatRepoSelection
});
Anh Cao
quelle
1

Ich habe viele Probleme bezüglich des folgenden Fehlers. Option 'Ajax' ist für Select2 nicht zulässig

In meinem Fall wird für select angezeigt, wenn Sie select2 Version 3.5 verwenden. Sie sollten also auf Version 4.0 aktualisieren, und Sie müssen keine versteckten Eingaben an Ihre select anhängen

Ebrahim
quelle
0

Geben Sie hier die Bildbeschreibung ein

Sie können die Auswahl einer Option (in diesem Fall der ersten) auslösen, indem Sie das select2Element programmgesteuert öffnen und dann einen returnTastendruck auslösen .

var e = jQuery.Event('keydown');
e.which = 13;

$('.offer_checkout_page_link select').select2('open');
$('.offer_checkout_page_link .select2-selection').trigger(e);

Dadurch wird die Option so eingestellt, als ob Sie darauf geklickt hätten. Sie können dies ändern, um eine bestimmte Option auszuwählen, indem Sie die entsprechende Anzahl von downTastendrücken auslösen, bevor Sie diese auslösen return.

Wenn Sie enterauf eine Option klicken (oder in diesem Fall drücken ), um eine Option auszuwählen, wird dem Auswahlelement ein Optionselement hinzugefügt. Sie werden feststellen, dass select2ausgewählte Elemente beim ersten Laden der Seite keine untergeordneten Elemente haben option. Aus diesem Grund schlagen andere Lösungen vor, ein Optionselement mit jQuery hinzuzufügen und dann auszuwählen.

Justin Leveck
quelle