Preenchimento automático aplicando valor e não rótulo à caixa de texto

86

Estou tendo problemas para tentar fazer o autocompletar funcionar corretamente.

Tudo parece ok para mim, mas ....

<script>
$(function () {
    $("#customer-search").autocomplete({
        source: 'Customer/GetCustomerByName',
        minLength: 3,
        select: function (event, ui) {
            $("#customer-search").val(ui.item.label);
            $("#selected-customer").val(ui.item.label);
        }
    });
});
</script>
<div>
<input id="customer-search" />
 </div>
@Html.Hidden("selected-customer")

No entanto, quando seleciono um item da lista suspensa, o valor é aplicado à caixa de texto em vez do rótulo.

O que eu fiz errado?

Se eu olhar a fonte usando o firebug, posso ver que meu campo oculto está sendo atualizado corretamente.

Diver Dan
fonte
1
O que você vê na resposta JSON no Firebug?
SLaks
[{"label": "Tom Smith", "value": "1234"}, {"label": "Tommy Smith", "value": "12321"}]
Diver Dan

Respostas:

211

O comportamento padrão do selectevento é atualizar inputcom ui.item.value. Este código é executado após seu manipulador de eventos.

Basta retornar falseou ligar event.preventDefault()para evitar que isso ocorra. Eu também recomendaria fazer algo semelhante para o focusevento para evitar que ele ui.item.valueseja colocado no inputenquanto o usuário passa o mouse sobre as opções:

$("#customer-search").autocomplete({
    /* snip */
    select: function(event, ui) {
        event.preventDefault();
        $("#customer-search").val(ui.item.label);
        $("#selected-customer").val(ui.item.label);
    },
    focus: function(event, ui) {
        event.preventDefault();
        $("#customer-search").val(ui.item.label);
    }
});

Exemplo: http://jsfiddle.net/andrewwhitaker/LCv8L/

Andrew Whitaker
fonte
1
Muito útil! Você não quis dizer$("#selected-customer").val(ui.item.value);
juanignaciosl
1
@juanignaciosl: Não - esse código se destina a atualizar a caixa de pesquisa com o em labelvez do value.
Andrew Whitaker
Estou armazenando valor em db, não em rótulo. Da próxima vez, quero definir de acordo com a etiqueta com base no valor. Qual é a maneira de fazer isso?
parth.hirpara
1
Ei, tentando fazer algo semelhante, mas colocar tudo em focusvez de select. O problema está item.valuesendo definido em vez de item.label. Como contornar isso? lookup.autocomplete({ source: data, focus: function(event, ui) { event.preventDefault(); $(this).val(ui.item.label) status.text(ui.item.value) submitted.text(ui.item.submitted) comments.html(ui.item.comments) } })
Batman
O mesmo aqui, quero o rótulo exibido, valor POSTADO. Consegui remendar um kludge envolvendo um elemento oculto (semelhante à resposta de @Yang Zhang abaixo, mas neste ponto parece que fazer meu próprio preenchimento automático será a abordagem menos deselegante.
Lori
15

Apenas gostaria de adicionar que, em vez de referenciar o elemento de entrada por "id" dentro das funções de retorno de chamada de seleção e foco , você pode usar este seletor, como:

$(this).val(ui.item.label);

é útil quando você atribui preenchimento automático para vários elementos, ou seja, por classe:

$(".className").autocomplete({
...
    focus: function(event, ui) {
        event.preventDefault();
        $(this).val(ui.item.label);
    }
});
Vlad
fonte
8

No meu caso, preciso registrar outro campo 'id' em uma entrada oculta. Portanto, adiciono outro campo aos dados retornados da chamada ajax.

{label:"Name", value:"Value", id:"1"}

E adicionou um link 'criar novo' na parte inferior da lista. Ao clicar em 'criar novo', um modal aparecerá e você poderá criar um novo item a partir dele.

$('#vendorName').autocomplete
    (
        {
            source: "/Vendors/Search",
            minLength: 2,
            response: function (event, ui)
            {
                ui.content.push
                ({
                    label: 'Add a new Name',
                    value: 'Add a new Name'
                });
            },
            select: function (event, ui)
            {
                $('#vendorId').val(ui.item.id);
            },
            open: function (event, ui)
            {
                var createNewVendor = function () {
                    alert("Create new");
                }
                $(".ui-autocomplete").find("a").last().attr('data-toggle', 'modal').addClass('highLight');
                $(".ui-autocomplete").find("a").last().attr('href', '#modal-form').addClass('highLight');
            }
        }
    );

Acho que a questão é que você pode adicionar qualquer campo de dados extra além de apenas 'rótulo' e 'valor'.

Eu uso o modal bootstrap e pode ser o seguinte:

<div id="modal-form" class="modal fade" aria-hidden="true">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-body">
            <div class="row">

            </div>
        </div>
    </div>
</div>

Yang Zhang
fonte