Dropdown-Liste 2 auswählen, aber neue Werte vom Benutzer zulassen?

125

Ich möchte eine Dropdown-Liste mit einer Reihe von Werten haben, aber dem Benutzer auch erlauben, einen neuen Wert "auszuwählen", der dort nicht aufgeführt ist.

Ich sehe, dass select2 dies unterstützt, wenn Sie es im tagsModus verwenden, aber gibt es eine Möglichkeit, dies ohne Verwendung von Tags zu tun?

John John
quelle
1
Select2 hat bei mir nie funktioniert, zumindest hat createSearchChoice in 4.0.3 nie bei mir funktioniert, und ich wollte nicht, dass meine Benutzer warten, bis Ajax abgeschlossen ist, um dasselbe Schlüsselwort zurückzugeben, also musste ich meine eigene Bibliothek ausrollen, ich bin es nur Teilen Sie es, weil ich denke, es könnte anderen helfen, die immer noch so verwirrt sind wie ich. Bitte stimmen Sie nicht ab, wenn Sie mit meiner Antwort nicht einverstanden sind: github.com/razzbee/tagcomplete
razzbee

Antworten:

100

Für Version 4+ überprüfen Sie diese Antwort unten von Kevin Brown

In Select2 3.5.2 und darunter können Sie Folgendes verwenden:

$(selector).select2({
  minimumInputLength:1,
  "ajax": {
    data:function (term, page) {
      return { term:term, page:page };
    },
    dataType:"json",
    quietMillis:100,
    results: function (data, page) {
      return {results: data.results};
    },
    "url": url
  },
  id: function(object) {
    return object.text;
  },
  //Allow manually entered text in drop down.
  createSearchChoice:function(term, data) {
    if ( $(data).filter( function() {
      return this.text.localeCompare(term)===0;
    }).length===0) {
      return {id:term, text:term};
    }
  },
});

(entnommen aus einer Antwort auf der select2-Mailingliste, kann den Link aber jetzt nicht finden)

fmpwizard
quelle
4
Entschuldigen Sie die verspätete Antwort, aber vielen Dank für Ihre Lösung! Das andere Poster hat übrigens einen Link zu deinem Kern gepostet, der dich doppelt großartig macht! :)
Johnjohn
rrauenza super, genau das, wonach ich gesucht habe
Matthias S
4
Das Hinzufügen des selectOnBlur: trueWillens erledigt
Alireza Fattahi
1
Nur ein Hinweis für zukünftige Leser, die Sie wahrscheinlich tags: []zusammen mit verwenden möchten createSearchChoice.
Kevin Brown
5
Die oben verlinkte Geige scheint gebrochen zu sein.
Wolfr
175

Die hervorragende Antwort von @fmpwizard funktioniert für Select2 3.5.2 und niedriger, funktioniert jedoch nicht in 4.0.0 .

Select2 unterstützt seit sehr früh (aber vielleicht nicht so früh wie diese Frage) "Tagging": Hier können Benutzer ihren eigenen Wert hinzufügen, wenn Sie dies zulassen. Dies kann über die tagsOption aktiviert werden , und Sie können mit einem Beispiel in der Dokumentation herumspielen .

$("select").select2({
  tags: true
});

Standardmäßig wird eine Option erstellt, die denselben Text wie der eingegebene Suchbegriff enthält. Sie können das verwendete Objekt ändern, wenn Sie es auf besondere Weise markieren möchten, oder das Objekt nach Auswahl aus der Ferne erstellen.

$("select").select2({
  tags: true,
  createTag: function (params) {
    return {
      id: params.term,
      text: params.term,
      newOption: true
    }
  }
});

select2:selectDie zusätzliche Eigenschaft dient nicht nur als leicht zu erkennendes Flag für das durch das Ereignis übergebene Objekt , sondern ermöglicht es Ihnen auch, die Option im Ergebnis etwas anders zu rendern. Wenn Sie also visuell signalisieren möchten, dass es sich um eine neue Option handelt, indem Sie " (neu) " daneben setzen, können Sie so etwas tun.

