How to pass an object using the Ajax.BeginForm() helper - ajax

I am trying to use the Ajax.BeginForm to post a message back to the server and I need to give a name to the form, i.e. use the parameter htmlAttributes. For that I am using the following signature:
#using (Ajax.BeginForm("SendEmail", "Contacts", null, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "sendMessageArea" }, new { Name = "sendEmail" }))
This code doestn't work, it updates the whole page and the controller is expecting an object as a paramenter:
public ActionResult SendEmail(Contacts contacts)
Here is the view:
<div class="row">
<div class="large-12 columns" >
#using (Ajax.BeginForm("SendEmail", "Contacts", null, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "sendMessageArea" }, new { Name = "sendEmail" }))
{
<fieldset class="form-group">
<legend>Leave a message</legend>
<div class="panel">
<div class="row">
<div class="large-offset-2 large-8 columns">
<div class="row">
<div class="large-2 columns">
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label" })
</div>
</div>
<div class="large-8 columns">
#Html.TextBox("Name", Model.Name, new { placeholder = "Your name..." })
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="large-2 columns">
</div>
</div>
<div class="row">
<div class="large-2 columns">
<div class="form-group">
#Html.LabelFor(model => model.EMail, new { #class = "control-label" })
</div>
</div>
<div class="large-8 columns">
<div class="form-group">
#Html.TextBox("EMail", Model.EMail, new { placeholder = "Your email..." })
#Html.ValidationMessageFor(model => model.EMail)
</div>
</div>
<div class="large-2 columns">
</div>
</div>
<div class="row">
<div class="large-2 columns">
<div class="form-group">
#Html.LabelFor(model => model.Message, new { #class = "control-label" })
</div>
</div>
<div class="large-8 columns">
#Html.TextArea("Message", Model.Message, new { placeholder = "Your message here...", #class = "comment-control", id = "message" })
#Html.ValidationMessageFor(model => model.Message)
</div>
<div class="large-2 columns">
</div>
</div>
<div class="row">
<div class="large-offset-8 large-3 columns">
<input type='submit' style='position:absolute;top:0;left:-9999px;width:1px;height:1px' />
<a class='submit-button' href="javascript:sendEmail.submit()">
<span class='submit-button-inner'>Submit</span>
</a>
</div>
</div>
</div>
<div class="large-2 columns">
</div>
</div>
</div>
</fieldset>
}
</div>
and the partial view:
<span class="success label">#Resources.Contacts.Index.SuccessSendMessage</span>
I think the problem should be related with the routeValues parameter because if I use a simple example without the htmlAttributes and routeValues it works well.
Any guess?

Related

Google Invisible Recaptcha - Enter press key not work

I implemented google invisible recaptcha on my login form but when i submit the form by pressing Enter key, it does not send any response token. However, when i clicked button whose type submit, it validates successfully.
How can I get response with both press enter and click button?
C# - MVC application used as technologhy. #Model.GoogleRecaptchaSiteKey property is filled on my application.
Here is my login form html
#using (Html.BeginForm("Login", "Account", new { ReturnUrl = Request.QueryString["ReturnUrl"] }, FormMethod.Post, new { #class = "login-form", id = "login-form" }))
{
<div class="login-form">
<h3 class="form-title">Login Form</h3>
<div class="form-group">
<!--ie8, ie9 does not support html5 placeholder, so we just show field title for that-->
<label class="control-label visible-ie8 visible-ie9">Kullanıcı Adı</label>
<div class="input-group">
<div class="input-group-addon">
<i class="fa fa-user"></i>
</div>
#Html.TextBoxFor(f => f.UserName, new { title = "Kullanıcı adınızı giriniz.", #class = "form-control placeholder-no-fix", #placeholder = "Kullanıcı Adı", #value = "", #autofocus = "true" })
</div>
#Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="form-group">
<label class="control-label visible-ie8 visible-ie9">password</label>
<div class="input-group" id="show_hide_password">
<div class="input-group-addon">
<i class="fa fa-lock"></i>
</div>
#Html.TextBoxFor(f => f.Password, new { #title = "password.", #type = "password", #class = "form-control placeholder-no-fix", #placeholder = "password", #value = "" })
<div class="input-group-addon">
<i class="fa fa-eye-slash" id="i_show_hide_password" aria-hidden="true"></i>
</div>
</div>
#Html.ValidationMessageFor(m => m.Password)
</div>
<div class="form-actions">
#Html.AntiForgeryToken()
<input id="login" type="submit" class="btn green pull-right g-recaptcha" data-size="invisible" data-sitekey="#Model.GoogleRecaptchaSiteKey" data-callback="onSubmit" value="Login" />
#Html.ValidationMessage("reCaptcha")
<br />
</div>
</div>
}
Script is below here
function onSubmit(token) {
document.getElementById("login-form").submit();
}

