0

I have a view that has a partial view with cascading dropdown list.

The Main View:

@model Production.ViewModels.SubmissionVM

@{
    ViewBag.Title = "Create";
}

<h3>Create</h3>

@using (Html.BeginForm("Create", "Submissions", FormMethod.Post, new { id = "SubmissionForm" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Submission</legend>

        <div id="planning" data-link="@(ViewBag.FormLink)">
            <table>
                <thead>
                    <tr>
                        <th>@Html.LabelFor(model => model.PlanningId)</th>
                        <th>@Html.Label("Quality")</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>@Html.DropDownList("PlanningId", (SelectList) ViewBag.Plannings, string.Empty)</td>
                        <td>
                            <select id="Quality">
                                <option></option>
                                <option>Good</option>
                                <option>MRB/Reject</option>
                            </select>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>

        <div id="workorder">
            @Html.Partial("LoadForm");
        </div>
     </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/Scripts/SubmissionScript.js")
}

I have partial view inside <div id="workorder"></div> that load different view depending on the value of dropdowns inside <div id="planning"></div>.

The Partial View:

@model Production.ViewModels.SubmissionVM

<h4>Part Info</h4>

<table id="workorder-table">
    <thead>
        <tr>
            <th>@Html.LabelFor(model => model.WorkorderId)</th>
            <th>@Html.LabelFor(model => model.SubmissionDate)</th>
            <th>@Html.LabelFor(model => model.PartId)</th>
            <th>@Html.LabelFor(model => model.ProductionTypeId)</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>@Html.DisplayFor(model => model.Workorder) @Html.HiddenFor(model => model.WorkorderId)</td>
            <td>@Html.TextBoxFor(model => model.SubmissionDate, "{0:MM/dd/yyyy}", new { @class = "datefield" })</td>

            @if (@ViewBag.Quality == "Good")
            {
                <td>@Html.DisplayFor(model => model.Part) @Html.HiddenFor(model => model.PartId)</td>                    
                <td>@Html.DisplayFor(model => model.ProductionType) @Html.HiddenFor(model => model.ProductionTypeId)</td>
            }
            else
            {
                <td>@Html.DropDownList("PartId", (SelectList)ViewBag.Parts, string.Empty, new { @data_link = (string)@ViewBag.PartLink })</td>
                <td>@Html.DropDownList("ProductionTypeId", (SelectList)ViewBag.ProductionTypes, string.Empty)</td>
            }
        </tr>
    </tbody>
</table>

The JS file:

$(function () {
    $('#PartId').change(function () {
        var partId = $(this).val();
        alert("PartId");

        $('#ProductionTypeId').empty();
        $('#ProductionTypeId').prop('selectedIndex', 0);

        if (partId > 0) {
            url = $('#ProductionTypeId').data('link');

            // AJAX call that re-populate ProductionType dropdown depending on the Part selected.
            $.ajax({
                type: 'POST',
                url: url,
                dataType: 'json',
                data: { partId: partId },
                success: function (codes) {
                    $('#ProductionTypeId').append('<option value=""></option>');
                    $.each(codes, function (i) {
                        $('#ProductionTypeId').append('<option value = "' + codes[i].Value + '">' + codes[i].Text + '</option>');
                    });
                },
                error: function (ex) {
                    $('#ProductionTypeId').append('<option value=""></option>');
                }
            }); // END $.ajax()
        } // END if(partId > 0)
    }); // END $('#Part').change()

    $('#Quality').change(function () {
        LoadForm();
    });

    $('#PlanningId').change(function () {
        LoadForm();
    });

    function LoadForm() {
        var planningId = $('#PlanningId').val();
        var quality = $('#Quality').val();

        if (planningId > 0 && quality != '') {
            var url = $('#planning').data('link');
            var queryString = url + '?planningId=' + planningId + '&quality=' + quality;

            $('#workorder').load(queryString);
            $('#workorder').show();
        }
    }
});

The partial view is rendering correctly. It displays different view depending on the dropdowns. But when I select a Part, the ProductionType does not re-populate. I know it does not execute the JS file because it does not display the alert. I include the JS file (SubmissionScript.js) in the Main View. I tried to also include it in the Partial View but it doesn't do anything.

What am I doing wrong?

adiga
  • 34,372
  • 9
  • 61
  • 83
Eric
  • 3,165
  • 1
  • 19
  • 25
  • 1
    Its not clear from your code if the partial is being loaded dynamically, but if so you need [event delegation](https://learn.jquery.com/events/event-delegation/) - `$('#workorder').on('change', '#PartId', function() { ...` –  Feb 01 '17 at 22:04
  • The Partial View is loaded dynamically on `$('#Quality').change()` and `$('#PlanningId').change()`. The partial view is rendering correctly. The cascading dropdowns inside the partial view are that one that don't work. – Eric Feb 01 '17 at 22:43
  • Which means you need event delegation - change `$('#PartId').change(function () {` to the code in my first comment –  Feb 01 '17 at 22:44
  • I have it in the JS file. It doesn't display the alert, so it is not executing it. – Eric Feb 01 '17 at 22:45
  • It makes no difference if its in an external file. Did you change the code? –  Feb 01 '17 at 22:46
  • I didn't change it. – Eric Feb 01 '17 at 22:47
  • Then change it! (and read the link to understand why you current code does not work) –  Feb 01 '17 at 22:48
  • @StephenMuecke It worked. Thank you. – Eric Feb 01 '17 at 23:02
  • @Eric apart from Stephen's solution the reason why the script doesn't work is the fact that your script reference `@Scripts.Render("~/Scripts/SubmissionScript.js")` is under the `@section Scripts {` block which means this script is placed in your head tag (usually that's where we write the render sections). So the final result of your returned HTML is that you have the script under head tag which means this script is loaded even before your partial views are rendered in the DOM. Hence your current jquery selector doesnt work but event delegation works. – Rajshekar Reddy Feb 02 '17 at 06:12
  • **Other options** move the `js` file out of the `@section Scripts {` block. – Rajshekar Reddy Feb 02 '17 at 06:12

0 Answers0