How should I improve my javascript form validation? - javascript

I grabbed the form from some random site because I'm only interested writing the javascript at the moment.
I am trying to check that a user has selected or entered text for all fields. I've made it a long if if-else but that can't be the best/most elegant/easiest solution.
Leaving aside the radio button validation for now, what's the better way to check that the text fields, drop down, and checkboxes all have a value/input?
I'm teaching myself javascript so I'm open to being told the proper way and I'll research it and do it on my own, or updating my fiddle would be fine too. (Be gentle with me. I'm sure this code is janky.)
Any thoughts on this would be appreciated.
Fiddle: https://jsfiddle.net/kiddigit/g0rur21a/
document.getElementById("newForm").addEventListener("submit", enterForm);
function enterForm(event) {
event.preventDefault();
var dropdown = document.getElementById('dropDown');
if (document.getElementById('fname').value === ''){
document.getElementById('fname').focus();
alert('Enter text.');
} else if (document.getElementById('eMail').value === ''){
document.getElementById('eMail').focus();
alert('Enter text.');
} else if (document.getElementById('textArea').value === '') {
document.getElementById('textArea').focus();
alert('Enter text.');
} else if (!dropDown.value) {
document.getElementById('dropDown').focus();
alert('Choose an option.');
} else if ( ( newForm.checkbox[0].checked == false ) && ( newForm.checkbox[1].checked == false ) )
{ alert ( "Please choose a checkbox" );
return false;
}
var radios = document.getElementsByName("radio");
var formValid = false;
var i = 0;
while (!formValid && i < radios.length) {
if (radios[i].checked) formValid = true;
i++;
}
if (!formValid) alert("Please check a radio button.");
return formValid;
return false;
};

If you use HTML5, and assuming you're NOT using jQuery for anything (just native JavaScript), a good convention would be to assign a class to all input elements in the form that you want to validate (or if they all need to be validated, you can get all child elements of the form), and use getElementsByClassName(). With HTML5 data-* attributes, you can assign something like data-invalid-error-message to set the error message for the element itself.
http://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp
From there, you can perform a loop across all elements, check if they're empty, and then grab the data-invalid-error-message attribute and display it to the user without doing nested if statements.
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes

document.getElementById("newForm").addEventListener("submit", function (event) {
event.preventDefault();
if (!document.getElementById('fname').value) {
return alert('Enter text.');
}
if (document.getElementById('eMail').value === '') {
document.getElementById('eMail').focus();
return alert('Enter text.');
}
if (document.getElementById('textArea').value === '') {
document.getElementById('textArea').focus();
return alert('Enter text.');
}
var dropdown = document.getElementById('dropDown');
if (!dropdown || !dropDown.value) {
document.getElementById('dropDown').focus();
return alert('Choose an option.');
}
if (( newForm.checkbox[0].checked == false ) && ( newForm.checkbox[1].checked == false )) {
return alert("Please choose a checkbox");
}
var radios = document.getElementsByName("radio");
var formValid = false;
var i = 0;
while (!formValid && i < radios.length) {
if (radios[i].checked) {
formValid = true;
}
i++;
}
if (!formValid) {
return alert("Please check a radio button.");
}
// Form is valid here
});
Here is some improvements. Updated Fiddle
I would like to validate form with required property, but it does not support validation of group of options and radio groups

If you're OK not supporting IE8, you can use querySelectorAll to dynamically get all the nodes of different types within your form and validate them accordingly. This will work for a form with any number of inputs:
function validateForm(formNode) {
var formValid = true;
var textFlds = formNode.querySelectorAll('input[type="text"],input[type="email"],input[type="password"],textarea');
var dropdowns = formNode.querySelectorAll('select');
var checks = formNode.querySelectorAll('input[type="checkbox"]');
var anyChecked = false;
var radios = formNode.querySelectorAll('input[type="radio"]');
var anyRadios = false;
for (var i = 0, l = textFlds.length; i < l; i++) {
if (!textFlds[i].value) {
textFlds[i].focus();
alert('Please enter text into the ' + textFlds[i].name + ' field.');
formValid = false
break;
}
};
for (var i = 0, l = dropdowns.length; i < l; i++) {
if (formValid && !dropdowns[i].value) {
dropdowns[i].focus();
alert('Please choose an option from the ' + dropdowns[i].name + ' selector.');
formValid = false
break;
}
};
for (var i = 0, l = checks.length; i < l; i++) {
if (checks[i].checked) {
anyChecked = true;
break;
}
};
if (formValid && !anyChecked) {
alert('Please choose at least one of the checkboxes.');
formValid = false;
}
for (var i = 0, l = radios.length; i < l; i++) {
if (radios[i].checked) {
anyRadios = true;
break;
}
};
if (formValid && !anyRadios) {
alert('Please check a radio button.');
formValid = false;
}
return formValid;
}
document.getElementById('newForm').addEventListener('submit', function (evt) {
evt.preventDefault();
validateForm(this);
});
This could be prettied up a bit, but you get the idea. (fiddle here)

