I am trying to render the response from an API call in HTML using JavaScript by creating option elements that are appended to a select element.

HTML

<input type="text" id='search_profile_query' class="focus:outline-none focus:ring-0 focus:border-gray-900 border p-2 rounded-md"> <div id="dropdown-container"class="min-w-0 flex flex-col items-center hidden"> <select id='id_my_dropdown' class="min-w-0 text-center absolute overflow-y-auto border-black focus:ring-0 focus:border-black rounded-md" onclick="redirect()" size="8"></select> </div>

JavaScript

document.addEventListener('DOMContentLoaded', function() { const searchQueryInput = document.getElementById('search_profile_query'); const myDropdown = document.getElementById('id_my_dropdown'); const container = document.getElementById('dropdown-container'); if(searchQueryInput && myDropdown && container){ searchQueryInput.addEventListener('keyup', function() { const searchTerm = this.value; fetch(`/get-dropdown-choices/?q=${searchTerm}`).then(response => response.json()).then(data => { myDropdown.innerHTML = ''; data.choices.forEach(choice => { const option = document.createElement('option'); option.value = choice[0]; option.textContent = choice[1]; myDropdown.appendChild(option); }); }) .catch(error => console.error('Error:', error)); }); } });

It works fine on desktop but when I test it using IOS, the options do not populate as control is given to the native select picker. The HTML select element renders empty. It is an issue because for every API call (on every keyup) the picker pops up and the user will have to click out of it every time a new letter is keyed in and I would rather not use a submit button to make the API call if I can help it. Is there a solution that developers use to make the select element appear as it does on desktop where the picker is bypassed? A solution that is common when searching for products or profiles using a web app on IOS?

Egraha's user avatar

Replace the native select with a custom dropdown using div elements:

<input type="text" id='search_profile_query' class="focus:outline-none focus:ring-0 focus:border-gray-900 border p-2 rounded-md"> <div id="dropdown-container" class="min-w-0 flex flex-col items-center hidden"> <div id="custom-dropdown" class="min-w-0 text-center absolute overflow-y-auto border-black focus:ring-0 focus:border-black rounded-md bg-white shadow-lg max-h-60" style="display: none;"></div> </div> document.addEventListener('DOMContentLoaded', function() { const searchQueryInput = document.getElementById('search_profile_query'); const customDropdown = document.getElementById('custom-dropdown'); const container = document.getElementById('dropdown-container'); let selectedOption = null; if(searchQueryInput && customDropdown && container){ searchQueryInput.addEventListener('input', function() { const searchTerm = this.value; if (searchTerm.length < 2) { hideDropdown(); return; } fetch(`/get-dropdown-choices/?q=${searchTerm}`) .then(response => response.json()) .then(data => { customDropdown.innerHTML = ''; if (data.choices && data.choices.length > 0) { data.choices.forEach(choice => { const option = document.createElement('div'); option.className = 'px-4 py-2 hover:bg-gray-100 cursor-pointer border-b border-gray-100 last:border-b-0'; option.dataset.value = choice[0]; option.textContent = choice[1]; option.addEventListener('click', function() { searchQueryInput.value = choice[1]; selectedOption = choice[0]; hideDropdown(); // Trigger any additional logic redirect(choice[0]); }); customDropdown.appendChild(option); }); showDropdown(); } else { hideDropdown(); } }) .catch(error => { console.error('Error:', error); hideDropdown(); }); }); // Close dropdown when clicking outside document.addEventListener('click', function(event) { if (!container.contains(event.target) && event.target !== searchQueryInput) { hideDropdown(); } }); // Close dropdown on escape searchQueryInput.addEventListener('keydown', function(event) { if (event.key === 'Escape') { hideDropdown(); } }); } function showDropdown() { customDropdown.style.display = 'block'; container.classList.remove('hidden'); } function hideDropdown() { customDropdown.style.display = 'none'; container.classList.add('hidden'); } function redirect(value) { // Your redirect logic here console.log('Selected:', value); } });

Reihandio's user avatar

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.