Es gibt Situationen, da wünscht man sich statt der hässlichen Selectbox, die nur eingeschränkt mit CSS zu formatieren ist, einen schönen Button. Man ist in dieser Situation vielleicht ein Designer. Diesen kühnen Wunsch als Vorlage war ich dann doch auch neugierig, ob das irgendwie zu machen ist.
Denn es hat auch einen durchaus praktischen Nutzen. Einsatzgebiet ist eine mobile HTML5-Applikation, die mehrere Auswahlfelder in einem Dialog bereitstellt. Native Applikationen nutzen für die Auflistung mehrerer Auswahloptionen für gewöhnlich eigene Seiten bzw. Dialoge, d.h. nach Klick auf einen "Auswahl-Button" erhält man eine gänzlich neue View mit allen Auswahlmöglichkeiten.
Ich wollte jedoch die native Implementierung der Auswahl auf iOS und Android beibehalten, da sie für den Benutzer gewohnt und bequem ist und natürlich auch nicht so viel Arbeit erfordert, wie die Erstellung einer eigenen Auswahl-Dialog-Komponente (von der Nutzung fertiger Frameworks, die dies natürlich bereitstellen, wurde aus anderen Gründen abgesehen).
D.h. die Aufgabe bestand darin einen Zwitter aus klassischer Selectbox und Button zu bauen. Es hat eine Weile gedauert, bis ich durch einen Tipp von Christian (Blog) auf den Trick gestoßen bin. Nachfolgend noch einmal meine davon abgeleitete Variante, die sich wirklich nur auf die Selectbox bezieht.
Wenn man zunächst überlegt, die Selectbox auszublenden und einfach einen Klick per JavaScript auf sie auszulösen, wird dies scheitern. Der Grund ist trivial: es gibt keine Möglichkeit mit JavaScript eine derartige Aktion für dieses HTML-Element zu erzeugen.
Kern der Lösung und Trick 17 ist es nun, die Selectbox dennoch auszublenden, aber so, dass sie klickbar bleibt. Wie? In dem man einfach die Opazität auf 0 setzt. Sie ist damit immer noch an Ort und Stelle vorhanden, klickbar, aber eben nicht zu sehen. Darüber setzt man nun einen Button - das tut man, in dem man ihn direkt vor der Selectbox im DOM einfügt und ihn absolut positioniert.
Der gesamte HTML-Code:
1: <!DOCTYPE>
2: <html>
3: <head>
4:
5: <title>Selectbutton</title>
6:
7: <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
8: <style type="text/css">
9:
10: select {
11: opacity: 0;
12: width: 100px;
13: }
14:
15: button {
16: position: absolute;
17: width: 100px;
18: }
19:
20: </style>
21: <script type="text/javascript">
22: $(document).ready(function () {
23: $("select").change(function () {
24: $("#tb").val($(this).val());
25: });
26: });
27: </script>
28: </head>
29: <body>
30:
31: <input type="text" id="tb" />
32:
33: <button>Auswählen</button>
34: <select>
35: <option></option>
36: <option>Deutschland</option>
37: <option>Österreich</option>
38: <option>Schweiz</option>
39: </select>
40:
41: </body>
42: </html>
Ein ausführbares Beispiel gibt es hier. Getestet auf allen aktuellen mobilen Browsern, sowie Chrome und Opera am Desktop. Im IE wird es schätzungsweise nicht funktionieren, was mir aber auch egal ist ;-).
Das Ganze kann man auch dynamisch per JavaScript machen, z.B. als Plugin für knockout.js, so dass es schön dynamisch funktioniert:
1: ko.bindingHandlers.replaceSelectByButton = {
2: update: function (element, valueAccessor) {
3:
4: var config = valueAccessor();
5:
6: /*
7: config = {
8: id: 0,
9: visible: true,
10: page: ''
11: }*/
12:
13: if (!config.visible) {
14: var button = $("#" + config.page + config.id, currentPage);
15: if (button != null) {
16: button.remove();
17: }
18: return;
19: }
20:
21: var button = document.createElement("button");
22: button.className = "selectButton";
23: button.innerHTML = "Auswählen";
24: button.id = config.page + config.id;
25:
26: element.parentNode.insertBefore(button, element);
27:
28: }
29: };
Viel Spaß damit.