How to update a DropDownList without refreshing the page

4

I have a Dropdown of States, and a Cities, and a ZIP field, which is making use of the online API of the mails, when I put a zip, my system checks if the city already exists in the database, and if it has not, it is added. so far so good, the problem is that I have a dropdown that brings the cities that were registered until the screen update, however when I type the zip, and it searches the city, that when it does not exist and inserts the new one, it does not update my Dropdown with cities, not displaying the 'new' city, but if I refresh the whole page, it displays this new city. I wanted an option so that as this new city was entered into the bank, my dropdown would be updated as well.

JavaScript Used:

<script>
    $(document).ready(function () {
        $("#cep").blur(function () {
            var cepValue = $(cep).val();
            $.ajax({
                type: 'POST',
                url: 'RetornaEndereco',
                data: { cep: cepValue },
                dataType: 'json',
                success: function (data) {
                    $('#bairro').val(data.bairro);
                    $('#endereco').val(data.end);
                    $('#cidade').val(data.cidade);
                    $('#estado').val(data.uf);
                },
                error: function (data) {
                    alert('Error' + data);
                }
            });
        });
    });
</script>

Controller

public JsonResult RetornaEndereco(string cep)
{
    var valor = Regex.Replace(cep, "[^0-9]", "");
    var ws = new WSCorreios.AtendeClienteClient();
    var resposta = ws.consultaCEP(valor);
    try
    {
        System.Console.WriteLine();
        System.Console.WriteLine("Endereço: {0}", resposta.end);
        System.Console.WriteLine("Bairro: {0}", resposta.bairro);
        System.Console.WriteLine("Cidade: {0}", resposta.cidade);
        System.Console.WriteLine("Estado: {0}", resposta.uf);
    }
    catch (Exception ex)
    {
        return Json("Erro ao efetuar busca do CEP: {0}", ex.Message);
    }

   Estado estado = (from u in db.Estados where u.Sigla == resposta.uf select u).SingleOrDefault();//Busca no banco pelo Estado

    Cidade iDCidade = (from u in db.Cidades where u.Nome == resposta.cidade && u.EstadoID == estado.EstadoID select u).SingleOrDefault();//Busca no banco pela cidade que está no mesmo estado
    Cidade levaCidade = new Cidade();
    if (iDCidade == null)//Se a cidade não estiver cadastrada, insere uma nova cidade. 
    {
        Cidade cidade = new Cidade();
        cidade.Nome = resposta.cidade;
        cidade.EstadoID = estado.EstadoID;
        db.Cidades.Add(cidade);
        db.SaveChanges();
        levaCidade.CidadeID = cidade.CidadeID;//Pega o ID da cidade cadastrada
        levaCidade.EstadoID = cidade.EstadoID;//pega o id do estado selecionado
    }
    else
    {
        Cidade cidade = new Cidade();
        cidade.Nome = resposta.cidade;
        cidade.EstadoID = estado.EstadoID;
        levaCidade.CidadeID = iDCidade.CidadeID;//Pega o ID da cidade cadastrada
        levaCidade.EstadoID = estado.EstadoID;//pega o id do estado selecionado
    }
    Endereco levarEndereco = new Endereco();//Cria o objeto para ser transportado pelo Json
    levarEndereco.CidadeID = levaCidade.CidadeID;
    levarEndereco.Numero = levaCidade.EstadoID;//Passando o id do estado na variavel numero para alterar no json
    levarEndereco.Bairro = resposta.bairro;
    levarEndereco.Descricao = resposta.end;
    ViewBag.CidadeID = new SelectList(db.Cidades, "CidadeID", "Nome", levarEndereco.CidadeID);

     return Json(levarEndereco);
}

DropdownList

 <div class="form-group">
    @Html.LabelFor(model => model.CidadeID, "Estado", htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownList("CidadeID", null, htmlAttributes: new { @class = "form-control", id = "Cidade", })
        @Html.ValidationMessageFor(model => model.CidadeID, "", new { @class = "text-danger" })
    </div>
</div
    
asked by anonymous 19.11.2016 / 03:34

1 answer

1

- Edited to improve response and add code.

In your Json you need to access the function that saves your new city and then return a complete list of all cities, including the new city added.

After that, in Json's 'success' you need to change the 'date' of your select2. With this it creates all the select2 again, so it is necessary to go over the desired options like placeholder, theme and etc ...

Code:

$.post('url do teu método', {post}).success(function(response) {    
    // o método precisa retornar uma lista atualizada das cidades
    // como array dentro do response (response.data)
    // o response == ao return do teu método

    // recebe os dados retornados
    let data = response.data;

    // seta o value do select
    $('seu select').select2({
        placeholder: 'Selecione ...',
        data: data,
        allowClear: 'true',
    });
});

But remember, select2 does not accept an object as a 'date', so if your application returns an object in place of an array, you have to transform it first:

let arrayData = [];
Object.keys(response.data).forEach(id => {
    arrayData.push({
        id: id,
        text: response.data[id],
    });
});

Then in the select2 "date" you pass the arrayData.

However, another not-so-elegant solution if you do not want to or are not familiar with querying the database, simply add the new option with append inside the select and activate a change event in the select.

$('seu select').append($('<option>', {
    value: 'o id da nova cidade',
    text: 'a descrição da nova cidade'
})).trigger('change');
    
14.01.2017 / 06:49