
聯絡表單問「想了解哪些服務」、會員後台要一次勾選好幾筆資料,選項一多,客人就希望有一個「全選」。
這篇用很短的 JavaScript 做出:
- 按「全選」,全部打勾;再按一次,全部取消。
- 只勾了一部分時,「全選」顯示半勾(一條橫線),一看就知道沒選完。
- 一個一個勾滿時,「全選」自動變成打勾。
- 不能選的選項(
disabled)自動跳過。 - 「全選」本身不會被當成表單資料送出去。
HTML
HTML
<form id="contact-form">
<fieldset class="check-group">
<legend>想了解的服務(可複選)</legend>
<label><input type="checkbox" class="check-all"> 全選</label>
<label><input type="checkbox" name="service[]" value="web"> 網頁設計</label>
<label><input type="checkbox" name="service[]" value="ads"> 關鍵字廣告</label>
<label><input type="checkbox" name="service[]" value="video"> 形象影片</label>
<label><input type="checkbox" name="service[]" value="care"> 網站管家年費</label>
<label><input type="checkbox" name="service[]" value="shop" disabled> 購物網站(額滿)</label>
</fieldset>
</form>- 所有選項放在同一個
<fieldset>,用<legend>寫這一組的標題,用報讀軟體的人也聽得懂這些選項是在問什麼。 - 每個核取方塊都包在
<label>裡,點文字也能勾選,手機上比較好按。 - 「全選」沒有
name,所以送出表單時不會出現在資料裡。 - 最後一個選項加了
disabled,用來示範「不能選」的情況。
JavaScript
JavaScript
document.querySelectorAll('.check-group').forEach((group) => {
const all = group.querySelector('.check-all');
// 不包含「全選」自己,也跳過不能勾的選項
const items = [...group.querySelectorAll('input[type="checkbox"]:not(.check-all):not(:disabled)')];
// 按「全選」:其他選項全部跟著打勾或取消
all.addEventListener('change', () => {
items.forEach((box) => { box.checked = all.checked; });
});
// 個別勾選時,更新「全選」的狀態:全部勾了就打勾,勾了一部分就顯示半勾
const update = () => {
const count = items.filter((box) => box.checked).length;
all.checked = count === items.length;
all.indeterminate = count > 0 && count < items.length;
};
items.forEach((box) => box.addEventListener('change', update));
update();
});- 用
.check-group找到每一組,同一頁有好幾組也各自獨立運作。 indeterminate就是「半勾」狀態。這個狀態沒辦法寫在 HTML 裡,只能用 JavaScript 設定,瀏覽器會把方塊畫成一條橫線。- 最後先呼叫一次
update(),如果表單一開始就有預設勾選的選項,「全選」的狀態也會是對的。
CSS(選用)
CSS
.check-group label {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 0;
cursor: pointer;
}
.check-group input[type="checkbox"] {
width: 20px;
height: 20px;
accent-color: #1e8a8a;
}
/* 「全選」那一行加粗、下面畫一條線 */
.check-group label:has(.check-all) {
font-weight: bold;
border-bottom: 1px solid #ddd;
}accent-color一行就能把核取方塊換成網站的品牌色,不用自己畫方塊。- 方塊放大到 20px,手機上比較好點。
:has(.check-all)選到包著「全選」的那個 label,讓它加粗、下面畫一條分隔線。
實際測試的結果
在 Chrome 用電腦和手機寬度各測了一輪,也檢查表單實際會送出的資料:
- 一開始什麼都沒勾:送出的資料是空的。
- 按「全選」:4 個可以選的都打勾,「購物網站(額滿)」維持不能選、沒有勾;送出的資料是 4 個服務,沒有「全選」。
- 取消「關鍵字廣告」:「全選」變成半勾。
- 在半勾的狀態再按「全選」:4 個全部打勾。
- 再按一次「全選」:全部取消。
- 只勾「網頁設計」,再把另外三個一個一個勾上:勾到第 4 個時,「全選」自動變成打勾。
- 用鍵盤 Tab 移到「全選」,按空白鍵:一樣可以全選、取消。
放進 WordPress
- 在頁面加一個「自訂 HTML」區塊,貼上 HTML,JavaScript 用
<script>包起來接在後面。只有管理員、編輯這類有權限的帳號,存檔時<script>才不會被拿掉。 - 用表單外掛(例如 Contact Form 7)做的表單,核取方塊的 HTML 是外掛產生的,結構不一樣。可以在外掛的欄位設定加上 class,再把 JavaScript 裡的選擇器改成對應的名稱。
延伸閱讀
- HTML 加入 CSS 的三種方法:外部樣式表、內部樣式表、行內樣式怎麼選
- 點連結出現外框怎麼拿掉?用 :focus-visible 取代 outline: none 的正確寫法
- CSS cursor 滑鼠游標樣式整理:pointer、not-allowed 等常用值與自訂游標寫法
表單好不好填,決定了客人願不願意留下聯絡資料。正威網路行銷是 25 年經驗的基隆網頁設計工作室,詢價表單、會員後台都會照實際使用情況設計,台北與全台客戶也歡迎來聊聊。







發表留言
還沒有人留言,歡迎第一個分享你的想法或問題。留言經審核後才會顯示,Email 不會公開。