2

In my project I have a modal window where a cascading dropdownlist is shown for two properties (Family, TypeID) of a class (Machine).

The issue: The dependant dropdownlist populates only when the modal window has been open for the second time. On the first time, nothing happens:

Here is a picture of how it works for a better understanding:

enter image description here

Notice that the row that says Modelo (Modelo is the name for TypeID) is empty in the first moment, but once re-opened, it populates with the expected information.

The code:

Note The Javascript is located in the Index page that contains the link to the modal window

This modal window is used when a New Machine is Created, or Edited. For that reason, in the first section of the Javascript, I check in which situation I am and check if the Machine property: MchName, has a value. In case it doesn't have a value, I assign the value of the variable items to the property TypeID that should be shown when the Modal opens.

@section scripts{
<script src="~/js/machine-index.js" asp-append-version="true"></script>


<script type="text/javascript">
    $(document).ready(function () {
        $('#FamilyID').change(function () {
            var url = '@Url.Content("~/")' + "Machines/GetModel";
            var ddlsource = "#FamilyID";
            $.getJSON(url, { FamilyID: $(ddlsource).val() }, function (data) {
                var items = '';
                $("#TypeID").empty();
                $.each(data, function (i, model) {
                    items += "<option value='" + model.value + "'>" + model.text + "</option>";
                });
                $('#TypeID').html(items);
            });
        });
        $('#modal-action-machine').on('shown.bs.modal', function () {
            var test = "#MchName";
            if ($(test).val()) {

            } else {
                var items = "<option value='0'>-- Seleccione Modelo --</option>";
                $('#TypeID').html(items);
            }
        });
    });
</script>
<script type="text/javascript">
    $(function () {
        $('.datepicker').datepicker({
            "autoclose": true,
            format: 'dd/mm/yyyy'
        }).datepicker("setDate", new Date());
    });
</script>
<script src="~/lib/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
}

Get Method:

    [HttpGet]
    public IActionResult CreateEdit(int? id)
    {
        //Lista de Familias
        List<MachineFamily> FamilyList = new List<MachineFamily>();
        FamilyList = (from family in _context.MachineFamilies
                      select family).ToList();
        FamilyList.Insert(0, new MachineFamily { FamilyID = 0, FamilyDescription = "-- Seleccione Familia --" });
        ViewBag.ListofFamily = FamilyList;

        ViewBag.TypeID = string.Empty;
        return PartialView("~/Views/Shared/Machines/_Create.cshtml");
    }

JsonResult:

    public JsonResult GetModel(int FamilyID)
    {
        List<MachineType> ListaModelos = new List<MachineType>();
        ListaModelos = (from model in _context.MachineTypes
                        where model.FamilyID == FamilyID
                        select model).ToList();
        ListaModelos.Insert(0, new MachineType { TypeID = 0, TypeDescription = "-- Seleccione Modelo --" });
        return Json(new SelectList(ListaModelos, "TypeID", "TypeDescription"));
    }

View: Modal

@model Application.Models.ApplicationviewModels.MachineIndexData
@using Application.Models

<form asp-action="CreateEdit" role="form">
    @await Html.PartialAsync("_ModalHeader", new ModalHeader
{ Heading = String.Format("Actualización de Modelo") })

    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="modal-body form-horizontal">
        <input type="hidden" asp-for="Id" />
        <div class="form-group">
            <label asp-for="FamilyID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="FamilyID" class="form-control"
                        asp-items="@(new SelectList(ViewBag.ListofFamily,"FamilyID","FamilyDescription"))"></select>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="TypeID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="TypeID" class="form-control"
                        asp-items="@(new SelectList(ViewBag.TypeID,"TypeID","TypeDescription"))"></select>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="BrandID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="BrandID" class="form-control" asp-items="ViewBag.BrandID">
                    <option value="">-- Seleccione Marca --</option>
                </select>
                <span asp-validation-for="BrandID" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="SupplierID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="SupplierID" class="form-control" asp-items="ViewBag.SupplierID">
                    <option value="">-- Seleccione Proveedor --</option>
                </select>
                <span asp-validation-for="SupplierID" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="StoreID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="StoreID" class="form-control" asp-items="ViewBag.StoreID">
                    <option value="">-- Seleccione Tienda --</option>
                </select>
                <span asp-validation-for="StoreID" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="MchName" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="MchName" class="form-control" />
                <span asp-validation-for="MchName" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="NumDevices" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input id="NumDevices" asp-for="NumDevices" class="form-control" readonly />
                <span asp-validation-for="NumDevices"  class="text-danger"></span>
                <input id="getNum" type="range" min="" max="10" step="1" onchange="fetch()" class="form-control" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="FechaCompra" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input data-format="0:dd/MM/yyyy" type="datetime" asp-for="FechaCompra" class="form-control datepicker" />
                <span asp-validation-for="FechaCompra" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="CostoMaq" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="CostoMaq" class="form-control" />
                <span asp-validation-for="CostoMaq" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="MachineStatus" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select name="MachineStatus" asp-for="MachineStatus" class="form-control" disabled>
                    <option value="0">Operativo</option>
                    <option value="1" selected="selected">Nuevo Item</option>
                    <option value="2">Reparación</option>
                </select>
                <input type="hidden" name="MachineStatus" value="1" />
                <span asp-validation-for="MachineStatus" class="text-danger"></span>
            </div>
        </div>

        @await Html.PartialAsync("_ModalFooter", new ModalFooter { })
    </div>
