I have a partial view with an ajax form
@using (Ajax.BeginForm("SaveSettings", "Config", new AjaxOptions
{
HttpMethod = "Post",
OnSuccess="settingsUpdateSucces"
}, new { enctype = "multipart/form-data", id = "SaveSettings" }))
{
@Html.HiddenFor(m => m.Id)
//other fields go here
<button id="btnSaveSettings" type="submit" >Save Settings</button>
}
This partial view and the form works in one scenario but not the other.
Let me explain both scenarios
- Scenario 1: The partial page is rendered using "Html.Partial" in an asp.net page
relevant parts of the page
@{
ViewBag.Title = "Edit";
Layout = "~/Layout/V1.cshtml";
}
<!--other non-relevant markup and code here-->
<div>
<h3>Settings</h3>
@Html.Partial("_Settings")
</div>
In this scenario the ajax form works without any problems and the page is not redirected. This code has been running for over 6 months and no issues whatsoever.
- Scenario 2
Now, I am trying to get the same partial to work on another new page.
This is a new page - which works like a wizard.
So, in one of the steps a partial page is added (using Html.Partial). This page has a dropdown, when selected, another partial page is rendered via ajax. One of the selection loads the above mentioned "_Settings" partial page using this code
function loadPartial(id) {
$.get('/Config/_Settings?sid=' id, function (data) {
$('#partialSettingsPlaceHolder').html(data);
});
}
The partial page and form is loaded fine, but when I submit a redirect happens and the JSON returned by the ajax form is shown.
I am unable to understand why this is happening in scenario 2.
PS:
I already searched for similar issues and the answers mention that this happens when the required js files - jquery, "jquery.validate.unobtrusive.min.js", "jquery.unobtrusive-ajax.js" - are not referenced and downloaded. Please note that in both scenarios, jquery, "jquery.validate.unobtrusive.min.js", "jquery.unobtrusive-ajax.js" are referenced and downloaded in the main page - ie the page containing the partial page.
CodePudding user response:
I think your issue could caused by submitting handler function for ajax form only binding at page loaded or document ready event of page which contain ajax form. Since your partial page is adding dynamic via ajax, so the dynamic added ajax form will be full submitted as a normal form.
You could try below work-around solution.
Manually adding submitting event handler function for newly added form, then inside this handler function, we do submitting via ajax instead of full submit.
function loadPartial(id) {
$.get('/Config/_Settings?sid=' id, function (data) {
var placeholder = $('#partialSettingsPlaceHolder');
placeholder.html(data);
$('form', placeholder).on('submit', submitHandler);
});
}
function submitHandler(event) {
event.preventDefault();
event.stopImmediatePropagation();
// validation code here depend on validation plugin you are using, for example:
// if (!$(this).valid()) return false;
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize()
}).done(function (data) {
// your code in case of success
}).fail(function (jqXHR, textStatus) {
// your code in case of fail
});
return false;
}
Of course, this is just a work-around solution. If you want to do it in more formal way, I suggest you to study auto generated source code for ajax form and aspx page (for example using Developer Tool of browsers).
CodePudding user response:
The reason why your second scenario is not working is that you are loading and adding your form dynamically to our page after the initial page load.
if you will take a look on jquery unobtrusive ajax code you will find that section which is doing few calls like $(document).on(...)
. That is basically adding listeners directly to html elements like form
or input
right after page is ready. But because of that those click
events are not being attached to elements which will be appended to page later. Unfortunarelly I cannot see in that script any possibility to reinitialise it. So maybe your only option might be to create script which can be called after adding your form and will do the same steps as the original version. That way ajax behaviour should remain the same.
Another option might be to render the form without ajax but hide it with css? That is very dependent on your page styling etc. That way event listeners will get applied and you could then only show the form instead of appending it as a fresh node