Problems with form validation

  • Thread starter timothy.pollard
  • Start date
T

timothy.pollard

Hi all

A few weeks ago a nice man called Evertjan helped me create a form
validation system that took a table of four columns of checkboxes and:

- allowed only one checkbox in each row to be checked
- totalised the number of checked boxes in each column

The system works fine until you have more than 10 rows, at which point
the myrow substr(1,1) fails to correctly identify the row number
because it needs to extract two characters instead of one, and the
mycol substr also then doesn't work.

I'm a noob at javascript, so I'd really appreciate any help in adapting
the code (below). It works fine up until row 10, then it goes
pear-shaped.

Thanks in advance for any help.

TP

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"
/>
<title>Untitled Document</title>

</head>

<body>
<table border=0>
<tr><td width="366">


<table>
<tr>
<td><input type=checkbox id=r0c0 onclick='c(this)'> blah
<td><input type=checkbox id=r0c1 onclick='c(this)'> blah
<td><input type=checkbox id=r0c2 onclick='c(this)'> blah
<td><input type=checkbox id=r0c3 onclick='c(this)'> blah
</table>


<tr><td>


<table>
<tr>
<td><input type=checkbox id=r1c0 onclick='c(this)'> blah
<td><input type=checkbox id=r1c1 onclick='c(this)'> blah
<td><input type=checkbox id=r1c2 onclick='c(this)'> blah
<td><input type=checkbox id=r1c3 onclick='c(this)'> blah
</table>


<tr><td>


<table>
<tr>
<td><input type=checkbox id=r2c0 onclick='c(this)'> blah
<td><input type=checkbox id=r2c1 onclick='c(this)'> blah
<td><input type=checkbox id=r2c2 onclick='c(this)'> blah
<td><input type=checkbox id=r2c3 onclick='c(this)'> blah
</table>


<tr><td>


<table>
<tr>
<td><input type=checkbox id=r3c0 onclick='c(this)'> blah
<td><input type=checkbox id=r3c1 onclick='c(this)'> blah
<td><input type=checkbox id=r3c2 onclick='c(this)'> blah
<td><input type=checkbox id=r3c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r4c0 onclick='c(this)'> blah
<td><input type=checkbox id=r4c1 onclick='c(this)'> blah
<td><input type=checkbox id=r4c2 onclick='c(this)'> blah
<td><input type=checkbox id=r4c3 onclick='c(this)'> blah
</table>

<tr><td>
<table>
<tr>
<td><input type=checkbox id=r5c0 onclick='c(this)'> blah
<td><input type=checkbox id=r5c1 onclick='c(this)'> blah
<td><input type=checkbox id=r5c2 onclick='c(this)'> blah
<td><input type=checkbox id=r5c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r6c0 onclick='c(this)'> blah
<td><input type=checkbox id=r6c1 onclick='c(this)'> blah
<td><input type=checkbox id=r6c2 onclick='c(this)'> blah
<td><input type=checkbox id=r6c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r7c0 onclick='c(this)'> blah
<td><input type=checkbox id=r7c1 onclick='c(this)'> blah
<td><input type=checkbox id=r7c2 onclick='c(this)'> blah
<td><input type=checkbox id=r7c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r8c0 onclick='c(this)'> blah
<td><input type=checkbox id=r8c1 onclick='c(this)'> blah
<td><input type=checkbox id=r8c2 onclick='c(this)'> blah
<td><input type=checkbox id=r8c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r9c0 onclick='c(this)'> blah
<td><input type=checkbox id=r9c1 onclick='c(this)'> blah
<td><input type=checkbox id=r9c2 onclick='c(this)'> blah
<td><input type=checkbox id=r9c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r10c0 onclick='c(this)'> blah
<td><input type=checkbox id=r10c1 onclick='c(this)'> blah
<td><input type=checkbox id=r10c2 onclick='c(this)'> blah
<td><input type=checkbox id=r10c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r11c0 onclick='c(this)'> blah
<td><input type=checkbox id=r11c1 onclick='c(this)'> blah
<td><input type=checkbox id=r11c2 onclick='c(this)'> blah
<td><input type=checkbox id=r11c3 onclick='c(this)'> blah
</table>
<tr><td>


<table>
<tr>
<td>total <span id=c0>0</span>
<td>total <span id=c1>0</span>
<td>total <span id=c2>0</span>
<td>total <span id=c3>0</span>
</table>


</table>


<script type='text/javascript'>


function g(x){
return document.getElementById(x)



}


function c(x){

my = x.id
myRow = my.substr(1,1)
myCol = my.substr(3,1)


// only one or less checked this row:
if (x.checked)
for (var c=0;c<4;c++)
if (c!=myCol)
g('r'+myRow+'c'+c).checked=false;


// recomputes the 4 columns:
for (c=0;c<4;c++){
t=0
for (r=0;r<12;r++){
if (g('r'+r+'c'+c).checked)
t++
g('c'+c).innerHTML=t
}
}



}