$("select").select2({
  tags: true,
  createTag: function (params) {
    return {
      id: params.term,
      text: params.term,
      newOption: true
    }
  },
  templateResult: function (data) {
    var $result = $("<span></span>");

    $result.text(data.text);

    if (data.newOption) {
      $result.append(" <em>(new)</em>");
    }

    return $result;
  }
});
Kevin Brown
quelle
Das war sehr hilfreich @ Markus1980Wien
abiieez
Ich glaube, ich habe dieses Snippet mehrmals verwendet.
Sahu V Kumar
Wenn dies nicht funktioniert, überprüfen Sie, ob Sie diese Option auf select2 hinzugefügt haben, ohne Ajax-Optionen hinzuzufügen. für select2 ajax
Zohaib
2
Die Arbeitsweise in Version select2 (4.0.6) lautet folgendermaßen: $ ("select"). Select2 ({tags: true, createTag: function (params) {return {id: params.term, text: params.term, newOption : true}}, templateResult: function (data) {var result = data.text; if (data.newOption) {result = result + '(new)';} return result;}}); danke @ Kevin Brown
M. Salah
Dies sollte die beste Antwort sein. Ich habe eine Weile danach gesucht und diese Option beantwortet jede Frage, die ich zu diesem Thema gesehen habe.
Justin
14

Nur um den Code am Leben zu erhalten, poste ich den Code von @rrauenza Fiddle aus seinem Kommentar .

HTML

<input type='hidden' id='tags' style='width:300px'/>

jQuery

$("#tags").select2({
    createSearchChoice:function(term, data) { 
        if ($(data).filter(function() { 
            return this.text.localeCompare(term)===0; 
        }).length===0) 
        {return {id:term, text:term};} 
    },
    multiple: false,
    data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
Michel Ayres
quelle
2
Ich bin zur Geige gegangen, aber in Chrome scheint es bei mir nicht zu funktionieren. Kannst du bestätigen?
IcedDante
@IcedDante der Code funktioniert. Der Punkt in der Geige ist nur zu zeigen, wie es gemacht werden soll (die Auswahl ist in der Geige versteckt)
Michel Ayres
4
Wenn ich zur Geige gehe, sehe ich nirgendwo ein Dropdown-Menü für select2. Wäre es nicht schön, ein Beispiel zu haben, das tatsächlich ... etwas tut?
IcedDante
Wie kann ich die Daten von einer externen Quelle einstellen? Ich meine, was ist, wenn ich Städte eines ausgewählten Landes laden möchte und das ausgewählte Land selbst ein Dropodown ist?
Ali Baig
12

Da viele dieser Antworten in 4.0+ nicht funktionieren, kann der Server bei Verwendung des Ajax den neuen Wert als Option hinzufügen. So würde es funktionieren:

  1. Benutzer sucht nach Wert (wodurch eine Ajax-Anfrage an den Server gestellt wird)
  2. Wenn der Wert groß ist, geben Sie die Option zurück. Wenn nicht, lassen Sie den Server diese Option wie folgt anhängen:[{"text":" my NEW option)","id":"0"}]
  3. Wenn das Formular gesendet wird, überprüfen Sie einfach, ob sich diese Option in der Datenbank befindet, und erstellen Sie sie vor dem Speichern, falls nicht.
Eric
quelle
6

Es gibt eine bessere Lösung, denke ich jetzt

Setzen Sie das Tagging in den Auswahloptionen einfach auf true.

tags: true

von https://select2.org/tagging

Steven Moffat
quelle
4

Verbesserte Antwort auf @fmpwizard:

//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
  if ( $(data).filter( function() {
    return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
  }).length===0) {
    return {id:term, text:term};
  }
},

//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined
Vikash Singh
quelle
Ich habe dies mit einer geringfügigen Änderung verwendet. Ich werde meine Antwort in einer Sekunde veröffentlichen, aber danke.
Sam
1
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;

In den meisten Fällen müssen wir Werte mit unempfindlichen Registern vergleichen. Und dieser Code gibt false zurück, was zur Erstellung doppelter Datensätze in der Datenbank führt. Darüber hinaus wird String.prototype.localeCompare () vom Browser Safary nicht unterstützt und dieser Code funktioniert in diesem Browser nicht.

return this.text.localeCompare(term)===0;

wird besser ersetzen

return this.text.toLowerCase() === term.toLowerCase();
übertroffen
quelle
1

Vielen Dank für die Hilfe, ich habe den folgenden Code in Codeigniter II verwendet und verwende Version: 3.5.2 von select2.

var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
    ajax: {
        url: location_url,
        dataType: 'json',
        quietMillis: 100,
        data: function (term) {
            return {
                term: term
            };
        },
        results: function (data) {
            results = [];
            $.each(data, function(index, item){
                results.push({
                    id: item.location_id,
                    text: item.location_name
                });
            });
            return {
                results: results
            };
        }
    },
    //Allow manually entered text in drop down.
    createSearchChoice:function(term, results) {
        if ($(results).filter( function() {
            return term.localeCompare(this.text)===0; 
        }).length===0) {
            return {id:term, text:term + ' [New]'};
        }
    },
});
Sam
quelle