Related

javascript check a box with value

I am trying to check boxes in JS. I wan't to only check when the value is equal to 0, if not don't check it. my code :
document.onreadystatechange = function check(e)
{
if (document.readyState === 'complete')
{
var inputElements = document.getElementsByTagName("input");
for(var i=0; i < inputElements.length; ++i)
{
if(document.getElementsByTagName("input")[i].value == "1")
{
document.getElementById("date").checked = false;
}
}
}
}
But it doesn't work. Can you help me?
thanks
What you are doing is, if the checkboxes have value of 1, then you are checking it. Make this change in the code and it should work. Also, you need to check if you are doing this on a checkbox and not on a radio or text:
if(document.getElementsByTagName("input")[i].value == 0 &&
document.getElementsByTagName("input")[i].getAttribute("type") == "checkbox")
{
document.getElementById("date").checked = true;
}
var eles = document.querySelectorAll("input[type='checkbox']");
var len = eles.length,
i = 0,
flag = true;
for (; i < len; i++) {
if (eles[i].value === "1") {
flag = false;
return;
}
}
if (flag) document.getElementById('date').checked = true;
If the value ( 0 or 1 ) is of an <input type='text'>, then change document.querySelectorAll("input[type='checkbox']"); to document.querySelectorAll("input[type='text']");

form validation with radio buttons and specific errors

I am trying to make a form validate where there are radio buttons and textarea. I want nothing to be left empty i.e the form should be completely filled. I have done the radio buttons part of validation where if a user does not select a radio button he will get an error for that particular question. you can see the code here for detailed code.
Please help me out. I am not getting error for textarea.
Just add another check for textarea
function RadioValidator() {
var ShowAlert = '';
var AllFormElements = window.document.getElementById("FormID").elements;
for (i = 0; i < AllFormElements.length; i++) {
var name = AllFormElements[i].name;
if (AllFormElements[i].type == 'radio') {
....
} else if (AllFormElements[i].type == 'textarea') {
if (AllFormElements[i].value == '') {
ShowAlert += name + ' textarea must be filled\n';
}
}
}
if (ShowAlert !== '') {
alert(ShowAlert);
return false;
} else {
return true;
}
}
you didn't write any validation for 'textarea' block. I have updated it with one textarea... add rest validations.
function RadioValidator()
{
var ShowAlert = '';
var AllFormElements = window.document.getElementById("FormID").elements;
for (i = 0; i < AllFormElements.length; i++)
{
if (AllFormElements[i].type == 'radio')
{
var ThisRadio = AllFormElements[i].name;
var ThisChecked = 'No';
var AllRadioOptions = document.getElementsByName(ThisRadio);
var problem_desc = document.getElementById("problem_desc");
for (x = 0; x < AllRadioOptions.length; x++)
{
if (AllRadioOptions[x].checked && ThisChecked === 'No' && problem_desc.value === "")
{
ThisChecked = 'Yes';
break;
}
}
var AlreadySearched = ShowAlert.indexOf(ThisRadio);
if (ThisChecked == 'No' && AlreadySearched == -1 && problem_desc.value === "")
{
ShowAlert = ShowAlert + ThisRadio + ' option must be selected\n';
}
}else if(AllFormElements[i].type =='textarea')
{
// add your rest of text area validations here
var problem_desc_1 = document.getElementById("problem_desc");
if(problem_desc_1.value === "")
{
ShowAlert = ShowAlert + '"Services (Please Specify)" can not be blank. \n';
}
}
}
if (ShowAlert !== '')
{
alert(ShowAlert);
return false;
}
else
{
return true;
}
}
You need to add a check for textarea as well
In your javascript check you have only added a condition for type radio.
check for textarea type as well and add error if the value is blank.

How to validate multiple checkbox with javascript

I have simple page with multiple check boxes and radio buttons, This is only validating the first system check box and skipping over the next comm check box. I'm fairly new to js and I'm sure this is a simple fix. Any assistance would be appreciated thanks!!!
if (countSelected(formElement, 'checkbox', 'system[]') == 0) {
alert('Please select System Access');
return false;
}
if (countSelected(formElement, 'radio', 'department') == 0) {
alert('Please choose a Department');
return false;
}
if (countSelected(formElement, 'checkbox', 'comm[]') == 0) {
alert('Please select Comm Access');
return false;
}
return true;
}
How can I get this to validate multiple check boxes? Will I also need to apply the same fix for multiple sets of radio buttons?
I think the problem is that you're returning from the function too soon. Try this:
function test() {
var valid = true;
if (countSelected(formElement, 'checkbox', 'system[]') == 0) {
alert('Please select System Access');
valid = false;
}
if (countSelected(formElement, 'radio', 'department') == 0) {
alert('Please choose a Department');
valid = false;
}
if (countSelected(formElement, 'checkbox', 'comm[]') == 0) {
alert('Please select Comm Access');
valid = false;
}
return valid;
}
This way, it validates everything you want, alerts what you need, and returns the validity like you expect.
Another option, which instead of alerting for each validation, you can do something like this:
function test() {
var valid = true;
var messages = [];
if (countSelected(formElement, 'checkbox', 'system[]') == 0) {
messages.push('Please select System Access');
valid = false;
}
if (countSelected(formElement, 'radio', 'department') == 0) {
messages.push('Please choose a Department');
valid = false;
}
if (countSelected(formElement, 'checkbox', 'comm[]') == 0) {
messages.push('Please select Comm Access');
valid = false;
}
if (messages.length > 0) {
alert(messages.join("\n"));
}
return valid;
}
In this case, you get one alert at the end with all the errors. Might be nicer for the user.
<script defer="defer" type="text/javascript"><!--function validateForm(formElement) {
if (formElement.first_name.value.length < 2)
return focusElement(formElement.first_name,
'Please enter a First Name that is at least 2 characters long.');
if (formElement.last_name.value.length < 2)
return focusElement(formElement.last_name,
'Please enter a Last Name that is at least 2 characters long.');
if (formElement.model_id.value.length < 7)
return focusElement(formElement.model_id,
'Please enter a Model ID that is at least 7 characters long.');
if (countSelected(formElement, 'checkbox', 'system[]') == 0) {
alert('Please select System Access');
return false;
}
if (countSelected(formElement, 'radio', 'department') == 0) {
alert('Please choose a Department');
return false;
}
if (countSelected(formElement, 'checkbox', 'comm[]') == 0) {
alert('Please select Comm Access');
return false;
}
return true; } function focusElement(element, errorMessage) {
alert((errorMessage.length > 0) ? errorMessage :
'You did not enter valid data; Please try again');
if (element.select) element.select();
if (element.focus) element.focus();
return false; } function countSelected(formElement, inputType, inputName) {
if (inputType == null) inputType = 'checkbox';
var returnValue = 0;
for (var loopCounter = 0; loopCounter < formElement.length; loopCounter++) {
var element = formElement.elements[loopCounter];
if (element.type == inputType && element.checked == true) {
if (inputName.length > 0)
if (element.name == inputName)
returnValue++;
else
returnValue++
}
}
return returnValue; } function countSelectedOptions(selectElement) {
var returnValue = 0;
for (var loopCounter = 0; loopCounter < selectElement.options.length; loopCounter++)
if (selectElement.options[loopCounter].selected == true)
returnValue++;
return returnValue;
}
//-->

retain form values onclick after javascript validation fails

