javascriptajaxasp.net-mvc

Execute Script on Partial View


I have the following script in my Main View which works great to create cascading dropdownlists. However, I cannot get it to execute on the partial view after it is loaded. From what I have read online, it seems that I need some sort of Ajax call in the partial view (which I am completely clueless on how to write). Any Assistance would be greatly appreciated.

<script type="text/javascript">
    $(function () {
        $("#SelectedCollateralClass").change(function () {
            var selectedItem = $(this).val();
            var ddlTypes = $("#SelectedCollateralType");
            var typesProgress = $("#types-loading-progress");
            typesProgress.show();
            $.ajax({
                cache: false,
                type: "GET",
                url: "@(Url.RouteUrl("GetCollateralTypesByClass"))",
                data: { "CollateralClassId": selectedItem },
                success: function (data) {
                    ddlTypes.html('');
                    $.each(data, function (id, option) {
                        ddlTypes.append($('<option></option>').val(option.id).html(option.name));
                    });
                    typesProgress.hide();
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert('Failed to retrieve types.');
                    typesProgress.hide();
                }
            });
        });
    });
</script>

My Main View is:

@model CollateralRowViewModel

<div class="APPLICATION">

    @*@Html.Partial("_SideBarView.cshtml");
    @Html.Partial("_CommentsView.cshtml");*@

    <!-- Content ======================================================================================-->

    <div class="container row">
        @using (@Html.BeginForm())
        {
            <div class="col-xs-16">
                <div class="hr">
                    <h3 class="inline-block"> Collateral</h3>
                    <a class="icon-add"></a>
                </div>
                <table class="dataentry">
                    <thead>
                        <tr>
                            <th>@Html.LabelFor(model => model.CollateralClass)</th>
                            <th>@Html.LabelFor(model => model.CollateralType)</th>
                            <th>@Html.LabelFor(model => model.Description)</th>
                            <th>@Html.LabelFor(model => model.MarketValue)</th>
                            <th>@Html.LabelFor(model => model.PriorLiens)</th>
                            <th>@Html.LabelFor(model => model.AdvanceRate)</th>
                            <th>@Html.Label("Grantor (if not Borrower)")</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>
                                <span class="inputROW">
                                    @Html.DropDownListFor(model => model.SelectedCollateralClass, Model.CollateralClass)
                                </span>
                            </td>
                            <td>
                                <span class="inputROW">
                                    @Html.DropDownListFor(model=>model.SelectedCollateralType, Model.CollateralType)
                                </span>
                            </td>
                            <td>
                                <span class="inputROW">
                                    @Html.TextBoxFor(model => model.Description)
                                </span>
                            </td>
                            <td>
                                <span class="inputROW">
                                    @Html.TextBoxFor(model => model.MarketValue)
                                </span>
                            </td>
                            <td>
                                <span class="inputROW">
                                    @Html.TextBoxFor(model => model.PriorLiens)
                                </span>
                            </td>
                            <td>
                                <span class="inputROW">
                                    @Html.TextBoxFor(model => model.AdvanceRate)
                                </span>
                            </td>
                            <td>
                                <span class="inputROW Smargin_bottom">
                                    @Html.TextBoxFor(model => model.GrantorFirstName)
                                </span>
                                <span class="inputROW">
                                    @Html.TextBoxFor(model => model.GrantorMiddleName)
                                </span>
                                <span class="inputROW">
                                    @Html.TextBoxFor(model => model.GrantorLastName)
                                </span>
                            </td>
                            <td class="minusRow">
                                <a class="btn btn-danger icon-subtract sm btn-xs" data-nodrag ng-click="remove(this)"></a>
                            </td>
                        </tr>

                    </tbody>

                </table>
                <div>
                    <input id="addBtn" type="button" value="Add New Collateral" />
                </div>
            </div>
        }
    </div> <!-- end container -->


    <footer id="APPfooter">
        <div class="pagination centerF">
            <ul>
                <li class="previous"><a href="#" class="icon-arrow-01"></a></li>
                <li class="next"><a href="#" class="icon-arrow-01"></a></li>
            </ul>
        </div>
    </footer>

</div><!-- end page content container-->


<script type="text/javascript" charset="utf-8">
        $(function () {
            $('.default').dropkick();
            $( "#datepicker" ).datepicker();
        });
</script>
<script>
    $("#addBtn").on("click", function () {

        $.get('@Url.Action("AddNewRow")', function (data) {
            $("table").append(data);
        });

    });
</script>

<script type="text/javascript">
    $(document).ready(
    $(function () {
        $("#SelectedCollateralClass").change(function () {
            var selectedItem = $(this).val();
            var ddlTypes = $("#SelectedCollateralType");
            var typesProgress = $("#types-loading-progress");
            typesProgress.show();
            $.ajax({
                cache: false,
                type: "GET",
                url: "@(Url.RouteUrl("GetCollateralTypesByClass"))",
                data: { "CollateralClassId": selectedItem },
                success: function (data) {
                    ddlTypes.html('');
                    $.each(data, function (id, option) {
                        ddlTypes.append($('<option></option>').val(option.id).html(option.name));
                    });
                    typesProgress.hide();
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert('Failed to retrieve types.');
                    typesProgress.hide();
                }
            });
        });
    }));
