Redirect to action with JsonResult in MVC - javascript

I have a Room record in my database and I want to edit it using a JsonResult Edit method in RoomController like this:
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult Edit(RoomViewModel roomViewModel)
{
if (roomViewModel == null) throw new ArgumentNullException(nameof(roomViewModel));
try
{
var apartmentRoomViewModel = new ApartmentRoomViewModel
{
Id = _entities.ApartmentRoom.Where(x => x.RoomID == roomViewModel.Id).Select(x => x.Id).Single(),
ApartmentID = _entities.ApartmentRoom.Where(x => x.RoomID == roomViewModel.Id).Select(x => x.ApartmentID).Single(),
RoomID = roomViewModel.Id
};
apartmentRoomViewModel.ApartmentID = roomViewModel.SelectedApartmentID;
var apartmentRoom = AutoMapper.Mapper.Map<ApartmentRoom>(apartmentRoomViewModel);
_entities.ApartmentRoom.AddOrUpdate(apartmentRoom);
_entities.SaveChanges();
var room = AutoMapper.Mapper.Map<Room>(roomViewModel);
var status = _roomRepository.Update(room);
_roomRepository.Save();
return Json(new { status, message = "Success!", url = Url.Action("List", "Room") });
}
catch
{
return Json(new { status = false, message = "Error!" });
}
}
After the method works, edit is successful but I cannot redirect the page to /Room/List. Instead, I am encountering a page like this:
My Script
<script type="text/javascript">
$(document).ready(function () {
$("#RoomEdit").click(function (e) {
e.preventDefault();
var data = {
DoorNumber: $("#DoorNumber").val(),
FloorNumber: $("#FloorNumber").val(),
Capacity: $("#Capacity").val(),
SelectedApartmentID: $("#SelectedApartmentID option:selected").val()
}
$.ajax({
type: "POST",
url: '#Url.Action("Edit","Room")',
dataType: "json",
data: JSON.stringify(data),
contentType: "application/json",
success: function (result) {
if (result.status) {
window.location.href = result.url;
}
},
error: function () {
}
});
return false;
});
});
Edit.cshtml
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="box">
<div class="box-header">
<h2>#ViewBag.Title</h2>
</div>
<div class="box-divider m-a-0"></div>
<div class="box-body">
#using (Html.BeginForm("Edit", "Room", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group row">
#Html.LabelFor(x => x.DoorNumber, new { #class = "col-sm-2 form-control-label" })
<div class="col-sm-10">
#Html.TextBoxFor(x => x.DoorNumber, new { #class = "form-control" })
#Html.ValidationMessageFor(x => x.DoorNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group row">
#Html.LabelFor(x => x.FloorNumber, new { #class = "col-sm-2 form-control-label" })
<div class="col-sm-10">
#Html.TextBoxFor(x => x.FloorNumber, new { #class = "form-control" })
#Html.ValidationMessageFor(x => x.FloorNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group row">
#Html.LabelFor(x => x.Capacity, new { #class = "col-sm-2 form-control-label" })
<div class="col-sm-10">
#Html.TextBoxFor(x => x.Capacity, new { #class = "form-control" })
#Html.ValidationMessageFor(x => x.Capacity, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group row">
#Html.LabelFor(x => x.ApartmentName, new { #class = "col-sm-2 form-control-label" })
<div class="col-sm-10">
#Html.DropDownListFor(x => x.SelectedApartmentID, Model.ApartmentList, new { #class = "form-control", id = "SelectedApartmentID" })
</div>
</div>
<div class="form-group row m-t-md">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" id="RoomEdit" class="btn green">Düzenle</button>
</div>
</div>
}
</div>
</div>
</div>
I couldn't understand what is wrong with my code. Any help will be appreciated.

