Submitting form with file using ajax and bootstrap modal - ajax

I am trying to submit some data and file to my controller's action:
[HttpPost]
public ActionResult Settle(SettlePrepaymentViewModel settlePrepaymentViewModel)
{
//Do something and return JSON
}
My view model contains the following properties:
public HttpPostedFileBase File { get; set; }
public Guid? PrepaymentId { get; set; }
In my form I have some textboxes and a file input. When I press button, I want my form (with file) to be submitted to my action:
$('#btnConfirmSettlement').click(function (e) {
$.ajax({
url: '#Url.Action("Settle", "Prepayments")',
type: "POST",
data: $("#uploadFile").serialize(),
success: function (data) {
if (data.isSuccess) {
toastr.success("Success");
} else {
toastr.error(data.errorMessage);
}
},
error: function (data) {
toastr.error(data.errorMessage);
}
});
return false;
});
However when using the above code it does not work (there is no file passed to my action. However when using the following code (where my form is simply submitted) it works fine:
#using (Html.BeginForm("Settle", "Prepayments", FormMethod.Post, new {enctype = "multipart/form-data", #id="uploadFileSubmi"}))
{
#Html.TextBoxFor(model => model.SettlePrepaymentViewModel.File, new {type = "file"})
<input type="submit" value="Settle"/>
}
I was trying to use form submit when I click "Save" on my twitter bootstrap modal but then it just returns me (redirects me to) a JSON result from my action - I don't want to be redirected. Can someone please help me with this? What am I doing wrong?

Related

Asp.net core controller function with return partial view with select2 not working and remote function validation is not firing in modal popup

Select2 is not working and remote validation is not firing, this is only happens when I convert the code to modal popup but if not everything is working properly. What Am I missing in my code? Any advise or help much appreciated.. Thank you
Here is my code the modal:
$('#tbProducts tbody').on('click', 'button', function () {
var data = productsTable.row($(this).parents('tr')).data();
//alert(data.id);
$.ajax({
url: '#Url.Action("Edit", "Products")',
type: 'GET',
data: { id: data.id },
success: function (result) {
$('#EditUnitModal .modal-content').html(result);
$('#EditUnitModal').modal()
}
});
});
Here is the controller edit code:
public async Task<IActionResult> Edit(int? id)
{
//code here
return PartialView("__Edit", product);
}
And here is my partial view __Edit code:
#model intPOS.Models.Master.ViewModel.ProductViewModel
//code here
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
$(function () {
$('#Unit').select2({
theme: 'bootstrap4',
dropdownParent: $('#EditUnitModal')
})
$('#Category').select2({
theme: 'bootstrap4',
dropdownParent: $('#EditUnitModal')
})
})
</script>
}
And View model code:
[Display(Name = "Product Code"), Required]
[Remote("CheckProduct", "Products", AdditionalFields = "Id", ErrorMessage = "Product already exists.")]
public string ProductCode
{
get
{
return _productcode;
}
set
{
_productcode = value.Trim();
}
}
Sample screen for not firing validation and select2 is not working:
sections aren't allowed in partial views. You can still use modals and partial views via Ajax for edit forms but there is a small modification you need to do in order for this to work:
Include all the necessary scripts in your page (this is mandatory as sections aren't allowed in partial views).
In your javascript code add these lines in order to parse the new form via jquery validation unobtrusive and your select elements via Select2.
$('#tbProducts tbody').on('click', 'button', function () {
var data = productsTable.row($(this).parents('tr')).data();
//alert(data.id);
$.ajax({
url: '#Url.Action("Edit", "Products")',
type: 'GET',
data: { id: data.id },
success: function (result) {
$('#EditUnitModal .modal-content').html(result);
//Here we parse the new form via jquery validation unobtrusive.
$.validator.unobtrusive.parse($('#EditUnitModal .modal-content form')[0]);
//Here we initialize select2 for the selected elements.
$(".yourSelect2ElementClass").select2({//options...});
//Now we launch the modal.
$('#EditUnitModal').modal()
}
});
});
Don't forget to remove the section from your partial view and include your scripts in the containing view.

Post model to controller using ajax jquery in MVC3

Can somebody help me how can I post model back to controller using jQuery and ajax.
When I post my form, my controller is receiving an empty model. Please corrent me where I am doing a mistake.
Model:
public class AllocateToStore
{
public IList<OrderLine> FailureAllocations { get; set; }
public IList<SelectListItem> AllocationStatus
{
get
{
// code to fetch list.
}
}
}
public class OrderLine
{
public long Id { get; set; }
public DateTime Date { get; set; }
public int Status { get; set; }
}
Controller:
public ActionResult AutoAllocate()
{
// This action will load the view with data.
// Get model data and send it to view.
return View("Allocated",model);
}
[HttpPost]
public ActionResult ResolveUnallocatedOrders(AllocateToStore coll)
{
// When user changes the selection in grid and post the page I need to get the selection // here. So that I can update that record.
return null;
}
And view is
#model AllocateToStore
#{
ViewBag.Title = "Orders";
}
#{
var grid = new WebGrid(Model.FailureAllocations, rowsPerPage: 100);
}
if (Model.FailureAllocations.Any())
{
<form>
<div>
#grid.GetHtml(
columns: grid.Columns(
grid.Column(columnName: "Order date", header: "Order Date", format: item => item.Order.Date),
grid.Column("dropdown", header: "Resolution", format:
#<span>
#{ var index = Guid.NewGuid().ToString(); }
#Html.Hidden("FailureAllocations.Index", index)
#Html.Hidden("FailureAllocations[" + index + "].Id", (long)item.Id)
#Html.DropDownList("FailureAllocations[" + index + "].Status", new SelectList(Model.AllocationStatus, "Value", "Text", item.Status))
</span>
)
),
tableStyle: "expandable-table",
htmlAttributes: new { id = "gridFailureAllocations" }
)
<br />
<input type="submit" value="Resolve" id="resolve-button" />
</div>
</form>
}
#section scripts
{
<script>
$("#resolve-button").click(function () {
debugger;
alert("here");
$.ajax({
url: '/OrderProcessing/ResolveUnallocatedOrders',
data: $('#form').serialize(),
type: 'POST'
});
});
</script>
}
Thanks,
Naresh
i did not test this answer .it is just suggestion . please try this way.
$.ajax({
url: o.url,
type: 'post',
contentType: "application/x-www-form-urlencoded",
data: {"FailureAllocations ":JSON.stringify(FailureAllocations), "AllocationStatus":JSON.stringify(AllocationStatus)}',
. . . .
});
I think you have a bug here data: $('#form').serialize(),
$('#form') will select all elements with the id "form". You form doesn't have an id, so your selector won't be working. Try changing that line to data: $('form').serialize(), and the selector should work.
Alternatively, give your form an id of "form" e.g. <form id="form"> and the original selector $('#form') should work.
See here for more details on the various jQuery selectors.

