Choices-js / Choices

A vanilla JS customisable select box/text input plugin ⚡️
https://choices-js.github.io/Choices/
MIT License
6.05k stars 597 forks source link

Does not show the icon (HTML) #1127

Open pdias opened 11 months ago

pdias commented 11 months ago

I have this html:

<div class="col-xs-12 col-sm-6 col-md-5 col-lg-5 col-xl-5">
     <select class="js-choice">
          <option><i class="fa fa-heart"></i> Ketchup</option>
          <option><i class="fa fa-film"></i> Relish</option>
          <option><i class="fa fa-home"></i> Mayonnaise</option>
     </select>
 </div>

And i do this:

const element = document.querySelector('.js-choice');
const choices = new Choices(element, {
      allowHTML: true
});

But the HTML is not show...

1

The idea is to show the icon (webfont)...

What i'm doing wrong?

Thanks.

HeIIow2 commented 4 months ago

Hi, I ran into the same issue. here is my reproducible example.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"/>
        <script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
    </head>

    <body>
        <div class="container">
            <div class="row g-3 mb-3">
                <h1>Reproducible example</h1>
            </div>

            <div class="row g-3 mb-3">
                <div class="col-md-6">
                    <label for="foo" class="form-label">foo</label>
                    <select class="form-select choices-single" name="foo" id="foo">
                        <option value="">Nichts ausgewählt</option>

                        <option value="1">bar 1 <span class="badge rounded-pill bg-secondary">bar</span></option>
                        <option value="2">bar 2 <span class="badge rounded-pill bg-secondary">bar</span></option>
                        <option value="3">foo 1 <span class="badge rounded-pill bg-secondary">foo</span></option>
                    </select>
                </div>
            </div>
        </div>
    </body>

    <script>
        const element = document.querySelector('.choices-single');
        const choices = new Choices(element, {
            allowHTML: true
        });
    </script>
</html>

However, what was weird is, that without initializing the select element, the html inside of the options are not rendered as well:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"/>
        <script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
    </head>

    <body>
        <div class="container">
            <div class="row g-3 mb-3">
                <h1>Reproducible example</h1>
            </div>

            <div class="row g-3 mb-3">
                <div class="col-md-6">
                    <label for="foo" class="form-label">foo</label>
                    <select class="form-select choices-single" name="foo" id="foo">
                        <option value="">Nichts ausgewählt</option>

                        <option value="1">bar 1 <span class="badge rounded-pill bg-secondary">bar</span></option>
                        <option value="2">bar 2 <span class="badge rounded-pill bg-secondary">bar</span></option>
                        <option value="3">foo 1 <span class="badge rounded-pill bg-secondary">foo</span></option>
                    </select>
                </div>
            </div>
        </div>
    </body>
</html>

image

That proves the "problem" does not lie with choices.js, but is an "issue" with html. As it turns out option tags can't contain any other tags.

One solution would be, to use the choices configuration option with javascript, or do something like this:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"/>
        <script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
    </head>

    <body>
        <div class="container">
            <div class="row g-3 mb-3">
                <h1>Reproducible example</h1>
            </div>

            <div class="row g-3 mb-3">
                <div class="col-md-6">
                    <label for="foo" class="form-label">foo</label>
                    <select class="form-select choices-single" name="foo" id="foo">

                    </select>
                    <div class="d-none" data-option-list>
                        <div value="" selected disabled>nothing selected</div>
                        <div value="1">bar 1 <span class="badge rounded-pill bg-secondary">bar</span></div>
                        <div value="2">bar 2 <span class="badge rounded-pill bg-secondary">bar</span></div>
                        <div value="3">foo 1 <span class="badge rounded-pill bg-secondary">foo</span></div>
                    </div>
                </div>
            </div>
        </div>
    </body>

    <script>
        function getOptions(selectElement) {
            const items = [];

            Array.from(selectElement.nextElementSibling.children).forEach((option) => {
                console.log(option);
                items.push({
                    value: option.attributes.value,
                    label: option.innerHTML,
                    selected: option.hasAttribute('selected'),
                    disabled: option.hasAttribute('disabled'),
                });
            })

            return items;
        }

        const element = document.querySelector('.choices-single');
        const choices = new Choices(element, {
            allowHTML: true,
            choices: getOptions(element)
        });
    </script>
</html>

image

@pdias