ASP.NET MVC - AJAX Submit Form does not fire appropriate event - javascript

In my personDetails.cshmtl file, I have the following form:
<form id="userUpdateForm" method="post">
<fieldset>
<legend>User Details</legend>
<input type="checkbox" name="authorisedCheckbox" value="Authorised" id="authCheck" />Authorised<br />
<input type="checkbox" name="enabledCheckbox" value="Enabled" id="eCheck" />Enabled<br />
</fieldset>
<fieldset>
<input type="hidden" name="personId" id="idCheck" value='#ViewData["personId"]'>
</fieldset>
<input type="submit" value="Save Changes" name="Save Changes">
<button type="button">Cancel</button>
</form>
I then have Javascript further down the page as follows:
$('#userUpdateForm').submit(function (e) {
var personDetails = {
Enabled: $('#eCheck').val(),
Authorised: $('#authCheck').val(),
Id: $('#idCheck').val()
};
$.ajax({
type: "POST",
url: '<%= Url.Action("submitForm", "Home") %>',
data: JSON(personDetails),
//contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
'#Url.Action("Index", "Home")';
},
error: function (result) {
alert("A problem occured when submitting the form.");
}
});
return false;
});
The Javascript is meant to fire when the Submit button is hit. First the method 'submitForm' in the 'HomeController' is fired, before it redirects back to 'Index' also in the 'HomeController', which just outputs a view.
The 'submitForm' currently resembles the following:
[HttpPost]
public ActionResult submitForm(JsonResult jsonForm)
{
System.Diagnostics.Debug.WriteLine("made it here");
System.Diagnostics.Debug.WriteLine(jsonForm);
return View();
}
So my question is: what am I missing with the current form to make the AJAX event fire? I'm fairly sure it is not currently firing as there is no alert and nothing output on the console from the method it's supposed to hit.
I would rather not change the form itself too much as I currently have another bit of Javascript that sets the checkboxes to checked onload where appropriate.
EDIT: I fixed the method with Stephen Muecke's advice. What I'm trying to do here is: hit button -> submit details to my submitForm method -> submitForm method takes details and does some stuff in the database -> return success when finished -> on success, redirected from personDetails.cshtml to index.cshtml.

You need to create one other class that should contain all the properties that you are posting to submitForm action method.
currently you are using JsonResult class that doesn't contain the properties that you trying to post so here ModelBinder will not bind the data. reference Model Binder..Great articles ...love it ....
public class personDetails {
public string Enabled {get;set;}
public string Authorised {get;set;}
public string Id {get;set;}
}
[HttpPost]
public ActionResult submitForm(personDetails ObjpersonDetails)
{
System.Diagnostics.Debug.WriteLine("made it here");
System.Diagnostics.Debug.WriteLine(jsonForm);
return View();
}

Example:
Model:
public class MyModel{
public string Id {get;set;}
public string Authorised {get;set;}
public string Enabled {get;set;}
}
Action:
[HttpPost]
public ActionResult submitForm(MyModel model)
{
System.Diagnostics.Debug.WriteLine("made it here");
System.Diagnostics.Debug.WriteLine(jsonForm);
return View();
}
Script:
$('#userUpdateForm').submit(function (e) {
var personDetails = {
Id: $('#idCheck').val(),
Authorised: $('#authCheck').val(),
Enabled: $('#eCheck').val()
};
$.ajax({
type: "POST",
url: '#Url.Action("submitForm", "Home")',
contentType: "application/json",
data: JSON.stringify({ model: personDetails })
success: function (result) {
window.location.href = "/home/index/";
},
error: function (result) {
alert("A problem occured when submitting the form.");
}
});
return false;
});

Related

IFormFile is null when Form in Razor Page submitted by JavaScript code

