dynamic form validation / multiple forms

J

jedimasta

Good evening all,

I'm a relatively new to javascript, but I've been working with
ColdFusion and PHP for years so I'm not necessarily ignorant, just
stuck and frustrated. Using ColdFusion I'm using an include to pull in
form elements (text fields, checkboxes, etc...) multiple times on a
single page.

The included page does not have a form tag of it's own, but the root
page has uniquely named forms for validation. Imagine it like this:

<form name="form1">
<cfinclude tempalte="formtemplate">
</form>

<form name="form2">
<cfinclude tempalte="formtemplate">
</form>

I've got a simple check-one-box-and-check-em-all script INSIDE the
included template. I want to reference very specifically the form name,
and only check the boxes inside that form, not the others.
Unfortunately, I'm not syntax savvy and my attempts to use:

<form name="form1">
<input type="checkbox" id="chkAllNorth"
onClick="chkAll('chkAllNorth','northChk',this.form)">
</form>

does nothing. I can remove the this.form from the function entirely,
but it checks ALL the specified boxes with that ID in ALL the forms on
the page. Any help is appreciated. Here is the script:

function chkAll(thisBox,group,thisForm){
var inputs = document.thisForm.getElementsByTagName("input");

if(document.thisForm.getElementById(thisBox).checked == true){
for (i=0;i<inputs.length;i++){
if(inputs.id == group){
inputs.checked = 1;
}
}
}else{
for (i=0;i<inputs.length;i++){
if(inputs.id == group){
inputs.checked = 0;
}
}
}
return true;
}
 
R

Richard Cornford

Good evening all,

I'm a relatively new to javascript, but I've been working with
ColdFusion and PHP for years so I'm not necessarily ignorant, just
stuck and frustrated. Using ColdFusion I'm using an include to pull in
form elements (text fields, checkboxes, etc...) multiple times on a
single page.

The included page does not have a form tag of it's own, but the root
page has uniquely named forms for validation. Imagine it like this:

<form name="form1">
<cfinclude tempalte="formtemplate">
</form>

<form name="form2">
<cfinclude tempalte="formtemplate">
</form>

I've got a simple check-one-box-and-check-em-all script INSIDE the
included template. I want to reference very specifically the form
name, and only check the boxes inside that form, not the others.
Unfortunately, I'm not syntax savvy and my attempts to use:

<form name="form1">
<input type="checkbox" id="chkAllNorth"
onClick="chkAll('chkAllNorth','northChk',this.form)">
</form>

Is this a representation of ColdFusion code or mark-up that gets sent to
the browser, and if the latter where are the INPUT element's NAME and
VALUE attributes? Without a NAME and a VALUE the value of the checkbox
will not be sent back to the server, so how can you know it value for
server-side (re)validation?
does nothing.

Nothing at all, or have you just failed to observe the (any) error
messages produced by the browser?
I can remove the this.form from the function entirely,

That sounds like precisely the last thing you want to do as -
this.form - is (in the context of intrinsic event attribute code) the
one reliable method of getting a reference to the form that contains the
INPUT element (so excluding the other form).
but it checks ALL the specified boxes with that ID in ALL
the forms on the page.

Not the code here.
Any help is appreciated. Here is the script:

