Checking multiple functions are true in Javascript before submission - javascript

I have been working on improving my javascript validation and with the help off the internet (including stackoverflow) have been able to create what I need. The only problem I have is checking multiple functions = true doesn't seem to work. It's been driving me crazy and I hope someone can help.
What I'm trying to do is check that the username and email are within the set variables and if the username and email haven't been used. The availability off the username and email shows whether it's available or not whilst you are typing. Which works great, the only problem is that if the user clicks register when they one or more are not available the form still gets submitted. To overcome this I thought off using an if statement that checks if multiple functions are true, if so pass the details to the php script if not the show an alert message.
For some reason it keeps bringing up the 'not available' alert message even if the username and email are showing as available on the form. I have checked the database table and the php code is working correctly.
Here is the code below
html:
<form name="regForm" role="form" action="php/registerphp.php" method ="post"
onsubmit="return RegFormValidation();">
<fieldset>
<div class="form-group">
<label for="username">Username</label><span>*</span><span> </span><span id="username_availability_result"></span>
<input type="username" class="form-control" id="username"
placeholder=" Enter a username" name="username">
</div>
<div class="form-group">
<label for="email">Email address</label><span>*</span><span> </span><span id="email_availability_result"></span>
<input type="email" class="form-control" id="email"
placeholder=" Enter email" name="email">
</div>
Javascript
function RegFormValidation()
{
if(check_username_availability() && check_email()) {
return true;
} else
{
alert("Username or Email not correct.");
return false;
}
}
$(document).ready(function username_correct_format()
{
var min_chars = 3;
var characterReg = /^\s*[a-zA-Z0-9,\s]+\s*$/;
var characters_error = ' - Min. characters required is 3, only use letters and numbers.';
var checking_html = 'Checking...';
$('#username').keyup(function()
{
if($('#username').val().length > min_chars || characterReg.test($('#username').val()))
{
//else show the checking_text and run the function to check
$('#username_availability_result').html(checking_html);
check_username_availability();
}else
{
//if it's bellow the minimum show characters_error text '
$('#username_availability_result').html(characters_error);
}
});
});
//function to check username availability
function check_username_availability()
{
var username = $('#username').val();
$.post("php/check_username.php", { username: username },
function(result)
{
if(result == 1)
{
//show that the username is available
$('#username_availability_result').html('<span class="is_available"> is available</span>');
return true;
}else
{
//show that the username is NOT available
$('#username_availability_result').html('<span class="is_not_available"> is not available</span>');
return false;
}
});
}
$(document).ready(function email_correct_format()
{
var min_chars = 4;
var characters_check = /^(([^<>()[\]\\.,;:\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,}))$/;
var characters_error = ' - only 1 email address per user.';
var checking_html = 'Checking...';
$('#email').keyup(function()
{
if($('#email').val().length > min_chars && characters_check.test($('#email').val()))
{
//else show the cheking_text and run the function to check
$('#email_availability_result').html(checking_html);
check_email();
}else
{
//if it's bellow the minimum show characters_error text '
$('#email_availability_result').html(characters_error);
}
});
});
//function to check email availability
function check_email()
{
var email = $('#email').val();
$.post("php/check_email.php", { email: email },
function(result)
{
if(result == 1)
{
//show that the email is available
$('#email_availability_result').html('is available ');
return true;
}else
{
//show that the email is NOT available
$('#email_availability_result').html('<span class="is_not_available"> is already registered.</span>');
return false;
}
});
}

Because your checks are done using asynchronous methods your check methods are going to return before the requests have been made, your functions also do not return anything anyways. Thus each one is going to be returning undefiend
You can use jQuery's .when method to wait for one or more requests to be completed and then execute some function.
First thing that will need done is pass the event object and the form object to the validation function. We will need the event object to call preventDefault so that the form will not submit before it is supposed to.
Then we need to change the validation function around so that it will call the two check functions and setup a promise to call a callback when they are complete.
We will also need to change your to check functions to return the promise object that the .post method returns so that the .when method can use them.
After that you just do your checks against the returned data and process.
HTML
<form name="regForm" role="form" action="php/registerphp.php" method ="post"
onsubmit="return RegFormValidation(event,this);">
Javascript
function RegFormValidation(e,form) {
//Prevent the form submission
e.preventDefault();
//Each check function returns a promise object
jQuery.when(check_username_availability(),check_email())
.done(function(usernameResponse,emailResponse){
//the responses passed back to the callback will be in an array
//element 0 is the actual data retrieved
//element 1 is the status (success, error, etc)
//element 2 is the promise object
if(usernameResponse[0] == 1 && emailResponse[0] == 1){
//if everything is ok manually submit the form
form.submit();
} else {
alert("Username or Email not correct.");
}
});
}
function check_username_availability() {
var username = $('#username').val();
return $.post("php/check_username.php", { username: username })
.then(function(data){
if(data == 1) {
$('#username_availability_result').html('<span class="is_available"> is available</span>');
} else {
$('#username_availability_result').html('<span class="is_not_available"> is not available</span>');
}
//We have to return the data here to make sure it gets passed
//to the done callback from the validation function
return data;
});
}
function check_email() {
var email = $('#email').val();
return $.post("php/check_email.php", { email: email })
.then(function(data){
if(data == 1) {
$('#email_availability_result').html('<span class="is_available"> is available</span>');
} else {
$('#email_availability_result').html('<span class="is_not_available"> is not available</span>');
}
//We have to return the data here to make sure it gets passed
//to the done callback from the validation function
return data;
});
}
You can look at jQuery's api section Deferred Objects to learn more about their deferred/promises. You can also look at other promise libraries like Q and see how they work, as they tend to work on the same principles and use similar method names.