ASP MVC 3: Client Validation not working properly when submitting a form using AJAX

I have the following scenario, I have a for that I'm submitting using ajax using the following code:
$("#cmdAjaxSave").click(function (evt) {
evt.preventDefault();
var $form = $('#frmItem');
if ($form.valid()) {
ajaxSave();
}
});
function ajaxSave() {
if (!onBeforeSubmit()) return; //item is not valid, so the ajax call should not be executed
//var token = $('[name=__RequestVerificationToken]').val();
popup('ajaxSplash');
$.ajax({
type: "POST",
url: '#Url.Action("Index")',
data: $("#frmItem").serialize(),
success: function (html) {
//console.log(html);
$("#formDiv").empty();
$("#formDiv").append(html);
initItemPage();
alert("Item was saved successfully");
},
error: function () { popup('ajaxSplash'); onFailure(); }
});
}
The problem I'm seeing here is that even though "frmItem" is returning "true" when I arrive clientside the ModelState is not valid. Specifically for three properties, which actually has the correct value.
Digging into the code made by the developer who originally coded this I found that for instance this property:
#Html.TextBoxFor(model => model.Item.Service.CPC_BW, htmlAttributes: new { #class = "Text", #onkeyup = "validItem();", #id = "SrvCPCBlk" })
Is actually defined like this:
private double _CPC_BW;
[Required]
[Range(0, 100000, ErrorMessage = "CPC value required")]
public string CPC_BW { get { return String.Format("{0:F}", _CPC_BW); } set { _CPC_BW = Convert.ToDouble(value); } }
I think he did it because TextBoxFor does not offers an obvious way to format a number and even though it looks fishy I don't know how could this be causing the error.
The Html of the form is rendered like this
<div id="itemPopUpForm">
#{Html.EnableClientValidation();}
<div id="formDiv">
#{ Html.RenderPartial("ItemData", Model, new ViewDataDictionary() { { "Machines", ViewBag.Machines }, { "WarehouseList", ViewBag.WarehouseList }, { WebConstants.FORM_ID_KEY, #ViewData[WebConstants.FORM_ID_KEY] } }); }
</div>
</div>
The partial view contains the form that is submited in the ajax request.
I think you should try and clear the model state then test whether its valid...
Its a common issue.
ModelState.Clear();
ModelState.IsValid();

