3

I have an edit partial view to load in a dialog, which works the first time it's called, the edit then saves the data, great.

However if you don't refresh the page, which I don't want to have to do, and click 'edit' again, you are redirected to the partial page I am trying to load.

It looks like the AJAX is being ignored and the Action method in the controller is being called instead.

I have unobtrusive added through the bundles in my layout page, which the main view uses, the partial doesn't, but I don't believe it needs to.

I have also tried using preventDefault and different approached of return false; with no success, like the below:

editBtn.click(function (e) {
            editDialogPlaceholder.load(this.href, function () {
                e.preventDefault(); //tried
                $(this).dialog('open');
                return false; //tried
            })
        return false;
    });

How can I stop this?

AJAX/JS

$(function () {
        var editBtn = $('.editLink');
        var editDialogPlaceholder = $('#editDialogUI');

        editBtn.button();
        // build the dialog form
        editDialogPlaceholder.dialog({
            autoOpen: false,
            modal: true,
            resizable: false,
            open: function (event, ui) {
                $(this).load('@Url.Action("Edit","Announcements")');
            },
            buttons: {
                "Save": function () {
                    saveAnnouncement();
                    fetchList();
                    $(this).dialog("close");
                },
                "Close": function () {
                    $(this).dialog("close");
                }
            }
        });
        // on click load the dialog form, return false to stop redirect
        editBtn.click(function () {
            editDialogPlaceholder.load(this.href, function () {
                $(this).dialog('open');
            })
            return false;
        });
    });
    //post data back to the controller to save to the db
    function saveAnnouncement() {
        $.ajax({
            url: '@Url.Action("Edit","Announcements")',
                type: 'POST',
                data: $('form').serialize()
            })
        }

        function fetchList() {
            var aList = $('#announcementList');
            aList.load('@Url.Action("Fetch")');
        }

Edit action method

[HttpGet]
        public ActionResult Edit(int id)
        {
                var announcementModel = (from a in db.DbAnnouncement
                           where a.Id == id
                           select a).SingleOrDefault();
                return PartialView("Edit", announcementModel);
        }

Html.ActionLinks being used to open the dialog - second time of clicking it redirects to the partial specified in the controller.

<div class="announcementTableCell">
                    @Html.ActionLink("Edit", "Edit", new { id = Model[i].Id }, new { @class = "editLink" })

                    @Html.ActionLink("Delete", "Delete", new { Model[i].Id }, new { @class = "dltLink" })
                </div>
PurpleSmurph
  • 2,055
  • 3
  • 32
  • 52
  • After you do the first AJAX call is the `.editLink` element replaced with a new copy? – Jasen Feb 10 '16 at 17:24
  • Ah, that could be it, that's the other thing I need to get the partial holding all the items in the list (where the editLink class btns are) to refresh through without full page reload - was going to sort that after. I attempted to do it with my fetchList() function. – PurpleSmurph Feb 10 '16 at 17:26
  • Then you'll need to bind the click event to a static parent. http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – Jasen Feb 10 '16 at 17:27
  • If I get the partial refresh working I won't need to bind it to a static element though, right? – PurpleSmurph Feb 10 '16 at 17:28
  • 1
    As long as you never replace the original link. But if you use a delegate like in that answer it's really not much more code. – Jasen Feb 10 '16 at 17:30
  • OK - thank you - quick try didn't work using `.on` - `editBtn.on("click", editBtn, function () { editDialogPlaceholder.load(this.href, function () { $(this).dialog('open'); }) return false; });` – PurpleSmurph Feb 10 '16 at 17:35
  • You're button click event is only getting called once. You're `@html.ActionLink("Edit")` is what is getting fired off the second time... – wahwahwah Feb 10 '16 at 17:35
  • 1
    it should be `$(document).on('click', '.editBtn', fuction(){ //..load stuff..// });` where `$(document)` could be any static parent element to `.editBtn`. – wahwahwah Feb 10 '16 at 17:38
  • 1
    You are still binding to the dynamic target `editBtn.on()`. It would be `$("parent_selector").on("click", ".editLink", function(e) { e.preventDefault(); }` – Jasen Feb 10 '16 at 17:39
  • Okay - thank you both for your help and explanations. =) – PurpleSmurph Feb 10 '16 at 17:41

1 Answers1

0

Solution as proposed in comments was to use jQuery.fn.on for the click button as the page wasn't being refreshed at the time, so binding to a static element that wasn't being refreshed meant that the action method was being called and as such redirecting to the partial view.

Therefore the working button click code:

$('#announcementList').on("click", ".editLink", function () {
            editDialogPlaceholder.load(this.href, function () {
                $(this).dialog('open');
            })
            return false;
        });
PurpleSmurph
  • 2,055
  • 3
  • 32
  • 52