Form validation with JavaScript using XHR - javascript

I'm fairly new to JavaScript, I've been using tutorials online but they seem to often validate with php and use JavaScript for warnings, the application I'm making users xhr to post the data to the server, but before this I want to have JavaScript complete some validations. Then I'll re validate with the PHP.
Here is the form code
<form id="booking" action="">
<span class="red">*</span>First Name:
<input type="text" name="firstName" id="firstName">
<br>
<span class="red">*</span>Last Name:
<input type="text" name="lastName" id="lastName">
<br>
<span class="red">*</span>Contact Number:
<input type="text" name="number" id="number">
<br>
Unit Number(optional):
<input type="text" name="unit" id="unit">
<br>
<span class="red">*</span>Street Number:
<input type="text" name="streetNumber" id="streetNumber">
<br>
<span class="red">*</span>Street Name:
<input type="text" name="streetName" id="streetName">
<br>
<span class="red">*</span>Suburb:
<input type="text" name="pickupSuburb" id="pickupSuburb">
<br>
Destination Suburb<span class="red">*</span>:
<input type="text" name="destinationSuburb" id="destinationSuburb">
<br>
Pick-Up Date and Time<span class="red">*</span>:
<input type="datetime-local" name="dateTime" id="dateTime">
<br>
<br>
<input type="button" value="Submit"
onclick="getData('bookingprocess.php','message', firstName.value, lastName.value, number.value, unit.value, streetNumber.value, streetName.value, pickupSuburb.value, destinationSuburb.value, dateTime.value)"/>
<input type="reset" value="Reset">
</form>
<div id="message">
</div>
I've created a div for the warning messages.
Here is the JavaScript
// file simpleajax.js
var xhr = createRequest();
function getData(dataSource, divID, firstName, lastName, number, unit, streetNumber, streetName, pickupSuburb, destinationSuburb, dateTime) {
if(xhr) {
var place = document.getElementById(divID);
var requestbody = "firstName="+encodeURIComponent(firstName)+"&lastName="+encodeURIComponent(lastName)+"&number="+encodeURIComponent(number)+"&unit="+encodeURIComponent(unit)+"&streetNumber="+encodeURIComponent(streetNumber)+"&streetName="+encodeURIComponent(streetName)+"&pickupSuburb="+encodeURIComponent(pickupSuburb)+"&destinationSuburb="+encodeURIComponent(destinationSuburb)+"&dateTime="+encodeURIComponent(dateTime);
xhr.open("POST", dataSource, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
place.innerHTML = xhr.responseText;
} // end if
} // end anonymous call-back function
xhr.send(requestbody);
} // end if
} // end function getData()
function checkForm(booking) {
var valid = true;
if(firstName.value.length <= 0) {
window.alert("Name is empty");
booking.firstName.focus();
return valid = false;
}
}
Note there will be more validations, my question is how can I call the validations from the form, or directly from the XHR, which is the best practice? I understand the call to the XHR from the form could be considered bad practice as well as I've hard coded all the values?
Getting this to work has been quite troublesome, so apologies if its a little Hodge podge.

Validating while the form is filled (when the cursor leaves a field) makes more sense since you can add some hints to user. Like, if a user enters an email, you check if it contains # and it doesn't, it's much more user-friendly to notify them that something's wrong with their email input (in contrast, they may send the form, you validate it then and tell them the form is not ok, but then they have to fill the form again, which is sort of frustrating).
Try
<input type="text" onblur="alert('out!');" />
This fires when the input loses focus. Now, you may wonder how to use functions defined elsewhere in such handling. That can be done, for instance, like this:
JS:
window.myHandler = function(input,event) { ... };
HTML:
<input type="text" onblur="window.myHandler(input,event);" />
Note that in HTML onblur attribute event is a "pre-defined" variable that contains the Event object "instance", but for elder versions of IE, you should use
window.myHandler = function(input,event) {
event = event || window.event; // elder IE store the Event object in window.event
// input is your DOM element. You can use input.value to get the value
// or this.classList to add some class which indicates (via CSS) that the input is wrong
...
};

Related

Can't get my simple JavaScript Event Handler working

I am trying to get an event handler on an HTML form. I am just trying t get the simplest thing working, but I just cannot see what I am missing.
It is part of a wider project, but since I cannot get this bit working I have reduced it down the most very basic elements 1 text field and a button to try and see what it is I am missing.
All I want to do is get some text entered and flash up message in a different area on the screen.
The user enters text into the input field (id=owner).
The plan is that when the button (id="entry") is pressed the event handler (function "entry") in the entry.js file should cause a message to display.
I don't want the form to take me to a different place it needs to stay where it is
I just want some form of text to go in the: <div id="feedback" section.
When I can get it working: I intend the create the text from the various text fields that get entered.
I Know that this is beginner stuff & I know that I have reduced this down such that it barely worth thought but I would welcome any input please & thank you.
HTML code is:
<form method="post" action="">
<label for="owner">Input Owner: </label>
<input type="text" id="owner" />
<div id="feedback"></div>
<input type="submit" value="enter" id="entry" />
</form>
<script src="entry.js"></script>
Code for entry.js is:
function entry() {
var elOwner = document.getElementById('owner');
var elMsg = document.getElementByID('feedback');
elMsg.textContent = 'hello';
}
var elEntry = document.getElementById('entry');
elEntry.onsubmit=entry;
I have tried:
Adding in a prevent default:
window.event.preventDefault();
doing this through an event Listener:
elEntry.addEventListener('submit',entry,false);
using innerHTML to post the message:
elMsg.innerHTML = "
At present all that happens is that the pushing submit reloads the page - with no indication of any text being posted anywhere.
One issue is that you have a typo, where getElementById capitalized the D at the end.
Another is that preventDefault() should be called on the form element, not the input.
Here's a working example that corrects those two mistakes.
function entry(event) {
var elOwner = document.getElementById('owner');
var elMsg = document.getElementById('feedback');
elMsg.textContent = 'hello';
event.preventDefault();
}
var entryForm = document.getElementById('entry').form;
entryForm.onsubmit = entry;
<form method="post" action="">
<label for="owner">Input Owner: </label>
<input type="text" id="owner" />
<div id="feedback"></div>
<input type="submit" value="enter" id="entry" />
</form>
I also defined a event parameter for the handler. I don't remember is window.event was ever standardized (it probably was), but I'd prefer the parameter.
Be sure to keep your developer console open so that you can get information on errors that may result from typos.
var elEntry = document.getElementById('entry');
elEntry.addEventListener("click", function(e) {
e.preventDefault();
var elMsg = document.getElementById('feedback');
elMsg.textContent = 'hello';
});
<form method="post" action="">
<label for="owner">Input Owner: </label>
<input type="text" id="owner" />
<div id="feedback"></div>
<input type="submit" value="enter" id="entry" />
</form>

validating a form using jQuery

I've tried, I've researched, and I still can't figure out how to validate this form using jQuery. I've even tried to check out the jQuery API and I had no luck with it. This shouldn't be as hard as it seems. There are a few id's that i'm not using yet because I want to get what I have so far working before I continue. The best I could find for validating emails is just straight up JavaScript. Here's my code.
$(document).ready(function(){
$("#sendForm").click(function(){
var validForm=true; //set valid flag to true, assume form is valid
//validate customer name field. Field is required
if($("#custName").val()) {
$("#custNameError").html(""); //field value is good, remove any error messages
} else {
$("#custNameError").html("Please enter your name.");
validForm = false;
}
//validate customer phone number. Field is required, must be numeric, must be 10 characters
var inPhone = $("#custPhone").val(); //get the input value of the Phone field
$("#custPhoneError").html(""); //set error message back to empty, assume field is valid
if(!inPhone) {
$("#custPhoneError").html("Please enter your phone number.");
validForm = false;
} else {
//if( !$.isNumeric(inPhone) || Math.round(inPhone) != inPhone ) //if the value is NOT numerice OR not an integer. Rounding technique
if( !$.isNumeric(inPhone) || (inPhone % 1 != 0) ) //if the value is NOT numerice OR not an integer. Modulus technique
{
$("#custPhoneError").html("Phone number must be a number.");
validForm = false;
} else {
if(inPhone.length != 10) {
$("#custPhoneError").html("Phone number must have 10 numbers");
validForm = false;
}
}
}
//ALL VALIDATIONS ARE COMPLETE. If all of the fields are valid we can submit the form. Otherwise display the errors
if(validForm) {
//all values are valid, form is good, submit the form
alert("Valid form will be submitted");
//$("#applicationForm").submit(); //SUBMIT the form to the server
} else {
//form has at least one invalid field
//display form and associated error messages
alert("Invalid form. Display form and error messages");
}
}); //end sendform.click
}); //end .ready
function isEmail(email) {
var regex = /^([a-zA-Z0-9_.+-])+\#(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return regex.test(email);
}
label {
width:150px;
display:inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h2></h2>
<h3>Form Validation Project - Complaint Form</h3>
<form id="form1" name="form1" method="post" action="">
<p>Please enter the following information in order to process your concerns.</p>
<p>
<label for="custName">Name:</label>
<input type="text" name="custName" id="custName" />
<span id="custNameError" class="errorMsg"></span>
</p>
<p>
<label for="custPhone">Phone Number: </label>
<input type="text" name="custPhone" id="custPhone" />
<span id="custPhoneError" class="errorMsg"></span>
</p>
<p>
<label for = "email">Email:</label>
<input type = "text" name = "emailAdd" id = "emailAdd" />
<span id = "emailError" class = "emailError"></span>
</p>
<p>Please Select Product Group:</p>
<p>
<label>
<input type="radio" name="custProducts" value="books" id="custProducts_0" />
Books
</label>
<br />
<label>
<input type="radio" name="custProducts" value="movies" id="custProducts_1" />
Movies
</label>
<br />
<label>
<input type="radio" name="custProducts" value="electronics" id="custProducts_2" />
Consumer Electronics
</label>
<br />
<label>
<input type="radio" name="custProducts" value="computer" id="custProducts_3" />
Computer
</label>
<br />
</p>
<p>Description of problem: (Limit 200 characters)</p>
<p>
<label for="custComplaint"></label>
<textarea name="custComplaint" id="custComplaint" cols="45" rows="5"></textarea>
</p>
<p>
<input type="submit" name="button" id="button" value="File Complaint" />
<input type="reset" name="button2" id="button2" value="Reset" />
</p>
</form>
<p> </p>
$("#button").click(function(e){
e.preventDefault(); // you need to stop the initial event to have a chance to validate
var validForm=true;
// etc...
You can use jquery.validate.js to validate your forms , it will overcome all your manual efforts to create the validation rules also it is providing the various predefined rules like required,email, minlength and maxlength, etc. So, it will be easier for you to achieve what you need very easily.
https://jqueryvalidation.org/
I have a simple jquery form validation and submission package - see if that's of any help - it's easy to install and you can customise quite a few things: https://github.com/sebastiansulinski/ssd-form
Just to get you started, your submit control in the html has id "button", so you should use $('#button').click, not $('#sendForm').click.
Also, if you want to stay on the page (like to do validations, show errors, etc), you have to prevent the form from submitting automatically when the button is clicked. There are lots of ways to do this, but the easiest way is to just change your button type from submit to button. Ie, replace this:
<input type="submit" name="button" id="button" value="File Complaint" />
with this:
<input type="button" name="button" id="button" value="File Complaint" />
------
That should get you started, at least your code will run, you can use console.log to debug, etc. Good luck.
UPDATE
I should add that if you take my advice, the form will never submit on it's own - that is good if some validation fails and you want to stay on the page and give some error feedback to the user.
When you do want the form to submit, you have to make it happen yourself. Again, there are lots of ways to do this, but the simplest one is probably:
$('#form1').submit();

How to change button state in javascript

I need to code a function in Javacript that updates the button colour and enables it when all fields are valid.
See picture below to understand the user interaction with the form
When the admin wants to update an user the update button needs to be green only if the following apply
At least one edit button is enabled. (When the edit button is enabled the respective fields is deleted and the user can write something)
The field must be validated in real time
If I uncheck the field the script has to revalidate the other open fields. For Instance if the open field is blank the button should be red but if I close the field and another field was enabled and filled with valid text (lets assume just 1 character means valid) the button from red should turn green
Could you please help me to figure this out. I think a solution is to use the JQuery keyup function but it is restricted only to one field. I need instead something more global.
Is there a way in javascript to create a global button listener than be useful for this scenario
In addition when I turn on the password checkbox two fields are enabled and the button should be valid only if password is valid and it matches with confirmed password
Please see below a brief summary of the jsp page
I have omitted the small icons of the password fields and the bootstrap part of the code
<sf:form class="form-horizontal"
role="form"
id="formsubmit"
method="POST"
action="${pageContext.request.contextPath}/updateprofile"
commandName="user">
<sf:input type="text" class="form-control" value="${user.username}" path="username" readonly="true"></sf:input>
<input type="checkbox" class="form-control" name="email-checkbox" checked />
<sf:input id="emailInput" type="text" class="form-control" path="email" placeholder="Type Email" name="email" disabled="true" />
<input type="checkbox" class="form-control" name="first-name-checkbox" checked />
<sf:input id="nameInput" type="text" class="form-control" placeholder="Type First Name" path="firstName" name="firstName" disabled="true" />
<input type="checkbox" class="form-control" name="last-name-checkbox" checked />
<sf:input id="surnameInput" type="text" class="form-control" placeholder="Type Last Name" path="lastName" name="lastName" disabled="true" />
<input type="checkbox" class="form-control" name="password-checkbox" checked />
<input id="password" type="password" class="form-control" name="password" placeholder="Insert Password" disabled>
<input id="confirmpassword" type="password" class="form-control" name="confirmpassword" placeholder="Confirm Password" disabled>
<button id="updateUserBtn" type="submit" class="btn btn-danger" data-loading-text="Creating User..." disabled>Update User</button>
</sf:form>
My first attemp with javascript is below and it works only for the password fields but it is not connected with the edit button
$("input[type=password]").keyup(
function() {
var ucase = new RegExp("[A-Z]+");
var lcase = new RegExp("[a-z]+");
var num = new RegExp("[0-9]+");
if ($("#password").val().length >= 8) {
$("#8char").removeClass("glyphicon-remove");
$("#8char").addClass("glyphicon-ok");
$("#8char").css("color", "#00A41E");
} else {
$("#8char").removeClass("glyphicon-ok");
$("#8char").addClass("glyphicon-remove");
$("#8char").css("color", "#FF0004");
}
if (ucase.test($("#password").val())) {
$("#ucase").removeClass("glyphicon-remove");
$("#ucase").addClass("glyphicon-ok");
$("#ucase").css("color", "#00A41E");
} else {
$("#ucase").removeClass("glyphicon-ok");
$("#ucase").addClass("glyphicon-remove");
$("#ucase").css("color", "#FF0004");
}
if (lcase.test($("#password").val())) {
$("#lcase").removeClass("glyphicon-remove");
$("#lcase").addClass("glyphicon-ok");
$("#lcase").css("color", "#00A41E");
} else {
$("#lcase").removeClass("glyphicon-ok");
$("#lcase").addClass("glyphicon-remove");
$("#lcase").css("color", "#FF0004");
}
if (num.test($("#password").val())) {
$("#num").removeClass("glyphicon-remove");
$("#num").addClass("glyphicon-ok");
$("#num").css("color", "#00A41E");
} else {
$("#num").removeClass("glyphicon-ok");
$("#num").addClass("glyphicon-remove");
$("#num").css("color", "#FF0004");
}
if ($("#password").val() == $("#confirmpassword").val()
&& ($("#confirmpassword").val() != 0)) {
$("#pwmatch").removeClass("glyphicon-remove");
$("#pwmatch").addClass("glyphicon-ok");
$("#pwmatch").css("color", "#00A41E");
} else {
$("#pwmatch").removeClass("glyphicon-ok");
$("#pwmatch").addClass("glyphicon-remove");
$("#pwmatch").css("color", "#FF0004");
}
if ($("#password").val().length >= 8
&& ucase.test($("#password").val())
&& lcase.test($("#password").val())
&& num.test($("#password").val())
&& $("#password").val() == $("#confirmpassword").val()
&& ($("#confirmpassword").val() != 0)) {
$("#updateUserBtn").removeClass("btn-danger");
$("#updateUserBtn").addClass("btn-success");
$("#updateUserBtn").prop('disabled', false);
} else {
$("#updateUserBtn").removeClass("btn-success");
$("#updateUserBtn").addClass("btn-danger");
$("#updateUserBtn").prop('disabled', true);
}
});
A keyup handler attached to the form element will be called for any field within it having a keyup event. That is because most events bubble up through all their ancestors and can be listened for at any level.
Small example as requested :)
$("form").keyup(
function() {
// your existing code here
});
If you want to target only specific inputs for the changes, you could use a delegated handler instead attached to the form (this one is using the specific form id):
$("#formsubmit").on('keyup', 'input[type=text],input[type=password]',
function() {
// your existing code here
});
This applies the selector at event time so is quite efficient, and also means the this value will be the control that changed (if that is useful to you).
As a general jQuery guideline, only run selectors once and save the element. This is faster & shorter and usually more readable. Also you can chain most jQuery functions together.
e.g.
var $password = $("#password");
var $8char = $("#8char");
if ($password.val().length >= 8) {
$8char.removeClass("glyphicon-remove").addClass("glyphicon-ok").css("color", "#00A41E");

Validating Form with Javascript (Simple Test)

var name = document.getElementById('contact-name'),
email = document.getElementById('contact-email'),
phone = document.getElementById('contact-phone'),
message = document.getElementById('contact-message');
function checkForm() {
if (name.value == '') {
alert('test');
}
}
I was simply trying to make sure everything was working before I began learning actual client-side validation.
Here is the HTML
<form role='form' name='contactForm' action='#' method="POST" id='contact-form'>
<div class="form-group">
<label for="contact-name">First and Last Name</label>
<input type="text" class="form-control" id="contact-name" name="contactName" placeholder="Enter your name.." pattern="[A-Za-z]+\s[A-Za-z]+">
</div>
<div class="form-group">
<label for="contact-email">Email address</label>
<input type="email" class="form-control" id="contactEmail" name="contactEmail" placeholder="Enter Email" required>
</div>
<div class="form-group">
<label for="contact-phone">Phone Number</label>
<input type="number" class="form-control" id="contactPhone" name="contactPhone" placeholder="Enter Phone Number" required'>
</div>
<div class="form-group">
<label for='contactMessage'>Your Message</label>
<textarea class="form-control" rows="5" placeholder="Enter a brief message" name='contactMessage' id='contact-message' required></textarea>
</div>
<input type="submit" class="btn btn-default" value='Submit' onclick='checkForm()'>
</fieldset>
</form>
I took the required attribute off, and if I leave the name field empty it goes right to the other one when i click submit. To check whether javascript was working at all, i did an basic onclick function that worked.
Maybe someone can explain to me what is wrong with the checkForm function. Thanks in advance.
P.S The form-group and form-control classes belong to bootstrap
Change your javascript to this:
var contactName = document.getElementById('contact-name'),
email = document.getElementById('contact-email'),
phone = document.getElementById('contact-phone'),
message = document.getElementById('contact-message');
function checkForm() {
if (contactName.value === '') {
alert('test');
}
}
Okay, Hobbes, thank you for editing your question, now I can understand your problem.
Your code faces three two issues.
Your control flow. If you want to validate your field, you have to obtain its value upon validation. You instead populate variable name when the page loads, but the user will enter the text only after that. Hence you need to add var someVariableName = document.getElementById(...); to the beginning of the checkForm() function.
global variables. Please do not use them like that, it is a good design to avoid global variables as much as possible, otherwise you bring upon yourself the danger of introducing side effects (or suffering their impact, which happens in your situation). The global context window already contains a variable name and you cannot override that. See window.name in your console. You can of course use var name = ... inside the function or a block.
Even if you fix the above, you will still submit the form. You can prevent the form submission if you end your checkForm() function with return false;
For clarity I append the partial javascript that should work for you:
function checkForm() {
var name = document.getElementById('contact-name');
if (name.value == '') {
alert('test');
return false;
}
}
EDIT: As Eman Z pointed out, the part 1 of the problem does not really prevent the code from working as there's being retrieved an address of an object (thanks, Eman Z!),

Validating an HTML form with onClick added form fields

I have a form I cobbled together with bits of code copied online so my HTML and Javascript knowledge is VERY basic. The form has a button that will add another set of the same form fields when clicked. I added some code to make it so that if the "Quantity and Description" field is not filled out, the form won't submit but now it just keeps popping up the alert for when the field's not filled out even if it is. Here's is my script:
<script type='text/javascript' src='http://code.jquery.com/jquery-1.5.2.js'>
</script><script type='text/javascript'>
//<![CDATA[
$(function(){
$('#add').click(function() {
var p = $(this).closest('p');
$(p).before('<p> Quantity & Description:<br><textarea name="Quantity and Description" rows="10"
cols="60"><\/textarea><br>Fabric Source: <input type="text" name="Fabric Source"><br>Style# & Name: <input
type="text" name="Style# & Name"><br>Fabric Width: <input type="text" name="Fabric Width"><br>Repeat Information:
<input type="text" name="Repeat Info" size="60"><input type="hidden" name="COM Required" /> </p><br>');
return false;
});
});
function checkform()
{
var x=document.forms["comform"]["Quantity and Description"].value
if (x==null || x=="")
{
alert("Quantity & Description must be filled out, DO NOT just put an SO#!!");
return false;
}
}
//]]>
</script>
And here's my HTML:
<form action="MAILTO:ayeh#janusetcie.com" method="post" enctype="text/plain" id="comform" onSubmit="return
checkform()">
<div>Please complete this worksheet in full to avoid any delays.<br />
<br />Date: <input type="text" name="Date" /> Sales Rep: <input type="text" name="Sales Rep" /> Sales Quote/Order#: <input type="text" name="SQ/SO#" /><br />
<br />Quantity & Description: <font color="red"><i>Use "(#) Cushion Name" format.</i></font><br />
<textarea name="Quantity and Description" rows="10" cols="60">
</textarea>
<br />Fabric Source: <input type="text" name="Fabric Source" /><br />Style# & Name: <input type="text" name="Style# & Name" /><br />Fabric Width: <input type="text" name="Fabric Width" /><br />Repeat Information: <input type="text" name="Repeat Info" size="60" /><br /><font color="red"><i>Example: 13.75" Horizontal Repeat</i></font><br />
<br /><input type="hidden" name="COM Required" />
<p><button type="button" id="add">Add COM</button></p>
</div>
<input type="submit" value="Send" /></form>
How can I get it to submit but still check every occurence of the "Quantity and Description" field?
First, I would not use spaces in your input names, as then you have to deal with weird escaping issues. Use something like "QuantityAndDescription" instead.
Also, it looks like you're trying to have multiple fields with the same name. The best way to do that is to add brackets to the name, meaning the values will be grouped together as an array:
<textarea name="QuantityAndDescription[]"></textarea>
This also means the code has to get all the textareas, not just the first. We can use jQuery to grab the elements we want, to loop over them, and to check the values. Try this:
function checkform()
{
var success = true;
// Find the textareas inside id of "comform", store in jQuery object
var $textareas = $("form#comform textarea[name='QuantityAndDescription[]']");
// Loop through textareas and look for empty values
$textareas.each(function(n, element)
{
// Make a new jQuery object for the textarea we're looking at
var $textarea = $(element);
// Check value (an empty string will evaluate to false)
if( ! $textarea.val() )
{
success = false;
return false; // break out of the loop, one empty field is all we need
}
});
if(!success)
{
alert("Quantity & Description must be filled out, DO NOT just put an SO#!!");
return false;
}
// Explicitly return true, to make sure the form still submits
return true;
}
Also, a sidenote of pure aesthetics: You no longer need to use the CDATA comment hack. That's a holdover from the old XHTML days to prevent strict XML parsers from breaking. Unless you're using an XHTML Strict Doctype (and you shouldn't), you definitely don't need it.

Categories

Resources