Dynamic "Favorite" button - ASP.NET MVC - c#

I have created a table which dynamically generates records using the "Infinite Loading" process, I have a button in my HTML Code which i need to use to allow users to add the item in their favourite - so this is my HTML code
#model List<PagesAuth.Models.Links.MLink>
#foreach (var I in Model)
{
<tr>
<td class="v-align-top" id="itemcard">
<h4 class="card-title">
#I._title
<small><cite>#I._tp_created.ToString("dd MMM yyyy")</cite> /small>
</h4>
<div class="pull-right" id="options">
<ul class="list-inline text-right" >
#if (I._tp_favourite == 0)
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="location.href='#Url.RequestContext .Action("_Fav", "Home", "#I._id")'"></button></li>
}
else
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="location.href='#Url.RequestContext .Action("_UnFav", "Home", "#I._id")'"></button></li>
}
</ul>
</div>
</div>
</td>
</tr>
}
I am trying to use "Favourite" button to allow user to add that website to their favourite list (I am ok with the DB updates etc)
<ul class="list-inline text-right" >
#if (I._tp_favourite == 0)
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="location.href='#Url.RequestContext .Action("_Fav", "Home", "#I._id")'"></button></li>
}
else
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="location.href='#Url.RequestContext .Action("_UnFav", "Home", "#I._id")'"></button></li>
}
</ul>
What I want to know is how to achieve this on user front-end - Like I thought I should just create a PartialView and make it child action only in my controller, send it ID and do DB Processing
[ChildActionOnly]
public ActionResult _Fav(int ID)
{//Do DB Processing
return PartialView(ID);
}
First of all the following does not work
onclick="location.href='#Url.RequestContext .Action("_UnFav", "Home", "#I._id")'"
Second, if I end up making this work, it will still refresh the page and I don't want that.
Is there a better way to achieve this
Cheers