When I submit Form in a Razor Page by click on Submit button, IFormFile send to OnPost action method properly. But if I submit the Form by JavaScript code, IFormFile is null in OnPost action method, other model members are not null.
Model
public string Applicant { get; set; }
public List<IFormFile> FormFiles { get; set; }
Form
<form method="post" name="ApplicantForm" enctype="multipart/form-data">
<input asp-for="#Model.ApplicantModel.Applicant" />
<input type="file" asp-for="#Model.ApplicantModel.FormFiles" multiple />
<button type="submit" id="btnSubmit">Submit</button>
<button type="button" onclick="doSomethingBeforeSubmit()">Do Something Before Submit</button>
</form>
JavaScript
function doSomethingBeforeSubmit() {
// Do something before submitting the form ...
.
.
document.forms["ApplicantForm"].submit();
// Or
document.getElementById("btnSubmit").click();
}
OnPost action method
[BindProperty]
public ApplicantModel ApplicantModel { get; set; }
public async Task<IActionResult> OnPostAsync()
{
ApplicantModel.Applicant // OK, Always ..
ApplicantModel.FormFiles // OK, if form submitted by click on Submit button.
ApplicantModel.FormFiles // Null, if form submitted by JavaScript code.
}
What is the right way to submit a form by JavaScript code in Razor Page with IFormFile in model?
.NET 6,
Visual Studio 2022,
ASP.NET Core Web App (Razor Pages)
If you want to pass files with js,you need to use FormData,here is a demo:
function doSomethingBeforeSubmit() {
var Form_Data = new FormData();
Form_Data.append('ApplicantModel.Applicant', $("#ApplicantModel_Applicant").val());
var files = $("#ApplicantModel_FormFiles").get(0).files;
for (var i = 0; i < files.length; i++) {
Form_Data.append('ApplicantModel.FormFiles', files[i]);
}
$.ajax({
type: "POST",
url: '',
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
data: Form_Data,
contentType: false,
processData: false,
success: function (data) {
},
error: function (result) {
}
})
}

How to pass multiple parameter from javascript function to controller inside a View?

