2015-12-08 18 views
5

Ho implementato un sistema di tagging in cui è possibile scegliere tra tag esistenti o aggiungere nuovi tag. Dopo che un nuovo tag è stato selezionato, continuerà a essere utilizzato con una chiamata AJAX.Seleziona2: opzione di aggiornamento dopo aver selezionato il nuovo tag

Per ottenere ciò, utilizzo la richiamata createTag e l'evento select2:select. Perché mi piace creare il tag solo quando è selezionato, faccio una chiamata AJAX per questo se viene attivato l'evento select2:select.

Il problema è che ho bisogno di aggiornare l'opzione già creata di select2 con l'ID che ottengo dal persistere del mio nuovo tag nel database. Qual è la soluzione più pulita per questo?

Ecco quello che ho:

$('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

Hai mai provato ad attivare un evento di modifica una volta creato il tag? – BuddhistBeast

+0

@BuddhistBeast dovrebbe questo aiutarmi esattamente? Se ascolto questo evento il mio ID è già andato? O dovrei ascoltare l'evento change invece dell'evento select? – TiMESPLiNTER

+0

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

risposta

4

Il mio problema è che non ho aggiunto il nuovo tag come un tag <option> al campo di selezione nativo.

Ciò è necessario perché select2 verifica i valori impostati tramite select2.val(values) se esiste un tag <option> con questo valore. In caso contrario, select2 invia automaticamente il valore fuori dalla matrice e imposta la matrice di valori con un tag di opzione corrispondente nel campo di selezione sottostante.

Quindi questo è come funziona corretto ora (per 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'); 
}); 

La risposta AJAX minima (formato JSON) deve assomigliare a questo:

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

Si può aggiungere ulteriori dati a ciascun risultato, diciamo il proprio rendering della lista dei risultati con ulteriori dati al suo interno.

Problemi correlati