function chkAll(thisBox,group,thisForm){

If the even handler above is fired the - thisForm - parameter will be a
reference to the FORM element.
var inputs = document.thisForm.getElementsByTagName("input");
^^^^^^^^
In this context the - thisForm - Identifier refers to a property of the
document with the name 'thisForm', and is completely unrelated to the -
thisForm - parameter (look up "javascript bracket notation" on google).
The symptoms you describe could only be attributed to there being an
object on the generated page that has an ID or NAME of 'thisForm', such
that the browser is creating a reference to that element as a named
property of the document, that is a container of both of the FORM
elements on the page. Otherwise this code should error-out at this line
an none of the checkboxes should be checked.

inputs.checked = 1;

inputs.checked = 0;

<snip>

The checked property of INPUT elements is of boolean type so setting the
values to 1 or 0 will just necessitate type-conversion. You may as well
set them to true or false directly.

Generally, when debugging client-side javascript it is a good idea to
look at (and post in preference to server side code) the mark-up and
code actually sent to the browser, as that is where the errors are most
easily identified. And the javascript console or error dialogs provided
by the browser would usually be expected to show pertinent error
messages (and diagnosis requires knowledge of all actually error
messages, or a positive confirmation that there are none).

Richard.
 
J

jedimasta

This is raw code, as it exists in my cfm, not rendered by firefox/ie.

Originally, I wrote the validation script for a single form....named
"form", so there wasn't an additional variable in the function. so
"document.thisForm" was simply "document.form" and it worked perfectly
with no java/browser errors whatsoever. As I originally stated "does
nothing" I should've said that an error is generated: "thisForm has no
properties". This is likely due to the bracket notation you mentioned.
Bracket notation typically escapes me, as I said, I'm relatively new to
JS, so thanks for that.

The input elements do indeed have names and ID's so please don't
misunderstand. In the interest of not providing gobs upon gobs of code,
I chose to explain that the include statements had properly syntaxed
form input elements, primarily checkboxes.

Should I then take to your meaning that the function should read
thusly?:

function chkAll(thisBox,group,thisForm){
var inputs = document[thisForm].getElementsByTagName("input");

if(document[thisForm].getElementById(thisBox).checked == true){
for (i=0;i<inputs.length;i++){
if(inputs.id == group){
inputs.checked = 1;
}
}
}else{

for (i=0;i<inputs.length;i++){
if(inputs.id == group){
inputs.checked = 0;
}
}
}
return true;


And the checkbox trigger should be?:
<form name="form1">
<input type="checkbox" id="chkAllNorth"
onClick="chkAll('chkAllNorth','northChk',this.form)">
<all the other boxes here id="northChk">
</form>

Will that succesfully pass the form name (in this case form1) to the
function and check all the boxes with the id 'northChk' in only the
form 'form1'? I apologize that I cannot try it for myself at the moment
because I am out of the office and do not have the pages available to
me until the morning.
 
R

Randy Webb

(e-mail address removed) said the following on 8/10/2006 9:03 PM:
This is raw code, as it exists in my cfm, not rendered by firefox/ie.

Originally, I wrote the validation script for a single form....named
"form", so there wasn't an additional variable in the function. so
"document.thisForm" was simply "document.form" and it worked perfectly
with no java/browser errors whatsoever. As I originally stated "does
nothing" I should've said that an error is generated: "thisForm has no
properties". This is likely due to the bracket notation you mentioned.
Bracket notation typically escapes me, as I said, I'm relatively new to
JS, so thanks for that.

The input elements do indeed have names and ID's so please don't
misunderstand. In the interest of not providing gobs upon gobs of code,
I chose to explain that the include statements had properly syntaxed
form input elements, primarily checkboxes.

Should I then take to your meaning that the function should read
thusly?:

function chkAll(thisBox,group,thisForm){
var inputs = document[thisForm].getElementsByTagName("input");

if(document[thisForm].getElementById(thisBox).checked == true){
for (i=0;i<inputs.length;i++){
if(inputs.id == group){
inputs.checked = 1;
}
}
}else{

for (i=0;i<inputs.length;i++){
if(inputs.id == group){
inputs.checked = 0;
}
}
}
return true;


And the checkbox trigger should be?:
<form name="form1">
<input type="checkbox" id="chkAllNorth"
onClick="chkAll('chkAllNorth','northChk',this.form)">
<all the other boxes here id="northChk">
</form>

Will that succesfully pass the form name (in this case form1) to the
function and check all the boxes with the id 'northChk' in only the
form 'form1'? I apologize that I cannot try it for myself at the moment
because I am out of the office and do not have the pages available to
me until the morning.


ID's must be unique in the page so any behavior you get with multiple
ID's is guess work.

function chkAllNorth(formName,elementNameToCheck){
//Now, simply loop through formName checking element
//type and name, if it is elementNameToCheck, then
//you set it to checked. Since you don't have time
//to be bothered to check code, I won't waste time
//writing the code for you.
}
 
R

Richard Cornford

This is raw code, as it exists in my cfm, not rendered by
firefox/ie.

Which means that it is not the code that is producing the errors. The
code that the browser actually gets is the only code that is interesting
for diagnosing the problems that produce errors on the browser.
Originally, I wrote the validation script for a single
form....named "form",

The name "form" is not particularly good, partly because form controls
already have a property named 'form', and partly because it says nothing
about what the form is for.
so there wasn't an additional variable
in the function. so "document.thisForm" was simply
"document.form" and it worked perfectly with no java/browser
errors whatsoever. As I originally stated "does nothing"
I should've said that an error is generated: "thisForm has no
properties".

That is not what the error actually said. it said - document.thisForm
has no properties (or something similar). The _precise_ error message
may not mean much to you yet but you will eventually see that they have
a very close relationship with what is going wrong on the browser.
This is likely due to the bracket notation you mentioned.

Not due to, but avoidable with.

The input elements do indeed have names and ID's so
please don't misunderstand.

I understood what I read. If that was a misunderstanding then I was
reading the wrong material (and only you have the power to influence
that).
In the interest of not providing gobs upon gobs of
code, I chose to explain that the include statements
had properly syntaxed form input elements, primarily
checkboxes.

So you were saying 'I have some code I would like help debugging, and
here is some other code that may be similar in some respects'.
Should I then take to your meaning that the function
should read thusly?:

function chkAll(thisBox,group,thisForm){
var inputs = document[thisForm].getElementsByTagName("input");

Not if you pass - this.form - as the third argument. The - form -
property of form controls is a reference to the form element, and any
property of the document being referenced by the form's name attribute
is also a reference to the form element, so the - document[ someName ] -
part is redundant as soon as you are passing the reference to the form
into the function from the event handler. If you passed -
this.form.name - into the fucntion then what you would get is the name
of the form element (if it has one) but then using that name to look-up
the reference is a bit silly as the reference was where the name was
look up prior to passing it.
if(document[thisForm].getElementById(thisBox).checked == true)

Comparing the boolean - checked - property with boolean true to give a
boolean result for the - if - expression is redundant as the comparison
will always produce the dame result as the - checked - property already
has.

Even if the - document[thisForm] - was being resolved into a reference
to FORM element, FORM elements do not have a - getElementById - method
(only documents do), and the document level method will not work
properly unless the element ID is unique.
{ for (i=0;i<inputs.length;i++){

The variable - i - is not declared in this function, that makes it
global. It does not need to be global and so should be subject to the
axiom; no variable should be given any more scope than it absolutely
needs. It should be a function local variable (as that is the most local
scope available), so declared within the function. Habitually using
global variables a loop counters is particularly problematic as it
becomes easy for a function to be called in the body of one loop that
itself uses a global loop counter with the same name. Unexpected
consequences include infinite loops and loops that end sooner than
expected.
if(inputs.id == group){
inputs.checked = 1;

<snip>

You decided to ignore my advice to assign true/false instead of 1/0?
Will that succesfully pass the form name (in this case form1)
No.

to the function and check all the boxes with the id 'northChk'
in only the form 'form1'?

IDs should be unique within an HTML document. You should fix that design
misconception before you do anything else.

Given the mark-up code you (appear to) have, passing the reference to
the form as:- onClick="chkAll('chkAllNorth','northChk',this.form);" -
the fucntion:-

function chkAll(thisBox, group, theForm){
var i, inputs = theForm.getElementsByTagName("INPUT");
var checkIt = thisForm.elements[thisBox].checked;
for (i=0;i<inputs.length;i++){
if(inputs.id == group){
inputs.checked = checkIt;
}
}
return true;
}

- should do the job of the original.
I apologize that I cannot try it for myself at the
moment because I am out of the office and do not have the pages
available to me until the morning.

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top