2015-12-08 8 views
5

Ich habe ein Tagging-System implementiert, bei dem Sie aus vorhandenen Tags auswählen oder neue Tags hinzufügen können. Nachdem ein neues Tag ausgewählt wurde, wird es mit einem AJAX-Aufruf beibehalten.Select2: Update-Option nach Auswahl des neuen Tags

Um dies zu erreichen, verwende ich den Rückruf createTag und das Ereignis select2:select. Da ich das Tag nur dann erstellen möchte, wenn es ausgewählt ist, mache ich einen AJAX-Aufruf, wenn das Ereignis select2:select ausgelöst wird.

Das Problem ist, dass ich die bereits erstellte Option von select2 mit der ID aktualisieren muss, die ich bekomme, indem ich mein neues Tag in der Datenbank persistiere. Was ist die sauberste Lösung dafür?

Hier ist, was ich habe:

$('select.tags').select2({ 
    tags: true, 
    ajax: { 
     url: '{{ path('tag_auto_complete') }}', 
     processResults: function (data) { 
      return { 
       results: data.items, 
       pagination: { 
        more: false 
       } 
      }; 
     } 
    }, 
    createTag: function (tag) { 
     return { 
      id: tag.term, // <-- this one should get exchanged after persisting the new tag 
      text: tag.term, 
      tag: true 
     }; 
    } 
}).on('select2:select', function (evt) { 
    if(evt.params.data.tag == false) { 
     return; 
    } 

    $.post('{{ path('tag_crrate_auto_complete') }}', { name: evt.params.data.text }, function(data) { 
     // ----> Here I need to update the option created in "createTag" with the ID 
     option_to_update.value = data.id; 

    }, "json"); 
}); 
+0

Haben Sie versucht, ein Änderungsereignis auszulösen, nachdem das Tag erstellt wurde? – BuddhistBeast

+0

@BuddhistBeast sollte mir das genau helfen? Wenn ich dieses Ereignis höre, ist meine ID schon weg? Oder sollte ich das Change-Event statt des Select-Events anhören? – TiMESPLiNTER

+0

bezogen http://stackoverflow.com/questions/23295168/how-doi-i-fire-a-new-ajax-on-select2-new-remove-tag-event –

Antwort

4

Mein Problem war, dass ich nicht den neuen Tag als <option> Tag zur nativen Auswahlfeld hinzugefügt haben.

Dies ist notwendig, weil select2 nach den Werten sucht, die durch select2.val(values) gesetzt wurden, wenn ein <option> Tag mit diesem Wert existiert. Wenn nicht, wählt select2 den Wert automatisch aus dem Array aus und setzt das Array mit Werten, die ein entsprechendes Options-Tag im darunter liegenden Auswahlfeld haben.

So ist dies, wie es richtig funktioniert jetzt (für select2 4.0.x):

$('select.tags').select2({ 
    tags: true, 
    ajax: { 
     url: '{{ path('tag_auto_complete') }}', 
     processResults: function (data) { 
      return { 
       results: data.items, 
       pagination: { 
        more: false 
       } 
      }; 
     } 
    }, 
    createTag: function (tag) { 
     return { 
      id: tag.term, 
      text: tag.term, 
      tag: true 
     }; 
    } 
}).on('select2:select', function (evt) { 
    if(evt.params.data.tag == false) { 
     return; 
    } 

    var select2Element = $(this); 

    $.post('{{ path('tag_crrate_auto_complete') }}', { name: evt.params.data.text }, function(data) { 
     // Add HTML option to select field 
     $('<option value="' + data.id + '">' + data.text + '</option>').appendTo(select2Element); 

     // Replace the tag name in the current selection with the new persisted ID 
     var selection = select2Element.val(); 
     var index = selection.indexOf(data.text);    

     if (index !== -1) { 
      selection[index] = data.id.toString(); 
     } 

     select2Element.val(selection).trigger('change'); 

    }, 'json'); 
}); 

Die minimale AJAX-Antwort (JSON-Format), wie diese auszusehen hat:

[ 
    {'id': '1', 'text': 'foo'}, 
    {'id': '2', 'text': 'bar'}, 
    {'id': '3', 'text': 'baz'} 
] 

Sie können Fügen Sie jedem Ergebnis zusätzliche Daten hinzu, um beispielsweise die Ergebnisliste mit zusätzlichen Daten zu rendern.