Currently I have a javascript function for a button inside a Razor view where when user clicked it, a popup message will appear.
$("#confirmBtn").click(function() {
alert("user confirmed address: " + address + street + country);
Now I want to change the function so that when user clicked on it, it will send the parameter to the controller "SaveAddress" as HttpPost.
How can I achieve this? Thanks.
You have 2 options either using Form Postback or by using AJAX
--by Using ajax like below
-- View Section
<input type="text" id="address" name="address"/>
<input type="submit" id="btnSubmit" Value="Submit"
onclick="return myFunction()" />
-- Script Section
<script type="text/javascript">
var address=$('#address').val();
function myFunction(shipId) {
$.ajax({
type: 'POST',
url: '#Url.Content("~/YourControllerName/SaveAddress")',
cache: false,
data: ({ add: address}),
success: function (data) {
if (data != null) {
alert("Operation Completed")
}
},
error: function () {
}
});
return false;
}
</script>
--Controller
public ActionResult SaveAddress(string add)
{
//Write your code here
return Json("", JsonRequestBehavior.AllowGet);
}
Note:- You can create your model class and able to send multiple value's as for
demo i am just sending single value.
--by Using Form Post like below
--Model Class
public class MyClass
{
public string address {get;set;}
public string street {get;set;}
}
-- Controller
[HttpGet]
public ActionResult SaveAddress()
{
//Write your code here
return View();
}
[HttpPost]
public ActionResult SaveAddress(MyClass myclass)
{
//Write your code here
return RedirectToAction();
}
-- View
#model YourSolutionName.Models.MyClass
#using (Html.BeginForm("SaveAddress","Your Controller Name",FormMethod.Post))
{
#Html.TextBoxFor(x => x.address )<br/>
#Html.TextBoxFor(x => x.street)
<br/>
<input type="submit" id="btnSubmit" Value="Submit" />
}
I hope it may help you. Thank You
Create a dto class:
public class AddressDto
{
public string Address { get; set; }
public string Street { get; set; }
public string Country { get; set; }
}
Your controller method:
public ActionResult SaveData(AddressDto dto)
{
// do stuff
return Json(true);
}
Your ajax request:
$("#confirmBtn").click(function() {
// get values and pass them to dto
var dto = {
Address: address,
Street: street,
Country: country
};
$.ajax({
url: 'MyController/SaveData',
type: 'POST',
data: { dto: dto },
success: function (result) {
// do stuff
}
});
}
use ajax form in MVC
#using (Ajax.BeginForm("SaveAddress", "YourController", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "elementwhichholdsthisform", OnSuccess = "OnFilterSuccess" }, new { id = "frmSaveAddress" }))
{
}
Also remember to add reference to
jquery.unobtrusive-ajax.js

how to increment value while clicking button click in MVC (ajax call not form submit)?

I tried to increase count when clicking button (ajax call) in MVC, but value is incremented one time only. actually i have update the model after increment but it is not keeping updated model. please suggest how to solve?
My ultimate aim is:
what i want is on ajax call i want to pass model to actionmethod and do some set value to model and send back. while next button click i have to send updated model. thats all.
public class MyModel
{
public int Integer { get; set; }
public string Str { get; set; }
}
public class Test1Controller : Controller
{
[HttpGet]
public ActionResult Index()
{
var m = new MyModel();
return View("Test1", m);
}
[HttpPost]
public ActionResult ChangeTheValue(MyModel model)
{
model.Integer++;
UpdateModel(model);
return Json(model.Integer.ToString());
}
}
enter code here
#model MvcApplication2.Model.MyModel
#{
ViewBag.Title = "Test1";
}
<script src="~/Scripts/jquery-2.2.0.js"></script>
<script src="~/Scripts/jquery-ui-1.11.4.js"></script>
<h2>Test1</h2>
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "form1" }))
{
<div>
<input type="button" onclick="ajaxcall()" id="changeButton" value="Click Me!" />
<input type="text" value="#Model.Integer" class="txt" id="str" name="str" />
</div>
}
<script type="text/javascript">
function ajaxcall() {
$.ajax({
type: 'POST',
url: '#Url.Action("ChangeTheValue", "Test1")',
data: $('form1').serialize(),
cache: false,
async: true,
success: function (data) {
$("#str").val(data);
},
error: function (data) {
alert("Err " + data);
}
});
}
</script>
Try sending data via str's value instead of the whole form:
function ajaxcall() {
$.ajax({
type: 'POST',
url: '#Url.Action("ChangeTheValue", "Test1")',
data: $('#str').val(),
cache: false,
async: true,
success: function (data) {
$("#str").val(data);
},
error: function (data) {
alert("Err " + data);
}
});
First of all your jQuery selecctor for the form is wrong! Since form1 is the id, you should prefix it with #
data: $('#form1').serialize(),
And in your Action method, you are updating the value of the property Integer. But you are setting it the field with name str after the ajax call. So next time, when you click again, it is going to read the default value of Integar property ( which is 0 and increase it once to 1) and return you again. (This happens for all the clicks since you are not sending the updated value of that property).So ideally you should fix your form to have the correct field names
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "form1" }))
{
<div>
<input type="button" onclick="ajaxcall()" id="changeButton" value="Click Me!" />
#Html.TextBoxFor(f => f.Str)
#Html.TextBoxFor(f=>f.Integer)
</div>
}
And in the success event you should be updating the form field for Integer property.
success: function (data) {
$("#Integer").val(data);
},

How to send ViewModel and a file in single Ajax POST request, in MVC 5?

