Javascript form validation only works in firefox - javascript

I am relatively new to Javascript so I'm hoping this is a simple mistake. I building a generic form validation function that is called on the form's onSubmit. The function loops through all the form's child elements, looks for certain classes, and analyzes the contents of the appropriate fields. If it finds something missing or erroneous, it displays the appropriate error message div and returns false, thus preventing the form from being submitted to the php page.
It works well in firefox 3.6.3, but in every other browser I've tested (Safari 4.0.4, Chrome 4.1, IE8) it seems to ignore the onSubmit and jump straight to the php processing page.
HTML CODE:
<form name='myForm' id='myForm' action='process_form.php' method='post' onSubmit="return validateRequired('myForm')">
<fieldset class="required radioset">
<label for='selection1'>
<input type='radio' name='selection' id='selection1' value='1'/>
Option 1
</label>
<label for='selection2'>
<input type='radio' name='selection' id='selection2' value='2'/>
Option 2
</label>
<label for='selection3'>
<input type='radio' name='selection' id='selection3' value='3'/>
Option 3
</label>
<label for='selection4'>
<input type='radio' name='selection' id='selection4' value='4'/>
Option 4
</label>
<div class='errorBox' style='visibility:hidden'>
Please make a selection
</div>
</fieldset>
<fieldset class="required checkset">
<label>
Choice 1
<input type='checkbox' name='choices' id='choice1' value='1'/>
</label>
<label>
Choice 2
<input type='checkbox' name='choices' id='choice2' value='2'/>
</label>
<label>
Choice 3
<input type='checkbox' name='choices' id='choice3' value='3'/>
</label>
<label>
Choice 4
<input type='checkbox' name='choices' id='choice4' value='4'/>
</label>
<div class='errorBox' style='visibility:hidden'>
Please choose at least one
</div>
</fieldset>
<fieldset class="required textfield" >
<label for='textinput1'>
Required Text:
<input type='text' name='textinput1' id='textinput1' size='40'/>
</label>
<div class='errorBox' style='visibility:hidden'>
Please enter some text
</div>
</fieldset>
<fieldset class="required email textfield">
<label for='email'>
Required Email:
<input type='text' name='email' id='email' size='40'/>
</label>
<div class='errorBox' style='visibility:hidden'>
The email address you have entered is invalid
</div>
</fieldset>
<div>
<input type='submit' value='submit'>
<input type='reset' value='reset'>
</div>
</form>
JAVASCRIPT CODE:
function validateRequired(id){
var form = document.getElementById(id);
var errors = 0;
var returnVal = true;
for(i = 0; i < form.elements.length; i++){
var elem = form.elements[i];
if(hasClass(elem,"required")){
/*RADIO BUTTON or CHECK BOX SET*/
if(hasClass(elem,"radioset") || hasClass(elem,"checkset")){
var inputs = elem.getElementsByTagName("input");
var check = false;
for(j = 0; j < inputs.length; j++){
if(inputs[j].checked){
check = true;
}
}
if(check == false){
errors += 1;
showError(elem);
} else {
hideError(elem);
}
}
/*TEXT FIELD*/
else if(hasClass(elem,"textfield")){
var input = elem.getElementsByTagName("input");
if(input[0].value == ""){
errors += 1;
showError(elem);
} else {
hideError(elem);
/*EMAIL ADDRESS*/
if(hasClass(elem,"email")){
if(isValidEmail(input[0].value) == false){
errors += 1;
showError(elem);
} else {
hideError(elem);
}
}
}
}
}
}
if(errors > 0){
returnVal = false;
} else {
returnVal = true;
}
return returnVal;}
I know this is a lot of code to look at, but any help would be appreciated. Since it works fine in one browser, Im not sure how to start debugging.
Thanks
Andrew

