Problems with form validation

Discussion in 'Javascript' started by timothy.pollard@btinternet.com, Aug 1, 2006.

  1. Guest

    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>
    , Aug 1, 2006
    #1
    1. Advertising

  2. Paul Guest

    wrote:
    > 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>
    Paul, Aug 1, 2006
    #2
    1. Advertising

  3. Guest

    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
    , Aug 2, 2006
    #3
  4. Paul Guest

    wrote:
    > 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.
    >
    > 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.

    no problem
    >
    > TP
    Paul, Aug 2, 2006
    #4
  5. JRS: In article <>,
    dated Tue, 1 Aug 2006 07:56:05 remote, seen in
    news:comp.lang.javascript, posted :
    >
    >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.
    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
    <URL:http://www.jibbering.com/faq/>? JL/RC: FAQ of news:comp.lang.javascript
    <URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
    <URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
    Dr John Stockton, Aug 2, 2006
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Colin Basterfield

    Web form validation vs object validation

    Colin Basterfield, Nov 28, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    420
    Tommy
    Nov 29, 2003
  2. Sumith Mathur
    Replies:
    0
    Views:
    2,186
    Sumith Mathur
    Sep 23, 2004
  3. OriginalBrownster

    string validation/ form validation

    OriginalBrownster, Aug 21, 2006, in forum: Python
    Replies:
    1
    Views:
    411
    Simon Forman
    Aug 21, 2006
  4. Grigory Temchenko
    Replies:
    0
    Views:
    314
    Grigory Temchenko
    Dec 28, 2008
  5. bnp
    Replies:
    4
    Views:
    289
Loading...

Share This Page