I don't know why you want to use partial views but you can do it this way.
Use ajax to send request to controller action.
Handle action result using JavaScript.
View:
#model List<PagesAuth.Models.Links.MLink>
#foreach (var I in Model)
{
<tr>
<td class="v-align-top" id="itemcard">
<h4 class="card-title">
#I._title
<small><cite>#I._tp_created.ToString("dd MMM yyyy")</cite> /small>
</h4>
<div class="pull-right" id="options">
<ul class="list-inline text-right" >
#if (I._tp_favourite == 0)
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="Fav(#I._id)"></button></li>
}
else
{
<li><button class="btn-link glyphicon glyphicon-heart-empty" onclick="UnFav(#I._id)"></button></li>
}
</ul>
</div>
</div>
</td>
</tr>
}
JS:
Here I am just alerting that the favorite action succeeded, else you have an array of string errors to work with. You could redirect or do some stuff, whichever you prefer.
<script type="text/javascript">
function Fav(id) {
var url = '#Url.Action("_Fav", "Home")';
$.ajax({
url: url,
type: 'POST',
data: {
id: id
},
success: function (data) {
if(data.length == 0) // No errors
alert("Fave success!");
},
error: function (jqXHR) { // Http Status is not 200
},
complete: function (jqXHR, status) { // Whether success or error it enters here
}
});
};
function UnFav(id) {
var url = '#Url.Action("_UnFav", "Home")';
$.ajax({
url: url,
type: 'POST',
data: {
id: id
},
success: function (data) {
if(data.length == 0) // No errors
alert("Unfave success!");
},
error: function (jqXHR) { // Http Status is not 200
},
complete: function (jqXHR, status) { // Whether success or error it enters here
}
});
};
</script>
Controller:
[HttpPost]
public ActionResult _Fav(int ID)
{
List<string> errors = new List<string>(); // You might want to return an error if something wrong happened
//Do DB Processing
return Json(errors, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult _UnFav(int ID)
{
List<string> errors = new List<string>(); // You might want to return an error if something wrong happened
//Do DB Processing
return Json(errors, JsonRequestBehavior.AllowGet);
}

Related

Delete btn in MVC.net

I might need an extra set of eyes but my delete btn is not working it does return a message but after clicking yes or ok it doesn't remove the data i wanted to delete basically nothing happens, I think I have an issue with the inventory.Id part. thank you, and i know this is not a good question for other users but i appreciate the help.
<tbody>
#foreach (var inventory in Model)
{
<tr>
<td>#Html.ActionLink(inventory.PartNumber, "Edit", "Inventory", new
{ id = inventory.Id }, null)</td>
<td>#inventory.PinNumber</td>
<td>#inventory.PartQuantity </td>
<td>#inventory.PartPrice </td>
<td>#inventory.PartDescrption</td>
<td> <button data-inventory-id="#inventory.Id" class="btn-link js-delete">Delete</button> </td>
</tr>
}
</tbody>
</table>
#section scripts
{
<script>
$(document).ready(function ()
{
$("#inventories").DataTable();
$("#inventories .js-delete").on("click", function () {
var button = $(this);
if (confirm("Are you sure you want to delete this Part Number?")) {
$.ajax({
url: "/inventory/" + button.attr("data-inventory-id"),
method: "DELETE",
success: function () {
button.parents("tr").remove();
}
});
}
});
});
</script>
}
this is my Controller for the Delete Action:
[HttpDelete]
public void DeleteInventory(int id)
{
var inventoryInDb = _context.Inventory.SingleOrDefault(c => c.Id == id);
_context.Inventory.Remove(inventoryInDb);
_context.SaveChanges();
}
I don't have an API in the Tutorial i am following He has an API but I didn't create one. I am trying to get around that.
Thank you.
How about using POST instead of DELETE as your ajax method? Or simply using the $.post method.
https://www.w3schools.com/jquery/ajax_post.asp
Most likely you did not create a DELETE method in your back-end API. To find out for sure, open Chrome's developer tools (making sure you're on the console tab) and then click your button. You will see an error message that says "Method DELETE is not found" or something similar.
If it says "method is not allowed" then that has to do with permissions (the user clicking the button does not have permission to access that API).
In controller:
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Inventory inventory = _context.Inventory.Find(id);
if (inventory == null)
{
return HttpNotFound();
}
return View(inventory);
}
in index add delete btn, this is an ajax call to the delete btn its used with dataTables to render data faster..
{
"render": function (data, type, row, meta) {
return '<a class="btn btn-danger"
href ="#Url.Action("Delete", "Inventory")/' + row.Id + '">Delete</a>';
}
create a Delete view:
#model InventoryTracker.Models.Inventory //this has to be re-named to your naming
convention.
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-primary" />
#Html.ActionLink("Cancel", "Index", null, new { #class = "btn btn-primary" })
</div>
}
}

View Component not detecting/returning Ajax request on 2nd submit