</script>
</body>
</html>
 
P

Paul

Hi all

A few weeks ago a nice man called Evertjan helped me create a form
validation system that took a table of four columns of checkboxes and:

- allowed only one checkbox in each row to be checked
- totalised the number of checked boxes in each column

The system works fine until you have more than 10 rows, at which point
the myrow substr(1,1) fails to correctly identify the row number
because it needs to extract two characters instead of one, and the
mycol substr also then doesn't work.

I'm a noob at javascript, so I'd really appreciate any help in adapting
the code (below). It works fine up until row 10, then it goes
pear-shaped.

Thanks in advance for any help.

TP

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"
/>
<title>Untitled Document</title>

</head>

<body>
<table border=0>
<tr><td width="366">


<table>
<tr>
<td><input type=checkbox id=r0c0 onclick='c(this)'> blah
<td><input type=checkbox id=r0c1 onclick='c(this)'> blah
<td><input type=checkbox id=r0c2 onclick='c(this)'> blah
<td><input type=checkbox id=r0c3 onclick='c(this)'> blah
</table>


<tr><td>


<table>
<tr>
<td><input type=checkbox id=r1c0 onclick='c(this)'> blah
<td><input type=checkbox id=r1c1 onclick='c(this)'> blah
<td><input type=checkbox id=r1c2 onclick='c(this)'> blah
<td><input type=checkbox id=r1c3 onclick='c(this)'> blah
</table>


<tr><td>


<table>
<tr>
<td><input type=checkbox id=r2c0 onclick='c(this)'> blah
<td><input type=checkbox id=r2c1 onclick='c(this)'> blah
<td><input type=checkbox id=r2c2 onclick='c(this)'> blah
<td><input type=checkbox id=r2c3 onclick='c(this)'> blah
</table>


<tr><td>


<table>
<tr>
<td><input type=checkbox id=r3c0 onclick='c(this)'> blah
<td><input type=checkbox id=r3c1 onclick='c(this)'> blah
<td><input type=checkbox id=r3c2 onclick='c(this)'> blah
<td><input type=checkbox id=r3c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r4c0 onclick='c(this)'> blah
<td><input type=checkbox id=r4c1 onclick='c(this)'> blah
<td><input type=checkbox id=r4c2 onclick='c(this)'> blah
<td><input type=checkbox id=r4c3 onclick='c(this)'> blah
</table>

<tr><td>
<table>
<tr>
<td><input type=checkbox id=r5c0 onclick='c(this)'> blah
<td><input type=checkbox id=r5c1 onclick='c(this)'> blah
<td><input type=checkbox id=r5c2 onclick='c(this)'> blah
<td><input type=checkbox id=r5c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r6c0 onclick='c(this)'> blah
<td><input type=checkbox id=r6c1 onclick='c(this)'> blah
<td><input type=checkbox id=r6c2 onclick='c(this)'> blah
<td><input type=checkbox id=r6c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r7c0 onclick='c(this)'> blah
<td><input type=checkbox id=r7c1 onclick='c(this)'> blah
<td><input type=checkbox id=r7c2 onclick='c(this)'> blah
<td><input type=checkbox id=r7c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r8c0 onclick='c(this)'> blah
<td><input type=checkbox id=r8c1 onclick='c(this)'> blah
<td><input type=checkbox id=r8c2 onclick='c(this)'> blah
<td><input type=checkbox id=r8c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r9c0 onclick='c(this)'> blah
<td><input type=checkbox id=r9c1 onclick='c(this)'> blah
<td><input type=checkbox id=r9c2 onclick='c(this)'> blah
<td><input type=checkbox id=r9c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r10c0 onclick='c(this)'> blah
<td><input type=checkbox id=r10c1 onclick='c(this)'> blah
<td><input type=checkbox id=r10c2 onclick='c(this)'> blah
<td><input type=checkbox id=r10c3 onclick='c(this)'> blah
</table>
<tr><td>
<table>
<tr>
<td><input type=checkbox id=r11c0 onclick='c(this)'> blah
<td><input type=checkbox id=r11c1 onclick='c(this)'> blah
<td><input type=checkbox id=r11c2 onclick='c(this)'> blah
<td><input type=checkbox id=r11c3 onclick='c(this)'> blah
</table>
<tr><td>


<table>
<tr>
<td>total <span id=c0>0</span>
<td>total <span id=c1>0</span>
<td>total <span id=c2>0</span>
<td>total <span id=c3>0</span>
</table>


</table>


<script type='text/javascript'>


function g(x){
return document.getElementById(x)



}


