The ASP MVC jquery function does not work in partial view but works in main view

advertisements

I have a main view with search criteria. Main view contains a partial view with an html table. The search results are loaded via ajax.

Now i am trying to implement edit, create and delete via bootstrap modal. So in the partial view on table row button click event i added a function to open the modal like this

<button class="btn btn-outline btn-primary" data-toggle="tooltip" title="Location Details" type="button" onclick="ShowModal();">
    <i class="fa fa-fw fa-info"></i>
</button>

<script type="text/javascript">
    function ShowModal() {
        $('#myModal').modal('show');
        //return false;
    }
</script>

This function does not work if placed in the partial view. However, once i place the same function inside my main view, the modal opens properly.

Why does this happen?

The reason why i wanted to have the script inside my partial view, is because i wanted to keep my client side code together so it is easier to understand and maintain.

Edit

The following is my main view together with related scripts:

@model MVC_Replica.Models.LocationSearchViewModel

@using (Html.BeginForm("index", "Locations", FormMethod.Get)){
<div id="page-wrapper">
    <div class="row">
        <div class="col-lg-12">
            <div id="">
                <h1 class="page-header" id="lblDboard">Location List</h1>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="panel panel-primary">
            <div class="panel-body">
                <div class="form-horizontal">
                    <div class="form-group">
                        <div class="col-md-3">
                            @Html.TextBoxFor(m => m.LocationSearch.LocationName, new { @class = "form-control", @placeholder = "Location Name", @name = "locationName" })
                        </div>
                    </div>
                </div>
            </div>
            <div class="panel-footer clearfix">
                <input type="button" id="cmdSearch" class="btn btn-primary" value="Search" />
            </div>
        </div>
    </div>
    <div class="row" id="locationGrid">
        @Html.Partial("_LocationGrid")
    </div>
</div>
}

An the scripts

<script type="text/javascript">
    $(function () {
        $('[data-toggle=tooltip]').tooltip();
        $('#cmdSearch').click(function () {
            var locationName = $('#LocationSearch_LocationName').val();

            $('#locationGrid').block({ message: '<img src="../media/ajax-loading.gif"/>' });

            setTimeout(SearchLocations, 2000);

            function SearchLocations() {
                $.ajax({
                    url: "/Locations/SearchLocations",
                    type: "POST",
                    data: { 'locationName': locationName },
                    dataType: "html",
                    success: function (response) {
                        $('#locationGrid').empty();
                        $('#locationGrid').html(response);

                        $('[data-toggle=tooltip]').tooltip();
                    },
                    error: function (xmlHttpRequest, errorText, thrownError) {
                        alert(xmlHttpRequest + '|' + errorText + '|' + thrownError);
                    }
                });
            }
        });
    });
</script>    <!--Search Locations AJAX-->

Partial View HTML

@model MVC_Replica.Models.LocationSearchViewModel
@{
    IEnumerable<MVC_Replica.Models.Location> location = Model.LocationList;
    Layout = null;
}
<div class="table-responsive">
    <table class="table table-responsive table-condensed table-bordered table-striped">
        <tr>
            <th>
                <button class="btn btn-outline btn-success" data-toggle="tooltip" title="Create New Location" data-placement="bottom"
                        onclick="location.href='@Url.Action("Create", "Locations")';return false;">
                    <i class="fa fa-fw fa-plus"></i>&nbsp; Create
                </button>
            </th>
            <th>
                Location Name
            </th>
            <th>
                Date Created
            </th>
            <th>
                Location State
            </th>

        </tr>

        @foreach (var item in location)
        {
            <tr>
                <td>
                    <button class="btn btn-outline btn-primary" data-toggle="tooltip" title="Edit Location"
                            onclick="location.href='@Url.Action("Edit", "Locations", new  { id=item.LocationId})';return false;">
                        <i class="fa fa-fw fa-pencil"></i>
                    </button>
                    <button class="btn btn-outline btn-primary" data-toggle="tooltip" title="Location Details" type="button"
                            onclick="ShowModal();">
                        <i class="fa fa-fw fa-info"></i>
                    </button>
                    <button class="btn btn-outline btn-danger" data-toggle="tooltip" title="Delete Location"
                            onclick="location.href='@Url.Action("Delete", "Locations", new  { id=item.LocationId})';return false;">
                        <i class="fa fa-fw fa-remove"></i>
                    </button>
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.LocationName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.DateCreated)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.LocationState)
                </td>
            </tr>
        }

    </table>

</div>
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
    <div class="modal-dialog">

        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Modal Header</h4>
            </div>
            <div class="modal-body">

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>

    </div>
</div>


This line of yours in the partial page....

 <button class="btn btn-outline btn-primary" data-toggle="tooltip" title="Location Details" type="button"
                        onclick="ShowModal();">

So when you do a $('#locationGrid').html(response);in your ajax call the page is added into the DOM and triggers a document ready event if any in your partial page scripts,So when the HTML is added to the DOM it starts to parse from top, while the HTML is being parsed the above line is hit and it tries to find a function with name ShowModal but it isn't loaded yet into the DOM. So you can either place your script in the beginning of your partial page so that the script tag is parsed prior to coming to this line and function is available. OR you can remove the onclick from the button tag and register the button click event in document ready function. That way you don't have to worry about the position where the script is placed.

Let me know if this resolved your issue.