DEV Community

Imam Ali Mustofa
Imam Ali Mustofa

Posted on • Originally published at darkterminal.prose.sh

1 1 1 1 1

Reusable Input Datalist

Reusable Input Datalist

Hello Punk! In my daily boring...

I found something interesting that I will share with you, this is not too fancy or glam but still "fun-cy" for me, cz In my stupid knowledge this is really helpful and enough for me and myself.

HTML5 Input Datalist

At least, this is what W3Schools said in their example:

W3Schools Example

What if I wrap inside PHP Function?

When I work with HTMX I need isolated component that can be reusable a form. So I create a PHP Function that generate the Input Datalist.

// Filename: helpers/Utils.php

public static function selectSearch(string $inputId, array $options, int|string $selected = ''): string
{
    $inputHTML = '<div class="relative">';
    $inputHTML .= '<input type="text" id="' . $inputId . '" list="" placeholder="Search..." autocomplete="off" class="transition-[0.2s] w-full input input-sm input-bordered focus:shadow-md" />';
    $inputHTML .= '<datalist id="' . $inputId . '_list" class="box-border overflow-y-auto absolute top-full mt-1 max-h-40 bg-white border shadow-md">';

    $selectedText = '';
    $selectedValue = '';
    foreach ($options as $option) {
        $text = \explode('#', $option)[1];
        $value = \explode('#', $option)[0];
        if ($selected == $value) {
            $selectedText = $text;
            $selectedValue = $value;
        }
        $inputHTML .= '<option class="block p-1 mb-px cursor-pointer hover:bg-gray-200" value="' . $option . '">' . $text . '</option>';
    }

    $inputHTML .= '</datalist>';
    $inputHTML .= '<input type="hidden" name="' . $inputId . '" id="target_' . $inputId . '" value="'.$selectedValue.'" />';
    $inputHTML .= '</div>';
    $inputHTML .= '<script type="text/javascript">';
    $inputHTML .= 'fancyDropdown("' . $inputId . '");';
    $inputHTML .= 'setTimeout(() => document.getElementById("' . $inputId . '").value = "'.$selectedText.'", 350);';
    $inputHTML .= '</script>';

    return $inputHTML;
}

Enter fullscreen mode Exit fullscreen mode

I create a static function inside Utils class so I can use that function everywhere in my project.

Is that using TailwindCSS? Yes, it's too dirty. But fck it! It's work! (Don't blame on me, if you really programmer so read it)

You can see this script:

$inputHTML .= '<script type="text/javascript">';
$inputHTML .= 'fancyDropdown("' . $inputId . '");';
$inputHTML .= 'setTimeout(() => document.getElementById("' . $inputId . '").value = "' . $selectedText . '", 350);';
$inputHTML .= '</script>';
Enter fullscreen mode Exit fullscreen mode

Yes! Again I wrote JavaScript as a string in PHP, why not! And where is the fckin fancyDropdown come from?!

Here is, I found a Question in StackOverflow that asked about

Question in StackOverflow

The Question: https://stackoverflow.com/q/13693482

Yes! Around 11 years ago, and the solution that match with my need is come around

the solution that match with my need

The Solution: https://stackoverflow.com/a/76178626

The updated version of

The updated version

Original Answer: https://stackoverflow.com/a/74786719

Here is this code:

function fancyDropdown(inputId) {
    const input = document.getElementById(inputId);
    const target = document.getElementById('target_' + inputId);
    const datalist = input.nextElementSibling;
    let minWidth = datalist.offsetWidth;

    function outputsize() {
        if (input.offsetWidth < minWidth) {
            datalist.style.minWidth = input.offsetWidth + 'px';
        } else {
            datalist.style.width = input.offsetWidth + 'px';
        }
    }

    new ResizeObserver(outputsize).observe(input);

    input.addEventListener("input", function(e) {
        datalist.style.display = "block";
        const text = input.value.toUpperCase();
        let hide = 1;
        for (let option of datalist.options) {
            if (option.value.toUpperCase().indexOf(text) > -1) {
                option.style.display = "block";
                hide = 0;
            } else {
                option.style.display = "none";
            }
        }
        if (hide) {
            datalist.style.display = "none";
        }
    });

    input.addEventListener("click", function(e) {
        let hide = 1;
        for (let option of datalist.options) {
            if (window.getComputedStyle(option, null).display == "block") hide = 0;
        }

        if (datalist.style.display == "block" || hide == 1) {
            datalist.style.display = "none";
        } else {
            datalist.style.display = "block";
        }
    });

    document.addEventListener("click", function(e) {
        if (e.target.tagName == "OPTION") {
            let inputValue = e.target.value.split('#');
            input.value = inputValue[1];
            target.value = inputValue[0];
        }
        if (e.target.tagName !== "DATALIST" && e.target.tagName !== "INPUT") {
            datalist.style.display = "none";
        }
    });

    datalist.style.display = "none";
}
Enter fullscreen mode Exit fullscreen mode

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

Top comments (0)

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay