Search code examples
javascriptasp.net-corerazor-pagesviewbag

ASP CORE Razor page, variable viewbag filter content with dropdownlist


I have three dropdownlists that I fill with the contents of viewbag variables. I want the content of the second variable to be filtered when I select a value of the first using JQuery or javascript. The same with the third dropdownlist, which is filtered by what is selected in the second.

 <script type="text/javascript">

        function SelectedIndexChanged(accion, idnum) {
            var nuevaSelProyecto = "";
            var proyecto = "";
            var nombre = "";
            switch (idnum) {
                case "ddlSelContrato": {
                    //var getValue = document.getElementById('ddlSelContrato').selectedOptions[0].value;
                    var e = document.getElementById("ddlSelContrato");
                    var getValue = e.options[e.selectedIndex].value;
                    nombre = "Contrato, indice seleccionado: " + getValue;
                };
                    break;
                case "ddlSelProyecto":
                    nombre = "Proyecto";
                    break;
                case "ddlPtoStudio":
                    nombre = "Punto Estudio";
                default:
                    nombre = "Defecto";
                    break;
            }
            alert("Alerta, indice: " + accion + " - " + nombre);
        }

    </script>
    <div>
        <text style="margin-left: 8px;">
            &nbsp   Contrato &nbsp
        </text>
        @*--------------------Listado desplegable de Contrato--------------------------*@
        @Html.DropDownList("ddlSelContrato", new SelectList(ViewBag.SelContrato, "Id", "Nombre"), new { Class = "ddlStyle", onchange = "SelectedIndexChanged(this.value ,id)" })

    </div>

    <div>
        <text style="margin-left: 8px;">
            &nbsp   Proyecto &nbsp
        </text>
        @*--------------------Listado desplegable de Proyecto--------------------------*@
        @Html.DropDownList("ddlSelProyecto", new SelectList(ViewBag.SelProyecto, "Id", "Nombre"), new { Class = "ddlStyle", onchange = "SelectedIndexChanged(this.value ,id)"})
    </div>
    <div>
        <text style="margin-left: 8px;">
            &nbsp   Punto de Medicion &nbsp
        </text>
        @*--------------------Listado desplegable de Puntos de estudio--------------------------*@
        @Html.DropDownList("ddlPtoStudio", new SelectList(ViewBag.PtoStudio, "Id", "Nombre"), new { Class = "ddlStyle", onchange = "SelectedIndexChanged(this.value ,id)" })
    </div>

Controller:

       // GET: PuntoEstudios
    public IActionResult Index()
    {
        ViewBag.SelContrato = _context.Contratos.OrderByDescending(x=>x.Nombre).ToList(); //Variable MVC donde paso a la vista el List de los Contratos
        ViewBag.SelProyecto = _context.Proyectos.ToList(); //Variable MVC donde paso a la vista el List de los Proyectos
        ViewBag.PtoStudio = _context.PuntoEstudios.ToList(); //Variable MVC donde paso a la vista el List de los pto de estudio

        return View();
    }

How can I do it without calling the server


Solution

  • I assume that the relationships between your three models like : Contrato-Proyecto(one-to-many),Proyecto-PtoStudio(one-to-many) . If you want to change the filter the value of dropdownlist without calling the server, you could refer to the below working demo:

    Models

    public class Contact
    {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public ICollection<Product> Products { get; set; }
    
    }
     public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<StudyPoint> StudyPoints { get; set; }
    
        [ForeignKey("Contact")]
    
        public int ContactId { get; set; }
        public Contact Contact { get; set; }
    }
    public class StudyPoint
    {
        public int Id { get; set; }
        public string Name { get; set; }
    
        [ForeignKey("Product")]
        public int ProductId { get; set; }
        public Product Product { get; set; }
    }
    

    Controller , use Include() to load the related data

    public IActionResult CascadeDropdownlist()
        {
            ViewBag.SelContrato = _context.Contact.OrderByDescending(x => x.Name).ToList(); 
            ViewBag.SelProyecto = _context.Product.Include(p=>p.Contact).ToList(); 
            ViewBag.PtoStudio = _context.StudyPoint.Include(s=>s.Product).ToList(); 
    
            return View();
        }
    

    View and the javascript , refer to https://sung.codes/blog/2018/02/24/approximate-equivalent-linq-methods-javascript/ to use linq in javascript

    @{
        ViewData["Title"] = "CascadeDropdownlist";
    }
    
    <h1>CascadeDropdownlist</h1>
    
    
    <div>
        <text style="margin-left: 8px;">
            &nbsp   Contact &nbsp
        </text>
        @*--------------------Listado desplegable de Contrato--------------------------*@
        @Html.DropDownList("ddlSelContrato", new SelectList(ViewBag.SelContrato, "Id", "Name"),"Select value" ,new { Class = "ddlStyle", onchange = "SelectedIndexChanged(this.value ,id)" })
    
    </div>
    
    <div id="">
        <text style="margin-left: 8px;">
            &nbsp   Product &nbsp
        </text>
        @*--------------------Listado desplegable de Proyecto--------------------------*@
        @Html.DropDownList("ddlSelProyecto", new SelectList(ViewBag.SelProyecto, "Id", "Name"),"Select value" , new { Class = "ddlStyle", onchange = "SelectedIndexChanged(this.value ,id)" })
    </div>
    <div>
        <text style="margin-left: 8px;">
            &nbsp   Study point &nbsp
        </text>
        @*--------------------Listado desplegable de Puntos de estudio--------------------------*@
        @Html.DropDownList("ddlPtoStudio", new SelectList(ViewBag.PtoStudio, "Id", "Name"),"Select value" , new { Class = "ddlStyle", onchange = "SelectedIndexChanged(this.value ,id)" })
    </div>
    
    @section Scripts
    {
        <script type="text/javascript">
    
            function SelectedIndexChanged(action, idnum) {
                var nuevaSelProyecto = "";
                var proyecto = "";
                var name = "";
                switch (idnum) {
                    case "ddlSelContrato": {
                        //var getValue = document.getElementById('ddlSelContrato').selectedOptions[0].value;
                        var e = document.getElementById("ddlSelContrato");
                        var array = @Html.Raw(Json.Serialize(ViewBag.SelProyecto));
                        var getValue = e.options[e.selectedIndex].value;
                        var projectdata = array.filter(a => a.contactId == getValue);
                        $("#ddlSelProyecto").empty();
                        $('#ddlSelProyecto').append($("<option value=0>Select value</option>"));
                        projectdata.forEach(function (e) {
                            $('#ddlSelProyecto').append($("<option></option>").attr("value",e.id).text(e.name));
                        });
    
                    };
                        break;
                    case "ddlSelProyecto":
                         {
                        //var getValue = document.getElementById('ddlSelContrato').selectedOptions[0].value;
                        var e = document.getElementById("ddlSelProyecto");
                        var array = @Html.Raw(Json.Serialize(ViewBag.PtoStudio));
                        var getValue = e.options[e.selectedIndex].value;
                        var projectdata = array.filter(a => a.productId == getValue);
                        $("#ddlPtoStudio").empty();
                        $('#ddlPtoStudio').append($("<option value=0>Select value</option>"));
    
                        projectdata.forEach(function (e) {
                            $('#ddlPtoStudio').append($("<option></option>").attr("value",e.id).text(e.name));
                        });
    
                    };
                        break;
                    case "ddlPtoStudio":
                        name = "Punto Estudio";
                    default:
                        name = "Defecto";
                        break;
                }
            }
        </script>
    }
    

    Result enter image description here