Returning the total number of clicked cells in a table

Hi,

I’m a newbie at coding and I really some help with the following:

I’ve created a simple time table using html with the days of the week across the top and hour slots going down. I’d like to make the following happen:

The individual cells are highlighted when a user clicks on them (and the reverse if the highlighted cell is clicked again)

Each cell represents one hour - clicking on the cells returns the total number of hours calculated

Can anyone help me do this?

Thanks in advance

I see two general ways to do that:

  • count the highlighted rows (there must be a difference to the not highlighted cells, right?)
  • use a counter object (Closure, table object property) that increases/decreases with every click

Thanks for your speedy reply @Dormilich.
My problem is I have no idea how to write the code for that, I’m afraid.
I wonder if you’d be kind and help me?

something for the general idea.

$(document).on('click', 'table td.marked', function (evt) {
    counter.up();
}).on('click', 'table td.unmarked', function (evt) {
    counter.down();
});

Thanks @Dormilich. I’ll see if I can manage :smile:

Here is a script that will do what you want. Clicking on a table cell increases the count and clicking again decreases the count. This script will work on any sized table. Just make sure you give the class “hdr” to the header cells to avoid making them active (counting) cells. Also, place this script at the bottom of your page - just above the </body> tag.

<script type="text/javascript">
 var cntObj=document.getElementById("cnt");
 var allTds=document.getElementById("T1").getElementsByTagName("td");
 var counter=0, bgC;
 for(var i=0; i<allTds.length; i++)
  { if(allTds[i].className!="hdr")
       { allTds[i].style.cursor="pointer";
         allTds[i].className="white";       
         allTds[i].onclick=cellChg;                                  
       }   
   } 
 // ----  
  function cellChg()
   { bgC=(this.className=="cyan")? { bg:"white",add:"-1"} : { bg:"cyan", add:"+1"};
     this.className=bgC.bg;
     counter+=parseInt(bgC.add);
     cntObj.innerHTML=counter;                       
   }   
//
</script>

I have created a working example on JSFiddle for you to experiment.

Why are you adding a separate event handler to each cell instead of just adding an event listener on the table? That would remove the need for the loops.

An excellent idea. It works well, and even though it doesn’t reduce the code by much, it certainly looks more elegant, and simplifies the DOM. :smile:

Here is the modified script:

<script type="text/javascript">
 var cntObj=document.getElementById("cnt"); 
 document.getElementById("T1").onclick=cellChg;
 // ----  
 var counter=0; 
  function cellChg(event)
   { var targElem, bgC; 
     event=event || window.event;
     targElem = event.target || event.srcElement;
     if(targElem.tagName.toLowerCase()=="td" && targElem.className!="hdr") 
      { bgC=(targElem.className=="cyan")? { bg:"white",add:"-1"} : { bg:"cyan", add:"+1"};
        targElem.className=bgC.bg;
        counter+=parseInt(bgC.add);
        cntObj.innerHTML=counter;                       
      }
   }   
</script>

A link to the working example on JSFiddle is here.

1 Like

there’s no need to use parseInt() if the property is a number to begin with (i.e. -1 and 1)

Thanks for your input. If you look at the script you will find I saved the +1 and -1 as strings (“+1”, “-1”) Since I am using counter+= to change the counter value I wanted to ensure that both counter and +1 were always numbers, rather than strings so that they would be added together. Hence the parseInt expression. :smile:

Thank you all so much for your help with this - I really appreciate it. :smile:

and that is what I question. you saved them as strings, but it would have been simpler to save them as numbers.

To convert strings to numbers you should use Number() not ParseInt() - ParseInt() is for converting numbers to numbers where the base of the original number is not 10.

Both parseInt() and Number() return a typeof of “number” when a string value is used as an argument. The standard says:

18.2.5 parseInt (string , radix)
The parseInt function produces an integer value dictated by interpretation of the contents of the string argument according to the specified radix. If radix is undefined or 0, it is assumed to be 10.

The use of parseInt() to convert strings to numbers is perfectly valid, even with the radix of 10 (decimal) being implied, rather than stated. The real question, as Dormilich has stated:

you saved them as strings, but it would have been simpler to save them as numbers.

Let’s put it down to personal preference. :smile:

Not always - consider

parseInt('0x100junk')

that will return 256 having assumed a radix of 16 not 10. If it had assumed a radix of 10 it would have returned 0.

Why use a function that has extra code in it to handle 34 other possible radix values when there is a function that has the sole purpose of converting a string to a number.

Anyway why write:

counter+=parseInt(bgC.add);

when you can achieve the same thing in a lot less code using:

counter+= +bgC.add;

The unary + operator is actually the most effective way to convert strings to numbers.

Consider when bgC.add = ‘0x100junk’;

+bgC.add gives you NaN
parseInt(bgC.add) gives you 256
parseInt(bgC.add, 16) gives you 256
parseInt(bgC.add, 10) gives you 0

I tend to prefer using parseInt with a radix as it’s easy to tell exactly what you’re gonna get.

Good point. Carolyn might like to use that in her solution to this enquiry. Thanks for the input. :grinning:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.