2013-02-11 12 views
12

Ho un problema piuttosto semplice la cui soluzione risulta non essere affatto così semplice.
Desidero aggiungere immagini davanti a ciascuna opzione di un selectfield. Per essere più precisi, voglio aggiungere immagini ai trigger picker e anche al valore corrente del campo selezionato.
Per ragioni di semplicità, creerò un piccolo esempio:Icone popolate in Sencha Touch selectfield

Diciamo, si desidera che un utente di scegliere tra uno dei quattro semi delle carte da gioco quadri, cuori, picche e club. Per supportare il riconoscimento visivo, si vuole anteporre il simbolo corrispondente a ciascun nome seme, in modo che possa essere simile a questa:
Selectfield with icons

La mia prima scelta di un componente sencha tocco, che consente la selezione da un dato insieme di opzioni naturalmente era selectfield. Sfortunatamente, sembra che sia in grado di visualizzare puro testo e nient'altro. Dopo aver scavato nelle sorgenti tattili di sencha, ho finalmente trovato una soluzione a metà. Fondamentalmente, ho passato il selectfield un defaultPhonePickerConfig personalizzato, in cui il corrispondente picker (che viene utilizzato da selectfield per visualizzare le opzioni) viene assegnato uno personalizzato itemTpl. Il itemTpl fa il resto, cioè l'aggiunta di alcuni html per visualizzare l'immagine:

defaultPhonePickerConfig: { 
    listeners: { 
     initialize: function() { 
      var slots = this.query('pickerslot'); 
      Ext.each(slots, function(slot) { 
       slot.setItemTpl('<img src="someImage.jpg"> {text}'); 
      }); 

     }, 

     change: function() { 
      // reconstruct the selectfield's change handler, 
      // since it gets overwritten 
      var iconSelect = Ext.Viewport.query('#IconSelect')[0]; 
      iconSelect.onPickerChange.apply(iconSelect, arguments); 
     } 
    } 
} 

Un lavoro violino per questa soluzione può essere trovato here.

mia soluzione non è poi così male, ma c'è un piccolo problema cosmetico, questo è solo non è accettabile per me: Le icone sono visualizzate solo nella picker (parte inferiore della schermata qui sopra), ma non il selectfield sé (parte superiore, ombreggiata) quando è stata selezionata l'opzione. E sembra che non ci sia un buon modo per aggiungere un'icona al valore corrente del campo di selezione.

E questa è la preoccupazione principale della mia domanda: quale buon modo è lì per aggiungere un'icona a sia le opzioni del selettore e anche al valore corrente del selecfield? Devo forse aggiungere un numero relativamente piccolo di codice alla mia soluzione esistente o devo prendere un approccio completamente diverso?
Ogni contributo è apprezzato. Grazie!

Aggiornamento:
Dopo un po 'di hacking intorno, ho trovato un modo (un brutto) da anteporre un'icona per il selectfield stesso. Si basa principalmente sulla brutale manipolazione del DOM HTML: ora definisco anche i gestori di eventi per lo stesso selectfield (change e painted). Al momento dell'inizializzazione e ogni volta che il valore viene modificato, i miei gestori cercano il DOM generato per il sottostante <input> e si scherzano con esso. (Quel ragazzaccio è probabilmente la ragione per cui non possiamo assegnare l'HTML in primo luogo, dal momento che il framework cambia il suo attributo value e il value d'altra parte può contenere solo testo normale.)
Così definisco s' listeners la selectfield:

listeners: { 
     change: function() { 
      var pickerDOM = document.querySelector('#' + this.getId() + ' input[name="picker"]'); 
      PickerIcons.app.prependIconToSelectfield(arguments[1], pickerDOM); 
     }, 
     painted: function() { 
      // Initialize an icon on creation 
      var pickerDOM = document.querySelector('#' + this.getId() + ' input[name="picker"]'); 
      PickerIcons.app.prependIconToSelectfield(this.getValue(), pickerDOM); 
     } 
} 

La funzione corrispondente prependIconToSelectfield() solo definisce alcuni CSS:

prependIconToSelectfield: function (optValue, domElement) { 
    var iconUrl = this.getIconUrl(optValue); 
    domElement.style.backgroundImage = 'url(' + iconUrl + ')'; 
    domElement.style.backgroundSize = '20px 20px'; 
    domElement.style.backgroundRepeat = 'no-repeat'; 
    domElement.style.backgroundPosition = 'left center'; 
    domElement.style.paddingLeft = '30px'; 
} 

Partenza this fiddle per un esempio operativo.

Questo non è ancora una buona soluzione per me, dal momento che fare questo tipo di manipolazione DOM hackish è troppo rogue per i miei gusti. Non so quali potrebbero essere gli effetti collaterali del fare disordine nel DOM nei progetti più grandi, e non voglio impararlo nel modo più difficile. Quindi, sto ancora cercando una soluzione più pulita.

risposta

3

I primi complimenti nel lavorare così duramente il tocco di sencha sono estremamente difficili da manipolare quando si tenta di fare qualcosa fuori dalla scatola. Detto questo fammi provare & proporre una soluzione per quello che vuoi. Un campo selezionato in sencha ha la seguente struttura di tag DOM.

div.x-field-select 
    div.x-field-input 
     input.x-input-el 
     div.x-clear-icon 
     div.x-field-mask 

Ora concentriamoci sul-icona di x-clear è normalmente nascosta dal momento che un selectfield non ha bisogno di un pulsante chiaro. Per prima cosa scrivi una classe CSS per visualizzarla (display: block). Questo lo mostrerebbe con un pulsante X simile al campo di testo & che sarà posizionato verso l'angolo destro. Puoi attraverso il CSS posizionarlo a sinistra e al cambio del campo di selezione puoi cambiare il suo sfondo con quello che vuoi. Non è una soluzione molto semplice ma l'ho provato per un problema simile & funziona. A giudicare da quello che hai fatto sopra, penso che tu possa farlo. Ti auguro il meglio. Spero che la mia soluzione aiuti.

+0

Grazie per la risposta. Per favore, non pensare che lascerò cadere questo oblio, ma prenderò come mille test nelle prossime settimane. Arriverò alla tua idea e riferirò i miei risultati al più presto. – MCL

+0

Va bene. Ho giocato un po ', ma non sono arrivato molto lontano. Il mio approccio è stato quello di affrontare il css 'position', combinato con' left' e 'top'. In questo modo, posso spostare 'x-clear-icon' dove voglio, ma il testo del campo di selezione (ad esempio ** Diamonds **) ora viene coperto e non viene messo da parte come speravo. Quindi, sembra che dovrò manipolare il 'input [name =" picker "]' comunque. Come hai spostato la 'x-clear-icon'? Edit: Ecco un violino (guarda il gestore 'painted'): [clicca] (http://jsfiddle.net/jTX22/1/) – MCL

+0

puoi impostare un padding per il testo Diamonds o forse un indent di testo che darebbe il risultato desiderato –