Make your Button first with type="Button" instead of Submit, also change the click function id from btnAdd to btnEdit.
At server side, roomViewModel.Id will be getting 0 if you using old method, instead of this do serialize so you can get all the Inputs at server side method.
Also use, #Html.HiddenFor(x => x.id) to pass the Id to Method.
Try this function so you can call your Method with AJAX,
<script type="text/javascript">
$(document).ready(function () {
$("#RoomEdit").click(function (e) {
e.preventDefault();
var data = $("#formName").serialize();
$.ajax({
type: "POST",
url: '#Url.Action("Edit", "Room")',
data: data,
success: function (result) {
if (result.status) {
alert(result.message);
setTimeout(function () {
window.location.href = result.url;
}, 1000);
}
}
});
});
})
</script>

You have code to do ajax submit. But from the image you shared, it looks like it is doing a normal form submit. Make sure that you are preventing the default form submit behavior when the button is clicked.
You already have return false; which should do it.
It should work as long as you do not have other script errors in the page. (you can verify this by opening up the browser console)
Also make sure that you are returning true as the value of status property of the json data you are returning. There is no need to specify JsonRequestBehavior.AllowGet enum in the Json method overload when you are returning from an HttpPost action method. It is needed if your action method is HttpGet
return Json(new { status= true, message = "Success!", url = Url.Action("List", "Room") });
Also, it does not make any sense to have the $.notify call after you redirect to the new page. That means that call will not be executed at all!

Related

Customize the view of Select2 Dropdown

In my view, I'm using select2Combobox as my dropdowns.
Here when the Country selection changes, I pass that selected id to the JSON result and get the results, assigning for the provinces Combobox.
When it happens, the dropdown view is changed to the square from the rounded edges.
I want to know how to add the same styles to the select2 combo boxes.
this is my code.
<div class="col-md-6 col-sm-6">
<div class="form-group row"> #Html.LabelFor(model => model.Country_Id, htmlAttributes: new { #class = "control-label col-md-3 required" }) <div class="col-sm-8">
<span class="asterisk_input"></span> #Html.DropDownList("Country_Id", null, "Select Country", new { #class = "form-control js-dropdown js-Country", #Id = "Country", #data_map = Model.TempId, #required = true }) #Html.ValidationMessageFor(model => model.Country_Id, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col-md-6 col-sm-6">
<div class="form-group row"> #Html.LabelFor(model => model.Province_Id, htmlAttributes: new { #class = "control-label col-md-3 required" }) <div class="col-sm-8">
<span class="asterisk_input"></span> #Html.DropDownListFor(model => model.Province_Id, new List <SelectListItem>(), new { #class = "form-control js-dropdown js-Province", #id = "ddlProvId" + Model.TempId, #data_map = Model.TempId, #required = true }) #Html.ValidationMessageFor(model => model.Province_Id, "", new { #class = "text-danger" })
</div>
</div>
</div>
Javascript
$(function () {
$('.js-Country').change(function () {
var mapperId = $(this).data('map');
setDropDownProvinces($(this).val(), mapperId)
});
});
function setDropDownProvinces(xVal, mapid) {
try {
$("#ddlProvId" + mapid).empty().trigger("changed");
$.ajax({
url: '/Account/FindProvinces',
type: 'POST',
dataType: 'json',
cache: false,
async: false,
data: {
CountryId: xVal
},
success: function (data) {
if (data.Success == true) {
$("#ddlProvId" + mapid).select2({
width: '100%',
data: JSON.parse(data.items)
});
}
}
});
} catch (err) {
console.log(err.message)
}
}
This is the dropdown before selecting the country
This is after the selection.
In the success function of your ajax call try this line after mapping the result:
$("#ddlProvId" + mapid).addClass('form-control js-dropdown js-Province');
Source:
jQuery $.addClass()

How to use validation for other button except than submit in cshtml?