function c(x){

my = x.id
myRow = my.substr(1,1)
myCol = my.substr(3,1)


// only one or less checked this row:
if (x.checked)
for (var c=0;c<4;c++)
if (c!=myCol)
g('r'+myRow+'c'+c).checked=false;


// recomputes the 4 columns:
for (c=0;c<4;c++){
t=0
for (r=0;r<12;r++){
if (g('r'+r+'c'+c).checked)
t++
g('c'+c).innerHTML=t
}
}



}


</script>
</body>
</html>

I'm going to offer two answers to this.
The short (wrong though it works) answer could be to replace:
myRow = my.substr(1,1)
myCol = my.substr(3,1)
with the following:
var colRowRE = new RegExp("r(\\d+)c(\\d+)");
colRowRE.exec(my);
var myRow = RegExp.$1;
var myCol = RegExp.$2;

The longer better answer is to change what you are doing.
Whether or not to use xhtml is a subject for debate. However, if don't
mark your code as xhtml if its not compliant.
Making it correct would be a good starting point then, making it
somewhat sematic and ditching the nested tables would be a good start
down the right path.
I'm going to offer up the following as an alternative starting point.
Maybe a more experienced javascript guru will post some code as an
improvement to this.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"
/>

<title>Untitled Document</title>

<style type="text/css">
table{
border: 0px;
width: 266px;
}
tr {
border: 0px;
}
td {
border: 0px;
}
label {
margin: 0px;
padding: 0px;
}
</style>

<script type="text/javascript">
// <![CDATA[
function ensureRowUniq(){
var parentRow = findParentTag(this,"tr");
var boxes = parentRow.getElementsByTagName("input");
for(var i=0;i<boxes.length;i++){
var currentCB = boxes;
if(currentCB != this){
currentCB.checked=false;
}
}
updateTally();
}

function updateTally(){
var myTable = bindEvents2Table.table;
var tallyNodes =
myTable.getElementsByTagName("tfoot")[0].getElementsByTagName("span");
var colCount = tallyNodes.length;
var counts = new Array(colCount);
for(var i=0; i<counts.length;i++){
counts = 0;
}
var rows =
myTable.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
for(var i=0;i<rows.length;i++){
var currentTr = rows;
var boxes = currentTr.getElementsByTagName("input");
for(var j=0; j<boxes.length;j++){
if(boxes[j].checked){
counts[j]+=1;
}
}
}
var ret = "";
for(var i=0; i<tallyNodes.length;i++){
var curNode = tallyNodes;
var countNode = document.createTextNode(counts);
curNode.replaceChild(countNode,curNode.childNodes[0]);
}
}

function findParentTag(elem,tagName){
var parent = elem.parentNode;
if(parent && parent.tagName.toLowerCase()!=tagName.toLowerCase()){
parent = findParentTag(parent,tagName);
}
return parent;
}

function bindEvents2Table(){
var myTable = document.getElementById("tblUniqRows");
arguments.callee.table = myTable;
var boxes = myTable.getElementsByTagName("input");
for(var i=0; i<boxes.length;i++){
boxes.onclick=ensureRowUniq;
}
}

window.onload=bindEvents2Table;
// ]]>
</script>

</head>

<body>
<form action="#">
<table id="tblUniqRows">
<tfoot>
<tr>
<td>Total: <span>0</span></td>
<td>Total: <span>0</span></td>
<td>Total: <span>0</span></td>
<td>Total: <span>0</span></td>
</tr>
</tfoot>
<tbody>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
<tr>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
<td><label><input type="checkbox" /> blah</label></td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
 
T

timothy.pollard

Paul

Many thanks for your help - I've tried the 'wrong' fix and it works
fine, as you say. I'm intrigued to know why you call it wrong, though?

The spurious code was added in by Dreamweaver when I did some changes
that way.

I'll have a go at the alternative version later, when I've got some
more time.

Many thanks again for your help.

TP
 
P

Paul

Paul

Many thanks for your help - I've tried the 'wrong' fix and it works
fine, as you say. I'm intrigued to know why you call it wrong, though?
I think, using a naming convention to establish the relationship
between elements is asking for trouble. Especially when html gives you
the means to establish the semantic of columns and rows.
 
D

Dr John Stockton

JRS: In article <[email protected]>,
dated Tue, 1 Aug 2006 07:56:05 remote, seen in
A few weeks ago a nice man called Evertjan helped me create a form
validation system that took a table of four columns of checkboxes and:

- allowed only one checkbox in each row to be checked
- totalised the number of checked boxes in each column

The system works fine until you have more than 10 rows, at which point
the myrow substr(1,1) fails to correctly identify the row number
because it needs to extract two characters instead of one, and the
mycol substr also then doesn't work.

simple change : Instead of "naming" them from 0 upwards, start at 10.
You'll then have 90 rows before needing more characters. If that's not
enough, start at 100 ... . Change the substr parameters accordingly, of
course.


If your page requires javascript in order to function, consider using
javascript to write the rather repetitive form structure, using loops.

Read the newsgroup FAQ.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top