MVC4 Ajax.BeginForm not replacing UpdateTargetId
Asked Answered
L

12

14

There are so many topics on SO about issues with the Ajax.BeginForm not correctly updating the target element with the return partial view:
mvc4 ajax updating same page
ASP.NET MVC 4 - Ajax.BeginForm and html5
MVC 4 (razor) - Controller is returning a partialview but entire page is being updated
MVC 4 Ajax is not updating the PartialView within the page
However, all of these are answered by either manually writing out the jQuery ajax, or including a missing javascript file.

  @using (Ajax.BeginForm("PostcardDetails", new AjaxOptions()
  {
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "details"
  }))
  {
    <div id="PostcardSearchResults">
      @{Html.RenderAction("PostcardSearchResults", Model);}
    </div>
  }
  <div id="details">
  </div>

Relevant controller code:

[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Get)]
public ActionResult PostcardSearchResults(PostcardSearchFilter filter)
{
        PostcardSearchResults model = new PostcardSearchResults(filter);
        return PartialView("_PostcardSearchResults", model);
}

In my layout, I am referencing these jQuery files. Additionally, I've verified that the page is outputting the proper path, and that it finds the correct files. I've tried switching the ordering of unobtrusive-ajax.min.js and validate.min.js, to no success.

<script type="text/javascript" src="@Url.Content("~/Scripts/globalize.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.9.1.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-ui-1.10.0.custom.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>

Additionally, in my website's root web.config, and the web.config in my View folder, I have included:

<add key="webpages:Version" value="2.0.0.0"/>
<add key="PreserveLoginUrl" value="true"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

I'm at a loss for where else to look. There are no javascript errors being thrown, and the controller is being properly hit, returning a PartialViewResult. The Form element in the HTML is populating all the correct data- attributes.

Lovell answered 26/2, 2013 at 17:50 Comment(0)
S
13

There is a problem with jquery.unobtrusive-ajax.min and JQuery 1.9 because JQuery 1.9 doesn't support the live() method any more. So you should use the JQuery migrate plug-in, and reference the JQuery migrate js.

