Ajax.BeginForm not working with Html.ValidationSummary - asp.net-mvc

I am trying to use the Ajax.BeginForm to post data to a controller. In the case of specific errors, the form should re-render and display the custom error message that was added to the ModelState. For some reason, the error message is not displaying. I am even trying the following test case which is not working, am I missing something?
Edit.cshtml:
#using (Ajax.BeginForm("Edit", "UserInformation", FormMethod.Post, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, UpdateTargetId = "divFormContainerMain", LoadingElementId = "divPreLoader", OnSuccess = "onSuccess" }))
{
<div id="divPreLoader" style="display:none; text-align: center"><img src="#Url.Content("~/Content/images/preLoader.gif")" alt="" /></div>
<div id="divFormContainerMain">
#Html.Partial("_EditPartialView", Model)
</div>
<div class="buttonContainerBottom">
<span class="buttonContainerInner">
<input type="submit" id="btnSave" name="buttonPress" value="save" class="orangeButton" />
</span>
</div>
}
_EditPartialView.cshtml:
#Html.ValidationSummary(false)
<div id="divFormContainerUserInformation" class="formContainer">
<div class="labelContainer">
#Html.LabelFor(m => m.UserName)
</div>
<div class="elementContainer">
#Html.TextBoxFor(m => m.UserName, new { style = "width: 200px" })
#Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="labelContainer">
#Html.LabelFor(m => m.Name)
</div>
<div class="elementContainer">
#Html.TextBoxFor(m => m.Name, new { style = "width: 200px" })
#Html.ValidationMessageFor(m => m.Name)
</div>
<div class="labelContainer">
#Html.LabelFor(m => m.EmailAddress)
</div>
<div class="elementContainer">
#Html.TextBoxFor(m => m.EmailAddress, new { style = "width: 200px" })
#Html.ValidationMessageFor(m => m.EmailAddress)
</div>
.
.
.
.
.
.
</div>
UserController:
[HttpPost]
public ActionResult Edit(UserModel userModel)
{
ModelState.AddModelError("", "This is a test");
return PartialView("_EditPartialView", userModel);
}

Where are your scripts added? In the _layout.cshtml or in the view itself? How are you loading the view? Is it with an ajax request to show a partial view?
If you are loading the partial view through ajax or as a partial view, maybe it could be that the partial view was not yet loaded in the jquery DOM model tree.
I would try the following. Change
<div id="divFormContainerMain">
#Html.Partial("_EditPartialView", Model)
</div>
to
<div id="divFormContainerMain">
#Html.Partial("_EditPartialView", Model)
<script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
</div>
or
<div id="divFormContainerMain">
#Html.Partial("_EditPartialView", Model)
#Scripts.Render("~/bundles/jqueryval") //if you have a bundle for it
</div>
My advice is anyway to load the validate and unobtrusive scripts only when you need them and not in the _layout.cshtml page.
Also don't forget to enable the following appSettings in the web.config
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />

Make sure that you have included the jquery.unobtrusive-ajax.js script to your view after jquery itself. Otherwise the Ajax.BeginForm helper won't do what you think it does:
<script type="text/javascript" src="#Url.Content("~/scripts/jquery-YOUR-VERSION.js")"></script>
<script type="text/javascript" src="#Url.Content("~/scripts/jquery.unobtrusive-ajax.js")"></script>

Related

Ajax.BeginForm on submit click not work and HTML.BeginForm returns partial view as view page