How to upload a file without reloading the whole page in mvc3?

I have been working with MVC for the past few days.
I have a problem in one of my pages, i.e I have a page where q user enters the required details and uploads a file. I have two buttons named Upload for Uploading File and Create for creating new profile.
My Problem
My problem is I don't want to reload the whole page when user clicks on upload button. I was thinking of using an webmethod for fileupload.
I don't know if what am I doing wrong here
Can any one correct me
This is my Webmethod in my controller named Create
Controller
[WebMethod]
public string FileUpload(HttpPostedFileBase file, BugModel model)
{
BugModel bug = null;
if (file != null && file.ContentLength > 0)
{
string path = "/Content/UploadedFiles/" + Path.GetFileName(file.FileName);
string savedFileName = Path.Combine(System.Web.HttpContext.Current.Server.MapPath ("~" +path));
file.SaveAs(savedFileName);
BugAttachment attachment = new BugAttachment();
attachment.FileName = "~" + path.ToString();
bug.ListFile.Add(attachment);
model = bug;
}
return "FileUploaded";
}
used a script to call the method
Javascript
<script type="text/javascript">
function UploadFile() {
$.ajax({
type:"Post",
url: "LogABug/FileUpload",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert("File Uploaded")
},
error: function () {
ErrorMessage("Try Again");
}
});
}
</script>
can any one tell me how can I do this ...if this is the wrong method correct me the right one with the ideas please
You are uploading the file separately. Therefore you will need two actions:
public string Something(BugModel model) for the model.
public string FileUpload(HttpPostedFileBase file) for the file
Now, I would use jQuery Form Plugin for ajax submitting. Here is an example:
<script type="text/javascript">
$(function () {
$("#file-upload-form").submit(function () {
$(this).ajaxSubmit({
target: "#message",
cache: false
});
return false;
});
});
</script>
#using(Html.BeginForm("FileUpload", "LogABug", FormMethod.Post, new { enctype = "multipart/form-data", id = "file-upload-form" })) {
#Html.ValidationSummary(true)
<fieldset>
#Html.EditorFor(model => model.File)
<input type="submit" value="Upload" />
</fieldset>
}
<div id="message">
</div>
What ever you return from your action will be displayed in the div with id message

How to get rid of this ajax form posting issue?

I am posting a form to controller action. I am getting an error from the controller.
This is the behavior I want:
If error - show the right error message on the same page without any page refresh.
If success - show the success message on the page again no page refresh
what I am getting is that the page gets fully refreshed with different url and shows this:
{"status":"Failed","msg":"\u0027Name\u0027 "}
The url changes to this: ../respond/update which is the action I post to
Basically I want to catch this Failed status and display the msg inside a span.
But why it is taking me to a different page?
Here is the view:
#using (Html.BeginForm("Update", "Respond", FormMethod.Post, new { id = "frmUpdate" }))
{
//have my form here
//submit button
}
Here is the js handler that posts the form:
$('#frmUpdate').submit(function () {
//validation
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
beforeSend: //show loader
success: function (result) {
alert(result.status);
},
error: function (xhr, status, error) { alert('error'); }
});
return false;
});
Here is controller:
[HttpPost]
public ActionResult Update(ResponseModel model)
{
return Json(new { status="Failed", msg = "Name" });
}
EDIT:
In Firefox it takes to differnt url.
But in IE8 I get this error from jquery itself. Interesting...
Message: Object doesn't support this property or method
Line: 28
Char: 12724
Code: 0
URI: /Content/js/external/jquery-1.6.2.min.js?v=3
I think you should stop the default submit behavior by doing so:
$('#frmUpdate').submit(function (e) {
e.preventDefault();
<your code here>
});
Otherwise the form submit will happen causing the behaviour you want to avoid.
Hope this helps.
#using (Html.BeginForm("Update", "Respond", FormMethod.Post, new { id = "frmUpdate" }))
{
//have my form here
//submit button
}
If you are using submit button than it will post the page. You need to use type button instead of submit.
It will work.
#using (Html.BeginForm("Update", "Respond", FormMethod.Post, new { id = "frmUpdate" }))
{
//have my form here
//use type button
}

Resources