2010-07-21 22 views
11

Sto avendo un sacco di problemi nel far funzionare il widget di completamento automatico di jQuery per me. Sto usando un elenco di coppie chiave/valore da un server.jQuery UI Completamento automatico con ricerca testo/ID ibrida

Ho i seguenti requisiti:

Se l'utente seleziona un valore dal widget, voglio passare l'ID al server.

Se l'utente non seleziona un valore e immette il testo non elaborato, oppure modifica un valore che è già stato selezionato, voglio che il campo ID venga cancellato e solo il testo non elaborato da inviare al server.

Si supponga che someAjaxFunction restituisca una matrice di oggetti che il widget di completamento automatico si aspetta: {label:label, value:key}.

Inizialmente ho impostato il completamento automatico widget di up in questo modo:

$(input).autocomplete({ 
    source: sourceFunction, 
    minLength: 1 
}); 

Modifica della selezione, anche posizionando il mouse sopra una delle voci cambia il testo nella casella di testo a cui fa riferimento $ (input) al tasto sottostante, piuttosto che l'etichetta. Questo è altamente indesiderabile dal punto di vista dell'interazione dell'utente - anzi, la ragione per cui sto indagando questo è perché gli utenti del sito che sto costruendo sono stati costantemente sconcertati dal testo che hanno inserito apparentemente trasformandosi in numeri casuali!

ho aggiunto un campo nascosto sotto la casella di testo e attuato la select() e messa a fuoco() eventi al fine di mascherare l'ID in questo modo:

$(input).autocomplete({ 
    source: sourceFunction, 
    minLength: 1 
    focus: function(event, ui) { 
     $(idField).val(ui.item.value); 
     $(this).val(ui.item.label); 
     return false; 
    }, 
    select: function(event, ui) { 
     $(idField).val(ui.item.value); 
     $(this).val(ui.item.label); 
     return false; 
    }, 
    minLength: 1 
}); 

Questo funziona bene quando l'utente è attaccare al script fornito dal menu a discesa del completamento automatico. L'ID è nascosto e correttamente inviato al server. Sfortunatamente, se l'utente vuole inserire del testo a mano libera nella casella e cercare in base a quel valore, il campo ID non viene ripristinato e l'ID precedentemente selezionato viene inviato al server. Anche questo è piuttosto confuso.

La documentazione di completamento automatico dell'interfaccia utente jQuery elenca un evento change e afferma che la proprietà item dell'argomento ui verrà impostata sull'elemento selezionato. Ho immaginato di poter resettare il campo ID nascosto su un tasto premuto e ri-compilare l'ID se il completamento automatico è stato modificato. Sfortunatamente, oltre all'evento keypress che cattura un intero gruppo di pressioni di tasti che non deve resettare l'ID, l'istruzione return false nell'evento select necessario per gestire il testo nella casella di testo impedisce l'evento change dall'avere ui .item correttamente assegnato.

Così ora sono bloccato - Non so davvero cos'altro posso provare per rendere la funzionalità di supporto widget che sembra dovrebbe supportare per impostazione predefinita. O questo processo è molto più complicato di quanto dovrebbe essere, o mi manca qualcosa di veramente ovvio. Ho raccolto tutti gli eventi disponibili e tutti gli esempi e sono venuto a mani vuote. Infatti, anche l'esempio "Dati personalizzati e visualizzazione" sulla pagina dell'interfaccia utente jQuery soffre di questo problema.

Posso aggiungere alcuni hack sul lato server per coprire per questo, ma io preferirei davvero essere in grado di farlo a livello di client.

Preferisco anche attenermi al widget di completamento automatico dell'interfaccia utente di jQuery piuttosto che passare a un altro.

+0

Spiacente, posso chiarire qualcosa? Almeno uno dei tuoi problemi è che desideri che la casella ID venga riempita * * dell'ID associato se l'utente immette un valore che ha un ID corrispondente o qualsiasi cosa l'utente sta digitando se non c'è un valore corrispondente - corretto/errata? – Stephen

+0

Nah, voglio solo che il campo ID nascosto sia vuoto se il testo nella casella di testo è impostato su qualcosa che non corrisponde a una selezione offerta dal completamento automatico. – Shabbyrobe

risposta

2

Nel modo in cui eseguo il completamento automatico, è necessario creare un contenitore div che contenga l'input.Quando seleziono un elemento, aggiungo un collegamento contenente uno span al contenitore e nascondo la casella di input.

Il collegamento e lo span sono in stile in modo che assomigli ad un pulsante, con una X, e ha un gestore di eventi click per rimuovere la voce dal DOM, cancellare il campo nascosto e mostrare nuovamente la casella di immissione quando si fa clic . Così, quando si seleziona una voce:

<div class="container"> 
    <a href="#"><span>Selected Item</span></a> 
    <input id="myautocomplete" type="text" /> 
    <input type="hidden" name="myvalue" value="1" /> 
    </div> 

E quando una voce non è selezionata:

