皆さんは、一貫性があり、クリーンでプロフェッショナルなスピンボックスを HTML で簡単に作成できると思うかもしれません...しかし、残念なことに、入力に整数値または 10 進数値のみを受け入れるように指示する標準属性がありません。 、すべての入力フィルタリングは JS である必要があります。アウト!
作業を楽にするために、Go、a-h/Templ、Tailwind、そして私の最愛の Alpine.js を使用してこの機能を実装する予定です。
まず、整数スピンボックスの基本テンプレートを作成します。
templ IntSpinbox(name, label, value, tooltip string, saveinput bool, interval *IntInterval) { ... }
IntInterval を次のように定義します。
type IntInterval struct { A, B int }
間隔で入力の最小値と最大値を設定します。整数スピンボックスを作成しているため、ステップは常に「1」に設定されます。
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) } } ...> }
ここで、2 つのクラスの追加を開始しましょう。次に、入力のレンダリングを制御するいくつかの特別なプロパティと疑似要素を示します。
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:テキストフィールド]
最後に、基本的なパディング、リング、色などを追加しましょう...
block w-fullrounded-l-md py-2 px-2.5 text-gray-900 リング-1 リングインセット リング-グレー-300 プレースホルダー:テキスト-グレー-400 フォーカス:アウトライン-なし フォーカス:リング-2 フォーカス:リング-プライマリ-400 bg-gray-50 sm:text-sm sm:leading-6
これをテンプレートに追加すると、次のようになります:
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]"> }
これで、マウスをその上に置くと、基本的な検証が行われた非常にテキストのような入力が得られるはずです。次のセクションでは、有効な整数入力をチェックする機能を追加します。
整数スピンボックスの基本的な考え方は、整数のみを受け入れる入力です。私は最初、次のように HTML の pattern 属性を使用してこの関数を実装しようとしました:
<input type="number" pattern="[0-9]+" ... >
パターン属性は正規表現文字列を受け取り、それを使用してユーザー入力を検証しますが、そもそも無効な入力の入力を防ぐことはできません。実際、これは簡単なクライアント側の検証のために作成されました。
ユーザーが入力ボックス内のキーを押すたびに、oninput イベントが生成されます。 Alpine の構文 x-on:input を使用してこのイベントをキャプチャし、input 要素に応じて値を修正します。 x-data 属性セットを使用して親 div を作成し、入力が数値であるかどうかを確認できる関数を追加しましょう。その後、それに応じて値を丸めることができます。
<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>
Alpine を知らない人のために説明すると、ここでの $el は現在の DOM 要素を参照するために使用されます。
前に作成した親 div に、次の class="flex" を追加し、x-ref="spinbox" 属性を入力に追加して、ボタンがマジック プロパティ $refs.spinbox を通じてその状態を変更できるようにします。
<div ... class="flex"> <input ... x-ref="spinbox"> </div>
次に、入力の後に新しい子を追加します。これにはボタンが含まれます。
<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>
ここでは、タブ オーダーを正しく保つ簡単な方法として flex-col-reverse を使用します。最初にタブを「-」に移動し、次に「+」に移動する必要があります。
次に、x-on:click を使用してイベント ハンドラーをボタンに追加します。完全なコード (CSS を除く) は次のとおりです。
<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>
e.value と e.step は文字列であるため、演算を行う前に変換する必要があります。
スピナー ボタンの CSS に関しては、入力と非常によく似たスタイルになっています。完全なコードは以下のとおりです。
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> }
お楽しみください:)
以上がGo/Templ でクリーンでフレンドリーなスピナーを作成するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。