I have written a html code for cshtml which consists two button save and update:
<div class="modal-body">
#using (Html.BeginForm("Create", "CustomActivity", FormMethod.Post, new { role = "form", #id = "customActivityForm", #class = "activityForm" }))
{
<div>
<div class="container" id="activity">
#Html.LabelFor(m => m.AdminCustomActivity.Activity, new { #class = "" })
#Html.TextBoxFor(m => m.AdminCustomActivity.Activity, new { #class = "w100p mb0" })
#Html.ValidationMessageFor(m => m.AdminCustomActivity.Activity, "", new { #class = "text-danger" })
</div>
<div class="container">
<div class="column one-fourth">
<div>
#Html.LabelFor(m => m.AdminCustomActivity.Rate, new { #class = "wcrate" })
#Html.TextBoxFor(m => m.AdminCustomActivity.Rate, new { #class = "w100p mb0" })
#Html.ValidationMessageFor(m => m.AdminCustomActivity.Rate, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="modal-footer">
#Html.HiddenFor(m => m.AdminCustomActivity.WorkOrderId, new { #id = "hfWorkOrderId" })
#Html.HiddenFor(m => m.AdminCustomActivity.Id, new { #id = "customActivityId" })
<button type="submit" class="btn btn-primary">Create</button>
<button class="btn btn-primary" id="updateActivity">Update</button>
</div>
</div>
}
</div>
Now in the footer there is two button add and update the validation works perfect for add button but the validation dosen't works for Update button since the function call of update button is from jquery
$("#updateActivity").click(function () {
event.preventDefault();
$.ajax({
type: "POST",
url: "/CustomActivity/Update",
data: {
WorkOrderId: #Model.Id,
},
success: function () {
location.reload();
window.scrollTo(0, 0);
},
error: function () {
//alert(erro.data)
}
});
})
How can I allow to check validation in update button same as add bututon. I tried using type='submit' but that doesn't works
You would have to call a function which implements the jQuery validatation to show validation messages at the Update button click:
function validateUpdate() {
$("#customActivityForm").validate({
rules: {
AdminCustomActivity_Activity: "required",
AdminCustomActivity_Rate: "required"
}
});
}
$("#updateActivity").click(function () {
validateUpdate();
$.ajax({
type: "POST",
url: "/CustomActivity/Update",
data: {
WorkOrderId: #Model.Id,
},
success: function () {
location.reload();
window.scrollTo(0, 0);
},
error: function () {
//alert(erro.data)
}
});
})

Json Result isn't working when I use db.Entry(x).State = EntityState.Modified;

