Unobstrusive onchange checkbox

Hi there

I’m trying to run the ‘onchange’ event not in the html code but from an external js file for checkboxes to activate ‘presupuesto’ function. I was trying pretty simple options without succes so far…

This would be the ‘regular’ in-html code:


<input type="checkbox" name="show" value="" id="show" onChange="presupuesto()"  />
<input type="checkbox" name="ilikeit" value="" id=ilikeit" onChange="presupuesto()"  />
<input type="checkbox" name="gallery" value="" id="gallery" onChange="presupuesto()"  />


And this is how I was trying it to work:


HTML
----------------

<input type="checkbox" name="show" value="" id="show"  />
<input type="checkbox" name="ilikeit" value="" id=ilikeit"   />
<input type="checkbox" name="gallery" value="" id="gallery"  />


External JS
----------------

document.getElementById("show", "ilikeit", "gallery").onchange=presupuesto();

Any sugestions??

Thx a million in advance.

Have a look at the following demo I build, all I did was simply assign classes to each input field with a type of checkbox and run through all the input elements on the page with a type of checkbox and a class of change. You could get the same result by using getElementsByClassName but this way is supported by all browsers.

For checkboxes, onclick is preferable to onchange.

Not tested but try it (below the checkboxes):


[FONT=Courier New]
(function()
{
  var evt = arguments[ 0 ],
      func = arguments[ 1 ];

  for( var i = 2; i < arguments.length;  i++ )
    document.getElementById( arguments[ i ] ) [ evt ] = func;

})( 'onclick', presupuesto, "show", "ilikeit", "gallery" );
[/FONT]

Hi again,

First off, thanks both of you for your time. I guess you know what this is like, you start playing with jquery, making show/hide a few divs and then you think you know your way around js and jquery. Truth is I keep freaking out a bit when I see any array, not because I don’t understand what they do (not a big accomplishment), but rather because I still feel unable to write them from scratch, not to talk about being creative!!

I went with Chris solution, because his array looked more familiar to me, and because the idea of simply substituting - onChange=“presupuesto()” - for - class=“change” - in each - input type=“checkbox” - looked like an easy way to handle the thing to me. I chose ‘onclick’ instead of ‘onchange’ though.

Despite the fact chris example at jsfiddle is definetely working I didn´t manage to make it work on my site.

The url is: http://www.ficoprieto.com
js external file is ‘presupuesto.js’

Sorry I haven’t got it translated into english yet. I’ll have it done soon.
Click on the euro symbol (€) top-right of the page. You’ll see no changes in <inputs> from the code I wrote on my 1st post. The reason for that is that the calculator is actually working (everywhere but IE8 - I’m not trying below version 8 - which shows a weird ‘behaviour’ for that form), but it does it with the obtrusive onchanges. I tested Chris solution locally.

My aim was to build up a calculator so users could be adding functionalities to their future website. Each functionality a checbkox, each checkbox a different price to be added (or substracted if the checkbox is deselected) to the ‘basic website’ price of 330€

You’ll see too that de id’s for the checkboxes go from ‘ch1’ to ‘ch7’ instead of ‘show’, ‘ilikeit’, ‘gallery’… this is because I was trying to add a “tick’em all” checkbox running an array through all checkboxes, which I didn’t managed to do either. But that’s a different matter.

Here is the html and js I’m keeping locally after applying Chris solution:

HTML



<input type="checkbox" name="show" value="" id="ch1" class="change" />
<input type="checkbox" name="ilikeit" value="" id="ch2" class="change" />
<input type="checkbox" name="gallery" value="" id="ch3" class="change" />
<input type="checkbox" name="contact" value="" id="ch4" class="change" />
<input type="checkbox" name="news" value="" id="ch5" class="change" />
<input type="checkbox" name="maps" value="" id="ch6" class="change" />
<input type="checkbox" name="llegar" value="" id="ch7" class="change" />


and here is the external js file ‘presupuesto.js’



function presupuesto() {  		
	
	 var total = 330;	
	
	  //checkboxes
	
	  if (document.getElementById("ch1").checked){ // slideshow
		  var vshow = 45;}
		  else
		  {var vshow = 0;}
		
	  if (document.getElementById("ch2").checked){ // Ilikeit
		  var vilikeit = 15;}
		  else
		  {var vilikeit = 0;}
		
	  if (document.getElementById("ch3").checked){ // gallery lightbox
		  var vgallery = 20;}
		  else
		  {var vgallery = 0;}
		
	  if (document.getElementById("ch4").checked){ // contact php form
		  var vcontact = 40;}
		  else
		  {var vcontact = 0;}
		
	  if (document.getElementById("ch5").checked){ // newsletter php form
		  var vnews = 20;}
		  else
		  {var vnews = 0;}
		
	  if (document.getElementById("ch6").checked){ // google maps
		  var vmaps = 20;}
		  else
		  {var vmaps = 0;}		
		
	  if (document.getElementById("ch7").checked){ // google maps 'cómo llegar'
		  var vllegar = 45;}
		  else
		  {var vllegar = 0;}	
	
		
	  var total_check = vshow + vilikeit + vgallery + vcontact + vnews + vmaps + vllegar;
	
	  // calculo del total 	
	
      document.getElementById("resultado").value = parseInt(total) + parseInt(total_check) + ' euros';
}


var ckbx = document.getElementsByTagName('input');

if (ckbx.length) {
    for (var i = 0, m = ckbx.length; i < m; i++) {
        if (ckbx[i].type === 'checkbox' && ckbx[i].className.match(/change/)) {
            ckbx[i].onclick = presupuesto;
        }
    }
}


Any idea why it wouldn’t work?

Thanks a lot again,

Whitecreek.

Currently your presupuesto.js file is been loaded in your <head> tags which would cause an error as the input fields don’t exist in the DOM yet, you would need to wrap the above code in a window.onload event so the page executes the code upon it been 100% finished loading.

window.onload = function() {
    var ckbx = document.getElementsByTagName('input');
     
    if (ckbx.length) {
        for (var i = 0, m = ckbx.length; i < m; i++) {
            if (ckbx[i].type === 'checkbox' && ckbx[i].className.match(/change/)) {
                ckbx[i].onclick = presupuesto;
            }
        }
    }
};

…as the input fields don’t exist in the DOM yet…

This I didin’t know. I knew is best to place js files just before the </body> closing tag so no js gets run by the browser until all elements in the <body> get loaded and displayed, which result in faster webpage display. But never thought of that, which sounds pretty logical on the other hand. I tried placing all js files just before the </body> closing tag but IE8 went mad turning elements in the page upside down and seeming to ignore some css rules (most likely that having to do with the slideshow js files), so I gave it up.

I actually thought document ready could be a reason for the code to fail when I saw ‘onDomReady’ selected in your jsfiddle framework options. But I wasn’t completely sure about it or about how to fix it. Even thought about somehow adding jquery


$(document).ready(function(){.......});

Anyways, works perfectly either with your

window.onload = function() {.......};

wrapping, or placing presupuesto.js just before </body> closing tag and without the wrapping. Even working in IE8 now!! O.o

Thx a lot for the tip Chris.

Just as a note you can also use jQuery to achieve the same result with one line of code compared to the 8 lines above, see the jsFiddle link below.

Sweet. I’ll definitely go the jquery way. I’m keeping the pure js chunk commented so I’ll be able to go back to it if I need to, but if jquery can do it I’d rather use it. I guess I could have figured that way myself!!! :rolleyes:

Not used yet to mix jquery syntax with regular js code… nevermind.

Cheers!!