This is part of an assignment. Everything that's supposed to work, already works, but there's something that bothers me. The only purpose of the code so far is to test our ability to validate from data. Anyway, right now the validate() function is attached to a submit button:
<input type="submit" value="Find Love" onclick="validate()">
When any validation fails, all the text boxes, drop downs, etc. are cleared, but I want them to retain their values and just focus on the first incorrect value (retaining their values is more important to me at this point). The actual Does that require some modification of the onclick function or a different function all together? Please help. If you need to see the javascript I can post that as well.
function validate()
{
var blnValid = true;
if(isBlank("txtFName"))
{
blnValid = false;
alert("First name cannot be blank!")
document.getElementById("txtFName").focus();
}
if(blnValid)
{
if(isBlank("txtLName"))
{
blnValid = false;
alert("Last name cannot be blank!")
document.getElementById("txtLName").focus();
}
}
if(blnValid)
{
if(isBlank("txtAge"))
{
blnValid = false;
alert("Age cannot be blank!")
document.getElementById("txtAge").focus();
}
}
if(blnValid)
{
var strInput = document.getElementById("txtAge").value;
if(!isInt(strInput))
{
blnValid = false;
alert("You must enter a valid number in the age field.")
document.getElementById("txtAge").select();
}
}
if(blnValid)
{
if(document.getElementById("selUserGender").selectedIndex <= 0)
{
alert("Please select your gender");
blnValid = false;
}
}
if(blnValid)
{
if(document.getElementById("selFindGender").selectedIndex <= 0)
{
alert("Please select your gender");
blnValid = false;
}
}
if(blnValid)
{
blnChecked = false;
arRadio = document.forms[0].rdbAgeRange;
for (var i = 0; i < arRadio.length; i++)
{
if(arRadio[i].checked)
{
blnChecked = true;
break;
}
}
if (!blnChecked)
{
alert("You must select an age group.");
blnValid = false;
}
}
if(blnValid)
{
if(!document.getElementById("chkSkeeball").checked
&& !document.getElementById("chkAir").checked
&& !document.getElementById("chkCliff").checked
&& !document.getElementById("chkHamster").checked)
{
blnValid = false;
alert("You must select a hobby.")
}
}
return blnValid;
}
function isInt(strValue)
{
var validNums = "0123456789";
var blnIsNumber = true;
var tempChar;
for (var i = 0; i < validNums.length; i++)
{
tempChar = strValue.substr(i, 1);
if (validNums.indexOf(tempChar) == -1)
{
return false;
}
}
return true;
}
function isBlank(elementID)
{
if(document.getElementById(elementID).value.length == 0)
{
return true;
}
return false;
}
Your problem is actually your HTML. Nothing in your Javascript is going to clear the elements but because you're using onClick the form is actually submitting anyway. I assume that it probably just submits back to the page and clears everything. Instead of onClick use onSubmit in the form element:
<form method="post" action="url_of_action" onSubmit="return validate()">
If it's not valid it will prevent the form from submitting.
Missing semi-colons:
if(isBlank("txtFName"))
{
blnValid = false;
alert("First name cannot be blank!") //here
document.getElementById("txtFName").focus();
}
if(blnValid)
{
if(isBlank("txtLName"))
{
blnValid = false;
alert("Last name cannot be blank!") //and here
document.getElementById("txtLName").focus();
}
}
if(blnValid)
{
if(isBlank("txtAge"))
{
blnValid = false;
alert("Age cannot be blank!") //and here
document.getElementById("txtAge").focus();
}
}

How do I create a "check all" link for a web form?

I've got a form with a bunch of checkboxes on it, and I'd like to provide a "check all" link/button.
I'm using the code below, but when it runs, it picks up some radio buttons on the page, and checks/unchecks those too. How do I fix this?
var check = 0;
function doNow()
{
void(d=document);
void(el=d.getElementsByTagName('INPUT'));
for(i=0;i<el.length;i++)
{
if(check == 0)
void(el[i].checked=1)
else
void(el[i].checked=0)
}
if(check == 0)
check = 1;
else
check = 0;
}
You're going to want to check the element's type to ensure you don't accidentally go checking the wrong kind of inputs.
Basic example:
function checkAll( toggle ) {
var inputs = document.getElementsByTagName( 'input' );
for( var i = 0; i < inputs.length; i++ ) {
if( inputs[i].type == 'checkbox' ) {
inputs[i].checked = toggle;
}
}
}
You may want to add other checks, such as only acting on check boxes in a certain logical "group", for example.
You can check the type of the input:
if(el[i].type == 'checkbox') {
el[i].checked = true;
}
You can store the current state as a property of the function as well as check the type
function checkAll() {
var all = document.getElementsByTagName('input');
for( var i = 0, l = all.length; i < l; i++ ) {
if( all[i].type == 'checkbox' ) {
all[i].checked = checkAll.checked;
}
}
checkAll.checked = !checkAll.checked;
}
checkAll.checked = true;

Categories

Resources