Search code examples
jqueryasp.net-coredrop-down-menudropdownchoicechoices.js

How to load a select choice-js with data from the database


I need to load a select choice-js with a list of countries and display the flag images. After making the Ajax request, I get a json (result.countries) and I don't know how to load the properties inside the custom html tags. Does anyone know how to help me?

Asp.Net core Razor - Class

public  class ImageOptionViewModel
{
    public string Id { get; set; } //1
    public string Value { get; set; } //1
    public string Label { get; set; } //Brazil
    public string imageUrl { get; set; } //~/img/brasil.svg
} 

Asp.net Core - Action

[HttpGet]
[Authorize]
[Route("pais-gerenciar/obter-lista-paises-com-imagens")]
public JsonResult GetPaisesComImagens()
{            
    var paises = _paisAppService.GetAllBy(null, null).Select(x => new ImageOptionViewModel
    {
        Id = x.Id.ToString(),
        Label = x.NomePtBr,
        Value = x.Id.ToString(),
        imageUrl = x.ImagemBandeiraURL
    });

    return Json(new { success = true, paises });
}

Asp.net Core - CSHTML

 <select class="form-control enderecamento-postal-sel-pais" asp-for="PaisId"></select>

JS

$.ajax({
    url: "/pais-gerenciar/obter-lista-paises-com-imagens",
    type: "GET",
    contentType: "application/json",
    success: function (result) {
        stopLoader();

        if (typeof result.success !== 'undefined') {
            if (!result.success) {
                Swal.fire({
                    title: 'Ops...',
                    text: result.message,
                    icon: 'error',
                    customClass: {
                        confirmButton: 'btn btn-primary w-xs'
                    },
                    buttonsStyling: false,
                    allowOutsideClick: false
                });

                return false;
            }
        }

        let selPais = $(genericModalOrBodyInstance).find('.enderecamento-postal-sel-pais')[0];
        new Choices(selPais, {
            allowHTML: true,
            placeholder: true,
            renderChoiceLimit: -1,
            position: 'auto',
            resetScrollPosition: true,
            searchEnabled: true,
            loadingText: 'Carregando...',
            noResultsText: 'Nenhum resultado encontrado',
            noChoicesText: 'Sem opções para escolher',
            itemSelectText: 'Clique para selecionar',
            callbackOnCreateTemplates: function (template) {
                let classNames = this.config.classNames;
                let itemSelectText = this.config.itemSelectText;
                return {
                    choice: function (classNames, data) {
                        return template(`<div class="${String(classNames.item)} ${String(classNames.itemChoice)} ${String(data.disabled ? classNames.itemDisabled : classNames.itemSelectable)}"
                        data-select-text="${String(itemSelectText)}"
                        data-choice ${String(data.disabled ? 'data-choice-disabled aria-disabled=true' : 'data-choice-selectable')}
                        data-id="${String(data.id)}"
                        data-value="${String(data.value)}"
                        data-label="${String(data.label)}"
                        ${String(data.groupId > 0 ? 'role="treeitem"' : 'role="option"')}>
                            <img src="${String(data)}" alt="">
                            ${String(data.label)}
                        </div>`)
                    }
                }
            }
        });

        return true;
    },
    error: function (e) {
        stopLoader();

        redirectToError(e.status);

        return false;
    }
});

Solution

  • Do you mean to dynamically generate option in select according to the results returned by ajax requests? You can use the setValue property of choices.js.

    For example, my ajax request returns an ImageOptionViewModel object:

    [HttpGet]
    public JsonResult GetPaisesComImagens()
    {
        var paises = new ImageOptionViewModel()
        {
            Id = "1",
            Label = "TestLabel",
            Value = "1",
            imageUrl = "/img/img1.jpg"
        };
    
        return Json(new { success = true, paises });
    }
    

    My ajax request:

    $.ajax({
            url: "/Home/GetPaisesComImagens",
            type: "GET",
            contentType: "application/json",
            success: function (result) {
                //.....
                var myDynamicItems = 
                [
                    {
                        value: result.paises.value,
                        label: '<img src=' + result.paises.imageUrl + '>' + result.paises.label,
                        id: result.paises.id
                    }
                ]
                
                var start = new Choices(document.querySelector('.enderecamento-postal-sel-pais'), {
                    allowHTML: true,
                    placeholder: true,
                    renderChoiceLimit: -1,
                    position: 'auto',
                    resetScrollPosition: true,
                    searchEnabled: true,
                    loadingText: 'Carregando...',
                    noResultsText: 'Nenhum resultado encontrado',
                    noChoicesText: 'Sem opções para escolher',
                    itemSelectText: 'Clique para selecionar',
                    callbackOnCreateTemplates: function (template) {
                        let classNames = this.config.classNames;
                        let itemSelectText = this.config.itemSelectText;
                        return {
                            choice: function (classNames, data) {
                                return template(`<div class="${String(classNames.item)} ${String(classNames.itemChoice)} ${String(data.disabled ? classNames.itemDisabled : classNames.itemSelectable)}"
                                data-select-text="${String(itemSelectText)}"
                                data-choice ${String(data.disabled ? 'data-choice-disabled aria-disabled=true' : 'data-choice-selectable')}
                                data-id="${String(data.id)}"
                                data-value="${String(data.value)}"
                                data-label="${String(data.label)}"
                                ${String(data.groupId > 0 ? 'role="treeitem"' : 'role="option"')}>
                                    
                                    ${String(data.label)}
                                </div>`)
                            }
                        }
                    }
                });
                start.setValue(myDynamicItems);
    
                return true;
            },
            error: function (e) {
                //.....
            }
        });
    

    Test Result: enter image description here