In my project, I have a main page for the document creation in DocumentsController where the user is able to change the status of the document. If the status is NEW, the user is allowed to add a new device ("part") to the document.
My goal is to insert a string to div#newDevice on ajax form submit. However, the html result is not rendered inside my main view but is rendered as a link ..../PartsBoxes/CreatePartial instead.
How could I fix that issue?
My main page part:
<input type="button" value="Add a new box" id="addNewBoxButton" class="add_new_btn" />
<input type="button" value="Add box from db" id="addDBBoxButton" class="add_existent_btn" />
<hr />
<div id="newDevice"></div>
<hr />
<script>
$("#addNewBoxButton").on("click", function () {
var deviceId = 1;
$.get('#Url.Action("CreatePartial", "PartsBoxes")',{
deviceId: deviceId
},
function (data) {
$("#newDevice").html(data);
});
});
</script>
my partial view:
#model NTStock.Models.BoxPartsViewModel
#{
ViewBag.Title = "Create";
}
#using (Ajax.BeginForm("CreatePartial", new AjaxOptions { UpdateTargetId = "newDevice" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.DocumentId)
<div class="form-group">
#Html.LabelFor(model => model.InternalName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.InternalName, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.InternalName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SerialNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SerialNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SerialNumber, "", new { #class = "text-danger" })
</div>
</div>
//......///
<div class="form-group deviceManipulations">
#Html.LabelFor(model => model.DeinstallationDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DeinstallationDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.DeinstallationDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save box" class="btn btn-default" />
</div>
</div>
</div>
}
and the method:
[HttpPost]
[ValidateAntiForgeryToken]
public ContentResult CreatePartial(BoxPartsViewModel partsBox)
{
if (ModelState.IsValid)
{
//do something
}
return Content("string to return");
}
as a result I get:
Firstly you should be sure jquery.unobtrusive-ajax is loaded in your page and you dont use jquery 1.9 version because it doesnt support jquery live methods.
Reference : http://jquery.com/upgrade-guide/1.9/
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
Then I would suggest to use jquery .load() function to load partial view into target element and use JsonResult instead of ActionResult to achieve your goal like following.
// jquery
<script>
$("#addNewBoxButton").on("click", function () {
var deviceId = 1;
$("#newDevice").load('#Url.Action("CreatePartial", "PartsBoxes")' + "/" deviceId );
});
</script>
//controller
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult CreatePartial(BoxPartsViewModel partsBox)
{
if (ModelState.IsValid)
{
//do something
}
return Json(new { data = "string to return" });
}
Related
Im trying to call the java script confirmation form submit but it skips it. It directly calls the controller even though i want to run first the java script for confirmation.
I dont know what im doing wrong. Still new to JV Scripts.
HTML
#model WMS_Web.Models.FileMaintenance.PrincipalModels
#section Scripts {
#Scripts.Render("~/Script/FileMaintenance/CommonFunction.js")
}
#{
ViewBag.Title = "PrincipalModel";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Principal</h2>
#using (Html.BeginForm("Create","Principal",FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.CompanyId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CompanyId, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CompanyId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button onclick='functionConfirm("Do you like Football?", function yes() {
alert("Yes")
},
function no() {
alert("no")
});'>XXX</button>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back", "ViewPrincipal")
</div>
Java Script
function functionConfirm(msg, myYes, myNo) {
var confirmBox = $("#confirm");
confirmBox.find(".message").text(msg);
confirmBox.find(".yes,.no").unbind().click(function () {
confirmBox.hide();
});
confirmBox.find(".yes").click(myYes);
confirmBox.find(".no").click(myNo);
confirmBox.show();
}
You can try this:
#using (Html.BeginForm("Create","Principal",FormMethod.Post))
{
#Html.AntiForgeryToken()
...
<input type="submit" name="name" value="Save" onclick="javascript: return SubmitForm();" />
}
Javascript:
function SubmitForm() {
var r = confirm("Are you sure you want to submit?");
if (r == false) {
return false;
}
// do something
return true;
}
MVC5 asp.net After validation the dialog form is break down
1. _Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - Moving Pro Services</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
#if (HttpContext.Current.User.Identity.IsAuthenticated)
{
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
#Html.ActionLink("Moving Pro Services", "Index", "Home", new {area = ""}, new {#class = "navbar-brand"})
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
Services <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>#Html.ActionLink("Companies", "Index", "Companies")</li>
<li>#Html.ActionLink("App Versions", "Index", "AppVersions")</li>
#if (User.Identity.IsAuthenticated)
{
if (User.IsInRole("Administrator"))
{
<li>#Html.ActionLink("Create User", "Register", "Account")</li>
}
}
</ul>
</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
#Html.Partial("_LoginPartial")
</div>
</div>
}
</div>
<div class="container body-content">
#RenderBody()
<hr/>
<footer>
<p>© #DateTime.Now.Year - Moving Pro Services</p>
</footer>
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
<div id='myModal' class='modal fade in'>
<div class="modal-dialog">
<div class="modal-content">
<div id='myModalContent'></div>
</div>
</div>
</div>
</body>
</html>
2. Model
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Maintenance.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Company
{
public int ID { get; set; }
[Display(Name = "Company Name")]
[StringLength(100)]
public string CompanyName { get; set; }
[Display(Name = "Server Alias")]
[StringLength(100)]
public string ServerAlias { get; set; }
[Display(Name = "Server Name")]
public string ServerName { get; set; }
[Display(Name = "Database Name")]
public string DatabaseName { get; set; }
[Display(Name = "Email Database Name")]
public string EmailDatabaseName { get; set; }
[Display(Name = "Integrated Security")]
public bool IntegratedSecurity { get; set; }
[Display(Name = "User Name")]
public string UserName { get; set; }
[Display(Name = "PWD")]
public string Password { get; set; }
[Display(Name = "App Key")]
public string AppKey { get; set; }
[StringLength(20)]
[Display(Name = "App Version")]
public string AppVersion { get; set; }
[Display(Name = "In Home Estimate")]
public bool InHomeEstimate { get; set; }
[Display(Name = "Foreman Inventory")]
public bool ForemanInventory { get; set; }
[Display(Name = "Docs")]
public bool Documents { get; set; }
[Display(Name = "Storage Scan In")]
public bool StorageScanIn { get; set; }
[Display(Name = "Storage Scan Out")]
public bool StorageScanOut { get; set; }
[Display(Name = "Scan At Delivery")]
public bool ScanAtDelivery { get; set; }
[Display(Name = "Amazon Rds")]
public bool AmazonRds { get; set; }
[Display(Name = "Amazon Region")]
[StringLength(20)]
public string AmazonRegion { get; set; }
[Display(Name = "Amazon Identifier")]
public string AmazonIdentifier { get; set; }
[Display(Name = "App Version")]
public virtual AppVersion AppVersion1 { get; set; }
}
}
3. Controller
// GET: Companies/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Company company = _db.Companies.Find(id);
if (company == null)
{
return HttpNotFound();
}
ViewBag.AppVersion = new SelectList(_db.AppVersions, "AppVersion1", "AppVersionDescription", company.AppVersion);
return PartialView(company);
}
// POST: Companies/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID,CompanyName,ServerAlias,ServerName,DatabaseName,EmailDatabaseName,IntegratedSecurity,AppKey,AppVersion,InHomeEstimate,ForemanInventory,Documents,StorageScanIn,StorageScanOut,ScanAtDelivery,AmazonRds,AmazonRegion,AmazonIdentifier")] Company company)
{
if (ModelState.IsValid)
{
_db.Entry(company).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.AppVersion = new SelectList(_db.AppVersions, "AppVersion1", "AppVersionDescription", company.AppVersion);
return PartialView(company);
}
4. View
#model Maintenance.Models.Company
#using (Html.BeginForm())
{
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Edit Company</h4>
</div>
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
<div class="modal-body">
<div class="form-horizontal">
<div class="form-group margin-small">
#Html.LabelFor(model => model.CompanyName, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.CompanyName, new { htmlAttributes = new { #class = "form-control", autofocus = "" } } )
#Html.ValidationMessageFor(model => model.CompanyName, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
<div class="form-group margin-small">
#Html.LabelFor(model => model.ServerAlias, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.ServerAlias, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ServerAlias, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
<div class="form-group margin-small">
#Html.LabelFor(model => model.ServerName, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.ServerName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ServerName, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
<div class="form-group margin-small">
#Html.LabelFor(model => model.DatabaseName, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.DatabaseName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.DatabaseName, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
<div class="form-group margin-small">
#Html.LabelFor(model => model.EmailDatabaseName, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.EmailDatabaseName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EmailDatabaseName, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
<div class="form-group margin-small">
<div class="col-md-5">
<div class="checkbox control-checkbox">
#Html.EditorFor(model => model.IntegratedSecurity, new { htmlAttributes = new { #class = "input-control-checkbox" } })
#Html.ValidationMessageFor(model => model.IntegratedSecurity, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
#Html.LabelFor(model => model.IntegratedSecurity, htmlAttributes: new { #class = "control-label col-md-7 control-label-checkbox" })
</div>
<div class="form-group margin-small">
#Html.LabelFor(model => model.AppKey, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.AppKey, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.AppKey, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
<div class="form-group margin-small">
#Html.LabelFor(model => model.AppVersion, "App Version", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownList("AppVersion", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.AppVersion, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
<div class="form-group margin-small">
<div class="col-md-5">
<div class="checkbox control-checkbox">
#Html.EditorFor(model => model.InHomeEstimate, new { htmlAttributes = new { #class = "input-control-checkbox" } })
#Html.ValidationMessageFor(model => model.InHomeEstimate, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
#Html.LabelFor(model => model.InHomeEstimate, htmlAttributes: new { #class = "control-label col-md-7 control-label-checkbox" })
</div>
<div class="form-group margin-small">
<div class="col-md-5">
<div class="checkbox control-checkbox">
#Html.EditorFor(model => model.ForemanInventory, new { htmlAttributes = new { #class = "input-control-checkbox" } })
#Html.ValidationMessageFor(model => model.ForemanInventory, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
#Html.LabelFor(model => model.ForemanInventory, htmlAttributes: new { #class = "control-label col-md-7 control-label-checkbox" })
</div>
<div class="form-group margin-small">
<div class="col-md-5">
<div class="checkbox control-checkbox">
#Html.EditorFor(model => model.Documents, new { htmlAttributes = new { #class = "input-control-checkbox" } })
#Html.ValidationMessageFor(model => model.Documents, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
#Html.LabelFor(model => model.Documents, htmlAttributes: new { #class = "control-label col-md-7 control-label-checkbox" })
</div>
<div class="form-group margin-small">
<div class="col-md-5">
<div class="checkbox control-checkbox">
#Html.EditorFor(model => model.StorageScanIn, new { htmlAttributes = new { #class = "input-control-checkbox" } })
#Html.ValidationMessageFor(model => model.StorageScanIn, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
#Html.LabelFor(model => model.StorageScanIn, htmlAttributes: new { #class = "control-label col-md-7 control-label-checkbox" })
</div>
<div class="form-group margin-small">
<div class="col-md-5">
<div class="checkbox control-checkbox">
#Html.EditorFor(model => model.StorageScanOut, new { htmlAttributes = new { #class = "input-control-checkbox" } })
#Html.ValidationMessageFor(model => model.StorageScanOut, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
#Html.LabelFor(model => model.StorageScanOut, htmlAttributes: new { #class = "control-label col-md-7 control-label-checkbox" })
</div>
<div class="form-group margin-small">
<div class="col-md-5">
<div class="checkbox control-checkbox">
#Html.EditorFor(model => model.ScanAtDelivery, new { htmlAttributes = new { #class = "input-control-checkbox" } })
#Html.ValidationMessageFor(model => model.ScanAtDelivery, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
#Html.LabelFor(model => model.ScanAtDelivery, htmlAttributes: new { #class = "control-label col-md-7 control-label-checkbox" })
</div>
<div class="form-group margin-small">
<div class="col-md-5">
<div class="checkbox control-checkbox">
#Html.EditorFor(model => model.AmazonRds, new { htmlAttributes = new { #class = "input-control-checkbox" } })
#Html.ValidationMessageFor(model => model.AmazonRds, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
#Html.LabelFor(model => model.AmazonRds, htmlAttributes: new { #class = "control-label col-md-7 control-label-checkbox" })
</div>
<div class="form-group margin-small">
#Html.LabelFor(model => model.AmazonRegion, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.AmazonRegion, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.AmazonRegion, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
<div class="form-group margin-small">
#Html.LabelFor(model => model.AmazonIdentifier, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.AmazonIdentifier, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.AmazonIdentifier, "", new { #class = "field-validation-error-tooltip" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input class="btn btn-primary" type="submit" value="Save changes" id="approve-btn" />
<button class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script>
$(function () {
$("form input").tooltipValidation({
placement: "right"
});
});
</script>
}
Script to show dialog
$(function () {
$.ajaxSetup({ cache: false });
$(document).on("click", ".modal-link", function (e) {
$('#myModalContent').load(this.href, function () {
$('#myModal').modal
(
{
keyboard: true
}, 'show'
);
bindForm(this);
});
return false;
});
$(document).on("click", "a[data-modal]", function (e)
{
$('#myModalContent').load(this.href, function ()
{
$('#myModal').modal
(
{
keyboard: true
}, 'show'
);
bindForm(this);
});
return false;
});
$(window.document).on('shown.bs.modal', '.modal', function () {
window.setTimeout(function () {
$('[autofocus]', this).focus();
}.bind(this), 100);
});
});
function bindForm(dialog) {
$('form', dialog).submit(function () {
var isValid = true; // assume all OK
$('form').validate(); // perform validation on the form
$('input[type="text"]').each(function (index, item) { // could change selector to suit e.g $('input, textarea').each(..
if (!$(this).valid()) {
isValid = false; // signal errors
return false; // break out of loop
}
});
if (!isValid) {
return false; // exit
}
$('#progress').show();
$.ajax({
url: this.action,
modal: true,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('#myModal').modal('hide');
$('#progress').hide();
location.reload();
alert(result.message);
}
});
return false;
});
}
Question
When I call dialog form for Edit Company I get dialog form as on Image1.
After validation $('form').validate(); // perform validation on the form
I get dialog form as on Image2. Please help me understand what do I wrong?
Image1
Image2
In Controller
public ActionResult Edit([Bind(Include = ....] Company company)
Need to use return View(company); instead of return PartialView(company)
I tried to add toastr notification in my code. Before adding it, it perfectly works fine. But when I tried to add toastr notification after jQuery validation, it shows that the record was successfully performed but it won't redirect or save data like previous. It seems that the jQuery didn't forward the viewModel data to the POST method. Following is my codes:
#model ESportsScreening.ViewModel.ScreeningFormViewModel
#{
ViewBag.Title = "New Screening ";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>New Screening</h2>
#using (Html.BeginForm("Create", "Screenings", FormMethod.Post, new { id = "createForm" }))
{
<p class="alert alert-info">All fields are <strong>required</strong></p>
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(m => m.TeamA)
#Html.TextBoxFor(m => m.TeamA, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.TeamA)
</div>
<div class="form-group">
#Html.LabelFor(m => m.TeamB)
#Html.TextBoxFor(m => m.TeamB, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.TeamB)
</div>
<div class="form-group">
#Html.LabelFor(m => m.Date)
#Html.TextBoxFor(m => m.Date, new { #class = "form-control", placeholder = "eg 1 Jan 2018" })
#Html.ValidationMessageFor(m => m.Date)
</div>
<div class="form-group">
#Html.LabelFor(m => m.Time)
#Html.TextBoxFor(m => m.Time, new { #class = "form-control", placeholder = "eg 24:00" })
#Html.ValidationMessageFor(m => m.Time)
</div>
<div class="form-group">
#Html.LabelFor(m => m.Ticket)
#Html.TextBoxFor(m => m.Ticket, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Ticket)
</div>
<div class="form-group">
#Html.LabelFor(m => m.Competition)
#Html.DropDownListFor(m => m.Competition, new SelectList(Model.Competitions, "Id", "Name"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Competition)
</div>
<div class="form-group">
#Html.LabelFor(m => m.Description)
#Html.TextAreaFor(m => m.Description, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Description)
</div>
<button class="btn btn-primary">Save</button>
}
#section scripts
{
#Scripts.Render("~/bundles/jqueryval")
<script>
$(document).ready(function () {
$("#createForm").submit(function (e) {
e.preventDefault();
$('#createForm').validate();
if ($('#createForm').valid()) {
toastr.success("Screening recorded succesfully!");
} else {
toastr.fail("Something unexpected happened..");
}
});
});
</script>
}
What are the changes required in my jQuery so that it can forward me to the POST method of ScreeningController and Create(viewModel)?
You need to remove e.preventDefault();. It preventing to post on server.
$("#createForm").submit(function (e) {
$('#createForm').validate();
if ($('#createForm').valid()) {
toastr.success("Screening recorded succesfully!");
} else {
toastr.fail("Something unexpected happened..");
}
});
I am working on an asp.net mvc-5 web application , and i have the following contact us form at the middle of the contact Us view:-
<div class="col-sm-8 col-sm-push-4">
<h2>Contact Us1</h2>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#if (TempData["message"] != null)
{
<div class="alert alert-success">
×
<strong> #TempData["message"].</strong>
</div>
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } }) <span style="color:red">*</span>
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Telephone, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Telephone, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Telephone, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Message, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Message, new { #cols = 60, rows = 10, #class = "form-control" })
#Html.ValidationMessageFor(model => model.Message, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-success" /><span id="progress" class="text-center" style="display: none;">
<img src="~/img/ajax-loader.gif" />
</span>
</div>
</div>
</div>
}
</div>
and here the Get and Post action methods:-
public ActionResult Contact()
{
ViewBag.Title = "Contact";
ViewBag.Description = "Home";
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Contact(Contact c)
{
if (ModelState.IsValid)
{
MailMessage mail = new MailMessage();
//code goes here
TempData["message"] = string.Format("Your Feedback has been submitted. Thanks");
return RedirectToAction("Contact");
}
ModelState.AddModelError("", "Cannot submit you Contact Form, please review the Contact Form for any missing info.");
return View(c);
}
now i am facing this problem:-
1. since the contact us form appear on the middle of the page, so users on small sized screens , might submit the form , then the Post request failed (model validation failed), where the contact us form will be rendered again with the validation errors shown, but users might not see the form, since by default the browser will move to the top. while on large screen the user can still see the form , but on mobile browser users might miss that there are errors on the form that they have just submit.
so i am thinking if there is a way to do this:-
if the form is rendered with errors, to force the browser (using jquery form example) to go to the form , so that users can see the validation errors ?
can anyone adivce on this please ?
Firstly you #Html.ValidationSummary() code should be inside the form tags in order for it to work correctly.
You can use javascript to scroll to the form in the view. Give the form (or an element near where you want to scroll to) an id attribute
#using (Html.BeginForm("Contact", "yourControllerName", FormMethod.Post, new { id = "form" }))
Then add the following script (inside document.ready)
if ('#ViewBag.HasError') {
location.href = '#form'; // or location.hash = '#form';
}
and modify the POST method to add the ViewBag property if there are errors
ModelState.AddModelError("", "Cannot ..... info.");
ViewBag.HasError = true; // add this
return View(c)
Side note: Not tested, but you should also be able to use
if ('#ViewContext.ViewData.ModelState.Values.SelectMany(v => v.Errors).Any()') {
as an alternative to using a ViewBag property.
Put #Html.ValidationSummary(false, "", new { #class = "text-danger" }) at the top of your page. Change true to false to show all property level errors.
I'm working on a form in my application, which I want to post using ajax. The posting works fine and my controller receives the data, but I'd like to just post a success message back to my view instead of refreshing the entire page. Do I have to return a partial view with the information for this, or can I just return a message from my controller? I can't seem to figure out how to do this properly.
<div class="panel panel-gray">
<div class="panel-body">
<form method="POST" action="#Url.Action("SaveWellDetails", "WellManagement")" id="wellform" class="form-horizontal">
<div class="form-group">
#Html.LabelFor(m => m.Id, new { #class = "col-md-3 control-label"})
<div class="col-md-9">
#Html.TextBoxFor(m => m.Id, new { #class = "form-control", disabled = "disabled", id = "WellId", name = "WellId" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Name, new { #class = "col-md-3 control-label" })
<div class="col-md-9">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Location, new { #class = "col-md-3 control-label" })
<div class="col-md-9">
#Html.TextBoxFor(m => m.Location, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.WellNumber, new { #class = "col-md-3 control-label" })
<div class="col-md-9">
#Html.TextBoxFor(m => m.WellNumber, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.WellType, new { #class = "col-md-3 control-label" })
<div class="col-md-9">
#Html.TextBoxFor(m => m.WellType, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.SpudDate, new { #class = "col-md-3 control-label" })
<div class="col-md-9">
#Html.TextBoxFor(m => m.SpudDate, new { #class = "form-control" })
</div>
</div>
<div class="panel-footer">
<input type="submit" id="submit" class="btn btn-primary" value="Save Changes" />
<div class="pull-right" id="wellsavesection">
<div id="processing_small" hidden="hidden">
<img src="~/Content/Kendo/Flat/loading_2x.gif" />
</div>
</div>
</div>
</form>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#wellform').submit(function () {
console.log("wellId = " + $("#WellId").val());
$("#processing_small").show().hide().fadeIn('slow');
$.ajax({
url: '#Url.Action("SaveWellDetails", "WellManagement")',
type: "POST",
dataType: "json",
data: {
wellId: $('#WellId').val(),
name: $('#Name').val(),
location: $('#Location').val(),
wellNumber: $('#WellNumber').val(),
wellType: $('#WellType').val(),
spudDate: $('#SpudDate').val()
},
error: function (msg) {
$('#wellsavesection').hide().html('<div class="alert alert-danger"><strong>Ouch!</strong> ' + msg.statusText + '</div>').fadeIn('slow');
},
success: function (msg) {
$('#wellsavesection').hide().html('<div class="alert alert-success"><strong>Success!</strong> Form Saved.</div>').fadeIn('slow').delay(1500).fadeOut();
}
});
});
});
</script>
Here's my controller:
[HttpPost]
public ActionResult SaveWellDetails(string wellId, string name, string location, string wellNumber, string wellType, DateTime spudDate)
{
try
{
var wellConctract = new WellContract
{
Id = Convert.ToInt32(wellId),
Name = name,
Location = location,
WellNumber = wellNumber,
WellType = wellType,
SpudDate = spudDate
};
WellService.UpdateWell(wellConctract);
}
catch (Exception e)
{
Log.Error(e);
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Message);
}
return Json(new {success = true}, JsonRequestBehavior.AllowGet);
}
Simply add return false; the end of the $('#wellform').submit(function () {... (after the ajax function, not inside it) and it should work, I tried it out in jsfiddle.
What this does it prevent the form from submitting.
you doesn't need a partial view to do that, your page will refresh each submit because it doing the usual event, try add event.preventDefault() http://api.jquery.com/event.preventdefault/
$('#wellform').submit(function (ev) {
ev.preventDefault();
// put your code below here
.....
});