-1

I have a problem filtering information in a second dropdown, that information should depend on the first selection of the first dropdown, I would like to know how I can filter that information

This is my code:

c# Controller:

 [HttpGet]
        public IActionResult SubTrails()
        {
            try
            {

                var n = _unitOfWork.SubTrails.GetAll().ToList();
                if (n == null)
                {
                    return NoContent();
                }



                return new ObjectResult(n);

            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return StatusCode(StatusCodes.Status500InternalServerError, new { Message = "Internal Server Error" });

            }
        }

        [HttpGet]
        public IActionResult Levels()
        {
            try
            {
                var n = _unitOfWork.Levels.GetAll().ToList();
                if (n == null)
                {
                    return NoContent();
                }



                return new ObjectResult(n);

            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return StatusCode(StatusCodes.Status500InternalServerError, new { Message = "Internal Server Error" });

            }
        }

        [HttpGet]
        public IActionResult Trails()
        {
            try
            {
                var n = _unitOfWork.Trails.GetAll().ToList();
                if (n == null)
                {
                    return NoContent();
                }



                return new ObjectResult(n);

            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return StatusCode(StatusCodes.Status500InternalServerError, new { Message = "Internal Server Error" });

            }
        }

cshtml:

@model DefinityFirst.Mobile.Admin.Web.Services.Marvel.Contracts.ListTrailSubTrailLevelContract
@inject DefinityFirst.Mobile.Admin.Web.Services.Marvel.IMarvelServices DropDownDataHelper

@{
    ViewBag.Title = "Create";
}@if (!ViewData.ModelState.IsValid)
{
    <div class="alert alert-danger alert-dismissible" role="alert">
        <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <strong>Warning!</strong> @Html.ValidationMessage("Error")
    </div>
}
<h2>Create</h2>
<p>New TrailSubTRailLEvel</p>
@using (Html.BeginForm("TrailSubTrailLevel", "TrailSubTrailLevel", FormMethod.Post, new { id = "demoForm" }))
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <h4>Trail</h4>

        <div class="form-group">
            @Html.Label("", "Trail", new { @class = "control-label col-md-2" })
            <div class="col-md-10" id = "partialDiv">
                @*@Html.DropDownListFor(model => model.TrailContract.Responsable.Id, Model.ManagersList, "Select one", new { @class = "form-control" })*@
                @Html.DropDownListFor(model => model.TrailId, await DropDownDataHelper.GetTrailsDdl(), "Select one", new { @class = "form-control", onchange = "SelectedIndexChanged()" })

                @Html.ValidationMessageFor(model => model.TrailId, "", new { @class = "text-danger" })
            </div>
        </div>



            <div class="form-group">
                @Html.Label("", "SubTrail", new { @class = "control-label col-md-2", @name = "Subtrail", @id= "Subtrail" })
                <div class="col-md-10">
                    @*@Html.DropDownListFor(model => model.TrailContract.Responsable.Id, Model.ManagersList, "Select one", new { @class = "form-control" })*@
                    @Html.DropDownListFor(model => model.SubtrailId, await DropDownDataHelper.SubTrailDdl(), "Select one", new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.SubtrailId, "", new { @class = "text-danger" })
                </div>
            </div>

        <div class="form-group">
            @Html.Label("", "Level", new { @class = "control-label col-md-2", @name = "Level", @id = "Level" })
            <div class="col-md-10">
                @*@Html.DropDownListFor(model => model.TrailContract.Responsable.Id, Model.ManagersList, "Select one", new { @class = "form-control" })*@
                @Html.DropDownListFor(model => model.LevelId, await DropDownDataHelper.LevelsDdl(), "Select one", new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.LevelId, "", new { @class = "text-danger" })
            </div>
        </div>





            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-success" />
                </div>
            </div>

</div>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    <script type="text/javascript">

        $('#SubtrailId').hide();
        $('#LevelId').hide();
        $("#Subtrail").hide();
        $("#Level").hide();

        $('#TrailId').on('change', function () {
           // alert("este valor es de trail", this.value)
            if (this.value != 0) {
                $("#Subtrail").show();
                $('#SubtrailId').show();

               alert(this.value)

            } else {
                $('#SubtrailId').hide();
                $('#LevelId').hide();
                // alert("no es diferente ")
            } 
        })
        $('#SubtrailId').on('change', function () {
            //alert("este valor es de subtrail", this.value)
            if (this.value != 0) {

                $("#Level").show();
                $('#LevelId').show();
                //alert(this.value)

            } else {

                $('#LevelId').hide();
                // alert("no es diferente ")
            }
        })

        function SelectedIndexChanged() {
            //Form post  
            //alert("esta validacion jala", this.value)
            document.demoForm.submit();
        }

    </script>
}

But when I enter the view loads all the data only once and when you change options in the dropdown does not reload dataView

