SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Enthusiast whitecreek's Avatar
    Join Date
    Aug 2011
    Location
    Madrid, Spain
    Posts
    42
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    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:

    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:

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

  2. #2
    SitePoint Wizard bronze trophy chris.upjohn's Avatar
    Join Date
    Apr 2010
    Location
    Melbourne, AU
    Posts
    2,192
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    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.

    http://jsfiddle.net/9rF6H/

  3. #3
    SitePoint Guru
    Join Date
    Sep 2006
    Posts
    731
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For checkboxes, onclick is preferable to onchange.

    Not tested but try it (below the checkboxes):
    Code:
    
    (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" );
    
    Tab-indentation is a crime against humanity.

  4. #4
    SitePoint Enthusiast whitecreek's Avatar
    Join Date
    Aug 2011
    Location
    Madrid, Spain
    Posts
    42
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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

    Code:
    <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'

    Code javascript:
     
    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.

  5. #5
    SitePoint Wizard bronze trophy chris.upjohn's Avatar
    Join Date
    Apr 2010
    Location
    Melbourne, AU
    Posts
    2,192
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    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.

    Code JavaScript:
    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;
                }
            }
        }
    };

  6. #6
    SitePoint Enthusiast whitecreek's Avatar
    Join Date
    Aug 2011
    Location
    Madrid, Spain
    Posts
    42
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ...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

    Code javascript:
    $(document).ready(function(){.......});

    Anyways, works perfectly either with your
    Code javascript:
    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.

  7. #7
    SitePoint Wizard bronze trophy chris.upjohn's Avatar
    Join Date
    Apr 2010
    Location
    Melbourne, AU
    Posts
    2,192
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    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.

    http://jsfiddle.net/chrisupjohn/9rF6H/3/

  8. #8
    SitePoint Enthusiast whitecreek's Avatar
    Join Date
    Aug 2011
    Location
    Madrid, Spain
    Posts
    42
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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!!!

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

    Cheers!!


Bookmarks

Posting Permissions

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