使用input+datalist簡單實現實時匹配的可編輯下拉列表-並解決選定后瀏覽器默認只顯示value的可讀性問題


問題背景

最近小伙伴提了一個希望提高后台下拉列表可操作性的需求,原因是下拉列表選項過多,每次下拉選擇比較費時費力且容易出錯,硬着頭皮啃了啃前端知識,網上搜尋了一些下拉列表實現的資料,這里總結一下。
PS: 以下所有代碼實現效果截圖均為chrome瀏覽器下效果,其他瀏覽器效果可能有一定差別,比如datalist在firefox和chrome下就有較明顯差別,這不是本文重點這里不做討論。

最簡單的下拉列表實現

在HTML中傳統顯示下拉框的方法是使用select+option標簽組合實現:

<select name="staff" id="id_list">
  <option value="10">張三</option>
  <option value="11">李四</option>
  <option value="12">王五</option>
  <option value="13">黃六</option>
  <option value="14">錢七</option>
</select>

顯示效果如下:

當選項較少的時候,此種下拉列表自然夠用了,然而當選項特別多(比如超過100個)的時候,用戶要從其中選擇特定項可能需要從頭拉到尾,還需要肉眼match,不但工作量巨大,而且容易出錯,於是自然出現了可編輯+自動匹配的下拉列表類型的需求。

最簡單的可編輯下拉列表實現

H5標准中新提出了一個datalist標簽,使用datalist+input可很簡單地實現可編輯、智能匹配的下拉框:

<input list="id_datalist">
<datalist id="id_datalist" name="staff">
  <option value="10">張三</option>
  <option value="11">李四</option>
  <option value="12">王五</option>
  <option value="13">黃六</option>
  <option value="14">錢七</option>
</datalist>

選擇顯示效果如下:

此下拉框支持人工輸入內容,並且會根據已輸入部分自動更新可匹配選項列表,直接使用input+datalist標簽實現,簡單易懂無需額外js邏輯代碼,單從使用上已可謂接近完美。
然而美中不足的是,選中option后,在輸入框中默認顯示的就是option.value 的值,而非其對應innerText,這對於value與innerText取值不一樣的場景,極大地降低了選項的可讀性,如下:選擇王五之后,輸入框只顯示了12這個value,而沒有顯示王五這個innerText內容:

可編輯且默認顯示option.innerText的下拉列表實現

為了解決上面提到的input默認顯示option.value而非option.innerText的問題,找遍網上資料,目前發現暫時還是只能通過額外添加一些js代碼邏輯來解決,其基本思想是使用兩個input輸入框,一個負責顯示選項,另外一個負責實際的value存儲(Show datalist labels but submit the actual value),用戶網頁實際只能看到負責顯示的input,而存儲實際value的input設置為type="hidden"隱藏掉,只有提交表單時會默默地提交到后端。
參考stackoverflow中Stephan Muller和cobbystreet兩位答主的答案,一個能區分不同value具有相同innerText內容選項的代碼實現如下:

<script type="text/javascript">
	function checkSelectSet(e) {
		var input = e.target,
			list = input.getAttribute('list'),
			options = document.querySelectorAll('#' + list + ' option[value="'+input.value+'"]'),
			hiddenInput = document.getElementById(input.getAttribute('id').replace('-display', ''));

		if (options.length > 0) {
			  hiddenInput.value = input.value;
			  input.value = options[0].innerText;
		  }
	}

	function addDataListListener(eid) {
		document.querySelector('#'+eid).addEventListener('input', checkSelectSet)
	}
</script>
<input type="text" name="staff-display" id="id_staff-display" list="list__staff" value="-" oninput="addDataListListener('id_staff-display')">
<datalist id="list__staff">
  <option value="10">張三</option>
  <option value="11">李四</option>
  <option value="12">王五</option>
  <option value="13">黃六</option>
  <option value="14">錢七</option>
  <option value="15">錢七</option>
</datalist>
<input type="hidden" name="staff" value="" id="id_staff">

實現效果如下:

選定后效果:

轉載請注明出處,原文地址:https://www.cnblogs.com/AcAc-t/p/readable_editable_dropdown_list_by_input_datalist.html

參考:

Show datalist labels but submit the actual value: https://stackoverflow.com/questions/29882361/show-datalist-labels-but-submit-the-actual-value


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM