Form validation works, but I can't get the Ajax call to fire correctly. The submitHandler is being reached, but the Ajax call isn't. I have included a Fiddle at the bottom, but obviously you can't fire ajax calls from there.
$(".player-code, .submit").hide();
//VALIDATION
$(function () {
$("#form").validate({
rules: {
playerClass: {
required: true
}
},
submitHandler: function () {
var accountNumber = $(".accountNumber").val();
var domain = $(".domain").val();
var playerClass = $(".playerClass").val();
var dataString = accountNumber + playerClass;
//Save Form Data........
$.ajax({
type: "POST",
dataType: "json",
url: "/",
contentType: "application/json",
data: dataString,
success: function () {
$(".player-code").show();
$('.render-info').html("<div class='alert alert-success'>You've successfully built your player code</div>");
},
failure: function () {
$('.render-info').html("<div class='alert alert-failure'>Submission Error</div>");
}
});
}
});
});
jQuery.validator.addMethod("domainChk", function (value, element, params) {
if (this.optional(element)) return true;
var regExp = new RegExp("^(?!www\\.|http:\/\/www\.)(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$");
return regExp.test(value);
}, "Valid hostname required for player code");
jQuery.validator.addClassRules({
domainChk: {
domainChk: true
}
});
$('input[type="text"]').on('click keyup blur', function () {
if ($('#form').valid()) {
$(".submit").show();
} else {
$(".submit").hide();
}
});
//PREPOPULATE ACCOUNT FROM QUERY STRING
var url = window.location.href;
var regex = /=.*/; // match '=' and capture everything that follows
var accountId = url.match(regex);
$(".accountNumber").val(accountId).remove("=");
//
jsFiddle: Link
There is no failure: option for $.ajax(). If you want to see any errors that happen in the ajax call, then use error: to capture the error.
To make form submit you should use
<button class="btn btn-default submit" type="submit">Submit</button>
instead of <div class="btn btn-default submit">Submit</div>
submitHandler will be called only on native form submit.
Fiddle
Related
Sorry if there are some mistakes, but I am a total noob and I am also posting for the first time on StackOverflow.
I am trying to configure a submit form, that controls if the inserted PIN is right, and if so goes on with the submission. I did some online research and found out that with jQuery we can use to function event.preventDefault(), I tried to insert it inside my AJAX request but it looks like it doesn't stop the form from being saved.
The code looks like these:
function verifyOTP() {
$(".error").html("").hide();
$(".success").html("").hide();
var otp = $("#contomovimentato").val();
var PIN = $("#PINvalue").val();
var input = {
"otp" : otp,
"PIN" : PIN,
"action" : "verify_otp"
};
if (otp != null) {
$.ajax({
url : 'm_ajaxpinr.php',
type : 'GET',
dataType : "json",
data : input,
success : function(response) {
$("." + response.type).html(response.message)
$("." + response.type).show();
},
error : function() {
alert("ss");
}
});
} else {
$(".error").html('XPIN non valido.')
$(".error").show();
error : function(event) { event.preventDefault(); };
}
//if I insert "return false;" here the submit is always blocked
}
I checked on atom if the parenthesis are right and it looks like it is.
Any ideas how I should use the preventDefault()?
I also checked if the output of m_ajaxpinr.php is correct, and it is. I also tried like these but it still didn't work...
if (otp != null) {
$.ajax({
url : 'm_ajaxpinr.php',
type : 'GET',
dataType : "json",
data : input,
success : function(response) {
$("." + response.type).html(response.message)
$("." + response.type).show();
$("form").submit(function(event) {
if (response.type == 'success')
{
alert(response.type);
}
else if (response.type == 'error')
{
alert(response.type);
event.preventDefault();
}
});
as said in comment above ajax call is asynchronous, you need to complete cancel default action for the form or put event.preventDefault(); on the top function, then submit it in success function if it valid otp.
.val() will not return null, it return empty if no input.
$('#myForm').on('submit', verifyOTP);
function verifyOTP(e) {
e.preventDefault(); // note this
$(".error").html("").hide();
$(".success").html("").hide();
var otp = $("#contomovimentato").val();
var PIN = $("#PINvalue").val();
var input = {
"otp": otp,
"PIN": PIN,
"action": "verify_otp"
};
if (otp) { // mean not null, undefined, empty, false, 0
$.ajax({
//url: 'm_ajaxpinr.php',
url: 'https://httpbin.org/anything/test',
type: 'GET',
dataType: "json",
data: input,
success: function(response) {
$("." + response.type).html(response.message)
$("." + response.type).show();
if(response.args.otp == 1234){
console.log('valid otp, continue submission')
$('#myForm').off('submit'); // remove submit event
$('#myForm').submit(); // then submit the form
}
else{
console.log('invalid pin,\nvalid pin: 1234');
}
},
error: function() {
console.log("server error, submission cancelled");
}
});
} else {
$(".error").html('XPIN non valido.')
$(".error").show();
console.log("otp maybe empty, submission cancelled");
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myForm">
<input id="contomovimentato">
<button>submit</button>
</form>
I have an HTML form which I am validating using JavaScript like below code. All the JavasCript code is in an app.js file.
App.js file
function validateForm () {
var amount = document.forms["salesform"]["amount"];
var buyer = document.forms["salesform"]["buyer"];
var buyerRegex = /^[a-zA-Z0-9_ ]*$/;
var receipt_id = document.forms["salesform"]["receipt_id"];
var receiptIdRegex = /^[a-zA-Z_ ]*$/;
let items = document.querySelectorAll(".items")
var itemsRegex = /^[a-zA-Z_ ]*$/;
var buyer_email = document.forms["salesform"]["buyer_email"];
var note = document.forms["salesform"]["note"];
var city = document.forms["salesform"]["city"];
var cityRegex = /^[a-zA-Z_ ]*$/;
var phone = document.forms["salesform"]["phone"];
var phoneRegex = /^[0-9]*$/;
var entry_by = document.forms["salesform"]["entry_by"];
var entryByRegex = /^[0-9]*$/;
function validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}
if (amount.value == "") {
alert("Please enter the amount.");
amount.focus();
return false;
} else if (isNaN(amount.value)) {
alert("Amount must be only numeric value.");
amount.focus();
return false;
} else if (amount.length > 10 ) {
alert("Amount must be less than 10 characters long.");
amount.focus();
return false;
}
// more validation.....
return true;
}
In this file I have another jQuery Ajax code validate the form using Server. So that I have added following Ajax code blow that JS validation code:
$("#salesForm").submit(function(e) {
e.preventDefault();
$.ajax({
url : '../process/add-data.php',
type: 'POST',
dataType: "html",
data : $(this).serialize(),
beforeSend : function () {
$(".formResult").html("Please wait...");
},
success : function ( data ) {
$(".formResult").html( data );
}
});
});
for the HTML form
<form name="salesform" id="salesForm" onsubmit="return validateForm();" method="POST">
Now when the form is validating using JavaScript then it also vaidating the form using Ajax.
But first its should validate using JavaScript and then Ajax.
Remove onSubmit from the element and modify your Ajax function to return invalid form BEFORE making the call.
$("#salesForm").submit(function(e) {
e.preventDefault();
if(!validateForm()) return;
$.ajax({
url : '../process/add-data.php',
type: 'POST',
dataType: "html",
data : $(this).serialize(),
beforeSend : function () {
$(".formResult").html("Please wait...");
},
success : function ( data ) {
$(".formResult").html( data );
}
});
});
You need to return false inside beforeSend callback, as it is described in official jQuery documentation:
beforeSend Type: Function( jqXHR jqXHR, PlainObject settings )
A pre-request callback function that can be used to modify the jqXHR (in
jQuery 1.4.x, XMLHTTPRequest) object before it is sent. Use this to
set custom headers, etc. The jqXHR and settings objects are passed as
arguments. This is an Ajax Event. Returning false in the beforeSend
function will cancel the request. As of jQuery 1.5, the beforeSend
option will be called regardless of the type of request.
So, you need to do something like this:
beforeSend : function () {
$(".formResult").html("Please wait...");
if(!validateForm()) {
// Here you remove your "Please wait..." message
return false;
}
// Or simply return the value from validateForm():
// return validateForm();
},
And, of course, remove the onsubmit="return validateForm();" from your form tag.
I don't know what I am doing wrong here. but jquery validation is not working in partialview.
let me explain what I did
I am loading parial view from parent (It is not ajax load)
Parent
<div id="EmailInformationBlock" class="profileSection">
<div class="sectionTitle">
<span>Email</span>
</div>
<div id="DivEmailContainer" style="display:block">
#Html.Partial("_DisplayEmail", Model)
</div>
<hr />
</div>
Partial view
#using (Html.BeginForm(null, null, FormMethod.Get, new { name = "frmEmail", id = "frmEmail" }))
{
<td>#Html.Label("Email Location", new { #class = "control-label" })</td>
<td>
#Html.DropDownListFor(model => model.CommunicationLocation,
Enumerable.Empty<SelectListItem>(),"Select ",
new { #class = "input-validation-error form-control",
#name="CommunicationLocationEmail" }
)
}
</td>
}
<script type="text/javascript">
$(function () {
$.validator.addMethod("selectNone",
function (value, element) {
return this.optional(element) || element.selectedIndex != 0;
},
"Please select an option."
);
$("#frmEmail").validate({
rules: {
CommunicationLocation: {
selectNone: true
}
},
messages: {
CommunicationLocation: {
selectNone: "This field is required"
}
},
submitHandler: function (form) {
('#frmEmail').submit(function () {
$.ajax({
url: 'customer/PostEditEmail',
type: 'Post',
data: $(this).serialize(),
success: function (result) {
// $('#DivEmailContainer').html(result);
}
});
});
}
});
$.ajax({
url: "customer/GetCommunicationLocationList",
type: 'GET',
dataType:"json",
success: function(d) {
// states is your JSON array
var data = d.Data;
// alert(JSON.stringify(d.Data));
$.each(data, function (i) {
if (data[i].Description != "Bulk Dues"){
var optionhtml = '<option value="' +
data[i].Code + '">' + data[i].Description + '</option>';
$("#CommunicationLocation").append(optionhtml);
}
});
},
error: function (xhr) { alert("Something seems Wrong"); }
});
});
</script>
After I submit form is redirecting to new url. It shouldn't go to any url.
what I am doing wrong here.
I might be wrong, but it looks like jquery is not aware that the partial view has any validation because it is loaded from a parent view.
Try reparsing the DOM by adding the following to your partial view
$(function(){
jQuery.validator.unobtrusive.parse();
jQuery.validator.unobtrusive.parse("#frmEmail");
});
and this to you parent view
$(function(){
$("#submitButtonId").click(function(){
if (!$("#frmEmail").valid()){
return false;
}
});
});
You effectively have ajax within a submit within a submit...
submitHandler: function (form) {
('#frmEmail').submit(function () {
$.ajax({
....
});
});
}
You forgot the $ in front of the ('#frmEmail') selector, which breaks everything inside the submitHandler, but that's not really the core issue here.
After I submit form is redirecting to new url.
You do not need to put .ajax() within a .submit() handler when you're already inside of the plugin's submitHandler function. That's the whole point of the submitHandler option... to replace the default submit handler of the form.
This is all you'd need....
submitHandler: function (form) {
$.ajax({
url: 'customer/PostEditEmail',
type: 'Post',
data: $(form).serialize(),
success: function (result) {
// $('#DivEmailContainer').html(result);
}
});
return false;
}
Also note that $(this).serialize is replaced with $(form).serialize() since this is meaningless inside the context of the submitHandler. The form argument is already passed into this function by the developer to represent the form object.
If you're using the unobtrusive-validation plugin, then you cannot call .validate() yourself since unobtrusive already handles it for you. In other words, the jQuery Validate plugin only pays attention to first time the .validate() method is called, so if your instance is subsequent, then it's ignored along with your options.
I want to prevent multiple ajax calls (user holds enter key down or multi presses submit or other)
I'm thinking, the best way is to use a var with the previous form post values and compare them at each click/submit.. Is it the same? : Then do nothing
But I don't know how to go about it
Here is my javascript/jquery:
$('form').submit(function() {
$theform = $(this);
$.ajax({
url: 'validate.php',
type: 'POST',
cache: false,
timeout: 5000,
data: $theform.serialize(),
success: function(data) {
if (data=='' || !data || data=='-' || data=='ok') {
// something went wrong (ajax/response) or everything is ok, submit and continue to php validation
$('input[type=submit]',$theform).attr('disabled', 'disabled');
$theform.unbind('submit').submit();
} else {
// ajax/response is ok, but user input did not validate, so don't submit
console.log('test');
$('#jserrors').html('<p class="error">' + data + '</p>');
}
},
error: function(e) {
// something went wrong (ajax), submit and continue to php validation
$('input[type=submit]',$theform).attr('disabled', 'disabled');
$theform.unbind('submit').submit();
}
});
return false;
});
Not very creative with naming vars here:
var serial_token = '';
$('form').submit(function() {
$theform = $(this);
if ($(this).serialize() === serial_token) {
console.log('multiple ajax call detected');
return false;
}
else {
serial_token = $(this).serialize();
}
$.ajax({
url: 'validate.php',
type: 'POST',
cache: false,
timeout: 5000,
data: $theform.serialize(),
success: function(data) {
if (data=='' || !data || data=='-' || data=='ok') {
// something went wrong (ajax/response) or everything is ok, submit and continue to php validation
$('input[type=submit]',$theform).attr('disabled', 'disabled');
$theform.unbind('submit').submit();
} else {
// ajax/response is ok, but user input did not validate, so don't submit
console.log('test');
$('#jserrors').html('<p class="error">' + data + '</p>');
}
},
error: function(e) {
// something went wrong (ajax), submit and continue to php validation
$('input[type=submit]',$theform).attr('disabled', 'disabled');
$theform.unbind('submit').submit();
}
});
return false;
});
You could combine this with a timeout/interval function which aborts the submit, but the code above should just compare the data in the form
If you have some kind of submit button, just add a class 'disabled' to it when you start the ajax call, and check if it is present before trying to make the call. Remove the class when the server gives a response. Something like:
...
$theform = $(this);
$button = $theform.find('input[type=submit]');
if ($button.hasClass('disabled')) {
return false;
}
$button.addClass('disabled');
$.ajax({
....
},
complete: function () {
$button.removeClass('disabled');
}
});
...
I am having strange behaviour when using jquery.on().
Basically, just trying to create a newsletter signup form (can be dynamically generated and not there on initial DOM load) and pass the details through in Ajax but it is not registering the first click on the submit button meaning that to successfully submit, the user has to click twice (only seeing the success message and 'subscribe' post on 2nd click).
The html:
<div class="newsletter-widget grid-item masonry-brick">
<input name="Email" type="email" placeholder="Please enter your email" required />
<input type="submit" value="Subscribe" class="newslettersubmit"/>
and the javascript (in document ready);
var newsletterFocus = $('.newsletter-widget').find('input[type=submit]');
$(document).on('submit', newsletterFocus, function (e) {
e.preventDefault();
var newsletterLinks = newsletterFocus;
DD.newsletter.behavior(newsletterLinks);
});
and the functions within an object that are called;
DD.newsletter = {
behavior: function (item) {
item.click(function (e) {
e.preventDefault();
var where = $('.newsletter-widget').find('input[type=submit]').parents('section').attr('id');
var email = $(this).siblings('[name$=Email]'),
emailVal = email.val();
DD.newsletter.subscribe(email, emailVal, where);
});
},
subscribe: function (self, email, where) {
$.ajax({
type: "POST",
data: '{"email":"' + email + '", "method":"' + where + '"}',
url: '/Subscriber/Subscribe',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
self.val(response);
},
failure: function (msg) {
self.val(msg);
}
});
},});
I've tried using 'click' as the action for on() but this registers an event on each click and i get thousands of forms submitted!
Any help appreciated!
Change the div container to a form element:
<form class="newsletter-widget grid-item masonry-brick">
You'll want to register the submit event to the form, not the input field. Here's a quick refactor of your form submission:
$(document).on('submit', '.newsletter-widget', function (e) {
e.preventDefault();
DD.newsletter.behavior(); //Submit the form via AJAX
});
If you wanted to hook this up to your behavior method, just unwrap the click:
behavior: function () {
var where = $('.newsletter-widget').find('input[type=submit]').parents('section').attr('id');
var email = $(this).siblings('[name$=Email]'),
emailVal = email.val();
DD.newsletter.subscribe(email, emailVal, where);
}
The first click on the button will cause the behaviour click event handler to be bound to the button. Bind the behaviour directly instead of in the click event handler.
Replace this:
var newsletterFocus = $('.newsletter-widget').find('input[type=submit]');
$(document).on('submit', newsletterFocus, function (e) {
e.preventDefault();
var newsletterLinks = newsletterFocus;
DD.newsletter.behavior(newsletterLinks);
});
with:
DD.newsletter.behavior($('.newsletter-widget input[type=submit]'));
It should probably (I think) be something like this:
DD.newsletter = {
behavior: function (item) {
var where = $(item).parents('section').attr('id');
var email = $(item).siblings('[name$=Email]'),
var emailVal = email.val(); // why were you declaring this without 'var'?
DD.newsletter.subscribe(email, emailVal, where);
},
subscribe: function (self, email, where) {
$.ajax({
type: "POST",
data: '{"email":"' + email + '", "method":"' + where + '"}',
url: '/Subscriber/Subscribe',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
self.val(response);
},
failure: function (msg) {
self.val(msg);
}
});
},});