i have a view in which there is a section and in section there are some links; section and one link are like this:
<section id="tabs-section">
<ul id="myTab" class="my-nav nav nav-tabs nav-justified responsive-tabs col-sm-12" style="padding:0;">
<li class="active">A</li>
</ul>
<div class="tab-content col-sm-12" style="border:1px solid #000000;"#*margin-top:-20px;padding-top:20px;*#>
<div class="tab-pane fade in active" id="RegisterEditUsers">#Html.Partial("RegisterEditUsers")</div>
</div>
when i click on A a partial view in this view is shown under links. partial view is like this:
<div class="panel" style="border:1px solid #ff6a00;margin:10px 10px 0
10px;padding:10px;">
<div class="row ">
<div id="register" class="col-sm-6 col-sm-offset-0 col-sm-pull-0
col-sm-push-6 col-xs-offset-3 col-xs-pull-1 btn btn-circle ">
#Ajax.ActionLink("AA", "Register", "Account", new AjaxOptions {
HttpMethod = "Get", UpdateTargetId = "Result", InsertionMode =
InsertionMode.Replace, OnComplete = "regClick" })
</div>
<div id="edit" class="col-sm-6 col-sm-offset-3 col-xs-offset-0 btn
btn-circle">
#Ajax.ActionLink("BB", "GetUsers", "UsersAdmin", new AjaxOptions
{ HttpMethod = "Get", UpdateTargetId = "Result", InsertionMode =
InsertionMode.Replace, OnComplete = "edClick" })
</div>
</div>
</div>
<div class="panel" style="border:1px solid #ff6a00;margin:0px 10px 10px
10px;">
<div id="Result" dir="rtl"></div>
</div>
and finally when i choose AA a new partial view is loaded bellow the former partial view, that is this:
#using (Ajax.BeginForm(
"Register",
"Account",
null,
new AjaxOptions
{
HttpMethod = "Post",
UpdateTargetId = "IdentifyPerson",
InsertionMode = InsertionMode.Replace
}))
{
#Html.AntiForgeryToken();
#Html.ValidationSummary(true, "", new { #class = "text-danger" });
<div id="IdentifyPerson" style="padding:10px">
<div class="panel" style="padding:10px; direction:rtl">
<div class="row">
<div class="form-group col-md-2">
<label class="sr-only" for="LastName">:</label>
#*<input type="text" class="form-control" id="LastName"
placeholder="" name="LastName">*#
#Html.TextBoxFor(c => c.LastName, new { #class = "form-
control", placeholder = "" })
#Html.ValidationMessageFor(model => model.LastName, "",
new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="pull-left">
<button type="submit" id="RegisterBtn"
name="RegisterBtn" class="btn btn-info" style="padding:10px">AAA</button>
</div>
</div>
</div>
</div>
}
everything goes Good until i click on submit button (AAA), nothing is happened. i also use this line in my pages:
<script type="text/javascript"
src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
if i use HTML.BeginForm instead of Ajax.BeginForm submit button works fine but in return part, when i want to load the second partial view, it is loaded as a view!!
Question: what i want is: when i click on submit button Ajax.BeginForm or HTML.beginForm works and returned page shows as partial view not a view.
any one can help me?
thanks to Stephen Muecke, it seems that bundle not work properly. i don't know why really, i just added these four lines directly to partial view and it work fine :)
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery-
3.1.1.min.js")"></script>
<script type="text/javascript"
src="#Url.Content("~/Scripts/jquery.validate.js")"></script>
<script type="text/javascript"
src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")"></script>
<script type="text/javascript"
src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")"></script>

Partial view doesn't load inside current view

So I have this partial view:
#model QueryQuestionManager.Models.Domain.Answer
<script src="~/Scripts/DynamicList.js"></script>
<div class="editorRow">
#using (Html.BeginCollectionItem("Answers"))
{
<div>
#Html.LabelFor(x => x.AnswerText)
#Html.EditorFor(x => x.AnswerText)
</div>
delete
}
</div>
I want to load this partial view in my main view when someone clicks the link:
#model QueryQuestionManager.Models.Domain.Question
#{
ViewBag.Title = "Create";
}
<script src="~/Scripts/DynamicList.js"></script>
<br />
#using (Html.BeginForm(new { #class = "form", role = "form" }))
{
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(m => m.QuestionText)
</div>
<div class="form-control">
#Html.TextBoxFor(m => m.QuestionText)
#Html.ValidationMessageFor(m => m.QuestionText)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Category)
</div>
<div class="form-control">
#Html.TextBoxFor(m => m.Category)
#Html.ValidationMessageFor(m => m.Category)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Answers)
</div>
<br />
<div id="editorRows">
#foreach (var item in Model.Answers)
{
#Html.Partial("EditorRow", item);
}
</div>
#Html.ActionLink("Add another...", "BlankEditorRow", "Question", new { id = "addItem" })
<br />
<input type="submit" value="Save" class="btn btn-success" />
</div>
}
<br />
<div>
#Html.ActionLink("Back to List", "Index", "Home")
</div>
This is the action result from the controller
public ActionResult BlankEditorRow()
{
return PartialView("EditorRow", new Answer());
}
And then I have a javascript file for the dynamic adding and deleting partial views.
$('#addItem').click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) {
$('#editorRows').append(html);
}
});
return false;
});
$('a.deleteRow').live('click', function () {
$(this).parents('div.editorRow:first').remove();
return false;
});
But for some reason my partial view doesn't load inside my current view and it opens only the partial view.
Am I forgetting something?
I'm thinking you don't want that action link. I believe your jQuery click handler has the correct approach, but your action link is linking to your new URL (Question/BlankEditorRow) and you don't want that. Rather you just need to fetch this html, and insert it as you do, but WITHOUT navigating the main page to that URL.
Instead of the ActionLink, use an anchor tag and a hidden field.
<a id="addItem" href="#" />
<input type="hidden" id="partialViewAction" value="#Url.Action("BlankEditorRow","ControllerName")"
Now in your ajax call, instead of using the href property of the anchor, use the value of the hidden field.
url: $('#partialViewAction').val()

MVC Partial view to register button control action is Not applicable

