Flame_Phoenix
Flame_Phoenix

Reputation: 17574

Run javascript in a partial view with MVC5 C# and Razor

I have a small web app in MVC5 and C# using the Razor Engine. In my code, I have a main view, which is a index of a table, with some buttons. When I click one of the buttons a Bootstrap modal appears.

So far so good, but the problem is that I want to perform certain actions when buttons on the modal are clicked, but nothing happens.

This is the main view:

    <div id="editModal"></div>
    <a class="btn btn-default editPackage"t itle="Edit Package"><i class="icon-edit"></i></a>
    <h1>Package List</h1>

    <table class="table" id="packagesTable">
        <!-- Big ass table here :D -->
    </table>

This is how I show the modal, by using jQuery:

 //Show Edit Package modal
    $(".btn.btn-default.editPackage").click(function () {

        $.ajax({
            url: $(this).data('url'),
            type: 'GET',
            cache: false,
            success: function (result) {
                $('#editModal').html(result).find('.modal').modal({
                    show: true
                });
            }
        });
        return false; //prevent browser defualt behavior
    });

So far so good. Everything works fine. The problem comes with the modal ...

This is the modal:

<div class="modal fade in" id="editPackageModal" tabindex="-1" role="dialog" aria-labelledby="editPackages" aria-hidden="true">
    <div class="modal-dialog" style="overflow-y: auto; max-height: 90vh; height: 80vh;">
      <div class="modal-content">
        <div class="modal-header">
          <h4 class="modal-title" id="myModalLabel">Edit Package MyPackage</h4>
        </div>
        <div class="modal-body">
          <form class="form-horizontal">
            <div class="control-group">
              <label class="control-label">Package Name:</label>
              <div class="controls">
                <input type="text" class="form-control" id="package-name" placeholder="MyPackageName">
              </div>
            </div>
            <!-- Other fields here -->
          </form>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary" id="savePackageChangesBtn">Save changes</button>
        </div>
      </div>
    </div>
  </div>

This is teh Javascript I wish to run when a button in the modal is clicked:

$(document).ready(function() {
  $("#savePackageChangesBtn").click(function() {
    $('.modal').modal({
      show: true
    });
    return false; //prevent browser defualt behavior
  });
});

The main view is in a file called "Index.cshtml". The modal view is a file called "_EditModal.cshtml" (because it is a partial view). The javascript code is a file called "custom.js", which is used and runs perfectly fine in the main view.

Why is this not working?

Upvotes: 0

Views: 795

Answers (2)

fly_ua
fly_ua

Reputation: 1054

Either add $("#savePackageChangesBtn").click(function() {}); code after you show modal

e.g.

//Show Edit Package modal
$(".btn.btn-default.editPackage").click(function () {

    $.ajax({
        url: $(this).data('url'),
        type: 'GET',
        cache: false,
        success: function (result) {
            $('#editModal').html(result).find('.modal').modal({
                show: true
            });
            $("#savePackageChangesBtn").click(function () {
                $('.modal').modal({
                    show: true
                });
                return false; //prevent browser defualt behavior
            });
        }
    });
    return false; //prevent browser defualt behavior
});

Or Add the following to your document.ready

$(document).on("click", "#savePackageChangesBtn", doSomething);

This makes your document to listen to elements created after init.

And in doSomething add what you want.

Upvotes: 1

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93561

Your modal is added dynamically, but your $("#savePackageChangesBtn").click(function() is registered at DOM ready time (when the target element does not exists to bind on).

If you added alert($("#savePackageChangesBtn").length); before the click handler it would return 0.

Use a delegated event handler, attached to a non-changing ancestor element.

e.g.

$(document).on('click', "#savePackageChangesBtn", function()

This works by listening for the event to bubble up to a non-changing ancestor, then applies the jQuery selector at event time not event registration time. This means the element only needs to exists when the click occurs.

You would normally choose a non-changing element close to the loaded content, so probably use #editModal instead of document

e.g.

$('#editModal').on('click', "#savePackageChangesBtn", function()

Note: document is the best default if nothing else is convenient, but do not use 'body' as styling can cause it to not respond to bubbled mouse events (e.g. if the calculated height of the body is zero).

Upvotes: 3

Related Questions