TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 04-22-2009, 05:47 PM   #1 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default count checkbox, radio and input....

Ok so I gave myself a simple project...I have 6 input types.
3 are of type radio, and the other 3 are checkboxes.

JS:
Code:
<script type="text/javascript">
var getCheck = document.getElementsByName('checkbox');
var getRadio = document.getElementsByName('radio');
var getInput = document.getElementsByTagName('input');
	
  
document.write('There are: ' +getCheck.length+ ' checkboxes');
document.write('There are: ' +getRadio.length+ ' radio buttons');
document.write('There are a total of: ' +getInput.length+ ' input types');
	
</script>
HTML:
Code:
<body>
<div><input type="checkbox" name="checkbox" value="checkbox" /></div>
<div><input type="checkbox" name="checkbox" value="checkbox" /></div>
<div><input type="checkbox" name="checkbox" value="checkbox" /></div>
<div><input type="radio" name="radio" /></div>
<div><input type="radio" name="radio" /></div>
<div><input type="radio" name="radio" /></div>
</body>
My output is:

There are: 0 checkboxes
There are: 0 radio buttons
There are a total of: 0 input types

I thought that the "getElementsByName and getElementsByTagName" were arrays? So I thought I could just use the ".length" to get the count?

So anyways, the output is suppose to say:

There are 3 checkboxes.
There are 3 radio buttons.
There are a total of: 6 input types.
allworknoplay is offline  
Reply With Quote
Old 04-22-2009, 05:59 PM   #2 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

You have to wait for those DOM elements to have been loaded before you can access them with JavaScript. Either hook into the body's onload event (or DOMReady if you're feeling adventurous) or place the script below the inputs in your HTML.
Salathe is offline  
Reply With Quote
Old 04-22-2009, 06:29 PM   #3 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
Kalle is on a distinguished road
Default

Like said by Salathe, you need to execute when your dom tree is fully loaded (this is called "domready"). Most frameworks includes support for the domready event, so you can bind a new domready even and execute your code then.

The fact that this does not work is because the browser does not have a 2 stage parsing/execution stage like PHP (4 and newer) does. Meaning that once this part is parsed, the browser will execute it, so when it executes your javascript code it havn't got to the HTML elements yet, making them render as 0 :)
__________________
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 04-22-2009, 06:36 PM   #4 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Thanks guys,

When I moved the JS code below the HTML, I got the output I was looking for. However, it doesn't seem "clean" to do that.

So I will look into how I can hook into the body "onLoad" event.
This way I can keep the majority of the JS code on the top part of the page...

As for Domready, the last 10 mins was the first time I ever even heard of that!!!
allworknoplay is offline  
Reply With Quote
Old 04-22-2009, 07:01 PM   #5 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
Kalle is on a distinguished road
Default

Don't use onload, its the same as running it in <head>, domready or on the bottom of your HTML, just before </body> to emulate a domready event.

;)
__________________
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 04-22-2009, 07:20 PM   #6 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Ok, well I didn't use onLoad, because I don't really know how to use it just yet...

But here's what I have, it DOESNT work, but it's what I have in mind. I am using "onLoad" in the INPUT tags *ONLY* as a placeholder because I don't know how to call the function within the INPUT tags.

JS:
Code:
<script type="text/javascript">
	var countCheck = 0;
	var countRadio = 0;
	var countInput = 0;
	var getCheck = document.getElementsByName('checkbox');
	var getRadio = document.getElementsByName('radio');
	var getInput = document.getElementsByTagName('input');
	
	function countMe(type){
	
		if(type == document.getElementsByName('checkbox')) countCheck += 1;
		if(type == document.getElementsByName('radio')) countRadio += 1;
		
	
	}
	
  
      countInput = (countCheck + countRadio);

  	document.write('There are: ' +countCheck+ ' checkboxes <br />');
	document.write('There are: ' +countRadio+ ' radio buttons <br />');
	document.write('There are a total of: ' +countInput+ ' input types <br />');
	
</script>
HTML:
Code:
<body>
<div><input type="checkbox" name="checkbox" value="checkbox" onLoad="countMe(this)" /></div>
<div><input type="checkbox" name="checkbox" value="checkbox" onLoad="countMe(this)" /></div>
<div><input type="checkbox" name="checkbox" value="checkbox" onLoad="countMe(this)" /></div>
<div><input type="radio" name="radio" onLoad="countMe(this)" /></div>
<div><input type="radio" name="radio" onLoad="countMe(this)" /></div>
<div><input type="radio" name="radio" onLoad="countMe(this)" /></div>
</body>
So now I will explain my intentions.

As each element loads, it calls the "countMe" function.
I use the "this" to dynamically tell the function what type of element it is.