I've got a really strange problem where my ajax post request works fine the first time after the page has loaded but if I submit my form again without doing a page refresh then the contents are returned to the whole page instead of just updating the DIV. I've spent days on this looking for answers and through trial and error and I suspect the issue relates to Request.Headers["X-Requested-With"] being empty on 2nd submit. Note that I am returning a View Component to the ajax request and my ajax code is in a separate js file.
View Component (this contains the form that gets submitted and gets replaced when the ajax request returns. It works correctly after the page has been loaded or refreshed)
#model MSIC.Models.ClientViewModels.VisitMovementViewModel
#{
bool inProgress = (bool)ViewData["inProgress"];
}
<form asp-controller="Client" asp-action="VisitMovement" asp-route-id="#Model.VisitMovementID" id="formVisitAction" method="post" onsubmit="AjaxSubmit(this)">
<input asp-for="VisitID" type="hidden" />
<input asp-for="StageNo" type="hidden" />
<input type="hidden" id="replaceID" name="replaceID" value="#ClientVisit" />
<input type="hidden" id="submitAction" name="submitAction" />
<div class="col-md-9 no-padding">
<input type="text" id="visitMovementComment" name="visitMovementComment" class="form-control" placeholder="Comment..." required>
</div>
<div class="input-group col-md-3">
<input type="text" id="visitMovementBoothNo" name="visitMovementBoothNo" class="form-control" placeholder="Booth..." required>
<div class="input-group-btn">
<button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" #((inProgress) ? "" : "disabled")>Action <span class="caret"></span></button>
<ul class="dropdown-menu dropdown-menu-right">
#if (Model.Buttons != null)
{
foreach (var item in Model.Buttons)
{
if (item.beforeDivider)
{
<li><button type="#item.Type" name="#item.Name" class="btn btn-link btn-block btn-flat" value="#item.Value" onclick="#item.OnClick">#item.Text</button></li>
}
}
<li role="separator" class="divider"></li>
foreach (var item in Model.Buttons)
{
if (!item.beforeDivider)
{
<li><button type="#item.Type" name="#item.Name" class="btn btn-link btn-block btn-flat" value="#item.Value" onclick="#item.OnClick">#item.Text</button></li>
}
}
}
</ul>
</div>
</div>
</form>
Ajax Request located in separate JS file (when debugging this everything runs through as expected the first time however after the View Component is returned and the form is submitted the 2nd time the success, error, complete functions never fire and the returned data loads in the whole page)
function AjaxSubmit(form) {
$form = $(form);
var replaceID = $('input#replaceID', $form).val();
var formData = $form.serialize();
if (!$form[0].checkValidity()) {
return false;
}
$form.submit(function (e) {
e.preventDefault();
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: formData,
async: true,
processData: false,
cache: false,
success: function (data) {
$(replaceID).html(data);
},
error: function (xhr, status, error) {
console.log(xhr.status + " - " + error);
},
complete: function (data) {
console.log(data);
}
});
});
}
Action Method (I suspect the issue may be related to the Request.Headers["X-Requested-With"] being Empty on the 2nd submit and therefore MVC does not realise this is an ajax request hence returns the result to the page instead of returning it to the ajax request)
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> VisitMovement(int id, int submitAction, int? visitMovementBoothNo, string visitMovementComment, VisitMovementViewModel model)
{
var test1 = Request.ContentType; //1ST REQUEST = "application/x-www-form-urlencoded; charset=UTF-8", 2ND REQUEST = "application/x-www-form-urlencoded"
var test2 = Request.Headers["X-Requested-With"]; //1ST REQUEST = "XMLHttpRequest", 2ND REQUEST = Empty
try
{
if (ModelState.IsValid)
{
bool complete = false;
switch (submitAction)
{
case 2: //Proceed to Stage 2
model.StageNo = 2;
break;
case 3: //Proceed to Stage 3
model.StageNo = 3;
break;
case 4: //Complete Visit
complete = true;
break;
default:
return BadRequest("Could not determine action.");
}
await visitAPI.VisitMovement(id, model.VisitID, submitAction, model.StageNo, visitMovementBoothNo, visitMovementComment, complete);
return ViewComponent("ClientVisit", new { visitID = model.VisitID });
}
else
{
return BadRequest(ModelState);
}
}
catch (Exception ex)
{
return StatusCode(500, ex.Message);
}
}
If my assumption is correct why is the ajax request not sending the the correct headers when it is submitted the 2nd time and how can i fix it? If not what else could be going wrong?
I think the problem was the form submit event was being lost when the data/view component returned. I solved the problem by changing my ajax post to below...
$(document).on('submit', 'form.ajax-form', function (e) {
var replaceID = $('input#replaceID', $(this)).val();
var replaceType = $('input#replaceType', $(this)).val();
e.preventDefault();
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: $(this).serialize(),
async: true,
processData: false,
cache: false,
success: function (data) {
$(replaceID).html(data);
},
error: function (xhr, status, error) {
AjaxOnFailure(xhr, status, error);
}
});
});

how to send uploaded file from javascript to controller in MVC?