I am use MVC Partial view .I have a two of Page AddPoll.cshtml and Listpoll.cshtml. page AddPoll.cshtml use Partial view.
I use AddPoll:partial view page to be placed a partial view with Listpoll.
#Html.Partial("/Areas/admin/Views/Poll/AddPoll.cshtml",new Mvc_baker.Areas.admin.Models.pollquestion());
AddPoll.cshtml
#model Mvc_baker.Areas.admin.Models.pollquestion
<link href="~/Content/bootstrapvalidform.css" rel="stylesheet" />
#using (Html.BeginForm(actionName: "AddPoll", controllerName: "Poll"))
{
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<form class="">
<div class="col-md-6">
<div class="panel panel-primary">
<label class="control-label">پرسش</label>
#Html.TextBoxFor(m => m.QuestionText, new { id = "Name",style="width:450px", #class = "form-control" })
#Html.ValidationMessageFor(m => m.QuestionText)
<input class="btn btn-primary btn-default" name="commit" value="register" type="submit">
</div>
</div>
</form>
}
When I click the register button control action is Not applicable
When the breakpoint action on control and I can not run
You seem to have 2 nested html forms which is invalid markup. The Html.BeginForm helper already generates a <form> tag. So you should get rid of the inner form.
#model Mvc_baker.Areas.admin.Models.pollquestion
<link href="~/Content/bootstrapvalidform.css" rel="stylesheet" />
#using (Html.BeginForm(actionName: "AddPoll", controllerName: "Poll"))
{
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-md-6">
<div class="panel panel-primary">
<label class="control-label">پرسش</label>
#Html.TextBoxFor(m => m.QuestionText, new { id = "Name",style="width:450px", #class = "form-control" })
#Html.ValidationMessageFor(m => m.QuestionText)
<input class="btn btn-primary btn-default" name="commit" value="register" type="submit" />
</div>
</div>
}

Upload file along with text in Create view

My first .Net/MVC project, I generated a view that allows me to list, edit, and create items in a database, and I would like to add a file upload control to the Create page, to just upload one file.
I understand that within [HttpPost] I need "public ActionResult Index(HttpPostedFileBase file)" but my current [HttpPost] is like this: "public ActionResult Create(lm_pics lm_pics)".
Why do you have 2 file inputs? Why do you have 2 forms? Isn't the first form sufficient (assuming of course you add the enctype="multipart/form-data" attribute to it as you cannot upload files without it)?:
#model PictureUploader_MVC.Models.lm_pics
#{
ViewBag.Title = "Create";
}
<h2>Upload Picture</h2>
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>lmit_pics</legend>
<div class="editor-label">
#Html.LabelFor(model => model.brand)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.brand)
#Html.ValidationMessageFor(model => model.brand)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.enabled)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.enabled)
#Html.ValidationMessageFor(model => model.enabled)
</div>
<div>
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
</div>
</fieldset>
<button type="submit">Create</button>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
and your controller action that will process the form submission:
[HttpPost]
public ActionResult Create(lm_pics lm_pics, HttpPostedFileBase file)
{
...
}

Firefox "jQuery is not defined" error in asp.net mvc 3

I'm using asp.net mvc also using jQuery ui dialog, i'm showing a partialview in a jQuery dialog but Firefox give me an error on these two files below. I post an Ajax.BeginForm() to server. on first post it's working fine but on sencond post it destroys my dialog.
jquery.validate.min.js
jquery.validate.unobtrusive.min.js
Error : jQuery is not defined
I dont have this problem in IE, please help.
#model MvcSmkApplication.Models.LoginModel
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Ajax.BeginForm("AuthenticateUser", "Members", new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "LoginForm",
OnSuccess = "OnSuccess",
}))
{
<div id="LoginForm">
#Html.ValidationSummary(true)
<fieldset>
<legend></legend>
<div class="editor-label">
#Html.LabelFor(model => model.EmailAddress)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmailAddress)<br />
#Html.ValidationMessageFor(model => model.EmailAddress)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)<br />
#Html.ValidationMessageFor(model => model.Password)
</div>
#foreach (ModelState modelState in ViewData.ModelState.Values)
{
foreach (ModelError error in modelState.Errors)
{
<div style="color: Red;">#error.ErrorMessage</div>
}
}
<div style="float: right;">
<input type="submit" value="Login" class="buttonAsLink" />
</div>
</fieldset>
</div>
}
<script type="text/javascript">
function OnSuccess(e) {
if (e["success"] == "true") {
$("#dialog").dialog("close");
location.reload();
}
else {
//alert('error');
}
}
</script>
You might try referencing your scripts like this:
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")"></script>
Here is the solution which I found it after 3 weeks research.
<script type="text/javascript">
function OnSuccess(e) {
if (e["success"] == "true") {
$("#dialog").dialog("close");
location.reload();
}
else {
$("#dialog").html(e);
return false;
}
}
</script>

Resources