</form>

Final notes: I believe that to fix this I should change the Javascript. Can someone please explain to me why this happens and how to fix it?

Update: Attempting to assign a new id to the ´MchName´ field and send it to the Script

View:

    <div class="form-group">
        <label asp-for="MchName" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input id="MchName2" asp-for="MchName" class="form-control" />
            <span asp-validation-for="MchName" class="text-danger"></span>
        </div>
    </div>

Script:

        $('#modal-action-machine').on('shown.bs.modal', function () {
            var test = document.getElementById("MchName2").value;
            if (test) {

            } else {
                var items = "<option value='0'>-- Seleccione Modelo --</option>";
                $('#TypeID').html(items);
            }
        });

No luck tho.

Update: Second attempt

View:

    <div class="form-group">
        <label asp-for="MchName" class="col-md-2 control-label"></label>
        <div class="col-md-10" id="MchName2">
            <input asp-for="MchName" class="form-control" />
            <span asp-validation-for="MchName" class="text-danger"></span>
        </div>
    </div>

Script:

        $('#modal-action-machine').on('shown.bs.modal', function () {
            var test = "#MchName2 #MchName";
            if ($(test).val()) {

            } else {
                var items = "<option value='0'>-- Seleccione Modelo --</option>";
                $('#TypeID').html(items);
            }
        });
22
  • On the first shown.bs.modal event, you are defining a change event handler... It does not execute, it just gets defined. Then, there probably is a change event occuring before the next shown.bs.modal... So you see the dropdown. Commented Sep 15, 2017 at 18:42
  • @LouysPatriceBessette That change event is for when the first dropdownlist changes (FamilyID), so the second one updates accordingly. A step prior to that is the script that works on 'shown.bs.modal' that executes when the window opens for the second time. Shouldn't it work on the first time it opens? Commented Sep 15, 2017 at 18:48
  • You should create a CodePen to reproduce that issue. Commented Sep 15, 2017 at 18:53
  • I don't know what is that. Time to google~ Commented Sep 15, 2017 at 18:57
  • @LuisAlbertoDelgadodelaFlo, in my answer i give you some real advices, but your error maybe come from another javascript function. Please post your entire javascript part. Commented Sep 15, 2017 at 19:38

2 Answers 2

2

You should wrap both shown.bs.modal event handlers in one single document.ready function.

Every time when shown.bs.modal event is fired, it will bind a change event handler to your select element. You should bind it only once.

script type="text/javascript">
$(document).ready(function () {
    $('#FamilyID').change(function () {
        var url = '@Url.Content("~/")' + "Machines/GetModel";
        var ddlsource = "#FamilyID";
        $.getJSON(url, { FamilyID: $(ddlsource).val() }, function (data) {
            var items = '';
            $("#TypeID").empty();
            $.each(data, function (i, model) {
                items += "<option value='" + model.value + "'>" + model.text + "</option>";
            });
            $('#TypeID').html(items);
        });
    });
    $('#modal-action-machine').on('shown.bs.modal', function () {
        var test = "#MchName";
        if ($(test).val()) {

        } else {
            var items = "<option value='0'>Select</option>";
            $('#TypeID').html(items);
        }
    });
});

Sign up to request clarification or add additional context in comments.

2 Comments

Your answer is sound, but would you please also consider leveraging the success parameter of the ajax asynchronous call?
@AlexanderDixon, asyncronous method is executed only when he changed the first select element.
0

I have found an answer that works for this specific case.

The first thing that was wrong was evaluate a variable that is not defined inside an ifstatement.

$('#modal-action-machine').on('shown.bs.modal', function () {
    var test = "#MchName";
    if ($(test).val()) {

In this code I was assigning the value of #MchName to testbut in a first moment, #MchName does not get defined until the modal opens for a first time, and for that, not executing the rest of the code.

Second: A turn around was to use click event of the Create button to identify if I'm in a case of a New Machine or just an update.

For this I will declare a global variable and assign it the value of zero. If the Create button is clicked, assign this variable the value of 1, and if this is true, assign the default value that was intended to the #TypeID variable.

After the modal closes, re-asign the global variable to zero. This, for the case that another button (Update) is hitted to call the modal.

This is the code:

var global = this;
var wasclicked = 0;

$(document).ready(function () {

    document.getElementById("modalbutton").onclick = function () {
        global.wasclicked = 1;
    };

    $('#modal-action-machine').on('hidden.bs.modal', function () {
        global.wasclicked = 0;
    });

    $('#modal-action-machine').on('shown.bs.modal', function () {
        if (global.wasclicked == 1) {
            var items = "<option value='0'>-- Seleccione Modelo --</option>";
            $('#TypeID').html(items);
        }

    });

With this, the project works as intended.

Thanks for the help!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.