<div class="container"> 
    <input id="myautocomplete" name="myautocomplete" type="text" /> 
    <input id="myvalue" name="myvalue" type="hidden" value="" /> 
    </div> 

In questo modo, o si è costretti a selezionare un elemento, o si entra in forma di testo libero. Nel back-end, se il parametro di richiesta con la chiave 'myvalue' è vuoto, allora preferiresti guardare il parametro request con la chiave 'myautocomplete'.

+0

Inoltre, nel gestore di selezione del completamento automatico dell'interfaccia utente jQuery, ogni volta che si seleziona un elemento, è possibile creare un campo nascosto con lo stesso nome, quindi se si selezionano più paesi, rendere l'attributo del nome del campo nascosto "Paesi". Se fai clic su una voce per rimuoverla, rimuove il campo nascosto associato. Sul lato server, si finisce per recuperare un elenco di ID separati da virgole che devono essere divisi e convertiti in un array intero/lungo. – jamiebarrow

+0

Questo è un grande suggerimento e, in assenza di qualcosa di più semplice, è il modo in cui andrò. Idealmente, preferirei qualcosa che richiede molto meno sviluppo sul widget dell'interfaccia utente jQuery - mi sembra che il widget debba supportare ciò che voglio fare più o meno fuori dalla scatola. – Shabbyrobe

+0

Beh, sono stato incaricato di qualcosa di simile, quindi ero anche alla ricerca di suggerimenti su come farlo bene :) Sono contento che il mio suggerimento sia stato d'aiuto! Un'altra cosa è se si sta utilizzando la stessa pagina per la creazione e l'editing - sul ricaricamento della pagina durante l'editing, è necessario ricreare tutte le estensioni ecc per i valori nel campo nascosto. Al momento lo sto facendo solo dal lato server. L'unico problema è che cose come le classi utilizzate ora devono essere mantenute nel codice di frontend e nel codice di back-end ... Non mi piace ma funziona. – jamiebarrow

1

Quando Presumo che hanno i seguenti campi set:

<div> 
    <input type="text" name="visible" class="autocomplete-reference" /> 
    <input type="hidden" name="hidden" /> 
</div> 

È necessario init seguente js (funziona con jQuery 1.5.2):

$(document).ready(function() { 
    $('.autocomplete-reference').each(function() { 
     $(this).keydown(function(e){ 
      /* 
      * this will reset hidden id reference on each visible field manual change 
      * we have to bind it on keydown because we want to recognize event of submiting form by enter after autocomplete set 
      */ 
      if (e.keyCode != 13) { 
       $(this).siblings('input[type=hidden]').each(function() { 
        $(this).val(''); 
       }); 
      } 
     }); 
     $(this).autocomplete({ 
      minLength: 1, 
      /* you can set appending of autocomplete menu into some container to set css contextually 
      appendTo: '#someElem',*/ 
      source: sourceFunction, 
      search:function (event, ui) { 
       //TODO ...spinner init... 
      }, 
      open:function (event, ui) { 
       /* you can grab autocomplete menu widget by this to manipulate some recognizing id, etc.. 
       * $(this).autocomplete('widget') 
       */ 
       //TODO ..stop spinner ... 
       $(this).keydown(function(e){ 
        /* this is important for live reference updates while arrow keys changes */ 
        if (e.keyCode == 37 || e.keyCode == 39) { 
         $($(this).data('autocomplete').menu.active).find('a').trigger('click'); 
        } 
       }); 
      }, 
      focus: function(event, ui) { 
       /* here we'll map our data object onto both fields */ 
       $(this).val(ui.item.label); 
       $(this).siblings('input[type=hidden]').each(function() { 
        $(this).val(ui.item.key); 
       }); 
      }, 
      select: function(event, ui) { 
       /* here we'll map our data object onto both fields */ 
       $(this).val(ui.item.label); 
       $(this).siblings('input[type=hidden]').each(function() { 
        $(this).val(ui.item.key); 
       }); 
      }, 
      close: function(event, ui) { 
       //TODO ..stop spinner ... 
      } 
     }); 
    }); 
}); 

E 'molto bello avere un po' validazione serveride che può convertire esattamente: valori di campo visibili in riferimenti per persone che digitano rapidamente, naturalmente.

0

Anche se è una vecchia domanda, il mio metodo può essere d'aiuto.

Su evento .change è possibile cercare il valore della casella di testo con il valore in dall'elenco Sorgente utilizzando il ciclo.

Goto per ulteriori dettagli: Eccolo nell'elenco dei sorgenti Ajax ma l'allenamento è simile. Search a text In Jquery AutoComplete Ui

Questa cosa mi aveva preoccupante molte volte e alla fine oggi ho capito :)

0

È possibile utilizzare event.preventDefault

Colleziona i tuoi valori selezionati attraverso ui.item.label o ui.item.value e ottieni il valore necessario e impostalo sulla stessa casella di testo.

var idNameCombo = ui.item.label; 
      event.preventDefault(); 
      $("#mID").val(idNameCombo.split(",")[0].trim()); 
Problemi correlati