I have an ASP.NET MVC 5 application. And I'm trying to send a POST request with the Model data, and also include user selected files.
Here is my ViewModel (simplified for clarity):
public class Model
{
public string Text { get; set; }
public long Id { get; set; }
}
Here is the controller Action:
[HttpPost]
public ActionResult UploadFile(long userId, Model model)
{
foreach (string file in Request.Files)
{
// process files
}
return View("Index");
}
Html input element:
<div>
<input type="file" name="UploadFile" id="txtUploadFile" />
</div>
And the JavaScript code:
$('#txtUploadFile').on('change', function (e) {
var data = new FormData();
for (var x = 0; x < files.length; x++) {
data.append("file" + x, files[x]);
}
data.append("userId", 1);
data.append("model", JSON.stringify({ Text: 'test text', Id: 3 }));
$.ajax({
type: "POST",
url: '/Home/UploadFile',
contentType: false,
processData: false,
data: data,
success: function (result) { },
error: function (xhr, status, p3, p4) { }
});
});
The problem is that when the Request reaches controller action, I have files and 'userId' populated, but 'model' parameter is always null. Am I doing something wrong when populating FormData object?
Here is what I test using with MVC5 and IE11 / chrome
View
<script>
$(function () {
$("#form1").submit(function () {
/*You can also inject values to suitable named hidden fields*/
/*You can also inject the whole hidden filed to form dynamically*/
$('#name2').val(Date);
var formData = new FormData($(this)[0]);
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: formData,
async: false,
success: function (data) {
alert(data)
},
error: function(){
alert('error');
},
cache: false,
contentType: false,
processData: false
});
return false;
});
});
</script>
<form id="form1" action="/Home/Index" method="post" enctype="multipart/form-data">
<input type="text" id="name1" name="name1" value="value1" />
<input type="hidden" id ="name2" name="name2" value="" />
<input name="file1" type="file" />
<input type="submit" value="Sublit" />
</form>
Controller
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(HttpPostedFileBase file1, string name1, string name2)
{
var result = new List<string>();
if (file1 != null)
result.Add(string.Format("{0}: {1} bytes", file1.FileName, file1.ContentLength));
else
result.Add("No file");
result.Add(string.Format("name1: {0}", name1));
result.Add(string.Format("name2: {0}", name2));
return Content(string.Join(" - ", result.ToArray()));
}
}
Thanks to Silver89 for his answer

Form data not being posted to controller when using AJAX

Ok so I have this form in my view:
<form id="MyForm">
<input type="text" name="myinput" />
<button type="submit" />
</form>
I have the following Javascript at the top of my view, which runs when the page loads:
<script type="text/javascript">
$(document).ready(
function () {
$("#MyForm").submit(
function () {
var url = "Home/TestAjax";
var dataToSend = $("#MyForm").serialize();
alert(dataToSend);
$.ajax
(
{
type: "POST",
url: url,
data: dataToSend,
success: function (data) {
alert(data);
}
}
);
return false;
}
);
}
);
</script>
The form is being serialised to ajax correctly, as verified by the alert box. Here is my TestAjax controller method:
[HttpPost]
public string TestAjax(string data)
{
return !string.IsNullOrEmpty(data) ? "Success" : "Failure";
}
The value being returned is Failure, because the AJAX isn't being posted back. What am I doing wrong here?
Thanks
The name of your input field is myinput not data. So make sure you have consistently named the argument of your action as well:
[HttpPost]
public ActionResult TestAjax(string myinput)
{
return !string.IsNullOrEmpty(myinput) ? Content("Success") : Content("Failure");
}
When you use $("#MyForm").serialize() this will return myinput=some_value where some_value is obviously the value that the user has entered in this input field.
And if you had 2 input fields in your form:
<form id="MyForm">
<input type="text" name="foo" />
<input type="text" name="bar" />
<button type="submit" />
</form>
you would of course write a view model:
public class MyViewModel
{
public string Foo { get; set; }
public string Bar { get; set; }
}
that your controller action will take as parameter:
[HttpPost]
public ActionResult TestAjax(MyViewModel model)
{
return !string.IsNullOrEmpty(model.Foo) ? Content("Success") : Content("Failure");
}
Also please notice that in ASP.NET MVC controller actions should return ActionResults, not strings or whatever.

Categories