Ihr denkt vielleicht, dass die Erstellung einer konsistenten, sauberen und professionellen Spinbox in HTML eine einfache Aufgabe wäre ... Zu unserer Verzweiflung gibt es jedoch kein Standardattribut, das einer Eingabe mitteilt, dass sie nur Ganzzahl- oder Dezimalwerte akzeptieren soll , alle Eingabefilter müssen JS sein. Autsch!
Ich werde diese Funktionalität mit Go, a-h/Templ, Tailwind und meinen geliebten Alpine.js implementieren, um das Leben einfacher zu machen.
Wir beginnen mit dem Schreiben einer Grundvorlage für unsere Integer-Spinbox:
templ IntSpinbox(name, label, value, tooltip string, saveinput bool, interval *IntInterval) { ... }
Wir definieren IntInterval wie folgt:
type IntInterval struct { A, B int }
Mit dem Intervall legen wir die Mindest- und Höchstwerte der Eingabe fest. Da wir eine ganzzahlige Spinbox erstellen, wird der Schritt immer auf „1“ gesetzt.
templ IntSpinbox(name, label, value, tooltip string, saveinput bool, interval *IntInterval) { <input type="number" placeholder="Enter Int…" step="1" if interval != nil { min={ strconv.Itoa(interval.A) } max={ strconv.Itoa(interval.B) } } ...> }
Beginnen wir nun mit dem Hinzufügen einiger zwei Klassen. Im Folgenden sind einige spezielle Eigenschaften und Pseudoelemente aufgeführt, die die Darstellung der Eingabe steuern.
select-none [-moz-user-select:none] [-ms-user-select:none] [-o-user-select:none] [-webkit-user-select:none]
Die folgenden zusätzlichen Klassen werden verwendet, um die Standard-Spinner-Schaltflächen zu entfernen:
[&::-webkit-inner-spin-button]:[-webkit-appearance:none] [&::-webkit-outer-spin-button]:[-webkit-appearance:none] [-moz-appearance: Textfeld]
Zuletzt fügen wir noch einige grundlegende Polsterungen, Ringe, Farben usw. hinzu...
Block w-voll abgerundet-l-md py-2 px-2.5 text-gray-900 ring-1 ring-inset ring-gray-300 Platzhalter:text-gray-400 Fokus:outline-none Fokus:ring-2 Fokus: ring-primary-400 bg-gray-50 sm:text-sm sm:leading-6
Wenn wir es zu unserer Vorlage hinzufügen, erhalten wir Folgendes:
templ IntSpinbox(name, label, value, tooltip string, saveinput bool, interval *IntInterval) { <input type="number" placeholder="Enter Int…" step="1" if interval != nil { min={ strconv.Itoa(interval.A) } max={ strconv.Itoa(interval.B) } } class="block w-full rounded-l-md py-2 px-2.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-primary-400 bg-gray-50 sm:text-sm sm:leading-6 select-none [-moz-user-select:none] [-ms-user-select:none] [-o-user-select:none] [-webkit-user-select:none] [&::-webkit-inner-spin-button]:[-webkit-appearance:none] [&::-webkit-outer-spin-button]:[-webkit-appearance:none] [-moz-appearance:textfield]"> }
Jetzt sollten Sie eine sehr textähnliche Eingabe erhalten, mit einer grundlegenden Validierung, wenn Sie mit der Maus darüber fahren. Im nächsten Abschnitt werden wir die Funktionalität zur Prüfung auf gültige Ganzzahleingaben hinzufügen.
Die Grundidee einer Integer-Spinbox ist eine Eingabe, die nur ganze Zahlen akzeptiert. Ich habe zunächst versucht, diese Funktion zu implementieren, indem ich das Musterattribut von HTML wie folgt verwendet habe:
<input type="number" pattern="[0-9]+" ... >
Das Musterattribut nimmt eine Regex-Zeichenfolge und verwendet sie, um die Benutzereingabe zu validieren. Es verhindert jedoch nicht, dass ungültige Eingaben überhaupt eingegeben werden. Eigentlich wurde es für eine einfache clientseitige Validierung erstellt.
Jedes Mal, wenn der Benutzer eine beliebige Taste im Eingabefeld drückt, wird ein oninput-Ereignis generiert. Erfassen Sie dieses Ereignis mit der Alpine-Syntax x-on:input und korrigieren Sie den Wert entsprechend für das Eingabeelement. Erstellen wir ein übergeordnetes Div mit einem X-Daten-Attributsatz und fügen wir eine Funktion hinzu, mit der wir überprüfen können, ob die Eingabe überhaupt eine Zahl ist ... Anschließend können wir den Wert entsprechend runden.
<div x-data="{isNumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) }}"> <input ... x-on:input="$el.value = isNumber($el.value) ? Math.round($el.value) : null"> </div>
Für diejenigen, die Alpine nicht kennen: $el wird hier verwendet, um auf das aktuelle DOM-Element zu verweisen.
Im zuvor erstellten übergeordneten Div fügen wir das folgende class="flex" und ein x-ref="spinbox"-Attribut zur Eingabe hinzu, damit unsere Schaltflächen ihren Status über die magische Eigenschaft $refs.spinbox ändern können:
<div ... class="flex"> <input ... x-ref="spinbox"> </div>
Wir fügen dann nach der Eingabe ein neues Kind hinzu, das unsere Schaltflächen enthalten wird:
<div ...> <input ... x-ref="spinbox"> <div class="flex flex-col-reverse"> <!-- Decrement input's value --> <button type="button" class="flex-1 ...">-</button> <!-- Increment input's value --> <button type="button" class="flex-1 ...">+</button> </div> </div>
Hier verwenden wir Flex-Col-Reverse als einfache Möglichkeit, die Tabulatorreihenfolge korrekt beizubehalten. Zuerst sollte die Tabulatortaste auf „-“ und dann auf „+“ gesetzt werden.
Wir fügen dann die Event-Handler mit x-on:click zu den Schaltflächen hinzu. Der vollständige Code (ohne CSS) lautet wie folgt:
<div ... x-data="{ inc() { var e = $refs.spinbox; e.value = Math.min(Number(e.value) + Number(e.step), e.max); }, dec() { var e = $refs.spinbox; e.value = Math.max(Number(e.value) - Number(e.step), e.min); }, isNumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) } }"> <input ... x-ref="spinbox" x-on:input="$el.value = isNumber($el.value) ? Math.round($el.value) : null"> <div ...> <!-- Decrement input's value --> <button type="button" ... x-on:click="dec">-</button> <!-- Increment input's value --> <button type="button" ... x-on:click="inc">+</button> </div> </div>
Wir müssen e.value und e.step konvertieren, bevor wir rechnen können, da es sich dabei um Zeichenfolgen handelt.
Wenn es um CSS für die Spinner-Schaltflächen geht, sind diese sehr ähnlich der Eingabe gestaltet, der vollständige Code ist unten aufgeführt.
templ IntSpinbox(name, label, value, tooltip string, saveinput bool, interval *IntInterval) { <!-- Disable inner & outer spinner buttons, use buttons to render increment and decrement input value... --> <div class="flex-1"> @InputLabel(name, label + " " + interval.toString(), tooltip) <input type="number" placeholder="Enter Int…" step="1" if interval != nil { min={ strconv.Itoa(interval.A) } max={ strconv.Itoa(interval.B) } } name={ name } value={ value } class="block w-full rounded-l-md py-2 px-2.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-primary-400 bg-gray-50 sm:text-sm sm:leading-6 select-none [-moz-user-select:none] [-ms-user-select:none] [-o-user-select:none] [-webkit-user-select:none] [&::-webkit-inner-spin-button]:[-webkit-appearance:none] [&::-webkit-outer-spin-button]:[-webkit-appearance:none] [-moz-appearance:textfield]" x-on:input="$el.value = !isNumber($el.value) ? null : Math.round($el.value)" x-ref="spinbox" autocomplete="off" > <div class="flex flex-col-reverse font-medium"> <!-- Decrement input's value --> <button type="button" class="flex-1 px-1 leading-none transition-colors ease-linear duration-100 rounded-br-md text-center text-sm bg-gray-100 hover:bg-gray-200 text-gray-500 hover:text-gray-900 ring-1 ring-inset ring-gray-300 focus:outline-none focus:ring-inset focus:ring-2 focus:ring-primary-400 select-none [-moz-user-select:none] [-ms-user-select:none] [-o-user-select:none] [-webkit-user-select:none]" x-on:click="dec">-</button> <!-- Increment input's value --> <button type="button" class="flex-1 px-1 leading-none transition-colors ease-linear duration-100 rounded-tr-md text-center text-sm bg-gray-100 hover:bg-gray-200 text-gray-500 hover:text-gray-900 ring-1 ring-inset ring-gray-300 focus:outline-none focus:ring-inset focus:ring-2 focus:ring-primary-400 select-none [-moz-user-select:none] [-ms-user-select:none] [-o-user-select:none] [-webkit-user-select:none]" x-on:click="inc">+</button> </div> </div> </div> }
Viel Spaß :)
Das obige ist der detaillierte Inhalt vonErstellen eines sauberen, freundlichen Spinners in Go/Templ. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!