Use input+datalist to simply realize the editable drop-down list of real-time matching - and solve the readability problem that the browser only displays value by default after selection

Posted by solarisuser on Mon, 06 Dec 2021 04:07:35 +0100

Problem background

Recently, the little partner put forward a demand to improve the operability of the background drop-down list. The reason is that there are too many drop-down list options. Each drop-down selection is time-consuming, laborious and error prone. He stubbornly chewed on the front-end knowledge and searched for some information about the implementation of the drop-down list on the Internet. Here is a summary.
PS: all the screenshots of the following code implementation effects are the effects of chrome browsers. The effects of other browsers may be different. For example, datalist is obviously different between firefox and chrome. This is not the focus of this article and will not be discussed here.

The simplest drop-down list implementation

The traditional method of displaying drop-down boxes in HTML is to use the combination of select+option Tags:

<select name="staff" id="id_list">
  <option value="10">Zhang San</option>
  <option value="11">Li Si</option>
  <option value="12">Wang Wu</option>
  <option value="13">a notorious liar</option>
  <option value="14">Qian Qi</option>
</select>

The display effect is as follows:

When there are few options, this kind of drop-down list is enough. However, when there are too many options (such as more than 100), users may need to pull from beginning to end and match with the naked eye to select specific items. It not only has a huge workload, but also is prone to errors. Therefore, there is a natural demand for editable + automatic matching drop-down list types.

The simplest implementation of editable drop-down list

A new datalist tag is proposed in H5 standard. The editable and intelligent matching drop-down box can be easily realized by using datalist+input:

<input list="id_datalist">
<datalist id="id_datalist" name="staff">
  <option value="10">Zhang San</option>
  <option value="11">Li Si</option>
  <option value="12">Wang Wu</option>
  <option value="13">a notorious liar</option>
  <option value="14">Qian Qi</option>
</datalist>

The selected display effect is as follows:

This drop-down box supports manual input, and will automatically update the list of matching options according to the input part. It is directly realized by using the input+datalist tag. It is easy to understand and does not need additional js logic code. It is almost perfect in use alone.
However, the drawback is that after option is selected, the value of option.value is displayed in the input box by default instead of its corresponding innerText, which greatly reduces the readability of the option for scenarios where the value and innerText values are different. As follows: after Wang Wu is selected, the input box only displays the value of 12 instead of the innerText content of Wang Wu:

It can be edited and the drop-down list of option.innerText is displayed by default

In order to solve the problem that the above-mentioned input displays option.value instead of option.innerText by default, I searched the online materials. At present, I found that it can only be solved by adding some additional js code logic. The basic idea is to use two input input boxes, one for displaying options and the other for actual value storage( Show datalist labels but submit the actual value )In fact, the user can only see the input responsible for displaying the web page, and the input storing the actual value is set to type="hidden" and hidden. Only when submitting the form will it be silently submitted to the back end.
Referring to the answers of Stephan Muller and cobbystreet in stackoverflow, a code that can distinguish different value s with the same innerText content options is implemented as follows:

<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">Zhang San</option>
  <option value="11">Li Si</option>
  <option value="12">Wang Wu</option>
  <option value="13">a notorious liar</option>
  <option value="14">Qian Qi</option>
  <option value="15">Qian Qi</option>
</datalist>
<input type="hidden" name="staff" value="" id="id_staff">

The results are as follows:

Effect after selection:

Please indicate the source and original address for Reprint: https://www.cnblogs.com/AcAc-t/p/readable_editable_dropdown_list_by_input_datalist.html

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

Topics: Front-end html