A. Rodriguez
  • 13
  • 10
  • Study the code in [this DotNetFiddle](https://dotnetfiddle.net/1bPZym) –  Feb 14 '17 at 21:53
  • Possible duplicate of [Get selected value in dropdown list using JavaScript?](http://stackoverflow.com/questions/1085801/get-selected-value-in-dropdown-list-using-javascript) – Lalith B Feb 14 '17 at 22:15

1 Answers1

1

I have implemented cascading dropdowns in my project using unobtrusive ajax This example is a country list populated on the server (state is also populated if country is already selected). If the country dropdown selection is changed the state list dropdown updates by ajax

CompanyInfoViewModel has these properties (some left out for brevity)

public IList<SelectListItem> AvailableCountries { get; set; }
public string CompanyCountry { get; set; } = string.Empty;
public IList<SelectListItem> AvailableStates { get; set; }
[StringLength(200, ErrorMessage = "State/Region has a maximum length of 200 characters")]
public string CompanyRegion { get; set; } = string.Empty;

In the controller I populate the initial data

var model = new CompanyInfoViewModel();

model.CompanyRegion = selectedSite.CompanyRegion;
model.CompanyCountry = selectedSite.CompanyCountry;

model.AvailableCountries.Add(new SelectListItem { Text = sr["-Please select-"], Value = "" });
var countries = await geoDataManager.GetAllCountries();
var selectedCountryGuid = Guid.Empty;
foreach (var country in countries)
{
    if (country.ISOCode2 == model.CompanyCountry)
    {
        selectedCountryGuid = country.Id;
    }
    model.AvailableCountries.Add(new SelectListItem()
    {
        Text = country.Name,
        Value = country.ISOCode2.ToString()
    });
}

if (selectedCountryGuid != Guid.Empty)
{
    var states = await geoDataManager.GetGeoZonesByCountry(selectedCountryGuid);
    foreach (var state in states)
    {
        model.AvailableStates.Add(new SelectListItem()
        {
            Text = state.Name,
            Value = state.Code
        });
    }
}

Requires jquery unobtrusive ajax This is my custom unobtrusivecascade script:

$(function () {
    var $elems = $('select[data-cascade-childof]');
    if ($elems) {
        $elems.each(function (index, ele) {
            var $parent = $('#' + $(ele).data('cascade-childof'));
            var serviceUrl = $(ele).data('cascade-serviceurl');
            var origVal = $(ele).data('cascade-orig-val');
            var selectLabel = $(ele).data('cascade-select-label');
            var disableOnEmptyParent = $(ele).data('cascade-disableonemptyparent');
            var emptyParentValue = $(ele).data('cascade-parent-emptyvalue');
            $parent.change(function () {
                $.getJSON(serviceUrl + $parent.val(), function (data) {
                    var items = '<option>' + selectLabel + '</option>';
                    $.each(data, function (i, item) {
                        items += "<option value='" + item.value + "'>" + item.text + "</option>";
                    });
                    $(ele).html(items);
                    if (origVal.length > 0) {
                        var found = $(ele).find("option[value=" + origVal + "]").length > 0;
                        if (found) {
                            $(ele).val(origVal);
                        }
                    }
                });
                if (disableOnEmptyParent) {
                    var emptyParent = ($parent.val() === emptyParentValue);
                    if (emptyParent) {
                        $(ele).prop("disabled", true);
                    }
                    else {
                        $(ele).prop("disabled", false);
                    }
                }

            });
        });
    }
});

The markup in the view is like this:

<div class="form-group">
    <label asp-for="CompanyCountry" class="col-md-2 control-label">@sr["Country"]</label>
    <div class="col-md-10">
        <select id="CompanyCountry" asp-for="CompanyCountry"
                asp-items="Model.AvailableCountries" class="form-control"></select>
        <span asp-validation-for="CompanyCountry" class="text-danger"></span>
    </div>
</div>
<div class="form-group">
    <label asp-for="CompanyRegion" class="col-md-2 control-label">@sr["State"]</label>
    <div class="col-md-10">
        <select id="CompanyRegion" class="form-control"
                asp-for="CompanyRegion"
                asp-items="Model.AvailableStates"
                data-cascade-childof="CompanyCountry"
                data-cascade-serviceurl='@Url.Content("~/CoreData/GetStatesJson/?countryCode=")'
                data-cascade-orig-val="@Model.CompanyRegion"
                data-cascade-select-label="-Please select-"></select>
        <span asp-validation-for="CompanyRegion" class="text-danger"></span>
    </div>
</div>

Another controller is used to return the json data for the state list based on the selected country

[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> GetStatesJson(
   string countryCode)
{
    var country = await dataManager.FetchCountry(countryCode);
    List<IGeoZone> states;
    if (country != null)
    {
        states = await dataManager.GetGeoZonesByCountry(country.Id);
    }
    else
    {
        states = new List<IGeoZone>(); //empty list
    }

    var selecteList = new SelectList(states, "Code", "Name");

    return Json(selecteList);

}
Joe Audette
  • 35,330
  • 11
  • 106
  • 99