How to populate a DropDownList from another DropDownList

7

I need to know how to populate a DropDownList from another DropDownList. Example: I have a DropDownList named Project that takes the information from my DB. When I select for example "Project 1" I need in my second DropDownList to load all Sub Projects belonging to "Project 1". All this information is in DB. I'm not getting popular the second DropDown. I saw what you can do via JavaScript / Json, but I have no idea how to do it. I need some help.

Here I populate my first dropdown

 public ActionResult CadastrarAtividades()
    {
        //Lista que recebe todos os PROJETOS ja cadastrados no banco
        List<Projeto> projetos = new ProjetoNegocio().Get();
        ViewBag.ListaProjeto = new SelectList(projetos.Where(x => x.ProjetoIdPai == null), "ProjetoId", "Nome");

        ViewBag.ListaProjetos2 = projetos;

Here I populate my second dropdown . But here I need the data to be according to what was selected in the first dropdown.

//Lista que recebe todos os SUBPROJETOS ja cadastrados no banco
        List<Projeto> subprojetos = new ProjetoNegocio().Get();
        ViewBag.ListaSubProjeto = new SelectList(subprojetos.Where(x => x.ProjetoIdPai != null), "ProjetoId", "Nome");

View

<div class="panel-body">
                <div class="col-lg-10">
                    @using (Html.BeginForm("CadastrarAtividades", "Apontamento", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                    {
                        @Html.AntiForgeryToken()
                        <br /><br />
                        <table class="table table-bordered table-hover">
                            <div class="form-group">
                                @Html.Label("Projeto")
                                <div>
                                    @Html.DropDownListFor(model => model.ProjetoId, new SelectList(ViewBag.ListaProjeto, "Value", "Text"), "Selecione", new { @class = "form-control" })
                                    @Html.ValidationMessageFor(m => m.ProjetoId, "", new { @class = "text-danger" })
                                </div>
                            </div>
                            <div class="form-group">
                                @Html.Label("Sub Projeto")
                                <div>
                                    @Html.DropDownListFor(model => model.ProjetoId, new SelectList(ViewBag.ListaSubProjeto, "Value", "Text"), "Selecione", new { @class = "form-control" })
                                    @Html.ValidationMessageFor(m => m.ProjetoId, "", new { @class = "text-danger" })
                                </div>
                            </div>
    
asked by anonymous 23.07.2015 / 13:54

2 answers

6

For this answer, I'll assume your project has jQuery and JSON.NET installed (both come by default in an ASP.NET MVC project).

First, isolate the search for a subproject in an Action that returns a JSON:

    public async Task<JsonResult> SelecionarPorProjeto(int id)
    {
        // Tomei uma liberdade poética aqui. Não sei se Get aceita
        // parâmetros, mas a título de exemplo, vamos supor que sim.
        var subprojetos = new ProjetoNegocio().Get(id);
        return Json(subprojetos.Where(x => x.ProjetoIdPai != null).ToList(), JsonRequestBehavior.AllowGet);
    }

Next, open a @section Scripts in your View and put a code that triggers an Ajax request when DropDown of projects is changed:

@section Scripts 
{
    <script>
        $("#ProjetoId").change(function () {
            $.ajax({
                url: "/Subprojetos/SelecionarPorProjeto/" + id,
                success: function (data) {
                    $("#SubprojetoId").empty();
                    $("#SubprojetoId").append('<option value>Selecione...</option>');
                    $.each(data, function (index, element) {
                        $("#SubprojetoId").append('<option value="' + element.ProjetoId + '">' + element.Text + '</option>');
                    });
                }
            });
        });
    </script>
}

This should be enough to solve.

    
23.07.2015 / 16:25
5

I think you're referring to a Cascade DropDownList . Where you select an object in the first and use the value as a parameter to fill the second. Very common in registrations using Country / State / City.

The way I usually do is populate the first DropDownList and use value of the option selected as a search parameter in an Action . This Action returns me a list with the data, at JSON .

To do this, first you create in your controller a method to return to the desired list, like this:

public JsonResult ObterProjetos(int projetoId)
        {
            var projetos = new ProjetoNegocio().Get();//Método para obter os projetos aqui
           //Retorna o valor em JSON
            return Json(projetos, JsonRequestBehavior.AllowGet);
        }

After this, you use this script to call your Action based on the value you selected.

<script type="text/javascript">
    $(document).ready(function () {
        //Coloque aqui o id do primeiro dropdownlist
        $('#ProjetoId').change(function () {
            //obtém o valor selecionado
            var id = $(this).find(":selected").val();
            //Chama a Action para popular o segundo DropDownList
            $.getJSON('/Projeto/ObterSubProjetos', { projetoId: id }, function (data) {
                //Remove os dados que já possui
               //Aqui entra o ID do segundo DropDownList
                $('#ProjetoIdNovo option').remove();
                $('#ProjetoIdNovo').append('<option value="">Selecione uma Cidade</option>');
                //Popula os options com os valores retornados em JSON
                for (var i = 0; i < data.length; i++) {
                    $('#ProjetoIdNovo').append('<option value="' +
                        data[i].ProjetoId + '"> ' +
                        data[i].NomeProjeto + '</option>');
                }
            });
        });
    });
</script>

The above code is responsible for "picking" the selected value in the first DropDownList , using it as a parameter for its controller , and filling the second DropDownList according to the list returned in JSON .

In this part of your code:

<div class="form-group">
   @Html.Label("Projeto")
   <div>
      @Html.DropDownListFor(model => model.ProjetoId, new SelectList(ViewBag.ListaProjeto, "Value", "Text"), "Selecione", new { @class = "form-control" })
      @Html.ValidationMessageFor(m => m.ProjetoId, "", new { @class = "text-danger" })
   </div>
</div>
<div class="form-group">
   @Html.Label("Sub Projeto")
   <div>
      @Html.DropDownListFor(model => model.ProjetoId, new SelectList(ViewBag.ListaSubProjeto, "Value", "Text"), "Selecione", new { @class = "form-control" })
      @Html.ValidationMessageFor(m => m.ProjetoId, "", new { @class = "text-danger" })
   </div>
</div>

You are wanting to save activities (according to your @using (Html.BeginForm("CadastrarAtividades"... ). You have two DropDownList with the same id and name . If you need to save the two data in DataBase , the fields should look different.

    
23.07.2015 / 16:24