Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 15 of 15
  1. #1
    New Coder
    Join Date
    Mar 2003
    Location
    San Francisco
    Posts
    83
    Thanks
    0
    Thanked 0 Times in 0 Posts

    iterating through form elements... a newer way?

    Is this still the cool/kosher/best way to iterate through form elements?

    (for example, below... checking all checkboxes in a form)

    for ( i = 0; i < document.myForm.elements.length; i++ )
    if (document.myForm.elements[i].type == 'checkbox' )
    document.myForm.elements[i].checked = true;

    Just wondering if there's some new technique I'm not aware of...

  • #2
    Regular Coder
    Join Date
    Nov 2002
    Posts
    596
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I like a while loop:

    var el, i = 0, oForm = document.myForm;
    while (el = oForm.elements[i++]) if (el.type == 'checkbox') el.checked = true;

    Easier if you simply pass the Form object: <form......onsubmit="whatever(this)">

  • #3
    Master Coder
    Join Date
    Feb 2003
    Location
    Umeå, Sweden
    Posts
    5,575
    Thanks
    0
    Thanked 83 Times in 74 Posts
    Haven't tested this, but I think you can do it through for...in:
    Code:
    var e=oForm.elements,i;
    for(i in e)
        if(e[i].type=='checkbox')
            e[i]=true;
    liorean <[lio@wg]>
    Articles: RegEx evolt wsabstract , Named Arguments
    Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
    Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards

  • #4
    Senior Coder
    Join Date
    Aug 2002
    Posts
    3,467
    Thanks
    0
    Thanked 0 Times in 0 Posts
    While loops are good and the faster between the two, but if you prefer for loops, this is your best bet
    Code:
    var e = document.myform.elements;
    for ( var elem, i = 0; ( elem = e[i] ); i++ )
    {
        if ( elem.type == 'checkbox' )
            elem.checked = true;
    }
    Really alot like a while loop in a for loop's clothing
    My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
    “Minds are like parachutes. They don't work unless they are open”
    “Maturity is simply knowing when to not be immature”

  • #5
    Master Coder
    Join Date
    Feb 2003
    Location
    Umeå, Sweden
    Posts
    5,575
    Thanks
    0
    Thanked 83 Times in 74 Posts
    You must make a distinction here - a for loop is as little connected to a for...in loop as a while loop is. for is overloaded, and for...in is really another kind of beast. In fact, the for and while loops are both closer to eachother than to the for...in loop.

    Evidently from actually testing that, you only get the enumerable members (length, item and namedItem) instead of the names of the children to iterate over, though. Thus, my nice little idea fell.
    liorean <[lio@wg]>
    Articles: RegEx evolt wsabstract , Named Arguments
    Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
    Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards

  • #6
    Regular Coder
    Join Date
    Nov 2002
    Posts
    596
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Form element objects are stored in the ordered 'portion' of the Form.elements[] array, not the hashtable portion. Why would you even want to iterate through dozens of properties looking for pointer data (names) referencing the objects, when you know where they are, and that every one has a .type property to be read? Not sure what loop structure has to do with this..

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <title>untitled</title>
    <script type="text/javascript" language="javascript">

    function iterator1(oForm) {
    var x = open('','','width=300,left=200,top=50,scrollbars,status=0');
    x.document.open('text/plain');
    var e = oForm.elements;
    for(var i in e) x.document.write(i + ' : ' + e[i] + '\n');
    x.document.close();
    }

    function iterator2(oForm) {
    var el, i = 0;
    while (el = oForm.elements[i++]) if (el.type == 'checkbox') el.checked = true;
    }

    </script>
    </head>
    <body>
    <form>
    <input name="box1" type="checkbox"><br />
    <input name="box2" type="checkbox"><br />
    <input name="box3" type="checkbox"><br />
    <input name="box4" type="checkbox"><br />
    <input name="box5" type="checkbox"><br /><br />
    <input type="button" value="check 1" onclick="iterator1(this.form)">
    <input type="button" value="check 2" onclick="iterator2(this.form)">
    </form>
    </body>
    </html>
    Last edited by cheesebagpipe; 04-01-2003 at 12:51 AM.

  • #7
    New Coder
    Join Date
    Mar 2003
    Location
    San Francisco
    Posts
    83
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I tried three tests (see code below), iterating through the form.elements array.

    In the first loop, output is over 100 attributes of the element (language, scrollHeight, isTextEdit, etc.), including, at the very end, the values 0, 1, 2 (indices into the elements[] array).

    In the second loop, I test only for these three indices, then print the "type" attribute, which is "text" for each of my three form elements (you can also print out "value" to show that it's definitely the form elements we're accessing here).

    In the third loop, I assumed (from the previous loop) that I could test for blah.type == 'text', but, for some reason, it doesn't work. Curious.

    Anyway, because of the sheer volume (around 135) of attributes that you'd have to cycle through to get to the data you want, looks like it's best to avoid for..in to cycle through form.elements[].

    For..in works great for a "regular" array, though, like [ 'one', 'two', 'three' ].

    Thanks for all the comments.

    ---

    <form name="_form">
    &nbsp;&nbsp;&nbsp;&nbsp;<input type=text value='one'>
    &nbsp;&nbsp;&nbsp;&nbsp;<input type=text value='two'>
    &nbsp;&nbsp;&nbsp;&nbsp;<input type=text value='three'>
    </form>
    <script>
    &nbsp;&nbsp;&nbsp;&nbsp;_a = document._form.elements;
    &nbsp;&nbsp;&nbsp;&nbsp;for ( _i in _a )
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.write( _i, ': ', _a[ _i ], '<br>' );
    &nbsp;&nbsp;&nbsp;&nbsp;document.write( '<p>' );

    &nbsp;&nbsp;&nbsp;&nbsp;for ( _i in _a )
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( _i == '0' || _i == '1' || _i == '2' )
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.write( _i, ': ', _a[ _i ].type, ': ', _a[ _i ], '<br>' );
    &nbsp;&nbsp;&nbsp;&nbsp;document.write( '<p>' );

    &nbsp;&nbsp;&nbsp;&nbsp;for ( _i in _a )
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( _a[ _i ].type == 'text' )
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.write( _i, ': ', _a[ _i ], '<br>' );
    </script>

  • #8
    Senior Coder
    Join Date
    Aug 2002
    Posts
    3,467
    Thanks
    0
    Thanked 0 Times in 0 Posts
    You should really only use for...in for objects, becuase that's the ONLY way to seqeuntially loop through the properties. Of course, any prototyped properties or methods will be caught by a for...in loop.

    Regular arrays are based on indexes, a looping implementation that includes an index incrementation only makes sense.

    Oh, and not ALL form elements have a type (SELECTs, TEXTAREAs)

    if ( elem.nodeName == 'INPUT' && elem.type == 'checkbox' )

    would be more appropriate
    Last edited by beetle; 04-01-2003 at 01:08 AM.
    My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
    “Minds are like parachutes. They don't work unless they are open”
    “Maturity is simply knowing when to not be immature”

  • #9
    New Coder
    Join Date
    Mar 2003
    Location
    San Francisco
    Posts
    83
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Re: beetle's previous comments... is there some performance (or other) reason why I shouldn't do this?
    Code:
    <script>
        var _a = [ 1, 2, 3 ];
        for ( var _i in _a )
            document.write( _a[ _i ] );
    </script>
    Code looks nice. No need for an explicit counter. Any downside? (I guess it's slower because it's using strings...)
    Last edited by bryndyment; 04-01-2003 at 01:36 AM.

  • #10
    Regular Coder
    Join Date
    Nov 2002
    Posts
    596
    Thanks
    0
    Thanked 0 Times in 0 Posts

  • #11
    Senior Coder
    Join Date
    Aug 2002
    Posts
    3,467
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Well, "PTHBHHBHBHBBBHBBHBBHBHB"

    Hehe, thanks cheesebagpipe, I didn't realize that.

    I swear, some days I open my mouth just to change feet.
    My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
    “Minds are like parachutes. They don't work unless they are open”
    “Maturity is simply knowing when to not be immature”

  • #12
    Master Coder
    Join Date
    Feb 2003
    Location
    Umeå, Sweden
    Posts
    5,575
    Thanks
    0
    Thanked 83 Times in 74 Posts
    Nice little problem this has turned in to:

    for...in works perfectly over arrays, as it gets all enumerable properties and only keyed members are enumerable (of which indiced members are a subset). I'll soon have benchmarks for comparison to while, for, do...while. (There are no keyed members in an array unless you explicitly add them, but if you do they will be iterated over. This includes enumerable prototype properties.)

    for...in also works perfectly over objects, but here there's no alternative. You get all the enumerable properties, which means all the keyed properties.


    for...in doesn't work very well over collections, however. Collections have a few keyed properties, and they have a few indiced, but the indices aren't really keys (the object is overloaded as a getter for object.item(), in fact, and is not an array) and thus aren't in the iteration. All this because XML objects have three types of members while JSObjects only have one.
    Last edited by liorean; 04-01-2003 at 02:19 AM.
    liorean <[lio@wg]>
    Articles: RegEx evolt wsabstract , Named Arguments
    Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
    Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards

  • #13
    New Coder
    Join Date
    Mar 2003
    Location
    San Francisco
    Posts
    83
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Nice summary... looking forward to the benchmarks.

  • #14
    Senior Coder
    Join Date
    Aug 2002
    Posts
    3,467
    Thanks
    0
    Thanked 0 Times in 0 Posts
    You can use my StopWatch class if you're gonna do timed tests
    My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
    “Minds are like parachutes. They don't work unless they are open”
    “Maturity is simply knowing when to not be immature”

  • #15
    Master Coder
    Join Date
    Feb 2003
    Location
    Umeå, Sweden
    Posts
    5,575
    Thanks
    0
    Thanked 83 Times in 74 Posts
    Quick benchmark

    Interesting facts:
    Code:
        ie     op7     moz     moz(strict)
    0   110    431     110     110
    1   120    431     110     13029
    2   160    380     110     12678
    3   141    341     100     100
    4   180    2123    1192    1272
    0. l=arr.length;for(i=0;l>i;i++)r+=arr[i];
    1. for(i=0;(e=arr[i]);i++)r+=e;
    2. i=0;while((e=arr[i++]))r+=e;
    3. i=arr.length;do r+=arr[--i];while(i);
    4. for(i in arr)r+=arr[i];


    Moz with strict warnings is seriously harmed by assignment of undefined, because both of the UI interaction that follows, and the hooks to the debugger.
    Last edited by liorean; 04-01-2003 at 04:38 AM.
    liorean <[lio@wg]>
    Articles: RegEx evolt wsabstract , Named Arguments
    Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
    Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •