Custom Dropdown with initally hidden items on Mobile

Hi all,

I have a javascript codes that changes the functionality of a drop-down select question.

In my dropdown there is a big list of company names and I ask participants to select one. Since I do not want them to be biased, I want the items of the list to be hidden until the participants start typing.

When they start typing "A" for example, only then should all companies starting with A be shown.

This javascript code enables that:

<script>
    document.addEventListener("DOMContentLoaded", function() {
        const select = document.getElementById("Q10");

        // Hide all options initially
        for (let i = 0; i < select.options.length; i++) {
            select.options[i].style.display = "none";
        }

        // Create an input field and add it before the select element
        const input = document.createElement("input");
        input.type = "text";
        input.id = "insuranceSearch";
        input.placeholder = "Bitte tippen Sie die ersten Buchstaben zur Auffindung Ihrer Gesellschaft ein und wählen Sie aus der Liste.";
        input.style.width = "100%";
        input.style.marginBottom = "10px";
        select.parentNode.insertBefore(input, select);

        // Style the select dropdown for better control
        select.style.position = "absolute";
        select.style.width = input.offsetWidth + "px"; // Match the width of the input field
        select.style.zIndex = "1";
        select.style.display = "none"; // Initially hide the dropdown

        // Event listener to show and filter options based on user input
        input.addEventListener("input", function() {
            const searchValue = input.value.toLowerCase();
            let matchCount = 0;

            // Filter and display matching options
            for (let i = 0; i < select.options.length; i++) {
                const option = select.options[i];
                const optionText = option.text.toLowerCase();

                if (optionText.startsWith(searchValue) && searchValue !== "") {
                    option.style.display = "block";
                    matchCount++;
                } else {
                    option.style.display = "none";
                }
            }

            if (matchCount > 0) {
                // Adjust the size of the select based on the number of matches (even if only 1 item matches)
                select.size = Math.max(matchCount, 2); // Set at least 2 to ensure visibility with a single match
                select.style.display = "block"; // Make the select dropdown visible
                select.style.height = `${Math.min(matchCount, 10) * 25}px`; // Adjust the height to fit
                select.style.width = input.offsetWidth + "px"; // Match the width of the input field dynamically
            } else {
                select.style.display = "none";
                select.size = 1;
            }
        });

        // Event listener to handle selection and hide dropdown when an option is selected
        select.addEventListener("click", function() {
            input.value = select.options[select.selectedIndex].text;
            select.style.display = "none";
        });

        // Hide the dropdown when the input loses focus, but allow click selection
        input.addEventListener("blur", function() {
            setTimeout(function() { // Timeout to allow click event on select options
                select.style.display = "none";
            }, 150);
        });

        // Show the dropdown again when the input is focused
        input.addEventListener("focus", function() {
            if (input.value !== "") {
                const searchValue = input.value.toLowerCase();
                let matchCount = 0;

                for (let i = 0; i < select.options.length; i++) {
                    const option = select.options[i];
                    const optionText = option.text.toLowerCase();

                    if (optionText.startsWith(searchValue) && searchValue !== "") {
                        option.style.display = "block";
                        matchCount++;
                    } else {
                        option.style.display = "none";
                    }
                }

                if (matchCount > 0) {
                    select.size = Math.max(matchCount, 2); // Set at least 2 to ensure visibility with a single match
                    select.style.display = "block";
                    select.style.height = `${Math.min(matchCount, 10) * 25}px`;
                    select.style.width = input.offsetWidth + "px"; // Match the width of the input field dynamically
                }
            }
        });
    });
</script>

This code works fine on desktop devices but not on mobile.

On desktop it behaves like this:

You type the letter and only then is a filtered list of items shown.

On mobile, when you type a letter, the dropdown opens but the items remain invisible.
However, since the length / heigth of the dropdown adapts to the number of items, the size of the "invisible" list is also different depending on the input. So it seems that the filter is working on mobile but for some reason the items are not shown. I can also not click onto the invisible list and select something.

Here is a screenshot:

Could someone help me out there?

Note: when using the "mobile test simulator" in the testmode on desktop, the functionality works as it should. The issue persists only on "real mobile".

I have tried both Android and iOS and 3 different browsers.

Thanks,
Onat

Resolved
1 reply