The function then just takes a look at what element it is, and adds "1" to the correct counter.

Is what I'm doing possible? How do you call a function within the INPUT tags? Everything I've looked up, it's always based on some kind of event like onClick, onFocus etc...
Is there any "passive" way to call a function without user input?
allworknoplay is offline  
Reply With Quote
Old 04-22-2009, 08:00 PM   #7 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
Kalle is on a distinguished road
Default

What you are doing is possible yes, but! Theres no such event called onload on input tags, also you can't determine the type of the current object by comparing it like you do so in "CountMe", so you need to check if the "type" property is what you expect.

javascript Code:
switch(el.type)
{
    case('...'):
    {
        /* ... */
    }
    break;
    /* ... */
}

You may also use the increment operators (both postfix and prefix in javascript):
javascript Code:
var $variable;

++$variable;
$variable++;

--$variable;
$variable--;

/* $variable = 0 */

As for what you are trying to do, then I think something along these lines should be correct:
javascript Code:
function CategorizeInputFields()
{
    var retval =
    {
        'checkbox'0,
        'radio':    0,
        'password'0,
        'file':  0,
        'button':   0,
        'hidden':   0,
        'image':    0,
        'reset':    0,
        'submit':   0,
        'text':  0,
 
        'total':    0
    };

    /* Browser does not support getElementsByTagName, return void */
    if(!document.getElementsByTagName)
    {
        return(retval);
    }

    var elements = document.getElementsByTagName('input');
    retval.total = elements.length;

    /* No input tags in tree */
    if(!retval.total)
    {
        return(retval);
    }

    for(var n = 0; n < retval.total; ++n)
    {
        /* I'm really lazy so I'll use eval here, don't do like this! */
        eval('++retval.' + elements[n].type.toLowerCase() + ';');
    }

    return(retval);
}

function Render()
{
    var elements = CategorizeInputFields();

    document.write('There are: ' + elements.checkbox + ' checkboxes <br />');
    document.write('There are: ' + elements.radio + ' radio buttons <br />');
    document.write('There are a total of: ' + elements.total + ' input types <br />');
}

And in your HTML:
HTML Code:
<body>
<!-- input elements -->

<script type="text/javascript">
<!--
Render();
// -->
</script>
</body>
__________________
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 04-22-2009, 08:27 PM   #8 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

Quote:
Originally Posted by Kalle View Post
javascript Code:
/* I'm really lazy so I'll use eval here, don't do like this! */
eval('++retval.' + elements[n].type.toLowerCase() + ';');
javascript Code:
/* Don't be lazy! */
++retval[elements[n].type.toLowerCase()];
Salathe is offline  
Reply With Quote
The Following User Says Thank You to Salathe For This Useful Post:
Kalle (04-22-2009)
Old 04-22-2009, 09:17 PM   #9 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Quote:
Originally Posted by Salathe View Post
javascript Code:
/* Don't be lazy! */
++retval[elements[n].type.toLowerCase()];
haha, you guys crack me up...


Ok, so it works now, I see where you went with the code. Although the "output" is written up on top, by using the Render() function after the elements have already loaded, you can now output the correct number of elements instead of diplaying 0.
gotchya...I have some questions about the CategorizeInputFields function, so I'll break it down here....


I am unsure of what is going on here. You create a variable called "retval" which I assume is short for "Retrieve Values".
Is this an array or are we creating an object?

Code:
var retval = 
    {
        'checkbox': 0, 
        'radio':    0, 
        'total':    0
    };


Are we passing "document.getElementsByTagName" to this conditional and if it doesn't exist we return nothing??

Code:
/* Browser does not support getElementsByTagName, return void */
    if(!document.getElementsByTagName)
    {
        return(retval);
    }

Here we get all the of the input tags, then count them and assign the count to retval.total
Code:
var elements = document.getElementsByTagName('input');
retval.total = elements.length;
return void, if no total from document.getElementsByTagName('input') return nothing?
Code:
/* No input tags in tree */
    if(!retval.total)
    {
        return(retval);
    }
declare "n" var and set to 0. If less than the total number of input elements, keep looping. Using the PRE-increment operator. Set all of the elements to lowercase to support all browser types with toLowerCase().
You then find the element type with: elements[n].type.
The [n] is just the increment for each type of element.

I know that this "The ++retval[]" is PRE-incrementing the element value and then returning it to the function (retval), but can someone explain to my how it works exactly?
The format just looks foreign to me...

Code:
    for(var n = 0; n < retval.total; ++n)
    {
        
      ++retval[elements[n].type.toLowerCase()];
    }

    return(retval);

let me know if I got most of the code right?

Thanks!
allworknoplay is offline  
Reply With Quote
Old 04-22-2009, 10:24 PM   #10 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

