I have many AJAX forms on the page and on button click I need to submit them all. Regular **forms.each(function (index, form) { $(form).submit();} won't work for me because in this way ONLY the last form will be submitted eventually. Therefore, I need submit them via $.ajax(...). But I want to enable submit ONLY and ONLY if form is VALID
On "submitForms" click the function "submitTest" is invoked.
From jQuery documantation "submitHandler" would be called if form is VALID.
So, the validation works and "submitHandler" is NOT invoked if form is INVALID. BUT, the XmlHttpRequest is sent anyway, though "submitHandler" isn't invoked.
Where is my mistake? Or is there other way to do it?
Thank you
<% using (Ajax.BeginForm("FormPost", "Customer", null, new AjaxOptions() { HttpMethod = "POST" }, new { #class = "form-container" }))
{ %>
<%: Html.TextAreaFor(m => m.Name, new { width = 440, height = 100 })%>
<input type="button" value="submitForms" />
<% }%>
<script type="text/javascript">
function submitTest(){
var forms = $(".form-container");
forms.each(function (index, form) {
$(form).validate({
submitHandler: function (form) {
$.ajax(
{
....
});
}
});
});
forms.each(function (index, form) {
$(form).submit();
});
}
</script>
EDITED
Most likely it's due to the Ajax.BeginForm as that sets up an onclick and an onsubmit handler. Which probably winds up triggering first before your validate submit handler.
UPDATE
If you want to keep using the ajax form in the module where you plan on submitting the form via jQuery.ajax, you can do the following.
$(function() {
$('.form-container').removeAttr('onsubmit').removeAttr('onclick');
});
This will remove the handlers Ajax.BeginForm puts on the form tag. You'll need a way to not include this script in the other module though.
Related
I am writing an AJAX function in ASP.Net MVC5 and I am getting a problem that the form AJAX request goes only one time. It is a search page. After I choose the filter I press search I get the correct result. However if I changed the filter and click the search submit again, nothing will happen.
var ajaxFormSubmit = function() {
var $form = $(this);
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $form.serialize()
};
$.ajax(options).done(function (data) {
var target = $($form.attr("data-enbw-target"));
target.replaceWith(data);
debugger;
});
return false;
};
$("form[data-enbw-ajax='true']").submit(ajaxFormSubmit);
<form method="get" id="documentForm" action="#Url.Action("Index", "DocumentSearch")" def data-enbw-ajax="true" data-enbw-target="#documentSearchResult">
<button type="submit" id="submitbtn" name="submitbtn" tabindex="100" class="k-button">
<img src="~/Content/search_small_icon.png" />
#WebResources.DocumentSearchButton
</button>
</form>
#Html.Partial("Results", #Model)
public ActionResult Index(DocumentSearchInput model)
{
if (Request.IsAjaxRequest())
{
return PartialView("Results", result);
}
return View(result);
}
I do not get any error. and when I get a debugger; in javascript. the new data is correct. can you please help me.
You are replacing the form in your ajax success. As such, the new form will not have the submit binding on it. If you truely want to do this you will have to rebind to the new form, or possibly use a delegate instead.
$('parentSelector').on('event', 'childSelector', function(){});
parentSelector - A parent element of the child that pre-exists the child element and should typically not be removed/created during the page lifespan.
childSelector - A selector for the element that will be created/changed/removed at some point in the lifespan of the page.
I found the answer.
the problem wasn't with the submit. the problem was with re-writing the data.
$.ajax(options).done(function (data) {
$("#documentSearchResult").empty();
$("#documentSearchResult").html(data);
});
simply, I empty the div then write inside.
I have a form with a simple button $builder->add('language_switcher', ButtonType::class); which should simply, if pressed, add another field. To do that, I used Symfony's cookbook http://symfony.com/doc/current/form/dynamic_form_modification.html
$builder
->get('language_switcher')
->addEventListener(
FormEvents::POST_SUBMIT,
function () use ($builder, $options) {
$preparedOptions = $this->prepareOptions($options['data']['productCustomizations']);
$builder->add('lang_switcher'), ChoiceType::class, $preparedOptions);
}
);
When now submitting it via AJAX
<script>
var $button = $('#xyz');
$button.click(function() {
var $form = $(this).closest('form');
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
success: function(html) {
console.log(html);
$('#xyz').replaceWith($(html).find('#lang_switcher'));
}
});
});
</script>
I'm getting the error Buttons do not support event listeners. So I tried it out with a hidden field. I added the hidden field to the Form, set the EventListener to it, and added this data to my AJAX request
data[$('#id_of_hidden_field').attr('name')] = 1;
However this did nothing. The example in the cockbook is after submitting a choice field so I don't know how to adapt it to my needs. I couldn't use a SubmitType, because then it would submit the form, right? I just want to have it with a simple button.
The problem is, that, when I do a console.log(html) I don't see the new html element, so it seems like I'm not getting to the EventListener which is weird, because if I dump contents inside the listener I'm getting some data. It just seems like I'm not getting it inside the response
Ok, got it. The problem was that I used the builder inside the POST_SUBMIT event but I had to use a FormInterface. Since I couldn't add it AFTER submit I had to buy the same callback function as in Symfony's cookbook
$formModifier = function (FormInterface $form, $preparedOptions) {
$form->add($this->childIdentifier, ChoiceType::class, $preparedOptions);
};
And then the listener is built like this
$builder
->get('lang_switcher')
->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier, $options) {
$preparedOptions = $this->prepareOptions($options);
$formModifier($event->getForm()->getParent(), $preparedOptions);
}
);
<script type="text/javascript">
function inputBtn(){
var input=document.createElement('input');
input.type="file";
input.name="img[]";
input.multiple="multiple";
//without this next line, you'll get nuthin' on the display
document.getElementById('target_div').appendChild(input);
}
</script>
<button id="ifile" onclick="inputBtn();">create</button>
<form action="test.php" method="post" enctype="multipart/form-data">
<div id="target_div"></div>
<input type="submit">
</form>
I have an AJAX form where the url id needs to be from JavaScript
#using(Ajax.BeginForm("Add","Comments", new { ArticleID = 3 }, new AjaxOptions { UpdateTargetId="Comments"}))
Where ArticleID = 3 should be replaced so that the ArticleID value is set equal to the result of a called Javascript function. Something like
JS:
function GetArticleID()
{
return 3;
}
Razor:
#using(Ajax.BeginForm("Add","Comments", new { ArticleID = GetArticleID() }, new AjaxOptions { UpdateTargetId="Comments"}))
Controller:
public ActionResult Add(int ArticleID, Comment model)
{
}
How can I use JavaScript function result as BeginForm parameter?
The line #using(Ajax.BeginForm(" will be executed by razor on server. At that time it does not have any knowledge of the javascript methods in your client browser. So you cannot mix a javascript function there.
I prefer to write clean custom code to do the ajax form submit (instead of using Ajax.BeginForm) because it allows me to customize any way i want.
Keep your form as a normal form.
#using(Html.BeginForm("Add","Comments"))
{
<input type="hidden" name="ArticleId" id="ArticleId" value=""/>
<input name="CommentText" type="text" />
<input type="submit" id="saveCmntBtn" />
}
Now listen to the click event of the submit button. Assign the ArticleId value to the input field, get the serialized version of the form and post to server. You may use jQuery serialize() method to get the serialized version of your form.
$(function(){
$("#saveCmntBtn").click(function(e){
e.preventDefault();
$("#ArticleId").val(GetArticleID());
var f=$(this).closest("form");
$.post(f.attr("action"),f.serialize(),function(res){
$("#Comments").append(res);
});
});
});
I am having a issue with Spring Webflow and JQuery.
I am using JQuery to check for the user changing the value in a dropdown box but once the user selects a new value in the dropdown box I need to change the eventID so spring webflow knows what I am trying to do and to post the fall form with all of the html..
Here is the old code that used to work before the firm requested that I removed dijit and use jquery only
<script type="text/javascript">
Spring.addDecoration(new Spring.ElementDecoration({
elementId : "borough",
widgetType : "dijit.form.Select",
widgetAttrs : {
promptMessage : "Enter Borough",
required : true,
onChange : function() {
Spring.remoting.submitForm(
'submit',
'member',
{_eventId: 'loadSchools', fragments:'contents'}
);
return false;
} }}));
</script>
now here is the new code that looks like it does change the eventID and does the post but I need all the data from the form on the post
<script type="text/javascript">
$(document).ready(function () {
$("#borough").change(function() {
$.post('${flowExecutionUrl}', {_eventId: 'loadSchools'}, function(){
alert('eventid was sent to url');
});
});
});
</script>
Can some someone help me out here....
You can pass the form data like this:
$(document).ready(function () {
$("#borough").change(function() {
// first, populate hidden field with the event ID
$('input[name="_eventId"]').val('loadSchools');
// serialize the form fields to a URL string
var params = $('#myForm').serialize();
$.post('${flowExecutionUrl}', params, function(){
alert('eventid was sent to url');
});
});
});
where you have a hidden input in your form, eg. <input type="hidden" name="_eventId" />. Hope that helps.
I am creating an MVC 3 web application. I want to use Data Annotations on my entity class and then use unobtrusive client side validation before making a post back to the server. This works fine when making a regular post. I get validation and the validation summary if any of the fields are not valid. However, I want to post back the information via ajax and json. How can I 'manually' validate the form on the client side first then make my ajax post back to the server. Below is a summarized version of my code.
public class Customer
{
[Required(ErrorMessage = "The customer's first name is required.")]
public string FirstName { get; set; }
[Required(ErrorMessage = "The customer's last name is required.")]
public string LastName { get; set; }
}
<% using (Html.BeginForm()) { %>
<%: Html.LabelFor(model => model.FirstName, "First Name")%>
<%: Html.TextBoxFor(model => model.FirstName, new { #class = "TextBox", id = "Customer.FirstName" })%>
<%: Html.ValidationMessageFor(model => model.FirstName, "*")%>
<%: Html.LabelFor(model => model.LastName, "Last Name")%>
<%: Html.TextBoxFor(model => model.LastName, new { #class = "TextBox", id = "Customer.LastName" })%>
<%: Html.ValidationMessageFor(model => model.LastName, "*")%>
<div id="CustomerEditSave" class="Button CustomerEditButtons" style="margin-right:40px;">
Save
</div>
<%: Html.ValidationSummary(true) %>
<% } %>
I have tried this code but it only validates the first name and does not display the validation summary.
$("#CustomerEditSave").click(function () {
$(form).validate();
//Ajax call here
});
Try:
//using the form as the jQuery selector (recommended)
$('form').submit(function(evt) {
evt.preventDefault();
var $form = $(this);
if($form.valid()) {
//Ajax call here
}
});
//using the click event on the submit button
$('#buttonId').click(function(evt) {
evt.preventDefault();
var $form = $('form');
if($form.valid()) {
//Ajax call here
}
});
This should work with jQuery ajax and MSAjax calls. Could also try using http://nuget.org/packages/TakeCommand.js or https://github.com/webadvanced/takeCommand it will automatically handle this for you.
I have been phaffing about with MVC client side validation for days:
Don't use .click use .submit:
$("#MyForm").on('submit',function () {
if($("#MyForm").valid())
{
//Do ajax stuff
}
//Return false regardless of validation to stop form submitting
//prior to ajax doing its thing
return false;
});
I'm going add an update to this, consider cancelling the event rather than returning false (or do both):
$("#MyForm").on('submit',function (e) {
if($("#MyForm").valid())
{
//Do ajax stuff
}
e.preventDefault();
//Return false regardless of validation to stop form submitting
//prior to ajax doing its thing
return false;
});
At least in my case (MVC 5), it was also necessary to add the following code or else .valid() would always return true:
$(function () {
$(document).ajaxComplete(function(event, request, settings){
//re-parse the DOM after Ajax to enable client validation for any new form fields that have it enabled
$.validator.unobtrusive.parse(document);
});
});
See http://johnculviner.com/the-unobtrusive-libraries-client-validation-on-ajax-in-asp-net-mvc-3/
IMPORTANT!!:
Paul's solution is the correct answer to the question, not Dr Rob's.
Although you can just use valid() instead of validate().form().
But more importantly, there really is no reason to restrict your code as suggested by Dr Rob, ie, not .click and only use .submit. That isn't what solved the problem! What solved the problem was wrapping the $.ajax(...) call in the if statement. Ie:
if($("#MyForm").valid())
{
//call to $.ajax or equivalent goes in here.
}
I think that needs clarifying as otherwise the real answer to the problem is obfuscated.
$(YourForm).data('unobtrusiveValidation').validate()
if(!$('#myform').data('unobtrusiveValidation').validate())
{
// add your extra custom logic
}
else
{
$('#myform').submit();
}
It triggers the validation and returns a boolean, so you can check before submit.
.Valid() works. i.e it tells you whether your form is valid. However alone it does not help to show AND hide messages correctly. here's my manual validation method
function validate()
{
//valid() not only tells us whether the form is valid but
//also ensures that errors are shown !!!
if ($("form").valid())
{
//if the form is valid we may need to hide previously displayed messages
$(".validation-summary-errors").css("display", "none");
$(".input-validation-error").removeClass("input-validation-error");
return true;
}
else
{
//the form is not valide and because we are doing this all manually we also have to
//show the validation summary manually
$(".validation-summary-errors").css("display", "block");
return false;
}
}
I tried all of the above solutions but none worked on MVC5.
I am using jQuery v2.1.4 and jQuery.Validation v1.11.1.
I need to trigger validation while on page render. Only below one worked for me.
$(document).ready(function () {
...
validateForm();
}
function validateForm() {`enter code here`
var elem = document.getElementById('btnSave');
elem.click();
}
$('#btnSave').click(function (evt) {
//evt.preventDefault();
var form = $('form');
if (form.valid()) {
//Ajax call here
}
//$(".validation-summary-errors").css("display", "block");
});
function Validate() {
// If no group name provided the whole page gets validated
Page_ClientValidate();
}