首頁  >  文章  >  後端開發  >  在 Go/Templ 中製作一個乾淨、友好的 Spinner

在 Go/Templ 中製作一個乾淨、友好的 Spinner

王林
王林原創
2024-09-10 18:30:42427瀏覽

無用的 HTML

你們可能會認為在HTML 中製作一個一致、乾淨且專業的旋轉框是一項簡單的任務...但是,令我們失望的是,沒有標準的屬性來告訴輸入它應該只接受整數或小數值,所有的輸入過濾都必須是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) }
    } ...>
}

新增 CSS

現在讓我們開始加入一些 tw 類,以下是一些控制輸入渲染的特殊屬性和偽元素。
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:文字欄位]

最後,讓我們加入一些基本的填充、環、顏色等...
區塊w-full rounded-l-md py-2 px-2.5 text-gray-900ring-1ring-insetring-gray-300佔位符:text-gray-400焦點:outline-none焦點:ring-2焦點: ring -primary-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]+" ... >

pattern 屬性採用正規表示式字串並使用它來驗證使用者輸入,但是,它並不能阻止輸入無效輸入。實際上,它是為了一些簡單的客戶端驗證而設計的。

'oninput' 事件

每次使用者按下輸入框中的任意鍵時,都會產生 oninput 事件。使用 Alpine 的語法 x-on: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 作為保持 Tab 鍵順序正確的簡單方法,它應該首先 Tab 鍵到“-”,然後是“+”。

然後我們使用 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 時,它們的樣式與輸入非常相似,完整的程式碼如下。

Making a Clean, friendly Spinner in Go/Templ

最終模板

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

享受吧:)

適用於

  • Mozilla Firefox 130.0(64 位元)
  • 版本 128.0.6613.120(官方版本)(64 位元)

以上是在 Go/Templ 中製作一個乾淨、友好的 Spinner的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:Go:整數溢出下一篇:Go:整數溢出