You dont have to wrap functions in
$(document).ready();
this will change the scope of function calling/referencing and is not a good practice. As this might help you out in resolving the return value from the function.
All the Best!

To do multiple boolean checks, I would create a global variable (eg, allValid) immediately set to your control value (true or false)... then on each validation function, change the variable ONLY if something is invalid, so:
var allValid = true;
if(!/*validation requirement*/) { allValid = false; }
allValid = anotherValidationFunction() || false;
if(!allValid) { /*something's invalid*/ }
I don't know if that makes sense.

It looks like you're making ajax calls for your validation. My guess is these are asynchronous calls (which won't work with your code).
My guess (sorry, I don't have time to test) is your functions check_username_availability and check_email will immediately return "undefined", which is why your validation is always throwing the alert.
Instead, what you'd want to do is make synchronous calls, or use callbacks to invoke the necessary functions.

A couple of things you could do to improve your code.
You probably don't have to make two separate requests, pass the username and email direct to your php code, and you'll save on HTTP requests going out.
onsubmit="return RegFormValidation();" should be changed in jQuery to a bind call. Give the form an ID and do something like this
<form id="registerForm">....
$("form#registerForm").on('submit', function(e){
});
You've got var username = $('#username').val();
then
if($('#username').val().length > min_chars || characterReg.test($('#username').val()))
{
You could probably clean that up a bit and reuse the variable, rather than continued calls to the jQuery functions. Patrick's answer above is a good start to some tidy ups and I reckon addresses the overall problem you are experiencing.

Related

The form does not work correctly when sent

I wrote the code for a form validation.
Should work like this:
It checks (allLetter (uName)) and if it's true, then validate the next input.
If any validation is false then it should return false.
My problem is that if both validations are true, then everything is exactly false and the form is not sent.
If I set true in formValidation (), if at least one check false, the form should not be sent.
<form name='registration' method="POST" onSubmit="return formValidation();">
<label for="userName">Name:</label>
<input type="text" name="userName" size="20" />
<label for="userPhone">Phone:</label>
<input type="text" name="userPhone" size="20" />
<input type="submit" name="submit" value="Submit" />
</form>
function formValidation() {
var uName = document.registration.userName;
var uPhone = document.registration.userPhone;
if(allLetter(uName)) {
if(phone(uPhone)) {}
}
return false;
}
function phone(uPhone){
var digts = /^[0-9]+$/;
if(uPhone.value.match(digts)){
return true;
} else {
alert('Phone must have only digits');
uPhone.focus();
return false;
}
}
function allLetter(uName) {
var letters = /^[A-Za-z]+$/;
if(uName.value.match(letters)) {
return true;
}else{
alert('Username must have alphabet characters only');
uName.focus();
return false;
}
}
First, you are using a 20+ year old way to gain references to your elements (document.form.formElementNameAttributeValue) and, while this still works for legacy reasons, it doesn't follow the standard Document Object Model (DOM) API.
Next, you've broken up your validation tests into different methods (and that's certainly not a bad idea for reusability), but in this case is is adding a ton of code that you just don't need. I've always found it's best to start simple and get the code working, then refactor it.
You're also not using the <label> elements correctly.
One other point, your form is set to send its data via a POST request. POST should only be used when you are changing the state of the server (i.e. you are adding, editing or deleting some data on the server). If that's what your form does, you'r fine. But, if not, you should be using a GET request.
Lastly, you are also using a 20+ year old technique for setting up event handlers using inline HTML event attributes (onsubmit), which should no longer be used for many reasons. Additionally, when using this technique, you have to use return false from your validation function and then return in front of the validation function name in the attribute to cancel the event instead of just using event.preventDefault().
So, here is a modern, standards-based approach to your validation:
// Get references to the elements you'll be working with using the DOM API
var frm = document.querySelector("form[name='registration']");
var user = document.getElementById("userName");
var phone = document.getElementById("userPhone");
// Set up event handlers in JavaScript, not with HTML attributes
frm.addEventListener("submit", formValidation);
// Validation function will automatically be passed a reference
// the to event it's associated with (the submit event in this case).
// As you can see, the function is prepared to recieve that argument
// with the "event" parameter.
function formValidation(event) {
var letters = /^[A-Za-z]+$/;
var digts = /^[0-9]+$/;
// This will not only be used to show any errors, but we'll also use
// it to know if there were any errors.
var errorMessage = "";
// Validate the user name
if(user.value.match(letters)) {
// We've already validated the user name, so all we need to
// know now is if the phone is NOT valid. By prepending a !
// to the test, we reverse the logic and are now testing to
// see if the phone does NOT match the regular expression
if(!phone.value.match(digts)) {
// Invalid phone number
errorMessage = "Phone must have only digits";
phone.focus();
}
} else {
// Invalid user name
errorMessage = "Username must have alphabet characters only";
user.focus();
}
// If there is an error message, we've got a validation issue
if(errorMessage !== ""){
alert(errorMessage);
event.preventDefault(); // Stop the form submission
}
}
<!-- 20 is the default size for input elements, but if you do
want to change it do it via CSS, not HTML attributes -->
<form name='registration' method="POST">
<!-- The for attribute of a label must be equal to the id
attribute of some other element, not the name attribute -->
<label for="userName">Name:</label>
<input type="text" name="userName" id="userName">
<label for="userPhone">Phone:</label>
<input type="text" name="userPhone" id="userPhone">
<input type="submit" name="submit" value="Submit">
</form>

Two text fields, only one required to be filled (either)

So I have two fields in my webpage, one for telephone number and the other for email address, I need to make either one of them required to be filled by using JavaScript NOT jQuery. Most of the answers I found here are for jQuery, any solutions with JavaScript would be much appreciated. Thanks!
function User_one(){
var phone = document.getElementById('PhoneText2').value;
var mail = document.getElementById('EmailText1').value;
if (phone && mail == ""){
alert("An error occurred.");
}else{
return false;
}
}
Update with actual code
Here's how I'd do it
(function () {
document.getElementById('myForm').addEventListener('submit', function(event){
// Get the length of the values of each input
var phone = document.getElementById('PhoneText2').value.length,
email = document.getElementById('EmailText1').value.length;
// If both fields are empty stop the form from submitting
if( phone === 0 && email === 0 ) {
event.preventDefault();
}
}, false);
})();
Since you haven't supplied any code for us to work with, I'll answer in pseudo-code:
On form submission {
If (both telephone and email is empty) {
throw validation error
}
otherwise {
submit the form
}
}
If you show me your code I'll show you mine :-)

Is there a way to reverse the suspension of form-submission or will it be better not to have it done in the first place?

I am trying to make a simple web application. In my login page I have a form with a text field, a password and a submit button. Form submission is prevented if either fields are empty. This is the script I use:
function checkLoginCredentials() {
var usernameFormValue = $("#usernameForm").val().trim();
var passwordFormValue = $("#passwordForm").val().trim();
var validated;
$("#loginForm").submit(function(event){
if (usernameFormValue === "" || passwordFormValue === "") {
$("span").html("Enter a username or password");
validated = false
} else {
validated = true;
}
return validated;
});
}
However, I noticed that once the script runs and form submission is prevented, the user can no longer make an attempt to log in again. The only alternative I can think of is to have ALL validations done by my login servlet and utility classes. Is there a way around this or must validations of invalid entries like empty strings be done by my Java Classes?
The issue here is how you are assigning the validation code. You have a checkLoginCredentials and when you call it you read the form values. And than you add a form submission. You should add the reading of the textbox values inside of the submit method, not outside.
$("#loginForm").submit(function(event){
var usernameFormValue = $("#usernameForm").val().trim(),
passwordFormValue = $("#passwordForm").val().trim(),
validated;
if (usernameFormValue === "" || passwordFormValue === "") {
$("span").html("Enter a username or password");
validated = false
} else {
validated = true;
}
return validated;
});

how to compare 2 form inputs live

I'm trying to compare two form inputs "password" and re-enter-password" to make sure there the same. I validate the password by sending it to a separate PHP that echoes back the results(which works fine)
<script type="text/javascript">
$(document).ready(function() {
$('#password_feedback').load('password-check.php').show();
$('#password_input').keyup(function() {
$.post('password-check.php', {
password: form.password.value
},
function(result) {
$('#password_feedback').html(result).show();
});
});
});
</script>
I tried sending password and re-enter=password to a PHP to compare with no luck. Can I compare the two with every keyup.
What are you checking for in your PHP script? Anything in particular that justifies the use of PHP?
You could do that only with JS, you don't need the AJAX part.
HTML :
<input type="password" id="password">
<input type="password" id="password_cf">
<div class="result"></div>
JS (jQuery) :
$('#password_cf').on('keyup', function(){
if($('#password_cf').val()== $('#password').val())
$('.result').html('They match');
else
$('.result').html('They do not match');
});
Fiddle : http://jsfiddle.net/2sapjxnu/
You can use the blur event if you want to only check once the focus is lost on that field. It's a bit less "responsive" than verifying on every key, but more performant I guess.
Not necessary jQuery, add the function:
function checkPass(input) {
if (input.value != document.getElementById('re-enter-password').value) {
input.setCustomValidity('Passwords should match.');
} else {
input.setCustomValidity('');
}
}
Add this to your re-enter-password: oninput="checkPass(this)"
OR
just call this function in the part where you want to make the comparison:
function checkPass() {
var input = document.getElementById('password');
if (input.value != document.getElementById('re-enter-password').value) {
input.setCustomValidity('Passwords should match.');
} else {
input.setCustomValidity('');
}
}
How about adding a class to each input and then:
if($(".password").val() == $(".re-enter-password").val()){
alert("it matches")
} else {
alert("no match yet");
}
Quick and dirty -
Given this markup -
<input type="password" name="pw1" />
<input type="password" name="pw2" />
You could check it client side without muliple round trips to the server using code like this -
$('[name="pw2"]').blur(function() {
var pw1 = $('[name="pw1"]').val();
var pw2 = $('[name="pw2"]').val();
if(pw2 != pw1) {
alert('passwords do not match');
}
});
Matching 2 form input fields with JavaScript by sending it off to the server to get an assertion response could render a bad user experience, because if you're doing this on each keyPress, then it generates unnecessary internet traffic - while the user is waiting.
So, instead, why not match these 2 fields directly with JavaScript?
If you are using a specific regular expression on the server for validation check as well, you can have the server put that regex "pattern" in the HTML fields - (no JavaScrpt needed for that). Then, onkeyup event you can simply do something like:
form.field2.onkeyup = function()
{
if (form.field1.value !== form.field2.value)
{
/* some code to highlight the 2 fields,
or show some message, or speech bubble */
return;
}
}
form.field1.onkeyup = form.field2.onkeyup;

javascript function inside function

I have just started with JavaScript and want to validate a form. All the tutorials I've found create an alert for feedback, but I'd like to use onblur and give an error message next to the field. I managed to do the two functions separately but can't merge them. I'd really appreciate your help!
This is what I came up with, but it doesn't do what I need:
function validateFirstName()
{
var x=document.forms["demo"]["firstname"].value;
if (x==null || x=="" || x==)
{
function addMessage(id, text)
{
var textNode = document.createTextNode(text);
var element = document.getElementById(id);
element.appendChild(textNode);
document.getElementById('firstname').value= ('Firstname must be filled out')
}
return false;
}
}
So the following is a simple way to validate a form field by checking the value of an input when the form is submitted. In this example the error messages are just sent to the div element about the form but this should still help you out.
The HTML code looks something like this:
<div id="errors"></div>
<form onSubmit="return validate(this);">
<input type="text" name="firstName" placeholder="What's your first name?">
<button type="submit" value="submit">Submit</button>
</form>
The Javascript code looks something like this:
function validate(form) {
var errors ='';
if(form.firstName.value =="") {
errors += '<li>Please enter your first name</li>';
}
if(errors !='') { //Check if there are any errors, if there are, then continue
var message = document.getElementById("errors"); //assigns the element with the id of "errors" to the variable "message"
message.innerHTML = "<ul>" + errors + "</ul>"; //adds the error message into a list with the error message into the HTML
return false;
} else {
return true;
}
}
Once you understand this you should be able to figure the rest out on your own or go to http://www.w3schools.com/ and check out the javascript section to help you out.
I'm not sure what you really looking for. If I understood right (and I can be very wrong) you are looking for something like:
var x = undefined; // Can be undefined, null, or empty string
if (x==null || x=="" || x==undefined) { // do no forget to check for undefined
function addMessage(id, text) {
// Your validation code goes here
alert(id + text);
};
addMessage(1234, "Mandatory field!");
}
Note, there are several ways to do it. I just showing the simplest way I can think of...

Categories