Quote:
Originally Posted by allworknoplay View Post
I am unsure of what is going on here. You create a variable called "retval" which I assume is short for "Retrieve Values".
Only Kalle really knows, but I'd assume something like "return value(s)".
Quote:
Originally Posted by allworknoplay View Post
Is this an array or are we creating an object?
Code:
var retval = 
    {
        'checkbox': 0, 
        'radio':    0, 
        'total':    0
    };
It's an 'object literal', a convenient way of creating a new object with some properties. Remember everything in JS is an object. The boring way of doing the same would be:
JavaScript Code:
var retval = new Object();
retval.checkbox = 0;
retval.radio    = 0;
retval.total    = 0


Quote:
Originally Posted by allworknoplay View Post
Are we passing "document.getElementsByTagName" to this conditional and if it doesn't exist we return nothing??
Code:
/* Browser does not support getElementsByTagName, return void */
    if(!document.getElementsByTagName)
    {
        return(retval);
    }
Basically, the condition asks if "document.getElementsByTagName" evaluates to boolean false. Since we're talking about a function, the condition will be false if it does not exist.

Also, it returns the retval object that was just created (with all zero values, remember) rather than void.

Quote:
Originally Posted by allworknoplay View Post
Here we get all the of the input tags, then count them and assign the count to retval.total
Code:
var elements = document.getElementsByTagName('input');
retval.total = elements.length;
return void, if no total from document.getElementsByTagName('input') return nothing?
Code:
/* No input tags in tree */
    if(!retval.total)
    {
        return(retval);
    }
Yep, you got it. (Again, not really void but the object with zero totals)

Quote:
Originally Posted by allworknoplay View Post
I know that this "The ++retval[]" is PRE-incrementing the element value and then returning it to the function (retval), but can someone explain to my how it works exactly?
The format just looks foreign to me...
Code:
    for(var n = 0; n < retval.total; ++n)
    {
        
      ++retval[elements[n].type.toLowerCase()];
    }

    return(retval);
elements[n].type.toLowercase() is processed as follows. Get the nth item in the elements array (ie, the current one that we want to work with). Then get its type property (which is a String object). Then call the toLowerCase() method on that type property (the method can be called on any string). So the result of that expression is "checkbox" or "radio".

Now, the ++retval[…] should make a little more sense. Say the current element is a radio button, we are asking: ++retval["radio"] or please increment the value of retval["radio"] which is just another way of writing retval.radio
Salathe is offline  
Reply With Quote
Old 04-23-2009, 12:22 AM   #11 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
Kalle is on a distinguished road
Default

As for the "retval", then yes it stands for "return value" and Salathe covered all the points I see ;)
__________________
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 04-23-2009, 12:23 AM   #12 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Thanks Salathe for explaining it to me in layman's terms.

I'll look into the object literal, that doesn't look like it's something that is available in PHP right?
Sounds pretty cool though, almost like a shortcut to using objects...

On your last explanation:

++retval[…]


Would that be considered a unary operator?


Also, when evaluating conditions like this:


Code:
if(!retval.total)
    {
        return(retval);
    }
Why must one return (retval)? Could we just do "nothing"?

Like this:


Code:
if(!retval.total)
    {
        return false;
    }
allworknoplay is offline  
Reply With Quote
Old 04-23-2009, 12:25 AM   #13 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Quote:
Originally Posted by Kalle View Post
As for the "retval", then yes it stands for "return value" and Salathe covered all the points I see ;)

Do you remember how long it took for you to get a good solid understanding of JS?

Was it 1 month? 6 months? a full year?
allworknoplay is offline  
Reply With Quote
Old 04-23-2009, 12:27 AM   #14 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
Kalle is on a distinguished road
Default

You can return nothing like there, but! That means the render function will generate an error unless modified, but in that condition it would be wrong to change, as no inputs were found. Only the "if-browser-does-not-support-getElementsByTagName" you should return void and then check for void return in the Render function.

As for the "object literal" or closure object, its one of the things I would really like with real closures now in PHP 5.3, but lets hope they can be in 6.0 if someone makes a patch for it :)
__________________
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 04-23-2009, 12:29 AM   #15 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
Kalle is on a distinguished road
Default

Quote:
Originally Posted by allworknoplay View Post
Do you remember how long it took for you to get a good solid understanding of JS?

Was it 1 month? 6 months? a full year?
hmm I don't know, I never really took time to learn it, I just did parts I needed to create for my projects so it's been all over the time while I've done frontend ;)
__________________
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 04-23-2009, 12:37 AM   #16 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Quote:
Originally Posted by Kalle View Post
You can return nothing like there, but! That means the render function will generate an error unless modified, but in that condition it would be wrong to change, as no inputs were found. Only the "if-browser-does-not-support-getElementsByTagName" you should return void and then check for void return in the Render function.
Yeahhhh.....I'll have to revisit this part because I have no idea what any of this means.