Server Side Field validation in .NET Core 3.1 MVC in modal popup not working

I have a partial view within a modal popup. Client side field validation works, such as required fields. But there are some server side validations that don't present themselves whilst keeping the modal popup open.
For example, I create a new 'teacher band' and the controller checks for a duplicate band. When I press submit, the page actually browses to the partial view and presents the error in the validationsumary, rather than keeping it within the modal.
Controller -
public async Task<IActionResult> Add()
{
CreateTeacherBandViewModel model = new CreateTeacherBandViewModel();
return PartialView(model);
}
[HttpPost]
public async Task<IActionResult> Add(CreateTeacherBandViewModel model)
{
if (ModelState.IsValid)
{
if (await _teacherBandService.BandExists(model.BandName))
{
ModelState.AddModelError("", "A band with that name already exists");
return PartialView(model);
}
else
{
await _teacherBandService.Add(model);
return RedirectToAction("Index", "TeacherBand", null);
}
}
else
{
return PartialView();
}
}
Partial View
#model Models.CreateTeacherBandViewModel
<script src="~/assets/js/plugins/pickers/color/spectrum.js"></script>
<script src="~/assets/js/demo_pages/picker_color.js"></script>
#using (Html.BeginForm("Add", "TeacherBand", null))
{
<!-- Iconified modal -->
<div id="modal_addband" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title"><i class="icon-user-plus mr-2"></i> Add New Band</h5>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Name</label>
#Html.TextBoxFor(model => model.BandName, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.BandName)
</div>
<h6 class="font-weight-semibold">Charge Rates</h6>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label>AM</label>
#Html.TextBoxFor(model => model.DefaultChargeRateAM, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultChargeRateAM)
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>PM</label>
#Html.TextBoxFor(model => model.DefaultChargeRatePM, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultChargeRatePM)
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Daily</label>
#Html.TextBoxFor(model => model.DefaultChargeRateDaily, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultChargeRateDaily)
</div>
</div>
</div>
<h6 class="font-weight-semibold">Pay Rates</h6>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label>AM</label>
#Html.TextBoxFor(model => model.DefaultPayRateAM, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultPayRateAM)
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>PM</label>
#Html.TextBoxFor(model => model.DefaultPayRatePM, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultPayRatePM)
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Daily</label>
#Html.TextBoxFor(model => model.DefaultPayRateDaily, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.DefaultPayRateDaily)
</div>
</div>
</div>
<hr />
<div class="form-group">
<label>Colour</label>
#Html.TextBoxFor(model => model.Colour, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.Colour)
</div>
#Html.ValidationSummary()
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Create Band</button>
</div>
</div>
</div>
</div>
<!-- /iconified modal -->
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js">
</script>
}
Finally, the Index page that renders the partial view
#Html.Partial("Add", new CreateTeacherBandViewModel())

Submit send values null in Ajax to Controller