for(i = 0; i < form.elements.length; i++){
var elem = form.elements[i];
if(hasClass(elem,"required")){
The problem is that your required and other classes are put on the <fieldset> element.
Fieldset elements are included in the form.elements collection on IE, Firefox and Opera, but not WebKit browsers (Chrome, Safari). It is these browsers where your form fails for me.
It has always been a weird quirk that <fieldset> was included in the elements collection. The DOM Level 2 HTML spec states that only ‘form control elements’ should be present in the collection, and by HTML4's definition that would seem not to include fieldsets, which have no control name or value.
You could perhaps change your code to use getElementsByTagName to pick up the fieldsets instead:
var fieldsets= form.getElementsByTagName('fieldset');
for (var i= 0; i<fieldsets.length; i++) {
var elem= fieldsets[i];

I would not use hasClass. Here's another way to try that might work better for you:
var node_list = document.getElementsByTagName('input');
for (var i = 0; i < node_list.length; i++) {
var node = node_list[i];
if (node.getAttribute('type') == 'text') {
// do something here with a <input type="text" .../>
alert(node.value);
}
}
I know that IE has problems getting the classes from some elements which have multiple classes associated with them. Regardless, this is a handy function.

If you have any kind of JavaScript error, the function will not return false, and therefore the default behavior of submitting the data will be triggered.
Try running your code through [http://www.javascriptlint.com/online_lint.php][1] first, then a debugger.

try not to use if(errors > 0)...just in every condition (for wrong input) put return false;
and at the end before the last bracket put return true;
and better use:
onSubmit="return validateRequired(this)"
and there is no need in this lines (in case you remove the errors var)
var form = document.getElementById(id);
var errors = 0;
var returnVal = true;

Not the cause of your problem, I'm sure, but it's best not to serve a set of radio buttons without one of them selected.
In your particular case, if you know that you set one when you serve the page, you don't need a "required" check; there's no way the user can get the radio buttons into a state where none are selected. Pick a sensible default, make it the first option, and make it selected. Simplify your life :)
From the W3C:
http://www.w3.org/TR/html401/interact/forms.html#radio
If no radio button in a set sharing
the same control name is initially
"on", user agent behavior for choosing
which control is initially "on" is
undefined. Note. Since existing
implementations handle this case
differently, the current specification
differs from RFC 1866 ([RFC1866]
section 8.1.2.4), which states:
At all times, exactly one of the radio
buttons in a set is checked. If
none of the <INPUT> elements of a set
of radio buttons specifies `CHECKED',
then the user agent must check the
first radio button of the set
initially.
Since user agent behavior differs,
authors should ensure that in each set
of radio buttons that one is initially
"on".

Back to basics for a second: You say it "seems to ignore the onsubmit". That leaves three possibilities that I can think of:
Your function is never called
It's called, and is bombing out part-way through due to an error
It's called, and isn't doing what you think it is, always returning true
It's not clear from your question which it is, so if I were you I'd start debugging this by putting an alert at the beginning of the function to see whether IE's calling it at all - then move that alert down and run the validation again, and see where it stops appearing (any error must be above that point).
I'd also want to alert the return value from the place it was called, to see what was coming back. If it's always true, then your code is working but not doing what you think it does.
From there, you at least have a clearer grasp of what's going on, if not an exact block of code to be scrutinising.

Related

How do you make a checkbox that is non interactive and is only checked if variable is?

I need a script where, if a value is higher then an assigned value. A non-interactive checkbox checks itself to show the user that the value they inserted is higher.
You should come with some code or the example that you have tried, still following example can you help you with your problem:
HTML
JSFiddle: http://jsfiddle.net/par409yx
document.getElementById('boxText').onchange = function() {
if (document.getElementById('boxText').value > 10)
document.getElementById('box').checked = true
else
document.getElementById('box').checked = false
};
<input id="box" type="checkbox" disabled/>
<input id="boxText" type="text" />

How to call multiple functions with DOM and Javascript

I'm working on an assignment and need to validate multiple inputs. I have created multiple functions and am having trouble calling each one. The first one is the only one that will call. The other two will just hang and do nothing.
If I do a single function call for oninput at the form tag it works. Just that it automatically calls the function and all validations. This causes all the prompts to come out at the same time which I don't want. This is why the oninput call is being done at the input tag.
HTML:
<div id="nameValidate"></div>
<label for="name">Name:</label>
<input type="text" id="nameID"
oninput="nameValidation()"/> <br />
<div id="emailValidate"></div>
<label for="email">Email:</label>
<input type="text" id="emailID"
oninput="emailValidation()"/> <br />
<div id="phoneValidate"></div>
<label for="phone">Phone Number:</label>
<input type="number" id="phoneID"
oninput="phoneValidation()"/>
Javascript
function nameValidation() {
var name = document.getElementById("nameID").value;
if (name.length < 3) {
document.getElementById("nameValidate").innerText = "Please
enter your full name.";
}
else if (name.length > 3) {
document.getElementById("nameValidate").innerText = "";
}
}
function emailValidation() {
var email = document.getElementById("emailID").value;
if (!email.match(".com") && email < 5) {
document.getElementById("emailValidate").innerText = "Please
enter your full email address.";
}
else {
document.getElementById("emailValidate").innerText = "";
}
}
function phoneValidation() {
var phone = document.getelementbyid("phoneID").value;
if (phone == "" || phone.length < 10) {
document.getelementbyid("phoneValidate").innertext = "please
enter your full phone number.";
}
else if () {
document.getelementbyid("phoneValidate").innertext = "";
}
}
Let's back up a minute and break some very bad habits that someone who doesn't know any better is teaching you.
Do not set up events using inline HTML event attributes (ie. onclick). This is a 25+ year old technique that persists today because people just copy/paste it and it seems to work in many cases. However, there are a number of very good reasons not to use this ancient technique that just will not die. Separate your JavaScript from your HTML and use modern, standards-based approaches to event handling with .addEventListener().
You've also mis-capitalized .getElementById() when you were getting the phone data and this would cause an error in your code that would prevent it from continuing. Always work with your developer tools (F12) open and the Console tab showing as this is where error messages will appear.
Next, only query the DOM once for elements that you'll need over and over. This means remove all the document.getElementById() lines from inside the functions and move them so they just get executed only once.
And, don't make references to properties of DOM elements, make the references to the element itself. This way, you scan the document just once to get the element reference, but then you can get any property you like when you need it without having to scan the document for the same element again.
Next, don't use .innerText as it is non-standard. Use .textContent instead.
And, don't use self-terminating tag syntax (ie.<br />, <input />). Here's why.
So, here's what your code should look like:
// Get references to the elements you'll be working with just once
var userName = document.getElementById("nameID");
var nameValidate = document.getElementById("nameValidate");
var email = document.getElementById("emailID");
var emailValidate = document.getElementById("emailValidate");
var phone = document.getElementById("phoneID");
var phoneValidate = document.getElementById("phoneValidate");
// Set up your event handlers in JavaScript, not HTML
userName.addEventListener("input", nameValidation);
email.addEventListener("input", emailValidation);
phone.addEventListener("input", phoneValidation);
function nameValidation() {
if (this.value.length < 3) {
nameValidate.textContent = "Please enter your full name.";
} else {
nameValidate.textContent = "";
}
}
function emailValidation() {
// Check the last 4 characters of the input
if ((this.value.substr(this.value.length - 4) !== ".com") && email.value.length < 5) {
emailValidate.textContent = "Please enter your full email address.";
} else {
emailValidate.textContent = "";
}
}
function phoneValidation() {
if (phone.value == "" || phone.value.length < 10) {
phoneValidate.textContent = "please enter your full phone number.";
} else {
phoneValidate.textContent = "";
}
}
<div id="nameValidate"></div>
<label for="name">Name:</label>
<input type="text" id="nameID"> <br>
<div id="emailValidate"></div>
<label for="email">Email:</label>
<input type="text" id="emailID"> <br>
<div id="phoneValidate"></div>
<label for="phone">Phone Number:</label>
<input type="number" id="phoneID">
Finally, as a professional technology trainer for over 25+ years, I would strongly advise you to inform whoever is teaching you these outdated techniques that they are doing you and anyone else they are teaching a disservice. Modern web development is hard-enough without having to unlearn bad habits brought on by those who don't know any better.
Firstly, your elseif has brackets but the condition is empty. Check your console, it should be showing a syntax error because:
} else if () {
document.getelementbyid("phoneValidate").innertext = "";
}
is not valid syntax. Turn it into an else.
Secondly, the function:
document.getelementbyid("phoneValidate").innertext = "";
does not exist on document, however, getElementById does.
Finally, ensure that you use the console to help you debug your code.

IsNullOrEmpty attribute

In HTML exists
required
attribute, which force user to enter some date before submit. But user can type only spaces. Is there attribute which check is typed content is whitespace before postback. In need attibute which works similar to string.IsNullOrWhitespace in c#.
It took me a while to get the Regex right, but the following creates a rule to only select if there's no whitespace:
<input type="text" pattern=".\S*" />
As #Paul S. noted, this isn't checking the first character, so the following will do that:
<input type="text" pattern="^.\S*" />
Also, this does indeed only work in HTML5 browsers, but since the question contained required, I'm assuming there if is some fallback kept in mind.
Using the pattern attribute, you can make it accept only spaces
<form action="?" method="post"> <!-- required for snippet -->
<input type="text" required pattern="\s*"/>
</form>
However, please note that required prevents the submission of empty input (i.e. your "null"), so to permit that remove required so that pattern is doing the requirement checking
<form action="?" method="post"> <!-- required for snippet -->
<input type="text" pattern="\s*"/>
</form>
Lastly, still perform validation on the server as you can never assume a client is a safe source, or conversely, always assume the client is trying to hack you
If you can't assume HTML 5 support, you can shim the behaviour using JavaScript, which would look something like this for required
if(!('required' in document.createElement('input'))) {
window.addEventListener('submit', function (e) {
var form = e.target,
inputs = form.getElementsByTagName('input'),
i;
for (i = 0; i < inputs.length; ++i)
if (inputs[i].getAttribute('required'))
if (!inputs[i].value)
e.preventDefault(); // + warn?
});
}
and for pattern
if(!('pattern' in document.createElement('input'))) {
window.addEventListener('submit', function (e) {
var form = e.target,
inputs = form.getElementsByTagName('input'),
i,
re;
for (i = 0; i < inputs.length; ++i)
if (re = inputs[i].getAttribute('pattern')) {
re = new RegExp('^' + re + '$');
if (!re.test(inputs[i].value))
e.preventDefault(); // + warn?
}
});
}
You could also set useCapture to true for the listener to skip ahead in the queue of handlers, letting you prevent the event reaching other handlers in the case of submission prevented
<
<form onsubmit="alert('Submitted.');return false;"> <input type="text" required="" pattern="(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))" value="" name="dates_pattern2" id="dates_pattern2" list="dates_pattern2_datalist" placeholder="Try it out." autocomplete="off"> <input type="submit" value="»"> <datalist id="dates_pattern2_datalist"> </datalist> </form>

Check if html form values are empty using Javascript

I want to check a form if the input values are empty, but I'm not sure of the best way to do it, so I tried this:
Javascript:
function checkform()
{
if (document.getElementById("promotioncode").value == "")
{
// something is wrong
alert('There is a problem with the first field');
return false;
}
return true;
}
html:
<form id="orderForm" onSubmit="return checkform()">
<input name="promotioncode" id="promotioncode" type="text" />
<input name="price" id="price" type="text" value="€ 15,00" readonly="readonly"/>
<input class="submit" type="submit" value="Submit"/>
</form>
Does anybody have an idea or a better solution?
Adding the required attribute is a great way for modern browsers. However, you most likely need to support older browsers as well. This JavaScript will:
Validate that every required input (within the form being submitted) is filled out.
Only provide the alert behavior if the browser doesn't already support the required attribute.
JavaScript :
function checkform(form) {
// get all the inputs within the submitted form
var inputs = form.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
// only validate the inputs that have the required attribute
if(inputs[i].hasAttribute("required")){
if(inputs[i].value == ""){
// found an empty field that is required
alert("Please fill all required fields");
return false;
}
}
}
return true;
}
Be sure to add this to the checkform function, no need to check inputs that are not being submitted.
<form id="orderForm" onsubmit="return checkform(this)">
<input name="promotioncode" id="promotioncode" type="text" required />
<input name="price" id="price" type="text" value="€ 15,00" readonly="readonly"/>
<input class="submit" type="submit" value="Submit"/>
</form>
Depending on which browsers you're planning to support, you could use the HTML5 required attribute and forego the JS.
<input name="promotioncode" id="promotioncode" type="text" required />
Fiddle.
Demo: http://jsfiddle.net/techsin/tnJ7H/4/#
var form = document.getElementById('orderForm'),
inputs=[], ids= ['price','promotioncode'];
//findInputs
fi(form);
//main logic is here
form.onsubmit = function(e){
var c=true;
inputs.forEach(function(e){ if(!e.value) {c=false; return c;} });
if(!c) e.preventDefault();
};
//findInputs function
function fi(x){
var f = x.children,l=f.length;
while (l) {
ids.forEach(function(i){if(f[l-1].id == i) inputs.push(f[l-1]); });
l--;
}
}
Explanation:
To stop submit process you use event.preventDefault. Event is the parameter that gets passed to the function onsubmit event. It could be in html or addeventlistner.
To begin submit you have to stop prevent default from executing.
You can break forEach loop by retuning false only. Not using break; as with normal loops..
i have put id array where you can put names of elements that this forum would check if they are empty or not.
find input method simply goes over the child elements of form element and see if their id has been metnioned in id array. if it's then it adds that element to inputs which is later checked if there is a value in it before submitting. And if there isn't it calls prevent default.

jquery validation

I have a poll with a couple a questions. Here is html code
<form id="pool">
<div class="questions>
<input type="radio" name="sex">Male
<input type="radio" name="sex">Female
</div>
<div class="questions>
<input type="radio" name="hair">Brown
<input type="radio" name="hair">Blonde
</div>
.... a lot of qestions div's
</form>
What to do so after the form is submitted to be sure that there is a checked radio button in all div`s ?
If you know how many groups you have you can just do:
if($('#pool input:radio:checked').length < numGroups){
// At least one group isn't checked
}
Otherwise you need to count the number of groups first. I can't think of any way to do this better then:
var rgroups = [];
$('#pool input:radio').each(function(index, el){
var i;
for(i = 0; i < rgroups.length; i++)
if(rgroups[i] == $(el).attr('name'))
return true;
rgroups.push($(el).attr('name'));
}
);
rgroups = rgroups.length;
if($('#pool input:radio:checked').length < rgroups)
alert('You must fill in all the fields.');
else
alert('Thanks!');
set default values or create handler for submit button and check if some values was checked. If no radio button is checked, show error message and do not submit form ( return false)
Untested code, but this is the idea:
if($('#pool').children().length == $('pool
div').find('#pool input:radio:selected').length) {
//do stuff
}
You can use the jquery validate plugin
from my experience this plugin is very efficient

Categories