</script>

My partial looks like:

@model CollateralRowViewModel

                <tr>
                    <td>
                        <span class="inputROW">
                            @Html.DropDownListFor(model=>model.SelectedCollateralClass, Model.CollateralClass)
                        </span>
                    </td>
                    <td>
                        <span class="inputROW">
                           @Html.DropDownListFor(model=>model.SelectedCollateralType, Model.CollateralType)
                        </span>
                    </td>
                    <td>
                        <span class="inputROW">
                            @Html.TextBoxFor(model=>model.Description)
                        </span>
                    </td>
                    <td>
                        <span class="inputROW">
                            @Html.TextBoxFor(model=>model.MarketValue)
                        </span>
                    </td>
                    <td>
                        <span class="inputROW">
                            @Html.TextBoxFor(model=>model.PriorLiens)
                        </span>
                    </td>
                    <td>
                        <span class="inputROW">
                            @Html.TextBoxFor(model=>model.AdvanceRate)
                        </span>
                    </td>
                    <td>
                        <span class="inputROW Smargin_bottom">
                            @Html.TextBoxFor(model=>model.GrantorFirstName)
                        </span>
                        <span class="inputROW">
                            @Html.TextBoxFor(model=>model.GrantorMiddleName)
                        </span>
                        <span class="inputROW">
                            @Html.TextBoxFor(model=>model.GrantorLastName)
                        </span>
                    </td>
                    <td class="minusRow">
                        <a class="btn btn-danger icon-subtract sm btn-xs" data-nodrag ng-click="remove(this)"></a>
                    </td>
                </tr>

The Controller Action is:

 [AcceptVerbs(HttpVerbs.Get)]
    public async Task<ActionResult> GetCollateralTypesByClass(Guid collateralClassId)
    {
        var collateralServiceProxy = base.ServiceProvider.CollateralServiceProxy;
        var collateralTypes = await collateralServiceProxy.GetCollateralTypesByCollateralClassIdAsync(collateralClassId);

        var selectCollateraltypes = (from t in collateralTypes
                                     select new
                                     {
                                         id = t.Id.ToString(),
                                         name = t.Name
                                     }).ToList();

        return Json(selectCollateraltypes, JsonRequestBehavior.AllowGet);
    }

The Partial is being called by a button "Add New" as follows:

<script>
    $("#addBtn").on("click", function () {

        $.get('@Url.Action("AddNewRow")', function (data) {
            $("table").append(data);
        });

    });
</script>

The Controller for the button is :

[HttpGet]
[Route("CreateRow")]
public async Task<ActionResult> AddNewRow()
{
    var collateralClasses = await GetCollateralClasses();
    var collateralTypes = await GetCollateralTypes();

    var model = new CollateralRowViewModel();

    model.CollateralClass.Add(new SelectListItem { Text = "-Please Select-", Value = "-1" });
    foreach (var _class in collateralClasses)
    {
        model.CollateralClass.Add(new SelectListItem()
        {
            Value = _class.Value.ToString(),
            Text = _class.Text.ToString()
        });
    }

    model.CollateralType.Add(new SelectListItem { Text = "-Please Select-", Value = "-1" });
    foreach (var type in collateralTypes)
    {
        model.CollateralType.Add(new SelectListItem()
        {
            Value = type.Value.ToString(),
            Text = type.Text.ToString()
        });
    }
    return PartialView("_newCollateralRow", model);
}

Solution

  • I got the answer. All I needed to do was to add new{@class = "ddlClass'} and new {@class = "ddlType"} to the Partial. Then I just copied the script to the Partial and changed the references from referencing the Id to referencing the new classes as below:

    <script type="text/javascript">
    
        $(function () {
            $(".ddlClass").change(function () {
                var selectedItem = $(this).val();
                var ddlTypes = $(".ddlType");
                var typesProgress = $("#types-loading-progress");
                typesProgress.show();
                $.ajax({
                    cache: false,
                    type: "GET",
                    url: "@(Url.RouteUrl("GetCollateralTypesByClass"))",
                    data: { "CollateralClassId": selectedItem },
                    success: function (data) {
                        ddlTypes.html('');
                        $.each(data, function (id, option) {
                            ddlTypes.append($('<option></option>').val(option.id).html(option.name));
                        });
                        typesProgress.hide();
                    },
                    error: function (xhr, ajaxOptions, thrownError) {
                        alert('Failed to retrieve types.');
                        typesProgress.hide();
                    }
                });
            });
        });
    </script>
    

    I hope this helps someone else!