I have several ajax.begin form within a Ajax.BeginForm "father".
The problem to the "parent" function or the first Ajax.BeginForm need to put another empty begin.form, but depending on the way place or father sends "nulls" information or the first Ajax.BeginForm send a submit to the Ajax.BeginForm "father".
my code :
#using (var f = Html.Bootstrap().Begin(new Form("","").Id("").HtmlAttributes(new { ReturnUrl = Request.QueryString["ReturnUrl"] })))
{
using (Ajax.BeginForm("", "", new AjaxOptions { }))
{
}
using (#Ajax.BeginForm("SaveChanges", "Requests", null, new AjaxOptions { HttpMethod = "POST" }, null))
{
using (Ajax.BeginForm("", "", new AjaxOptions { }))
{
}
using (#Ajax.BeginForm("AddMoney","Requests", null, new AjaxOptions { HttpMethod = "POST" }, null))
{
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-title">
<h3>
<i class="fa fa-bars"></i>Money</h3>
<div class="box-tool">
<label class="control-label">
</label>
<a data-action="collapse" href="#"><i class="fa fa-chevron-up"></i></a>
</div>
</div>
<div class="box-content">
<div class="row">
<div class="col-md-3">
<div class="form-group">
#f.FormGroup().TextBoxFor(_ => _.Money).Class("form-control").HtmlAttributes(new { mask = "999999999999" })
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
using (#Ajax.BeginForm("AddDate", "Request", null, new AjaxOptions { HttpMethod = "POST"}, null))
{
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="row">
<div class="col-md-2" id="divDtFinalCorrecao" style="display: none;">
<div class="form-group">
#f.FormGroup().TextBoxFor(_ => _.date).Class("datepicker"))
</div>
</div>
</div>
</div>
</div>
</div>
}

Validate Modal Form

I am trying to popup a form so user fill it then I save that record. If data is wrong I want to inform the user just a classic validation issue.
I am trying this code but when model is not valid it show the mistake but literally it only returns what is in the partial view, it is not loading my layout nor my modal form, all I get is a white page just with my partial.
so what am I doing wrong?
This is my modal form:
And after validation all I get is this:
Code:
Model:
public class Car
{
public int Id { get; set; }
[Required]
[StringLength(50, MinimumLength = 6)]
public string Model { get; set; }
public string Brand { get; set; }
public string Year { get; set; }
public string Color { get; set; }
}
View:
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Add Car</h4>
</div>
<div class="modal-body">
#Html.Partial("CreatePartialView",new Car())
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" id="savechanges">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
my partial:
#model ControliBootstrap.Models.Car
#using (Ajax.BeginForm("ModalAdd", "Cars",new AjaxOptions()
{
UpdateTargetId = "mymodalform"
}))
{
<div class="form-horizontal" id="mymodalform">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Model, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Model)
#Html.ValidationMessageFor(model => model.Model)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Brand, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Brand)
#Html.ValidationMessageFor(model => model.Brand)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Year, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Year)
#Html.ValidationMessageFor(model => model.Year)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Color, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Color)
#Html.ValidationMessageFor(model => model.Color)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
and finlly my controler:
public ActionResult ModalAdd(Car car)
{
if (ModelState.IsValid)
{
db.Cars.Add(car);
db.SaveChanges();
return RedirectToAction("Index");
}
return PartialView("CreatePartialView",car);
}
Don't forget to include jQuery Unobtrusive AJAX - it's the library that makes normal HTML forms have some AJAX capabilities.

2 validation groups

I have 2 validation forms on page.
<div id='LogOn' style="background-color: White;">
#using (Ajax.BeginForm("LogOnAjax", "Home", new AjaxOptions { UpdateTargetId = "LogOn", OnSuccess = "logInComplete" }))
{
//ITW2012Mobile.ViewModels.LogOnModel m = Model;
#Html.HiddenFor(model => model.IsLoggedIn)
#Html.HiddenFor(model => model.ReturnUrl)
<div>
#Html.ValidationSummary()
</div>
<div>
#Html.LabelFor(model => model.UserName)
#Html.EditorFor(model => model.UserName)
</div>
<div>
#Html.LabelFor(model => model.Password)
#Html.EditorFor(model => model.Password)
</div>
<div>
<input type="submit" value="Login" />
</div>
}
</div>
and
<fieldset>
#using (Html.BeginForm(Model.ActionMethod, Model.Controller))
{
#Html.ValidationSummary()
.....
<div class="display-label"> E-mail Address * </div>
<div class="display-field">
#Html.EditorFor(model => model.Username)
#Html.ValidationMessageFor(model => model.Username)
</div>
<div class="display-label"> Create Password * </div>
<div class="display-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<p>
<input type="submit" value="Create" />
</p>
}
</fieldset>
How can I mark that ModelState.AddModelError is for first of form, because I see the same error in the both places of validation summary?
How can I mark that ModelState.AddModelError is for first of form
You can't.
What you can do is having ValidationMessageFor for each form properties instead of the ValidationSummary

Resources