Quote:
Originally Posted by Kalle View Post
As for the "object literal" or closure object, its one of the things I would really like with real closures now in PHP 5.3, but lets hope they can be in 6.0 if someone makes a patch for it :)
You have a PHP.net account! You can make it happen!!
allworknoplay is offline  
Reply With Quote
Old 04-23-2009, 09:39 AM   #17 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

Quote:
Originally Posted by allworknoplay View Post
I'll look into the object literal, that doesn't look like it's something that is available in PHP right?
Sounds pretty cool though, almost like a shortcut to using objects...
No, as Kalle said, object literals are not in PHP (yet). The closest thing, visually, that I can think of would be:

PHP Code:
$retval = (object) array(
  
'checkbox' => 0,
  
'radio'    => 0,
  
'total'    => 0
);

++
$retval->total;
print_r($retval); 
The ArrayObject (in PHP) would also allow the object- and array-syntaxes to be used ($retval->total and $retval['total']) if you wanted/needed them both.

Quote:
Originally Posted by allworknoplay View Post
On your last explanation:

++retval[…]


Would that be considered a unary operator?
Yep, because the operator acts on only one variable, it is a unary operation.

Quote:
Originally Posted by allworknoplay View Post
You have a PHP.net account! You can make it happen!!
PHP is an open source project, meaning anyone is free to contribute. A php.net account is not required!
Salathe is offline  
Reply With Quote
The Following User Says Thank You to Salathe For This Useful Post:
allworknoplay (04-23-2009)
Old 04-23-2009, 10:17 AM   #18 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
Kalle is on a distinguished road
Default

Quote:
Originally Posted by Salathe View Post
No, as Kalle said, object literals are not in PHP (yet). The closest thing, visually, that I can think of would be:

PHP Code:
$retval = (object) array(
  
'checkbox' => 0,
  
'radio'    => 0,
  
'total'    => 0
);

++
$retval->total;
print_r($retval); 
The ArrayObject (in PHP) would also allow the object- and array-syntaxes to be used ($retval->total and $retval['total']) if you wanted/needed them both.


Yep, because the operator acts on only one variable, it is a unary operation.


PHP is an open source project, meaning anyone is free to contribute. A php.net account is not required!
Exactly (about the last part), however I do have commit access to php-src, but my skills digging into ZE is abit too poor, but the API is pretty straight forward ;)

As for the ArrayObject, any class that implements the ArrayAccess interface should be able to be accessed like arrays and objects :)
__________________
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 04-23-2009, 05:28 PM   #19 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Hey guys, quick question, this goes a little back when Salathe suggested to use onLoad in the Body tag...

Here's what I currently have and it works...

shortened code:

Code:
<body>
<div><input type="checkbox" name="checkbox" value="checkbox" /></div>
<div><input type="checkbox" name="checkbox" value="checkbox"  /></div>
<div><input type="checkbox" name="checkbox" value="checkbox"  /></div>
<div><input type="radio" name="radio"  /></div>
<div><input type="radio" name="radio"  /></div>
<div><input type="radio" name="radio"  /></div>

<script type="text/javascript">
<!--
showCount();
// -->
</script>

</body>
I move the function to be an onLoad event in the BODY tag and it works too...is this considered best practice?

Code:
<body onLoad="showCount();">
<div><input type="checkbox" name="checkbox" value="checkbox" /></div>
<div><input type="checkbox" name="checkbox" value="checkbox"  /></div>
<div><input type="checkbox" name="checkbox" value="checkbox"  /></div>
<div><input type="radio" name="radio"  /></div>
<div><input type="radio" name="radio"  /></div>
<div><input type="radio" name="radio"  /></div>

</body>
allworknoplay is offline  
Reply With Quote
Old 04-23-2009, 05:32 PM   #20 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Quote:
Originally Posted by Kalle View Post
Exactly (about the last part), however I do have commit access to php-src, but my skills digging into ZE is abit too poor, but the API is pretty straight forward ;)

As for the ArrayObject, any class that implements the ArrayAccess interface should be able to be accessed like arrays and objects :)
Speaking of contributing to PHP...

So I now learned that in JS you don't have to do backward slashes if you use double quotes.


var test = "today's a great day";


But in PHP you do...

$test = "today\'s a great day";

Unless you use single quotes in JS, then you would have to use backslash too...

Do you know if PHP is going to do something like this in the future so we don't have to use backslash if using double quotes?
allworknoplay is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 07:45 PM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design