Strunk answered 26/2, 2013 at 17:57 Comment(8)
A bit confused, what does it have to do with OP issue ? Are you saying .live is what Ajax.Beginform uses under the hood ?Washbowl
Forgot to mention that I'd already updated my `jquery.unobtrusive-ajax.min.js' with the suggestions from this post: https://mcmap.net/q/403161/-unobtrusive-ajax-stopped-working-after-update-jquery-to-1-9-0 If I hadn't, I would be getting javascript errors. I also tried using the jquery-migrate.Lovell
Yeah Ajax Beginform uses live under the hoodStrunk
The controller is being called correctly? and what you got when you got the return?Strunk
I've added the code for the action in the Controller. It returns the PartialView, rendered correctly, but the browser replaces the entire page with the table, as opposed to placing it in the #details div.Lovell
You are using MVC4 so you don't need to put the @Url.Content("~/Scripts/globalize.js") use just "~/Scripts/globalize.js" the scenario that you describe usually happen when the scripts are not referenced correctlyStrunk
I ended up rolling my jquery.unobtrusive-ajax.min.js back to the original file (which takes it back to using the live() method, and including the jQuery migrate plug-in. This solved the issue.Lovell
This solved my issue!!! Wish I read it 5 hours before banging my head on my desk!.. Thanks Gabriel.Rhyme
S
5

Make sure you include the unobtrusive-ajax.js to the page, which you have placed your ajax form.

<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
Stable answered 9/11, 2014 at 16:20 Comment(0)
J
2

I had this problem, I just installed the latest unobtrusive package from NuGet and solved the problem

PM> Install-Package Microsoft.jQuery.Unobtrusive.Ajax

Will need JQ 1.8+

Junna answered 27/4, 2014 at 20:42 Comment(0)
H
2

I don't know if anyone else will run into this, but in my case, it only appeared to not be updating. I was building an simple edit form where you select the item you wish to edit from a dropdown, click a button, and it AJAX loads an edit form for the selected item.

It worked the first time, but after changing my selection in the drop down list, and clicking the button, none of the form values changed, even though I verified my server-side code was loading the new item into the view model. So it appeared Replace was not working. After stepping through jquery.unobtrisive-ajax.js, I found that it was replacing the contents of my target element, just with the same view markup it already had, which did not match the model that was passed to the view!

That's when I realized, it was the ModelState that was getting me. The second time I clicked the load button, it submitted my dropdown selection but also my filled out edit form. All of the values in the edit form were added to ModelState (as you would expect). My controller code then replaced the submitted view model (that the model binder created from the edit form values) with the view model for the selected drop down value and passed it to the partial view. However, the partial view uses a bunch of the Html.[X]For helper methods. These ignore the updated view model and pull their values directly from the ModelState. For example:

@Html.DisplayFor(m => m.Name)
@Model.Name

would display two different values for Name; the former displaying the submitted Name and the latter, the updated Name. This is the mechanism that lets MVC remember your user's form entries after a (server-side) validation error. In this case, because this is a partial page load and I'm just throwing out all of the submitted values, I don't need any of the ModelState values so I just call ModelState.Clear() before returning my view for the updated view model.

    public ActionResult GetItemEditForm(EditItemsViewModel editItemsVM)
    {
        if (editItemsVM.SelectedItemID != null)
        {
            //Load the selected item
            ItemsModelManager.GetEditItemsVM(editItemsVM);

            //Clear the submitted form values
            ModelState.Clear();
        }

        return PartialView("_ItemsEditor", editItemsVM);
    }
Hilltop answered 23/9, 2015 at 21:47 Comment(1)
Thanks fren. Your answer made me look back at the code again to realize the previous dev was returning Content(singleProperty) instead of a PartialView(model) which is what my updated markup expected.Schwinn
A
1

I was having similar problems to you - I had all my scripts bundled and loading correctly, and had all code implemented correctly. I checked package manager to see if any scripts needed to be updated and jQuery and jquery.unobtrusive-ajax did. jQuery went from 1.9 to 1.9.1. When I rebuilt my solution the target DIV was updated successfully. Try and update all JS in your solution, it may work.

Among answered 3/3, 2013 at 15:33 Comment(0)
P
1

The following needs to be on any page that uses ajax.

@section Script {
    @Scripts.Render("~/bundles/jqueryval")
}
Pincers answered 20/11, 2013 at 23:20 Comment(0)
S
1

Wow, there are a lot of answers here. My problem was due to a bootstrap panel. It was creating a "nested" panel. I removed the panel markup and just used a plain old div and it worked. I think the UpdateTargetId has to be a direct parent of the AJAX form.

Here is the html illustrating the problem.

<div class="panel panel-default" id="notes-form">
  <div class="panel-body">
    @using (Ajax.BeginForm("EditNote", new { id = Model.Id }, new AjaxOptions { UpdateTargetId = "notes-form" }, htmlAttributes: new { @class = "form-horizontal" }))
    {
    }
  </div>
</div>
Sunstone answered 12/8, 2016 at 19:7 Comment(0)
C
0

For those that need a bit more explanation....

Type this in Package Manager Console PM> Install-Package jQuery.Migrate

Reference this in your partialview:

script src="~/Scripts/jquery.unobtrusive-ajax.js">

Happy coding everyone.

Carrasco answered 4/3, 2015 at 21:33 Comment(0)
M
0

User xr280xr's answer for including

ModelState.Clear();

worked for me. The app I'm working with is on an older jQ (1.7.x) so migrate wouldn't work in our situation. Clearing the model state in the controller did exactly what we expected BeginForm to do.

Monomania answered 10/11, 2015 at 20:13 Comment(0)
D
0

Check The Master Page OR Your Page's Scripts Reference about jquery.unobtrusive-ajax.js if not add Reference about this js :jquery.unobtrusive-ajax.js

Debunk answered 13/1, 2016 at 6:18 Comment(2)
add what? This is an incomplete answer.Buckden
Reference about this: jquery.unobtrusive-ajax.jsDebunk
B
0

The live() method was deprecated in jQuery version 1.7, and removed in version 1.9. Use the on() method instead.For more info refer: http://www.w3schools.com/jquery/event_live.asp

Begun answered 17/6, 2016 at 11:8 Comment(0)
W
0

First, install 'Microsoft.JQuery.Unobtrusive.Ajax' from NuGet Manager and later include "~/Scripts/jquery.unobtrusive" in "BundleConfig" after including "jquery-{version}.js"; which will look something similar to this:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                "~/Scripts/jquery-{version}.js",
                "~/Scripts/jquery.unobtrusive*));
Wareing answered 22/12, 2016 at 7:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.