I Have a view where I can edit and add new Rows on my SQL called by AddOrEdit. All I need is to press the button Submit after fill/change the fields. It calls my ActionResult on AccountController that brings me a JsonResult and my AJAX function on button click get the JsonResult to fill a Notify.js message to say that the submit was successfully done.
Problem:
When I create a new row, all works how should be but when I update a existing row, the Success message comes to my browser as raw Json.
Controller:
[HttpPost]
public ActionResult AddOrEdit(UserPortal user)
{
using (ModelEntities db = new ModelEntities())
{
try
{
if (user.UserID == 0)
{
db.UserPortals.Add(user);
}
else
{
db.Entry(user).State = EntityState.Modified;
}
db.SaveChanges();
return Json(new { success = true, message = "Submitted Successfully. Redirecting..." }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(new { success = true, message = ex.Message }, JsonRequestBehavior.AllowGet);
}
}
}
View:
#using (Html.BeginForm("AddOrEdit", "Account", FormMethod.Post, new { onsubmit = "return SubmitForm(this)" }))
{
<form id="AddOrEditUserForm">
#Html.HiddenFor(model => model.UserID)
<div class="form-group">
#Html.LabelFor(model => model.UserEmail, new { #class = "control-label" })
#Html.EditorFor(model => model.UserEmail, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.UserEmail)
</div>
<div class="form-group">
#Html.LabelFor(model => model.UserName, new { #class = "control-label" })
#Html.EditorFor(model => model.UserName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="form-group">
#Html.LabelFor(model => model.UserCompany, new { #class = "control-label" })
#Html.EditorFor(model => model.UserCompany, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.UserCompany)
</div>
<div class="form-group">
#Html.LabelFor(model => model.UserPosition, new { #class = "control-label" })
#Html.EditorFor(model => model.UserPosition, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="form-group">
#Html.LabelFor(model => model.UserAccessLevel, new { #class = "control-label" })
#Html.EditorFor(model => model.UserAccessLevel, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.UserAccessLevel)
</div>
<div class="form-group">
<input type="submit" name="Submit" value="Salvar" class="btn btn-primary" />
</div>
</form>
}
Javascript on View:
function SubmitForm(form) {
$.validator.unobtrusive.parse(form);
if ($(form).valid()) {
$.ajax({
type: "POST",
url: form.action,
data: $(form).serialize(),
success: function (data) {
var delay = 2000; // time in milliseconds
if (data.success) {
$.notify(data.message, {
globalPosition: "top center",
className: "success",
})
setTimeout(function () {
window.location.href = '#Url.Action("AdminUsers", "Account")'; //redirect to the main page after some seconds
}, delay);
}
},
error: function (jqXHR, textStatus, errorThrown) { errorFunction(); },
});
}
return false;
}
Notify.js working when I add a new user:
image 1
When I click on submit button to update a existing user
image 2
What I've tried:
1- I add some console.log on my Submit Function and after if ($(form).valid()) I just don't receive anymore my console.log test. I think the problem is the Function and the ajax inside it.
2- On controller I gave a single JsonResult for each situation: to create I had a message saying "Created Successfully" and It worked but on the message below "Update Successfully" I got the same problem: a raw json on my screen but working perfectly on backend updating the row I requested.

relation between two dropdownlist in mvc

I have two dropdownlist,when i select an option from first one,related options show in second dropdown.i have used jquery but i dont know why it doesent work.
this is cshtml page:
<div class="form-group">
#Html.LabelFor(model => model.ProductSubGroup.ProductGroupID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProductGroupID", (SelectList)ViewBag.Type, "-- انتخاب ---", htmlAttributes: new { #class = "form-control",id = "rdbGroup" })
#Html.ValidationMessageFor(model => model.ProductSubGroup.ProductGroupID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProductSubGroupID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProductSubGroupID", (SelectList)ViewBag.ProductSubGroupID, "-- انتخاب ---", htmlAttributes: new { #class = "form-control",id = "rdbSubGroup" })
#Html.ValidationMessageFor(model => model.ProductSubGroupID, "", new { #class = "text-danger" })
</div>
</div>
and this is controller
public ActionResult SelectCategory(int id)
{
var categoris = db.ProductSubGroup.Where(m => m.ProductGroup.ProductGroupID == id).Select(c => new { c.ProductSubGroupID, c.ProductSubGroupTitle});
return Json(categoris, JsonRequestBehavior.AllowGet);
}
// GET: Admin/Products/Create
public ActionResult Create()
{
ViewBag.ProductGroupID=new SelectList(db.ProductGroup,"ProductGroupID","Produ ctGroupTitle");
ViewBag.ProductSubGroupID = new SelectList(db.ProductSubGroup, "ProductSubGroupID", "ProductSubGroupTitle");
return View();
}
and this is javascript
$('#rdbGroup').change(function () {
jQuery.getJSON('#Url.Action("SelectCategory")', { id: $(this).attr('value') }, function (data) {
$('#rdbSubGroup').empty();
jQuery.each(data, function (i) {
var option = $('<option></option>').attr("value", data[i].Id).text(data[i].Title);
$("#rdbSubGroup").append(option);
});
});
});
a sample of mine
cs.html
<div class="form-group">
#Html.LabelFor(m => m.FakulteId, "Fakülte", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-6">
#Html.DropDownListFor(m => m.FakulteId, ViewBag.Fakulte as SelectList, "Fakülte Seçiniz", htmlAttributes: new { #class = "form-control", #id = "fakulteSec", #onchange = "secim()" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.BolumId, "Bölüm", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-6">
#Html.DropDownListFor(m => m.BolumId, ViewBag.Bolum as SelectList, "Bölüm Seçiniz", htmlAttributes: new { #class = "form-control", #id = "bolum" })
</div>
</div>
controller
public JsonResult FakulteBolumDrop(int id)
{
db.Configuration.ProxyCreationEnabled = false;
List<Bolum> bolum = db.Bolum.Where(b => b.FakulteId == id).ToList();
return Json(bolum, JsonRequestBehavior.AllowGet);
}
.js
function secim() {
var fakulteId = $('#fakulteSec').val();
//alert(fakulteId);
$.ajax({
url: '/Rektor/FakulteBolumDrop?id=' + fakulteId,
type: "POST",
dataType: "JSON",
data: { Fakulte: fakulteId },
success: function (bolumler) {
$("#bolum").html("");
$.each(bolumler, function (i, bolum) {
$("#bolum").append(
$('<option></option>').val(bolum.BolumId).html(bolum.Adi));
});
}
});
}
You have to register your change event of rdbGroup Drop Down inside the
$(document).ready(function(){
});
Otherwise it will not be fired.
use this.value or $(this).val() instead of $(this).attr('value').
Try
$('#rdbGroup').on('change',function () {// or $(document).on('change', '#rdbGroup',function (){
$.getJSON('#Url.Action("SelectCategory")', { id: this.value }, function (data) {
$('#rdbSubGroup').empty();
$.each(data, function (i,item) {// if data is json string form the replace data by $.parseJSON(data)
//console.log(item.Id); console.log(item.Title);
$('#rdbSubGroup').append($('<option>', {
value:item.Id,
text :item.Title
})); //OR you can use --- $('#rdbSubGroup').append($("<option></option>").attr("value",item.Id).text(item.Title));
});
});
});
OR
$('#rdbGroup').on('change',function () {// or $(document).on('change', '#rdbGroup',function (){
var id= this.value;
$.ajax({
url: '#Url.Action("SelectCategory")',
data: {
id: id
},
dataType: 'json',
async: false
}).done(function (data) {
$("#rdbSubGroup").html("");
$.each(data, function (i,item) {
$('#rdbSubGroup').append($("<option></option>").attr("value",item.Id).text(item.Title));
//OR $('#rdbSubGroup').append($('<option>', { value:item.Id, text :item.Title}));
});
});
});

Adding a list of complex data models to form

I'm using Entity Framework 7 with ASP.NET MVC 5.
I have some forms that look like this. Clicking on one of the "new" buttons brings up a Bootstrap modal that looks like this. Submitting the modal form adds a new entity to the database before appending its name and primary key to the selectlist.
This works, but if the user changes their mind, the item(s) created via the modal (location in this case) stick around forever. So ideally none of the child items would be created until the main form is finished. While the example only has two simple fields, other data models have more than half a dozen, which may include complex fields of their own (but preventing that wouldn't be a horrible restriction).
So what's the best way to do this, nested divs serialized by JavaScript? Nested divs would also make it easy to allow reordering by the user, which is the end goal.
Does ASP.NET have a better way to handle this?
This feels hacky, but it works.
Using BeginCollectionItem, you can have the modal add hidden input elements to the DOM.
I wrote an action method that returns JSON with the modelstate (valid/invalid) and errors or partial HTML for invalid and valid submissions, respectively. Based on this, JavaScript either adds the errors to the summary or adds the requisite label and hidden inputs to the initial form.
Then have the main form's viewmodel contain an ICollection of your data model, called Contacts in below code, and ASP.NET handles the data binding with no troubles.
Example:
_CollectionItem.cshtml (partial HTML added to main form after valid submission)
#model Project.Models.ContactCreateViewModel
<li>
<div class="collection-item">
#using (Html.BeginCollectionItem("Contacts"))
{
<span class="item-name">#Model.LastName, #Model.FirstName</span> <span class="btn btn-danger delete-item">Delete</span>
#Html.HiddenFor(model => model.FirstName)
#Html.HiddenFor(model => model.LastName)
#Html.HiddenFor(model => model.PhoneNumber)
#Html.HiddenFor(model => model.PhoneExt)
#Html.HiddenFor(model => model.Email)
}
</div>
</li>
_CreateModal.cshtml (partial used for the body of the modal)
#model Project.Models.ContactCreateViewModel
<div class="modal-header">
<button type="button" class="close btn-modal-close" data-dismiss="modal"><i class="fas fa-times"></i></button>
<h4 class="modal-title">New Contact</h4>
</div>
<div class="modal-body">
#using (Html.BeginForm("CreateModal", "Contacts", FormMethod.Post, new { id = "new-contact-form" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummaryPlaceholder()
#* First Name *#
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
</div>
#* Last Name *#
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
#* Phone Number *#
<div class="form-group">
#Html.LabelFor(model => model.PhoneNumber, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.PhoneNumber, new { htmlAttributes = new { #class = "form-control phone" } })
#Html.ValidationMessageFor(model => model.PhoneNumber, "", new { #class = "text-danger" })
</div>
</div>
#* Phone Ext *#
<div class="form-group">
#Html.LabelFor(model => model.PhoneExt, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.PhoneExt, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PhoneExt, "", new { #class = "text-danger" })
</div>
</div>
#* Email *#
<div class="form-group">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
#* SUBMIT *#
<div class="form-group">
<div class="col-md-offset-4 col-md-8">
<input type="submit" value="Create" class="btn btn-success" />
</div>
</div>
</div>
}
</div>
#Scripts.Render("~/Scripts/Custom/ajax-add-collection-item.js")
<script>
$(function () {
ajaxAddCollectionItem("new-contact-form", "contacts", function () {
alertify.success("Added new contact");
})
});
</script>
ajax-add-collection-item.js (capture modal form submission, add _CollectionItem.cshtml to main form)
// Posts form and adds collection item to ul
function ajaxAddCollectionItem(formId, listId, onSuccess = function () { }) {
let $form = $("#" + formId);
$form.submit(function (event) {
event.preventDefault();
$.ajax({
method: "POST",
url: $form.attr("action"),
data: $form.serialize(),
success: function (data) {
let successful = data["success"];
// If form is valid, close modal and append new entry to list
if (successful) {
$("#" + listId).append(data["html"]);
$(".delete-item").click(function (event) {
$(this).closest("li").remove();
});
$(".btn-modal-close").trigger("click");
onSuccess();
}
// If form is not valid, display error messages
else {
displayValidationErrors(data["errors"]);
}
},
error: function (error) {
alert("Dynamic content load failed.");
console.error("Ajax call failed for form: " + $form);
}
});
});
// Populate validation summary
function displayValidationErrors(errors) {
let $ul = $('div.validation-summary-valid.text-danger > ul');
$ul.empty();
$.each(errors, function (i, errorMessage) {
$ul.append('<li>' + errorMessage + '</li>');
});
}
}
ContactsController.cs
public class ContactsController
{
// GET: Contacts/CreateModal
public ActionResult CreateModal()
{
return PartialView("_CreateModal");
}
// POST: Contacts/CreateModal
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> CreateModal(ContactCreateViewModel viewModel)
{
// If form is valid and email does not already exist, send HTML for collection item,
// otherwise send modelstate errors
if (ModelState.IsValid)
{
User user = await UserManager.FindByEmailAsync(viewModel.Email);
if (user == null)
// RenderPartialView returns partial HTML as a string,
// see https://weblog.west-wind.com/posts/2012/May/30/Rendering-ASPNET-MVC-Views-to-String
return Json(new { success = true, html = RenderPartialView("_CollectionItem", viewModel) });
else
ModelState.AddModelError("Email", "Email already exists.");
}
return Json(new { success = false, errors = GetModelStateErrors() });
}
// Actually in base controller class
protected string[] GetModelStateErrors()
{
return ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage).ToArray();
}
}

Categories

Resources