In my MVC, i have a view and that contains one file upload control and one button.
<input type="file" id="Uploadfile" />
<input type="button" onclick()="GetFile();/>
Javascript function as follows
function GetFile()
{
var file_data = $("#Uploadfile").prop("files")[0];
window.location.href="Calculation/Final?files="+file_data;
}
I need to pass/send the selected file via fileupload control to controller in mvc.
i have the controller
public ActionResult Final(HttpPostedFileBase files)
{
//here i have got the files value is null.
}
How to get the selected file and send it to the controller?
Plz help me to fix this issue.
I had similar functionality to deliver in my project.
The working code looks something like this:
Controller Class
[HttpPost]
public ActionResult UploadFile(YourModel model1)
{
foreach (string file in Request.Files)
{
HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength > 0)
{
string folderPath = Server.MapPath("~/ServerFolderPath");
Directory.CreateDirectory(folderPath);
string savedFileName = Server.MapPath("~/ServerFolderPath/" + hpf.FileName);
hpf.SaveAs(savedFileName);
return Content("File Uploaded Successfully");
}
else
{
return Content("Invalid File");
}
model1.Image = "~/ServerFolderPath/" + hpf.FileName;
}
//Refactor the code as per your need
return View();
}
View
#using (#Html.BeginForm("UploadFile", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<table style="border: solid thin; margin: 10px 10px 10px 10px">
<tr style="margin-top: 10px">
<td>
#Html.Label("Select a File to Upload")
<br />
<br />
<input type="file" name="myfile">
<input type="submit" value="Upload" />
</td>
</tr>
</table>
}
you cannot send file content via javascript (unless HTMl5). and you are doing totally wrong. if you want to do HTML5 based solution via FileReader api then you need to check this out. FileReader Api
Just put a form tag and use the same name of the input in the controller action to perform model binding
#using(Html.BeginForm("yourAction","YourControl",FormMethod.Post))
{
<input type="file" id="fileUpload" />
}
then in controller.
[HTTPPost]
public ActionResult Final(HttpPostedFileBase fileUpload)
{
//here i have got the files value is null.
}
Below code will do a full post back in an hidden form which will give an illusion of ajax file upload. Try it:
Update:
JS
function Upload(sender) {
var iframe = $("<iframe>").hide();
var newForm = $("<FORM>");
newForm.attr({ method: "POST", enctype: "multipart/form-data", action: "/ControllerName/Final" });
var $this = $(sender), $clone = $this.clone();
$this.after($clone).appendTo($(newForm));
iframe.appendTo($("html")).contents().find('body').html($(newForm));
newForm.submit();
}
HTML
<input type="file" id="Uploadfile" name="Uploadfile" />
<input type="button" onclick="Upload($('#UploadFile'));"/>
Controller
public ActionResult Final(HttpPostedFileBase Uploadfile)
{
//here you can use uploaded file
}
As a completion from Ravi's answer, I would suggest to use the following using statement:
#using(Html.BeginForm("yourAction","YourControl",FormMethod.Post, new { enctype="multipart/form-data" }))
{
<input type="file" id="fileUpload" />
}
You can do it by using json data to view.
As instance,
Controller
public ActionResult Products(string categoryid)
{
List<catProducts> lst = bindProducts(categoryid);
return View(lst);
}
public JsonResult Productsview(string categoryid)
{
//write your logic
var Data = new { ok = true, catid = categoryid};
return Json(Data, JsonRequestBehavior.AllowGet);
}
View:
#{
ViewBag.Title = "Index";
}
#model ASP.NETMVC.Controllers.Categories
<h2>List Of Categories</h2>
#Html.ListBox("lst_categories", (IEnumerable<SelectListItem>) ViewBag.Categories)
<script type="text/javascript">
$(function () {
$('#lst_categories').change(function () {
var catid = $('#lst_categories :selected').val();
$.ajax({
url: '#Url.Action("Productsview", "Jquery")',
type: 'GET',
dataType: 'json',
data: { categoryid: catid },
cache: false,
success: function (Data) {
if (Data.ok) {
var link = "#Url.Action("Products", "Jquery", new { categoryid = "catid" })";
link = link.replace("catid", Data.catid);
alert(link);
window.location.href = link;
}
}
});
});
});
</script>

Reloading partial page after jQuery ajax command

