2013-02-11 12 views
12

Ich habe ein ziemlich einfaches Problem, dessen Lösung sich als gar nicht so einfach herausstellt.
Ich möchte Bilder vor jeder Option eines selectfield hinzufügen. Um genauer zu sein, möchte ich Bilder zum picker hinzufügen, die es auslöst, und auch zum aktuellen Wert des selectfield.
Aus Gründen der Einfachheit werde ich ein kleines Beispiel erstellen:Füllen von Icons in Sencha Touch Selectfield

Sagen wir mal, wollen Sie ein Benutzer zwischen einem der vier Spielkarte Anzüge Karo, Herz, Pik und Clubs zur Auswahl. Um die visuelle Erkennung zu unterstützen, mögen Sie das entsprechende Symbol zu jedem Anzug Namen vorge, so könnte es in etwa so aussehen:
Selectfield with icons

Meine ersten Wahl einer Sencha Touch-Komponente, die aus einer gegebenen Menge von Optionen ermöglichen die Auswahl natürlich war selectfield. Leider scheint es nur reinen Text anzuzeigen, und nichts mehr. Nachdem ich mich in die Sencha-Touch-Quellen vertieft hatte, kam ich schließlich auf eine halbe Lösung. Grundsätzlich gebe ich die selectfield eine benutzerdefinierte defaultPhonePickerConfig, in der die entsprechende picker (die von der selectfield verwendet wird, um die Optionen anzuzeigen) erhält eine benutzerdefinierte itemTpl zugeordnet. Die itemTpl erledigt den Rest, nämlich eine html Hinzufügen um das Bild anzuzeigen:

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); 
     } 
    } 
} 

Eine Arbeits Geige für diese Lösung kann here finden.

ist meine Lösung nicht so schlimm, aber es gibt ein leichtes kosmetisches Problem, dass ich einfach nicht akzeptabel ist: Die Symbole nur in dem picker (unteren Teil der Abbildung oben) angezeigt werden, aber nicht die selectfield selbst (oberer, ausgegrauter Teil) wenn die Option ausgewählt wurde. Und es scheint keine gute Möglichkeit zu geben, dem aktuellen Wert des Auswahlfelds ein Symbol hinzuzufügen.

Und das ist das Hauptanliegen meiner Frage: Welchen guten Weg gibt es, ein Symbol zu sowohl den Optionen des Pickers und auch zum aktuellen Wert des selecfield hinzuzufügen? Muss ich meiner bestehenden Lösung vielleicht nur relativ wenig Code hinzufügen oder sollte ich einen ganz anderen Ansatz wählen?
Jeder Beitrag wird geschätzt. Vielen Dank!

Update:
Nach einigen Hacking um, fand ich einen Weg (ein hässliches) ein Symbol, um die selectfield selbst vorangestellt wird. Es basiert hauptsächlich auf brutaler HTML-DOM-Manipulation: Ich definiere nun auch Event-Handler für die selectfield selbst (change und painted). Bei der Initialisierung und jedes Mal, wenn der Wert geändert wird, durchsuchen meine Handler das generierte DOM nach dem zugrunde liegenden <input> und machen damit herum. (Dieser böse Junge ist wahrscheinlich der Grund, warum wir HTML überhaupt nicht zuordnen können, da das Framework sein value Attribut ändert. Und value kann andererseits nur Klartext enthalten.)
Dies ist, wie ich die selectfield ‚s listeners definieren:

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); 
     } 
} 

Die entsprechende Funktion prependIconToSelectfield() nur einige CSS definiert:

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'; 
} 

Check out this fiddle für ein funktionierendes Beispiel.

Dies ist immer noch keine gute Lösung für mich, da diese Art von hackish DOM Manipulation ist auch zu Rogue für meinen Geschmack. Ich weiß nicht, was die Nebenwirkungen von aktivem Herumspielen im DOM in größeren Projekten sein können, und will es nicht auf die harte Art lernen. Also, ich bin immer noch auf der Suche nach einer saubereren Lösung.

Antwort

3

Erstes Lob an die harte Arbeit Sencha touch ist extrem schwer zu manipulieren, wenn man versucht, etwas aus der Box zu machen. Lassen Sie mich versuchen & schlagen eine Lösung für was Sie wollen. Ein Selectfield in Sencha hat die folgende DOM-Tag-Struktur.

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

konzentrieren sich nun auf der x-clear-Symbol, um es normalerweise, da eine SELECT eine Löschtaste muss nicht verborgen ist. Schreiben Sie zuerst eine CSS-Klasse, um sie anzuzeigen (Anzeige: Block). Dies würde es mit einer X-Taste ähnlich dem Textfeld & angezeigt wird es in der rechten Ecke positioniert werden. Sie können durch css es nach links positionieren und bei Änderung des Auswahlfeldes können Sie den Hintergrund auf das ändern, was Sie wollen. Es ist keine sehr direkte Lösung, aber ich habe es für ein ähnliches Problem versucht & es funktioniert. Ausgehend von dem, was Sie oben getan haben, denke ich, dass Sie es tun können. Alles Gute. Hoffe, meine Lösung hilft.

+0

Danke für Ihre Antwort. Bitte denk nicht, dass ich das in Vergessenheit geraten lasse, aber ich werde in den nächsten Wochen wie tausend Tests nehmen. Ich werde auf Ihre Idee kommen und meine Ergebnisse so schnell wie möglich melden. – MCL

+0

Alles in Ordnung. Ich habe ein bisschen herumgespielt, bin aber nicht sehr weit gekommen. Mein Ansatz war es, die css 'position', kombiniert mit' left' und 'top', anzugehen. Auf diese Weise kann ich das 'x-clear-icon' verschieben, wo immer ich möchte, aber der Text des Auswahlfelds (z. B. ** Diamonds **) wird jetzt nur noch abgedeckt und nicht wie gewünscht gehängt. Es sieht so aus, als müsste ich den 'input [name =" picker "] irgendwie manipulieren. Wie hast du das 'x-clear-icon' ersetzt? Edit: Hier ist eine Geige (sehen Sie sich den 'painted' Handler an): [click] (http://jsfiddle.net/jTX22/1/) – MCL

+0

Sie können ein Padding für den Diamonds-Text oder vielleicht einen Texteinzug festlegen, der geben würde Sie das gewünschte Ergebnis –