自己設計 pizza 材料表單!
input
可以用在表單輸入上,而內建的種類有很~多種,像是預設的文字輸入或是數字輸入、顏色點選甚至是日期視窗等...
MDN input type,今天要來玩的是 input type='radio'
,稱為單選按鈕,讓使用者可以點選。
今天就設計一張 pizza 標單讓客人選自己想要的配料!
基本的 html 架構設定,在 form
表單下放置 label
+ input
作為選填項目。
<form id="first-form">
<p>How would you like your pizza?</p>
<fieldset class="sauces option">
<legend>Sauce:</legend>
<label for="pesto">
<input type="radio" name="sauce" id="pesto" value="pesto" />
<span class="checkmark">pesto</span>
</lable>
</fieldset>
....
</form>
重點:
input
包在 label
內可以增加點擊範圍,或是用 label for='input 的 id 名稱'
來綁定同一組的 input
和 label
。
相同 name
屬性名稱的input
是單選效果,name
名稱不同變為多選 -> 套用在第二種 ingredient 選擇上。
input
的 value
屬性設置跟材料稱呼一樣。
先刻出以下畫面:
需要監聽的動作:
change
Event當 radio type 的 input 被點選狀態變為 checked
時,change event 可以偵測的這個變化,啟動相應的動作。
利用這個事件,偵測滑鼠點選到哪一個材料,右邊框框 background-image 改為該材料圖片。
// 先選好需要的元素
let get = (tag) => document.querySelector(tag);
let display = get('.displayImg'); // 右邊展示框
// 直接對 document 綁定 change event
document.addEventListener('change', function (event){
// event.target 會是點選的該材料標籤,取該節點的 value 屬性
let componentImg = event.target.value; // 將點選的 材料 value 存入變數中
// 改變右框框背景圖片為點選的材料
display.style.backgroundImage = `var(--${componentImg})`;
});
綁定 document 的 change event,每次偵測到有框框被點擊時,event.target
會指向該 input,在每個 input 上都有設定屬性 value
值,event.target.value
可以取得設定的材料名稱,放入變數中方便修改背景圖使用。
tips:
利用 css 設定變數的方式,將材料的圖片路徑預先放入 css 變數中,而變數的命名須和屬性value
值設定一致,就可以依目前印出的 value 值換上該名稱的 css 變數。
submit
Event注意:submit event 需綁定在 form
上才有效果,不是 input
也不是 button
唷!因為提交的是整個 form
才對。
form
的 submit
事件有預設行為會傳送到 server,但今天的實作不需要傳到後端,因此要用 event.preventDefault()
取消預設行為。
let form = get('#first-form'); // form 表單
// submit 監聽事件綁定在 form 表單上
form.addEventListener('submit', submitOrder);
function submitOrder() {
event.preventDefault(); //必須取消預設行為
let options = [...this.elements]; // form 表單下的所有物件存成陣列
// 將背景圖片清空
display.style.backgroundImage = ''
// 取出點選的元素
let chosedTarget = options.filter((e) => e.checked);
// 設定 3 秒後印出選擇的材料名稱
setTimeout(()=>{
for(let item of chosedTarget){
display.textContent+= item.value+'';
}
},3000)
}
透過展開運算子將 form
表單下的所有元素 this.elements
存入陣列中,不然原本取出的會是 nodeList,使用 filter
取出狀態是 checked = true
的元素,結果要將選擇的材料名稱印在畫面上,用 for...of
+ display.textContent+= item.value+''
的方式依序加入右框框的 textContent
內,外面包一層 setTimeout
選擇延遲 3 秒後印出,這樣可以先跑 preparing ... 的動畫效果。
MDN change event
PJCHENder - CSS Variables
換 input 按鈕 Styling a radio button with only CSS
圖片來源 - freePik
參考: https://codepen.io/gretema/pen/qzwzrG
終~於~快~結~束~了~