I am very new to both JQuery and Asp.net MVC 3 (C#), so I apologize if this is trivial. I have an MVC partial view (Index.cshtml) that has a list of tasks. These tasks are contained within indivudal divs that I have in a list style layout. I have a button called "add task" that opens a dialog. This dialog will save the added task to the database via an AJAX Json call to the controller.
This is where I am having trouble - after the dialog closes I would like the list of tasks to reload with the task i just added. I have found examples where the entire page is reloaded, and I found examples where the controller is supposed to return a rendered view. My problem is that the dialog is being opened from the partial I want to reload. Is there a way to accomplish what I am trying to do.
Index.cshtml
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
#foreach(var task in item.Tasks) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
</div>
</div>
}
</div>
<div id="dialog-form" title="Create new user">
<p class="validateTips">All form fields are required.</p>
<form>
<fieldset>
<label for="TaskName">Task Name</label>
<input type="text" name="TaskName" id="name" class="text ui-widget-content ui-corner-all" />
<label for="TaskDescription">Task Description</label>
<input type="text" name="TaskDescription" id="description" value="" class="text ui-widget-content ui-corner-all" />
<input type="hidden" name="TaskID" id="ID" />
<input type="hidden" name="ProjectID" id="ProjectID" />
</fieldset>
</form>
</div>
Partial Javascript
function GetTask(id) {
if (id.length > 0) {
$.ajax({
url: '/Project/GetTaskFromID',
type: "POST",
data: { "id": id },
success: PopulateDialogFields,
error: HandleError
});
}
}
function PopulateDialogFields(data) {
$("#name").val(data.TaskName);
$("#description").val(data.TaskDescription);
$("#ID").val(data.TaskID);
}
function HandleError(data) {
alert(data.error);
var foo = data;
}
function SaveTask() {
var taskName = $("#name").val();
var taskDescription = $("#description").val();
var id = $("#ID").val();
var projectID = $("#ProjectID").val();
if (id.length > 0) {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
});
}
else {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "projectID": projectID }
});
}
}
$("#dialog-form").dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
"OK": function () {
SaveTask();
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
},
close: function () {
allFields.val("").removeClass("ui-state-error");
window.location.reload(true);
},
open: function () {
var id = $(this).data("id");
var projectID = $(this).data("projectID");
$("#ProjectID").val(projectID);
var button = $("#" + id);
GetTask(id);
}
});
$(".editTaskButton")
.button()
.click(function () {
$("#dialog-form").data('id', this.id).dialog("open");
});
$(".createTaskButton")
.button()
.click(function () {
$("#dialog-form").data('projectID', this.id).dialog("open");
});
I am relatively new to jQuery and ASP.NET MVC as well, however, here's what first comes to mind.
In order to maintain the AJAX-y aspect of the page, I suggest that you create a method that handles a POST which returns a JSON formatted set of TaskManagementApplication.Models.Project. This method can optionally return filtered results.
The markup would look like this,
<div id="ProjectAccordionWrapper">
<div id="ProjectWrapperTemplate" class="ProjectWrapper" style="display: none;">
<h3 id="itemName"></h3>
<div class="column">
<button class="createTaskButton" id="itemProjectID">Create New Task</button>
<div id="portletTemplate" class="portlet">
<div class="portlet-header" id="taskName"></div>
<div class="portlet-content" id="taskDescription"></div>
<button class="editTaskButton" id="taskID">Edit Task</button>
</div>
</div>
</div>
</div>
Next, you would have jQuery clone the ProjectWrapperTemplate element, and set all of the corresponding fields.
$(function () {
$.ajax({
url: '/Project/GetTasks',
type: "POST",
data: { }
}).done(function (data) {
data.forEach(function (element) {
AppendProjectWrapper(element);
});
});
function AppendProjectWrapper(data) {
var projectAccordionWrapper = $('#ProjectAccordionWrapper');
var projectWrapper = $('#ProjectWrapperTemplate').clone(true, true);
projectWrapper.id = nothing; // remove the id, so as to not have duplicates
projectWrapper.style.display = nothing; // remove the style "display: none"
var itemName = projectWrapper.children('#itemName'); // h3
itemName.id = nothing;
itemName.text(data.ItemName);
var itemProjectID = projectWrapper.children('#itemProjectID'); // button Create New Task
itemProjectID.id = data.ItemProjectID;
var portletTemplate = projectWrapper.children('#portletTemplate'); // div
data.Tasks.forEach(function (element) {
var portlet = portletTemplate.clone();
portlet.id = nothing;
var taskName = portlet.children('#taskName');
taskName.id = nothing;
taskName.text(element.TaskName);
var taskDescription = portlet.children('#taskDescription');
taskDescription.id = nothing;
taskDescription.text(element.TaskDescription);
var editTaskButton = portlet.children('#taskID');
editTaskButton.id = element.TaskID;
portlet.appendTo(projectWrapper);
});
portletTemplate.remove(); // remove the portlet template element
projectWrapper.appendTo(projectAccordionWrapper);
}
}
Finally, have '/Project/SaveTask' return a JSON formatted TaskManagementApplication.Models.Project of the currently saved task.
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
}).done(function (data) {
AppendProjectWrapper(data);
});
The return data for '/Project/GetTasks' should look as follows:
[
{
ItemName: '#item.Name',
ItemProjectID: '#item.ProjectID',
Tasks: [
TaskName: '#task.TaskName',
TaskDescription: '#task.TaskDescription',
TaskID: '#task.TaskID'
]
}
]
The return data from '/Project/SaveTask' should follow the same format, except or the outer-most array.
Please note that a lot of this code is untested.
It may be easiest to refactor the list into another action+view. Then, you can call this in both the original Index.cshtml view, and via the .load() method in jQuery. So, assuming this:
Projects controller
[HttpGet]
[ChildActionOnly]
public ActionResult Tasks(int id)
{
// create the appropriate model object as an IEnumerable of your Task type
return View(model);
}
Tasks.cshtml
#foreach(var task in Model) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
You would adjust Index.cshtml like so:
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
<div id="tasks-#item.ProjectID">
#Html.Action("Tasks", "Project", new { id = item.ProjectID })
</div>
</div>
</div>
}
</div>
//... the rest of the view
And finally,
// this should happen inside the callback of your .ajax() method
$('#tasks-'+projectID).load('/project/tasks/'+ projectID);

