New to Javascript. My function is muddled and I would like some guidance on how to execute this properly.
This function shall display a message (from the msg[]) contingent on the status of an input field. Currently, there is only one condition for an input to be considered erroneous - if the input field is empty. I would like to add another condition (if an input is NaN, display appropriate message from another array called msg2[]) but I am lost on how to write it in. I know I could just simply utilize HTML5's 'required' attribute or input type="number" however, I would like to hard code this function for my personal gain.
How can I make the function choose between 2 conditions and display appropriate message from corresponding array?
function validateForm(someForm) {
document.getElementById('errorMsg').innerHTML = "";
var allInputs = document.getElementById("studentform").getElementsByTagName("input");
for (var i = 0; i < allInputs.length; i++) {
if (allInputs[i].name != "final-average-result" && allInputs[i].name != "final-letter-grade-result") {
if (allInputs[i].value == "") {
document.getElementById('errorMsg').innerHTML = msg[i];
if (currentField) {
currentField.style.border = "2px solid #CCC";
}
allInputs[i].style.border = "2px dotted #F00";
currentField = allInputs[i];
allInputs[i].onclick = function () {
this.style.border = "2px dashed #CCC";
}
return;
}
}
} // end for
} // end validateForm
var msg = ["Name should not be empty", "This field should not be empty",
"This 3rd field should not be empty", "The last field should not be empty."];
var msg2 = ["Invalid input", "error message here",......."]
Us if else and isNaN() function
function validateForm(someForm) {
document.getElementById('errorMsg').innerHTML = "";
var allInputs =
document.getElementById("studentform").getElementsByTagName("input");
for (var i = 0; i < allInputs.length; i++) {
if (allInputs[i].name != "final-average-result" && allInputs[i].name != "final-
letter-grade-result") {
if (allInputs[i].value == "") {
document.getElementById('errorMsg').innerHTML = msg[i];
if (currentField) {
currentField.style.border = "2px solid #CCC";
}
allInputs[i].style.border = "2px dotted #F00";
currentField = allInputs[i];
allInputs[i].onclick = function () {
this.style.border = "2px dashed #CCC";
}
return;
} else if(isNaN(allInputs[i].value)) {
// display error
}
}
} // end for
} // end validateForm
var msg = ["Name should not be empty", "This field should not be empty",
"This 3rd field should not be empty", "The last field should not be empty."];
var msg2 = ["Invalid input", "error message here",......."]
There are lots of different possibilites to consider when performing input validation. There are plugins, and frameworks etc that help you, where you have gone down a fairly manual brick and mortar approach. But thats beside the point...
I find that there are problems with your logic, and there is where you should start to refactor your solution. You are using an array implicitly to hold the error messages for all imput fields. So that first input has a custom error message in the first slot in msg array. This seems to be extremely brittle and will break at some point, you already have a filter which removes two fields from this order, are you sure you compensate for that? Also, you seem to stop at first invalid field?
When trying to validate type of value for msg2, and if you want to support differnet kind of values and validations, this logic won't work. You need to be able to use different requirements for different fields, and perhaps several validation criterias for one field...
You simply need to work out another strategy. One close to your attempt would be to structure your fields in a object by field name or id, and then have a corresponding object for validation, where fields represent validation error for a specific type of error.
var inputFieldValidationErrorMap = {
'first-field-name': {
empty: 'Name should not be empty',
wordchars: 'Name must be only valid letter chars'
},
'second-field-name': {
empty: 'This field should not be empty',
nan: 'This field must contain only numbers'
}
}
To use this in your current code, you'd write something like
function validateForm(someForm) {
document.getElementById('errorMsg').innerHTML = "";
var allInputs = document.getElementById("studentform").getElementsByTagName("input");
for (var i = 0; i < allInputs.length; i++) {
if (allInputs[i].name != "final-average-result" && allInputs[i].name != "final-letter-grade-result") {
var name = allInputs[i].name;
var errorElement = document.getElementById('errorMsg');
var validation = inputFieldValidationErrorMap[name];
if (allInputs[i].value === "" && 'empty' in validation) {
errorElement.innerHTML = validation.empty;
return;
} else if(isNaN(allInputs[i].value) && 'nan' in validation) {
errorElement.innerHTML = validation.nan;
return;
}
//... Go on here for every type of validation you support
}
} // end for
} // end validateForm
Further improvements
This solution is by no means perfect, and it has its limitations as well. You could also use some data attribute on your input fields to contain your validation requirements, and you should combine your solution with setting correct input types etc, using native html attirbutes for better usability. You should allow each input to display its own error, and run validation passes through all fields in the form so that all errors are current. There are frameworks and plugins to consider as well, to be sure your not running into trouble.
You can use an else if statement like
if (input != condition ){}
else if (input != condition ){}
The statement if (allInputs[i].name != "final-average-result" && allInputs[i].name != "final-letter-grade-result") is also incorrect. You should use || operator instead of &&. allInputs[i].name will not be equal to 2 strings at same time
Related
I need to transfer date from one asp form to another based on some checks.
In the source page I do the check and send as following:
if (txtFinalized.Text == "" && rblPhysicalrecords.SelectedValue=="1" && ddlResponsibility.SelectedIndex == 5)
{
//String s = Request.QueryString["finlalisationDate"] = txtFinalized.Text;
Session["finlalisationDate"] = txtFinalized.Text;
}
Then I try to read the value in the target form but so far I can't get the resut inserted into the input field as I need.
txtFinalised.Text = (string)(Session["finlalisationDate"]);
Do I need to write a method in javascript to fetch the result and insert it to the field and if yes how do I do that?
Your condition block has a flaw, it says txtFinalized must be empty to set a value to your session variable.
For learning and and understand session you could write your code like this...
//remove txtFinalized from condition
if (rblPhysicalrecords.SelectedValue=="1" && ddlResponsibility.SelectedIndex == 5)
{
//check if textFinalized NOT is null or empty
if (!String.IsNullOrEmpty)
{
Session["finlalisationDate"] = txtFinalized.Text;
}
//if textFinalized is empty set session to a value just to see some text
else
{
Session["finlalisationDate"] = "n/a";
}
}
Now when you load your second form you will always see something in your textFinalized textbox and from what you see you know if the user made some input in the first form.
You can modify your condition block like below
if (!String.IsNullOrEmpty(txtFinalized.Text) && rblPhysicalrecords.SelectedValue=="1" && ddlResponsibility.SelectedIndex == 5)
{
//String s = Request.QueryString["finlalisationDate"] = txtFinalized.Text;
Session["finlalisationDate"] = txtFinalized.Text;
}
I have some code here that will make validations of whether or not the input from a text box is NOT an empty string and isNaN. When i do these validations on amounts entered, i would like it to add them up.. however when a user does not enter anything in one or more amount fields the program should just add entered fields. But instead i get NaN showing in the total field.
link to full code: http://jsfiddle.net/KxNqQ/
var $ = function (id) {
return document.getElementById(id);
}
var calculateBills = function () {
var myErrorFlag = "N";
for (i = 1; i <= 4; i++) {
AmountNumber = 'amount' + i;
AmountValue = $(AmountNumber).value;
if (AmountValue != "" && isNaN(AmountValue)) {
$(AmountNumber).style.color = "red";
myErrorFlag = "Y";
} else {
$(AmountNumber).style.color = "black";
myErrorFlag = "N";
}
}
if (myErrorFlag != "Y") {
var Amount = 0;
for (i = 1; i <= 4; i++) {
Amount += parseInt($('amount' + i).value,10);
}
$('total').value = Amount;
}
}
var clearFields = function () {
for (i = 1; i <= 4; i++) {
itemName = 'item' + i;
$(itemName).value = "";
}
for (i = 1; i <= 4; i++) {
amountName = 'amount' + i;
$(amountName).value = "";
}
$('total').value = "";
}
window.onload = function () {
$("clearfields").onclick = clearFields;
$("addbills").onclick = calculateBills;
}
I think you've got your requirements a little bit confused, or at the very least I was confused by them. So in order to answer your question, I'm going to rephrase the requirements so I understand them better. This is a useful exercise that I try to do when I'm not 100% sure of the requirements; if I can't get the requirements right, what's to say I'll get the code right?
So the requirements – as I understand them – are:
Given each amount input
When the input has a value
And that value is a number
Then add the value to the total
And make the input color black
But if the input does not have a value
Or that value is not a number
Then make the input color red
Going through your code, I can see a number of problems with it. First, I noticed that both AmountNumber and AmountValue are global variables, because they were not declared local with the var keyword. So before fixing our code, let's change that. Let's also change the variable names to something that more accurately describe what they are, hopefully making the code easier to understand:
var input = $('amount' + i);
var value = input.value;
Now, note that I chose to store the element in the input variable. This is so we don't have to look it up multiple times within the loop. Looking things up in the DOM can be expensive so we'll want to keep it to a minimum. There are other was to look up elements as well, such as getElementsByClassName, querySelector and querySelectorAll; those are left as an exercise for the reader to research and evaluate.
Next, in each iteration of the loop, you check that AmountValue is not a string and simultaneously is not a number:
if (AmountValue != "" && isNaN(AmountValue)) {
This will be true so long as AmountValue is truthy (which is the case for non-empty strings) and so long as isNaN thinks it's a number (which is the case for strings that contain numbers.) It really is rather confusing; if I understand your code correctly this clause is there to check for invalid input and if it is true should mark the input field red and set a flag. I.e. this is the but clause in the aforementioned requirements.
Let's rewrite this to be the when clause instead, we'll take care of the but later. Before we do that, let's look at the myErrorFlag. It's used – I think – to see whether all input is well formed and in that case, add it all up. Well, validation and summation can be done in one fell swoop, so let's get rid of the flag and sum the values while validating them. So we replace myErrorFlag with a total variable:
var total = 0;
Now, let's get back to our clause. The requirements say:
When the input has a value
And that value is a number
Then add the value to the total
In code, that should look something like this:
if (value && !isNaN(value)) {
total += parseInt(value, 10);
input.style.color = 'black';
}
There are a couple of things going on here. For one, the if statement has been turned on its head a bit from what it was. It first checks to see that value is truthy, then that it is a number. The second check can be a bit tricky to read, because it is essentially a double negation; in english it reads "is not not a number", i.e. "is a number". I'll leave it as an exercise for the reader to figure out whether there's a more easily understood way of writing this check.
Now what about the but clause in our requirements?
But if the input does not have a value
Or that value is not a number
Then make the input color red
Well, it's essentially the inverse of our previous statement, so let's simply add an else clause:
else {
input.style.color = 'red';
}
Because the requirements doesn't mention the total variable in this clause, it is simply ignored and doesn't show up in the end result.
Adding it all up (no pun intended) the code – with comments – looks like this:
var calculateBills = function () {
var total = 0;
for (i = 1; i <= 4; i++) {
// Given each amount input
var input = $('amount' + i);
var value = input.value;
if (value && !isNaN(value)) {
// When the input has a value
// And that value is a number
// Then add the value to the total
total += parseInt(value, 10);
// And make the input color black
input.style.color = 'black';
} else {
// But if the input does not have a value
// Or that value is not a number
// Then make the input color red
input.style.color = 'red';
}
}
$('total').value = total;
};
There are more things that could be learned from this to make for better code. For instance, this code will break if the number of inputs change, or if their id names change. This is because they are selected specifically by their IDs and as such, if those change then this code will no longer function.
Another potential issue is that we're setting inline styles on the inputs as we loop over them. This means that in order to keep this code up to date with the styling of the site, it'll have to change. Generally, mixing styling and functionality like this is not a good idea and should be avoided. One way of doing so is to use class names instead, and toggle these on and off. Incidentally, this could also help the previous problem I mentioned.
There are other problems as well, but we'll leave those for another day. Hope this helps!
Try this
var calculateBills = function () {
var Amount = 0;
for (i = 1; i <= 4; i++) {
var AmountElement = $('amount' + i),
AmountValue = AmountElement.value;
if (AmountValue != "" && !isNaN(AmountValue)) {
AmountElement.style.color = "red";
Amount += parseInt(AmountValue,10);
} else {
AmountElement.style.color = "";
}
}
$('total').value = Amount;
};
Demo
Anyway, instead of using elements with id like id="amount1", id="amount2", id="amount3", etc., you could use classes (e.g class="amount") and get them with .getElementsByClassName
I've found a lot of discussion about javascript validation functions for forms but can't find anyone running into this particular problem.
In the code below, even though there are 21 values in the array 'fields[]', the for loop ends after 2 iterations. The last alert it pops reads "1 < 21" - it's as though it thinks 2 is not less than 21.
I thought it might be a data type error but can't figure it out. Thanks to anyone who can see it.
var fields = new Array;
var fields = [
document.forms["survey"]["Q1Age"].value,
document.forms["survey"]["Q2Gender"].value,
document.forms["survey"]["Q3Education"].value,
document.forms["survey"]["Q4Field"].value,
document.forms["survey"]["Q6Other"].value,
document.forms["survey"]["Q7Edited"].value,
document.forms["survey"]["UserAccount"].value,
document.forms["survey"]["Whole"].value,
document.forms["survey"]["Sections"].value,
document.forms["survey"]["Images"].value,
document.forms["survey"]["Keywords"].value,
document.forms["survey"]["writing"].value,
document.forms["survey"]["trustworthy"].value,
document.forms["survey"]["accuracy"].value,
document.forms["survey"]["bias"].value,
document.forms["survey"]["info"].value,
document.forms["survey"]["Viz1"].value,
document.forms["survey"]["Viz2"].value,
document.forms["survey"]["VizDescription"].value,
document.forms["survey"]["VizOver"].value,
document.forms["survey"]["submit2"].value
];
var err = 0;
//Start Validation Loop
for(var i = 0; i < fields.length; i++) {
alert(i + " < " + fields.length); //test how many iterations
//Check Fields in Array to Make Sure they are not Empty
if(fields[i].value == "" || fields[i].value == "Select One") {
err++;
}
}
if(err === 0) {
//Submit Form
//document.survey.submit();
return true;
} else {
//If there are errors, return false and alert the user
alert("Please fill out all of the fields.");
return false;
}
}
Since you are getting the input's value when you are creating the array your array elements are already strings, so in your if statement you are trying to get property value from a string, which is probably causing the script to end cause it is trying to access an undefined property
Your if statement should be this.
if(fields[i] == "" || fields[i] == "Select One") {
err++;
}
I am completely new to JavaScript.
I have size and color dropdowns on a page for users to order a product, but only certain combinations are available i.e. pink is the only color in large sizes.
I thought I'd make an array of allowed sizes and test the user input against these.
If the choice is invalid then I want a popup to tell the user why.
In the real world I'll use SQL & PHP to create the array of allowed choices, in the example below I've hard coded 3 valid choices for testing. Unfortunately the code below doesn't do anything.
I'm sure it's a simple newb mistake. I really don't know what I'm doing :)
Can somebody help me out?
The validation function is supposed to happen when user clicks the form submit...
<form id="form1" name="form1" method="post" onsubmit="return validate_form()"
action="cart.php">
Here's the function:
<script type="text/javascript">
function validate_form() {
var allowed = new Array();
allowed[0]="10,beige";
allowed[1]="10,black";
allowed[2]="10,pink";
var chosenColInd = document.getElementById("colID");
var chosenColText = colID.options[colID.selectedIndex].text;
var chosenSizeInd = document.getElementById("sizeID");
var chosenSizeText = sizeID.options[sizeID.selectedIndex].text;
var chosenSizeCol = chosenSizeText+","+chosenColText;
var found = "false";
for ( var i = 0; i < allowed.length; i++ ) {
if (allowed[i]=chosenSizeCol) {
found = "true";
}
}
if (found = "false") {
alert( 'The variation you have selected is currently unavailable. Please select another.' );
return false;
} else {
return true;
}
}
</script>
There are a few lines where you use the assignment operator (that is single equals =) instead of one of the equality operators (that is double or triple equals, triple is usually preferred in JavaScript). Example:
if (found = "false") {
Would appear to be the problem at first sight - it's an assignment not a comparison :) use triple equals === instead of single:
if(found === "false") {
Also, consider the following (commented) updates to your code, which reflects more the typical style of JavaScript code:
function validate_form() {
//no need to use new Array(), use array literal instead
var allowed = [
"10,beige",
"10,black",
"10,pink"
];
var chosenColInd = document.getElementById("colID");
var chosenColText = colID.options[colID.selectedIndex].text;
var chosenSizeInd = document.getElementById("sizeID");
var chosenSizeText = sizeID.options[sizeID.selectedIndex].text;
var chosenSizeCol = chosenColText+","+chosenSizeText;
var found = "false";
for ( var i = 0; i < allowed.length; i++ ) {
//use equality operator instead of assignment
if (allowed[i]===chosenSizeCol) {
found = true; //may as well use a boolean rather than string
break; //exit loop early, no need to continue if we've already found
}
}
if (!found) { //no need to do a comparison with already boolean values
alert( 'The variation you have selected is currently unavailable. Please select another.' );
}
//may as well just return found here now that we're using a boolean
return found;
}
I am trying to write a javascript validation and if statement to represent the following:
Field 1 can be entered and submitted on its own.
Field 2 can be entered but if that is the case then Field 3 must also
be entered and then fields 1, 2 and 3 can be submitted or just Fields
2 and 3 with out Field 1.
Field 3 if it is entered according to the last sentence must also
include Field 2.
Which VAR's do I select all three of them for the one validation?
This is what I have written so far:
function DoCustomValidation()
{
var first = document.forms["readings"] ["GlucoseLevel"].value;
var second = document.forms["readings"] ["SBP"].value;
var third = document.forms["readings"] ["DBP"].value;
if (
I know how to and where to create and put the validation in my .PHP file etc its just I am having a hard time writing the if else statement as its been a while for me with java and I have lost my touch.
Any help much appreciated.
This is about as stripped down as I can make it.
function DoCustomValidation()
{
var first = document.forms["readings"] ["GlucoseLevel"].value;
var second = document.forms["readings"] ["SBP"].value;
var third = document.forms["readings"] ["DBP"].value;
if(!second==!third){
if(!first===false){
return true;
}
else if (!second===false){
return true;
}
}
return false;
}
EDIT: Add Messages
If you want messages on when the form fails to submit, try this
function DoCustomValidation()
{
var first = document.forms["readings"] ["GlucoseLevel"].value;
var second = document.forms["readings"] ["SBP"].value;
var third = document.forms["readings"] ["DBP"].value;
if(!second==!third){
if(!first===false){
return true;
}
else if (!second===false){
return true;
}
else{
alert("You cannot submit a blank form.");
}
}
else{
alert("The SBP and DBP must both be blank or both be filled.");
}
return false;
}
That written, I don't advise using alerts (and that particular text) for your validations messages, but that's the best I can do without more information.
i think this will do the trick the if second and third is to send if both have values even if first doesn't have, then you just have one more chose if first has a value and the other two are empty
function DoCustomValidation()
{
...
if(second !="" && third != ""){
//form submit
return;
}
if(first != "" && second == "" && third == ""){
//form submit
return;
}
}