I am working on a jQuery validation "plugin" (not yet a plugin) that use my Zend_Form validators to verify the fields before submitting, client-side, so I only have to specify my constraints one time instead of two (Zend Validators + jQuery Validate Plugin, for example).
I store the validation AJAX requests for each field, then wait for them to finish, and then read the results and show or not an error message.
The problem : when I enter validated strings and hit submit, it shows no errors (good so far), but I have to re-click the submit button the form to really submit it.
Making a return true or false inside the .whenAll function is ignored and does not work, that's why I used a flag to tell the function if yes or no it can really submit the form.
$(function() {
var form = $('form'); // target form
var requests = [], validations = []; // used to store async requests and their results
var nbInputs = $('input[type="text"], input[type="password"]').length; // number of inputs we want to check in the form
var cancelSubmit = true; // skip validation flag
form.submit(function( ) {
// if we call the submit inside the function, skip validation and do submit the form
if(cancelSubmit === false) {
console.log('[-] cancelSubmit is false. Validation skipped.');
this.submit();
return true;
}
console.log('[-] Entering validation');
// resetting requests and validations
requests.length = 0;
validations.length = 0;
// for each input (text/password), storing the validation request
$('input[type="text"], input[type="password"]').each(function(i) {
var validatorField = $(this).attr('data-validator');
var valueField = $(this).val();
postData = {
validator: validatorField,
value: valueField
};
// storing requests into an array
requests.push($.post('/validate', postData));
});
(function($) {
$.whenAll = function() {
return $.when.apply($, arguments);
};
})(jQuery);
// when all the requests are done and returned a response
$.whenAll(requests).then(function() {
// show the validation status for each input
$.each(requests, function(i, element) {
element.done(function(data) {
// response is formatted like this
// { valid: 1 } or { valid: 0, message:"This is the error message" }
json = $.parseJSON(data);
formGroup = $('input:eq('+i+')').parent();
// if it isn't valid, show error and store result
if(json.valid == 0) {
if($('span.help-block', formGroup).length == 0) {
$(formGroup).addClass('has-error').append('<span class="help-block">'+json.message+'</span>');
$('label', formGroup).addClass('control-label');
}
validations.push(0);
}
// else, remove error (if there was) and store the result
else if(json.valid == 1) {
if($(formGroup).hasClass('has-error'))
{
$(formGroup).removeClass('has-error');
$('.help-block', formGroup).remove();
}
validations.push(1);
}
// if we got all the validations required
if(validations.length == nbInputs)
{
console.log('[-] All validations have been done.');
// and if no error ("0") in the results, we resubmit the form with skip-flag
if($.inArray(0, validations) == -1){
console.log('[-] No errors. Submitting form.');
cancelSubmit = false;
form.off('submit');
form.submit();
}
else
console.log('[-] There is still errors.');
}
});
});
});
// there are errors, so we won't submit the form
if(cancelSubmit === true)
return false;
});
});
Do you see a logic flaw in my code ? Maybe re-submitting the form with a flag isn't the right way to do it ?
You're returning from a sub scope rather than from the form submit handler. Instead, always prevent the submit, and then force it to submit with form[0].submit() when you want it to submit.
form.submit(function(e) {
e.preventDefault();
...
// now i want to submit...
form[0].submit();
form[0].submit() will bypass your jquery bound submit handler.
Related
The javascript is supposed to handle form submission. However, even if called with
script src="js/registerform.js"> Uncaught ReferenceError: sendreg is not defined .
The function is called onclick. Can be reproduced on www.r4ge.ro while trying to register as well as live edited. Tried jshint.com but no clue.
I will edit with any snips required.
function sendreg() {
var nameie = $("#fname").val();
var passwordie = $("#fpass").val();
var emailie = $("#fmail").val();
if (nameie == '' || passwordie == '' || emailie == '') {
alert("Please fill all the forms before submitting!");
} else {
// Returns successful data submission message when the entered information is stored in database.
$.post("http://r4ge.ro/php/register.php", {
numeleluii: nameie,
pass: passwordie,
mail: emailie
}, function(data) {
alert(data);
$('#form')[0].reset(); // To reset form fields
setTimeout(fillhome, 1000);
});
}
}
function sendpass() {
var oldpassw = $("#oldpass").val();
var newpassw = $("#newpass").val();
if (oldpassw == '' || newpassw == '') {
alert("Please fill all the forms before submitting!");
} else {
// Returns successful data submission message when the entered information is stored in database.
$.post("http://r4ge.ro/php/security.php", {
xoldpass: oldpassw,
xnewpass: newpassw
}, function(data2) {
alert(data2);
$('#passform')[0].reset(); // To reset form fields
});
}
}
function sendmail()
{
var curpass = $("#curpass").val();
var newmail = $("#newmail").val();
if (curpass == '' || newmail == '')
{
alert("Please fill all the forms before submitting!");
}
else
{
// Returns successful data submission message when the entered information is stored in database.
$.post("http://r4ge.ro/php/security.php", {
curpass: curpass,
newmail: newmail
}, function(data3) {
alert(data3);
$('#mailform')[0].reset(); // To reset form fields
});
}
}
I'm guessing here but... I imagine you are doing something like
...<button onclick="sendreg">...
And you have your <script> in the bottom on the code. Just put them on top or use $("#mybtn").click(sendreg)
Try using $("#mybtn").click(sendreg) instead of inline onclick.
The script wasn't called in the html. sorry for wasting time. A simple
<script src="js/registerform.js"></script> Fixed it.
There is no syntax error there, and I don't see any such error when trying the page.
The error that you get is that you can't make a cross domain call. Do the request to the same domain:
$.post("http://www.r4ge.ro/php/register.php", {
or:
$.post("/php/register.php", {
I wrote a script which allows me to validate a form with my Zend_Form validators instead of a classic client-side validation (like jQuery Validate) + server-side validation.
$(document).ready(function() {
var form = $('form'); // target form
var requests = [], validations = [];
var nbInputs = $('input[type="text"], input[type="password"]').length; // number of inputs (text/password) in the form
var cancelSubmit = true;
form.submit(function() {
// if we call the submit inside the function, skip validation
if(cancelSubmit === false) {
console.log('[-] cancelSubmit is false. Validation skipped.');
return true;
}
console.log('[-] Entering validation');
// resetting requests and validations results
requests.length = 0;
validations.length = 0;
// for each input (text/password), get the validation status from the server
$('input[type="text"], input[type="password"]').each(function(i) {
var validatorField = $(this).attr('data-validator');
var valueField = $(this).val();
postData = {
validator: validatorField,
value: valueField
};
// storing requests into an array
requests.push($.post('/validate', postData));
});
(function($) {
$.whenAll = function() {
return $.when.apply($, arguments);
};
})(jQuery);
// when all the requests are done and returned a response
$.whenAll(requests).then(function() {
// show the validation status for each input
$.each(requests, function(i, element) {
element.done(function(data) {
json = $.parseJSON(data);
formGroup = $('input:eq('+i+')').parent();
// if it isn't valid, show error
if(json.valid == 0) {
if($('span.help-block', formGroup).length == 0) {
$(formGroup).addClass('has-error').append('<span class="help-block">'+json.message+'</span>');
$('label', formGroup).addClass('control-label');
}
// and store the validation status
validations.push(0);
}
// else, remove error
else if(json.valid == 1) {
$(formGroup).removeClass('has-error');
$('.help-block', formGroup).remove();
// and store the validation status
validations.push(1);
}
// if we got all the validations required
if(validations.length == nbInputs)
{
console.log('[-] All validations have been done.');
if($.inArray(0, validations) == -1){
console.log('[-] No errors. Submitting form.');
cancelSubmit = false;
form.submit();
}
else
console.log('[-] There are still errors.');
}
});
});
});
return false;
});
});
The validation page server-side send a JSON : { valid: 0, message: "error message" } or { valid: 1}.
I can't have the form to be submitted. When I enter valid values, it does skip validation, but don't submit the form. I have to hit the submit button again to make it work (but, I could have entered non-valid values that wouldn't be checked in this time, as cancelSubmitis set to false).
Isn't return true; supposed to submit the form when used inside a .submit() ?
I have a form for both creation and editing some fields.I am using Ajax validation for that before submitting the form like
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'candidates-profiles-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
'validateOnChange'=>false,
'beforeValidate'=>"js:function(form) {
if((form.data('submitObject')[0].id ) == 'cancel'){
alert('cancalclicked');
this.validateOnSubmit = false;
this.validateOnChange = false;
this.beforeValidate = ''; // the problem is caused by this line
form.submit();
return false;
}
else{
alert('submitclicked');
return true;
}
}",
'afterValidate'=>"js:function(form, data, hasError) {
if(hasError) {
alert('We have detected some input errors and has not saved your data. Please click Ok to correct them.');
return false;
}
else {
if(confirm('We have validated your input and we are ready to save your data. Please click Ok to save or Cancel to return to input.'))
return true;
else
return false;
}
}",)
)); ?>
After creation it is perfectly coming in afterValidate function and works fine.But after editing it is not all coming in afterValidate. But it is coming in beforeValidate and submitting the form with out reaching afterValidate .
Make sure you have $this->performAjaxValidation($model); in your controller for that action.
Im having a issue, I need to combine 2 scripts together. One of which is a validation and the other is variables/ajax script. I tried but i cannot get it to work. I put it within the script under the area that checks if it has the needfilled element attached however it submits without executing the ajax call.
Script 1:
$(document).ready(function(){
$("#loading").hide();
// Place ID's of all required fields here.
required = ["parentFirstName", "parentLastName", "parentEmailOne", "parentZip"];
// If using an ID other than #email or #error then replace it here
email = $("#parentEmailOne");
errornotice = $("#error");
// The text to show up within a field when it is incorrect
emptyerror = "Please fill out this field.";
emailerror = "Please enter a valid e-mail.";
$("#theform").submit(function(){
//Validate required fields
for (i=0;i<required.length;i++) {
var input = $('#'+required[i]);
if ((input.val() == "") || (input.val() == emptyerror)) {
input.addClass("needsfilled");
input.val(emptyerror);
errornotice.fadeIn(750);
} else {
input.removeClass("needsfilled");
}
}
// Validate the e-mail.
if (!/^([a-zA-Z0-9_\.\-])+\#(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(email.val())) {
email.addClass("needsfilled");
email.val(emailerror);
}
//if any inputs on the page have the class 'needsfilled' the form will not submit
if ($(":input").hasClass("needsfilled")) {
return false;
} else {
errornotice.hide();
return true;
}
});
// Clears any fields in the form when the user clicks on them
$(":input").focus(function(){
if ($(this).hasClass("needsfilled") ) {
$(this).val("");
$(this).removeClass("needsfilled");
}
});
});
Script 2:
// Form Varables
var parentFirstNameVal = $("#parentFirstName").val();
var parentLastNameVal = $("#parentLastName").val();
var emailaddressVal = $("#parentEmailOne").val();
var parentPhoneVal = $("#parentPhone").val();
var parentAddressVal = $("#parentAddress").val();
var parentAddressContVal = $("#parentAddressCont").val();
var parentCityVal = $("#parentCity").val();
var parentStateVal = $("#parentState").val();
var parentZipVal = $("#parentZip").val();
var parentListenVal = $("#parentListen").val();
var codeVal = $("#code").val();
var getUpdateVal = $("#getUpdate").val();
input.removeClass("needsfilled");
$("#message-space").html('<br /><br /><span class="greenText">Connected to Facebook.</span><br />');
$("#loading").show();
var counter = 0,
divs = $('#div1, #div2, #div3, #div4');
function showDiv () {
divs.hide()
.filter(function (index) { return index == counter % 3; })
.show('fast');
counter++;
};
showDiv();
setInterval(function () {
showDiv();
}, 10 * 600);
alert(parentFirstNameVal);
$.ajax({
type: "POST",
url: "includes/programs/updateEmailsTwo.php",
data: "parentFirstName="+parentFirstNameVal+"&parentLastName="+parentLastNameVal+"&UserEmail="+emailaddressVal+"&parentPhone="+parentPhoneVal+"&parentAddress="+parentAddressVal+"&parentAddressCont="+parentAddressContVal+"&parentCity="+parentCityVal+"&parentState="+parentStateVal+"&parentZip="+parentZipVal+"&parentListen="+parentListenVal+"&code="+codeVal+"&getUpdate="+getUpdateVal+"&ref=<?php echo $_SESSION["refid"]; ?>",
success: function(data){
$("#message-space").html('<br /><br /><span class="greenText">Complete</span><br />');
divs.hide()
}
});
In addition to the suggestions that #JeffWilbert gave, I am going to follow it up with some more suggestions to make your code a bit more cleaner and efficient.
First, just like you did in script 1, where you have an array of field names, you can do the same for script 2. Below is an example of what you can do make your code a bit more readable.
var fields = ['parentFirstName', 'parentLastName', 'parentEmailOne', 'parentPhone'];
var fieldsValue = [], dataString;
for(i = 0; i < fields.length; i++){
fieldsValue.push(fields[i] + "Val=" + $('#' + fields[i]).val());
}
dataString = fieldsValue.join("&");
Second, If Script 2 is not dependent on any variable declared from Script 1, I would convert Script 2 into its own function and call it from Script 1. I think adding all that code inside the else like Jeff suggested is not best.
function Script2(){
//Script 2 Code
}
$("#theform").submit(function(){
//Call Script 2
});
And Third, If you are going to submit the form via AJAX and not through its default method, I would recommend using .preventDefault and then handle the flow of the submission inside the event handler function.
$("#theform").submit(function(e){
e.preventDefault();
//rest of your code here.
});
The code in script 2 needs to go inside script 1 where I marked below with a comment; if your code in script 2 is submitting the form via ajax call then you don't need to return true if no errors are found, by doing so your telling the form to submit normally.
if ($(":input").hasClass("needsfilled")) {
return false;
} else {
errornotice.hide();
// SCRIPT 2 CODE HERE BEFORE THE RETURN
// If the ajax call in script 2 is submitting your form via ajax then change
// the line below to return false so your form doesn't submit
return true;
}
What I am trying to accomplish is a (very simple) email validation using jQuery, but no matter what I do, the form will just keep submitting.
<form id="rfq" name="rfq" action="rfq_form" method="post" enctype="multipart/form-data">
...
<input type="image" id="submit" name="submit" src="submit.png" border="0" />
JS email validation:
//$("#rfq").submit(function() { doesnt seem to work either
$('#submit').click(function() {
var email = $('#email').val();
if(email.indexOf("#") == -1){
$("#email").addClass('invalid');
return false; // cancel form submission if email invalid
}
return false; // return true if no errors once i get it working
});
Working Example
First, make sure all event handlers are attached once the DOM is "ready"
I'm using .submit() on the actual form.
$(document).ready(function() {
// now that document is "ready"
$('#formId').submit(function() {
var email = $('#emailInput').val();
alert(email);
if(email.indexOf("#") == -1){
alert("invalid!");
return false; // cancel form submission if email invalid
}
alert("valid!");
return true; // return true if no errors once i get it working
});
});
Try wrapping your code in a ready block.
$(document).ready(function(){
// your code here
});
You should also be using the submit event on the <form> element, I think.
This is going to work. If you don't understand why, feel free to ask :)
var validated = false;
$(document).ready(function(){
$("#rfq").submit(function(event) {
if (validated === true) {
return true;
}
event.preventDefault(); // prevent submission
var email = $('#email').val();
if(email.indexOf("#") == -1){
$("#email").addClass('invalid');
return;
}
validated = true;
return $(this).trigger('submit');
});
});
You could try using this function to validate your address.
function validateEmail(elementValue){
var emailPattern = /^[a-zA-Z0-9._-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
return emailPattern.test(elementValue);
}
And then modify your code to submit the form.
$('#submit').click(function() {
var email = $('#email').val();
if(!validateEmail(email)){
$("#email").addClass('invalid');
}
else {
$("form").submit();
}
});