前言
今天接到一個使用者需求,希望將下拉選單改成多選
其實隨便找個JQuery套件,應該馬上搞定…
不過由於專案實在是挺舊的,是個.NET 2.0 WebFrom專案
想了一會兒,反正也不是什麼困難的需求,剛好就拿來練練基本功吧..
既然要練習基本功,那麼就決定回歸原始!只用最基本的CSS + JavaScript來做這個功能..
(本網頁Demo不支援IE瀏覽器..)
思考過程
為了配合一下WebForm的控制項,這樣在PostBack取值的時候只要把 DropDownList 改成 ListBox 並設成 SelectionMode="MultiSimple"
應該就搞定了
觀察一下就知道, ListBox 在網頁上其實會產生像這樣的 Element:
1 2 3 4 5
| <select class="multi-selector" multiple> <option value="Item1">Item1</option> <option value="Item2">Item2</option> <option value="Item3">Item3</option> </select>
|
Demo:
嗯…這東西實在是很醜,且完全不是我們想要的,
那麼只好自己寫一個UI,將選項同步,然後將原本的UI藏起來讓使用者看不到,這樣就可以了吧!
動工
Step1. 首先先定義一下我們的結構
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div class="dropdown"> <div class="item text"> <label></label> </div> <div class="item"> <input type="checkbox" value="Item1"/> <span>Item1</span> </div> <div class="item"> <input type="checkbox" value="Item2"/> <span>Item2</span> </div> <div class="item"> <input type="checkbox" value="Item3"/> <span>Item3</span> </div> </div>
|
Step2. CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| .dropdown { display:inline-block; height: 30px; z-index: 2; }
.dropdown .item { width: 180px; height: 30px; border: 1px solid #ccc; margin: -1px 0px 0px; padding: 0px 10px; box-sizing: border-box; box-shadow: 0 0 3px #ccc; background: #fff; }
.dropdown .item + .item{ display:none; }
.dropdown:hover .item { display: block; }
.dropdown .text label, .dropdown .item span, .dropdown .item input[type="checkbox"] { line-height: 30px; }
.dropdown .text label:empty:after { content: '請選擇項目'; color: #ccc; }
|
跟原本的元素放在一起比較看看:
嗯…看起來長相差不多了
Step3. JavaScript產生結構
接下來,就用JavaScript來讀取原本的element,並產生剛剛定義好的新的結構
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function initMultiElement() { var multiElement = document.createElement('div'); multiElement.setAttribute('class', 'dropdown'); var html = `<div class="item text"> <label></label> </div>`;
document.querySelectorAll('.multi-selector option').forEach(function(optionItem){ html += `<div class="item"> <input type="checkbox" value="${optionItem.value}"/> <span>${optionItem.text}</span> </div>` }) multiElement.innerHTML = html; document.querySelector('.multi-selector').parentElement.appendChild(multiElement); setMultiElementEvent(); }
|
點擊checkbox時,要連動原本的ListBox選項
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function setMultiElementEvent() { document.querySelectorAll('.item input[type="checkbox"]').forEach(function(checkItem){ checkItem.addEventListener("click", function(e){ let resultText = ''; let checkedItems = document.querySelectorAll('.item input:checked[type="checkbox"]') checkedItems.forEach(function(selectItem){ if(resultText !== '') resultText += ',' resultText += selectItem.value })
document.querySelector('.dropdown .text label').innerText = resultText document.querySelector('.multi-selector option[value="'+e.srcElement.value+'"]').selected = e.srcElement.checked }); }) }
|
最後在window.onload
時呼叫initMultiElement()
1 2 3
| window.onload = function() { initMultiElement(); }
|
搞定
結果
現在我們定義好的HTML結構已經全部用JavaScript來產生,那馬上來看看結果:
成功,現在選取的元素時會將原本的 ListBox 也一起選取起來了,
那最後只要把原本的 ListBox 給偷偷藏起來不要讓使用者發現就行囉!
1 2 3 4 5 6
| .multi-selector { width: 0px; height: 0px; opacity: 0; }
|
心得
在剝奪了各種框架套件之後,要寫這些功能確實是麻煩了許多,
不過這種練習還是能學到蠻多東西的,算是重新練習基本功吧!
↓↓↓ 如果喜歡我的文章,可以幫我按個Like! ↓↓↓
>> 或者,請我喝杯咖啡,這樣我會更有動力唷! <<<
街口支付
街口帳號: 901061546