2015-09-26 7 views
9

Sto migrando su select2 to use as a tagging plugin da un altro plug-in, ma c'è una lacuna che sto cercando di capire se select2 può supportare.Con plug-in jquery select2 con tag: true, come è possibile evitare che le scelte vengano visualizzate nel menu a discesa che sono già selezionate?

Lasciate guardare un esempio. Diciamo che la mia lista di scelte (provenienti retro server dalla richiesta Ajax) è

"Dog", "Cat", "Monkey", "Giraffe" 

Nel vecchio plug-sto usando, dopo scelgo una delle scelte (diciamo "Cat") e si presenta in la casella di testo, la prossima volta che cerco la stessa stringa parziale (diciamo "Ca"), DOESN "T have" Cat "appare nel menu a discesa delle scelte (poiché sa che l'hai già scelto in precedenza)

Sembra che select2 mostri ancora l'elemento nel menu a discesa durante la ricerca, indipendentemente dal fatto che lo abbia già selezionato. Select2 impedisce di entrare se dopo aver premuto invio ma sembra un po 'non intuitivo, quindi sto cercando di capire se c'è un modo per select2 replicare lo stesso comportamento ior dell'altro plug-in (dove le scelte non vengono nemmeno visualizzate)

Un altro esempio di questo funziona correttamente, anche la sezione del tag stackoverflow di una domanda fa la cosa giusta. Se aggiungo "jquery" alla mia lista di tag per questa domanda e poi cerco di nuovo "jquery", è DOESN "T mostra che nella lista (come è già stato scelto) .Questo è il comportamento che sto cercando per

Ecco il mio codice select2 corrente:.

HTML:

<select id="Tags" name="Tags" multiple="multiple"> 
</select> 

Javascript:

function SetupAppTags() { 
$("#Tags").select2({ 
    theme: "classic", 
    width: "98%", 
    tags: true, 
    ajax: { 
     url: "/Tag/Search", 
     dataType: 'json', 
     delay: 300, 
     data: function(params) { 
      return { q: params.term }; 
     }, 
     processResults: function(data, params) { 
      return { results: data }; 
     }, 
     cache: false 
    }, 
    escapeMarkup: function(markup) { return markup; }, 
    minimumInputLength: 3, 
    templateResult: tagFormatResult, 
    templateSelection: tagSelectionResult 
}); 
} 

function tagFormatResult(tag) { 

    if (tag.loading) { 
    return "Loading . . ."; 
} else { 
    if (tag.name) { 
     return tag.name; 
    } 
    return tag.text + " [NEW]"; 
} 
} 

function tagSelectionResult(tag) { 
    if (tag.name) { 
    return tag.name; 
    } 
    return tag.text; 
} 

Penso che in qualche modo nella funzione templateResult esiste un modo per restituire false o qualcosa per non mostrare quell'elemento se è già selezionato. E 'qualcosa di simile a questo possibile (non riesce a trovare nulla in linea o nella documentazione)

risposta

5

E ' sembra che tu stia cercando a custom matcher. L'utilizzo di uno consentirà di filtrare gli elementi a discesa prima di visualizzarli all'utente.

var $t = $('#target'); 
 
$t.select2({ 
 
    multiple: true, 
 
    tags: true, 
 
    data: ["Pasty", "Pasta", "Posters"], 
 
    matcher: function(params, option) { 
 
    var selected = $t.select2('data'); 
 
    var optionSelected = selected.some(function(item) { 
 
     return (item.text === option.text); 
 
    }); 
 
    if (optionSelected) return false; 
 
    return option; 
 
    } 
 
});
#target { 
 
    width: 100%; 
 
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script> 
 
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" /> 
 
<select id="target"></select>

+0

sai cosa differenza tra un matcher personalizzato e il ritorno di null nella funzione templateResult? – leora

+0

@leora Ho esaminato i documenti e ho fatto un po 'di debug, entrambe sono opzioni praticabili in quanto offrono funzionalità un po' duplicate. Dai documenti: _ "[Select2 usa il]' matcher' per determinare se [ogni risultato] deve essere visualizzato. "_ _" Il 'templateResult' può anche restituire' null', che impedirà la visualizzazione dell'opzione nel lista dei risultati. "_ Così come puoi vedere, permettono all'utente di fare la stessa cosa attraverso percorsi diversi. Perché la libreria è stata progettata in questo modo non è troppo chiara, ma il motivo è probabilmente la facilità d'uso se si desidera modificare l'uno o l'altro in piccoli dettagli. – Nit

+1

Grazie per il seguito – leora

0

Si dovrebbe guardare a cambiare la funzione templateResult ...

La funzione templateResult dovrebbe restituire una stringa contenente il testo per essere visualizzato, o un oggetto (come un oggetto jQuery) che contiene i dati che dovrebbero essere visualizzati. Può anche restituire null, il che impedirà la visualizzazione dell'opzione nell'elenco dei risultati.

https://select2.github.io/options.html#templateSelection

+1

grazie James. Ho aggiornato la tua risposta con la soluzione che sembra funzionare. Per favore fatemi sapere se vedete qualche problema con la mia soluzione o avete un altro suggerimento – leora

+0

In realtà, ho appena realizzato la risposta di cui sopra che ho aggiunto alla vostra domanda DOESN "T lavoro come se rimuovessi un tag che ancora compare nella lista in modo da ottenere un problema per cui se rimuovi un tag e vuoi aggiungerlo di nuovo, non ti permette di ... Quindi sono tornato al tavolo da disegno. Sai come posso prevenire? – leora

+0

scusa non lo faccio :(Non l'ho mai usato prima, ma dalla lettura della documentazione sembrava che funzionasse – JamesHalsall

-1

È possibile raggiungere questo semplicemente come qui di seguito,

È necessario nascondere le opzioni selezionate utilizzando CSS

$('select').select2();
.select2-container--default .select2-results__option[aria-selected=true] { 
 
    display: none; 
 
}
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" /> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script> 
 

 
<select id="Tags" name="Tags" multiple="multiple"> 
 
    <option value="1">first</option> 
 
    <option value="2">second</option> 
 
    <option value="3">third</option> 
 
    <option value="4">fourth</option> 
 
</select>

+2

È un trucco che funziona, ma potrebbe causare altri problemi, come la selezione della tastiera –

+0

@ MarcosPérezGude concordare .. – jlocker

+0

Ehi, non preoccuparti, io rendilo in un progetto e funziona, ma in altre situazioni non riesco a scrivere questo trucco A seconda delle esigenze dell'OP. Buona fortuna! –

Problemi correlati