How to load model errors into modal dialog

is it possible to load the modelstate errors to the same modal dialog after submitting a form with javascript?
My code is something like this:
Controller:
public ActionResult Create(MyModel model){
if(ModelState.isValid){
// DB Save
return RedirectToAction("Index");
}
else{
return View(model);
}
}
Ajax Method
$.ajax({
type: 'POST',
url: '/Receipt/Create',
cache: false,
data: $("#CreateForm").serialize(),
success: function (e) { window.location="/Controller/Action"; },
error: function (e) { e.preventDefault(); /*Code here to load model error into page*/ }
});
I've solved today this problem, with something like this
public ActionResult Create(MyModel model){
if(ModelState.isValid){
// DB Save
return RedirectToAction("Index");
}
else{
return PartialView("_myPartialForm",model);
}
}
and
$.ajax({
type: 'POST',
url: '/Receipt/Create',
cache: false,
data: $("#CreateForm").serialize(),
success: function (e) {
if(e.Valid){
window.location="/Controller/Action";}
else{
return false;
} },
error: function (e) { e.preventDefault();$("#mymodal").load(e) }
});
it is something like jmrnet said. Thanks
I was able to accomplish this by using Ajax.BeginForm method with an UpdateTargetId AjaxOption. Here is the code I used. It doesnt exactly fit what you are doing, but it should point you in the right direction.
In the View:
#using (Ajax.BeginForm(new AjaxOptions(){ UpdateTargetId="loginresult" }))
{
<b>User:</b><br />
#Html.TextBoxFor(m => m.UserName)<br />
<br />
<b>Password:</b><br />
#Html.PasswordFor(m => m.Password)<br />
<div id="loginresult"><br /></div>
<input id="Button1" type="submit" value="Login" class="touch-button" />
}
In the Controller:
[HttpPost]
public ActionResult Index(LoginModel model)
{
//Execute Log-in code.
//Capture any errors and put them in the model.LoginResponse property.
return PartialView("LoginResult", model);
}
In the LoginResult partial view:
#model MerchantMobile.Models.LoginModel
#if (String.IsNullOrEmpty(Model.LoginResponse))
{
Html.RenderPartial("_AjaxRedirect", Url.Content("~/Home/Activity"));
}
else
{
<div id="loginresult">
<div style="color: Red; font-weight: bold;">
#Model.LoginResponse
</div>
</div>
}
You could easily replace the loginresult <div> with one used by jquery ui to pop up a modal dialog box rather than just show some text in the div.
Hope this helps!

Categories

Resources