td Color Change onClick

  • milesdavis
  • Newbie
  • Newbie
  • milesdavis
  • Posts: 5

Post 3+ Months Ago

Hi,

I'm am completly new to coding JavaScript and would like some help.

I want to have a 5 x 5 table and when i click in a td cell I would like the bgcolor to change to red. if i click in the same cell again I would like the color to change to blue and so on. I would like to be able to cycle through 5 different colors for each td cell.

I haven't any idea on how to do this so any pointers would be really appreciated.

Appologies if this has been posted elsewhere in the forums, I did do a seach but nothring relevant came up.

Thanks in advance,
Miles
  • Anonymous
  • Bot
  • No Avatar
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post 3+ Months Ago

  • joebert
  • Fart Bubbles
  • Genius
  • User avatar
  • Posts: 13503
  • Loc: Florida

Post 3+ Months Ago

First a script section,
Code: [ Select ]
<script language="javascript">
/* First we setup out colors in the order they will be used using an array */
colors = ["#ff0000", "#00ff00", "#0000ff", "#ffff00", "#00ffff"];

/* Next we declare an empty array that we will fill with RGB forms of our colors for MSIE & Mozilla compatability */
cRGB = [];

/* This is the function that transforms the hex values into RGB values, it splits the color paramater into 3 substrings, parses a decimal from the hex, & creates a RGB(rrr, ggg, bbb) string and returns the string to whatever called the function */
function toRGB(color){
    var rgb = "rgb(" + parseInt(color.substring(1,3), 16) + ", " + parseInt(color.substring(3,5), 16) + ", " + parseInt(color.substring(5,7), 16) + ")";    
    return rgb;
}

/* This loops through our colors & fills our cRGB array with the RGB string values returned from the toRGB function */
for(var i=0; i<colors.length; i++){
    cRGB[i] = toRGB(colors[i]);
}

/* this is the function that takes care of grabbing the current background color & changing accordingly (see inner comments) */
/* target paramater will be passed (this.id) from the td onclick events */
function changeColor(target){

    /* This checks if the browser is an MSIE browser, if it is it converts the hex value that will be returned from checking the targets background into an rgb string, if not MSIE it uses the value as is, the result from either is assigned to the local variable "swapper" */
    var swapper = navigator.appVersion.indexOf("MSIE")!=-1 ? toRGB(document.getElementById(target).style.backgroundColor) : document.getElementById(target).style.backgroundColor;

    /* declare some helper variables to keep track of what color is found */
    var set = false;
    var xx;

    /* Loop through the cRGB array comparing each value against the value of the swapper variable */
    for(var i=0; i<cRGB.length; i++){

        /* if they match */
        if(swapper == cRGB[i]){

            /* if adding 1 to i makes it equil to the length of the cRGB array then we need to use zero as then next index of the array to use, else we can use i+1 */
            if(((i+1)) >= cRGB.length){
                xx = 0;
            }else{
                xx = i+1;
            }
    
            /* set the background */
            document.getElementById(target).style.background = colors[xx];

            /* keep the condition at the end of the function from assigning a default value, make i equil to the length of the array so the loop will exit */
            set = true;
            i=cRGB.length;
        }
    }

    /* if no match was found then assign a default value */
    set ? null : document.getElementById(target).style.background = colors[1];
}
</script>
  1. <script language="javascript">
  2. /* First we setup out colors in the order they will be used using an array */
  3. colors = ["#ff0000", "#00ff00", "#0000ff", "#ffff00", "#00ffff"];
  4. /* Next we declare an empty array that we will fill with RGB forms of our colors for MSIE & Mozilla compatability */
  5. cRGB = [];
  6. /* This is the function that transforms the hex values into RGB values, it splits the color paramater into 3 substrings, parses a decimal from the hex, & creates a RGB(rrr, ggg, bbb) string and returns the string to whatever called the function */
  7. function toRGB(color){
  8.     var rgb = "rgb(" + parseInt(color.substring(1,3), 16) + ", " + parseInt(color.substring(3,5), 16) + ", " + parseInt(color.substring(5,7), 16) + ")";    
  9.     return rgb;
  10. }
  11. /* This loops through our colors & fills our cRGB array with the RGB string values returned from the toRGB function */
  12. for(var i=0; i<colors.length; i++){
  13.     cRGB[i] = toRGB(colors[i]);
  14. }
  15. /* this is the function that takes care of grabbing the current background color & changing accordingly (see inner comments) */
  16. /* target paramater will be passed (this.id) from the td onclick events */
  17. function changeColor(target){
  18.     /* This checks if the browser is an MSIE browser, if it is it converts the hex value that will be returned from checking the targets background into an rgb string, if not MSIE it uses the value as is, the result from either is assigned to the local variable "swapper" */
  19.     var swapper = navigator.appVersion.indexOf("MSIE")!=-1 ? toRGB(document.getElementById(target).style.backgroundColor) : document.getElementById(target).style.backgroundColor;
  20.     /* declare some helper variables to keep track of what color is found */
  21.     var set = false;
  22.     var xx;
  23.     /* Loop through the cRGB array comparing each value against the value of the swapper variable */
  24.     for(var i=0; i<cRGB.length; i++){
  25.         /* if they match */
  26.         if(swapper == cRGB[i]){
  27.             /* if adding 1 to i makes it equil to the length of the cRGB array then we need to use zero as then next index of the array to use, else we can use i+1 */
  28.             if(((i+1)) >= cRGB.length){
  29.                 xx = 0;
  30.             }else{
  31.                 xx = i+1;
  32.             }
  33.     
  34.             /* set the background */
  35.             document.getElementById(target).style.background = colors[xx];
  36.             /* keep the condition at the end of the function from assigning a default value, make i equil to the length of the array so the loop will exit */
  37.             set = true;
  38.             i=cRGB.length;
  39.         }
  40.     }
  41.     /* if no match was found then assign a default value */
  42.     set ? null : document.getElementById(target).style.background = colors[1];
  43. }
  44. </script>


Now for the style/body of the example document,
Code: [ Select ]
<style type="text/css">
td{width:100px; height:100px;background:#ff0000;}
</style>

</head>
<body>

<table border="0" cellspacing="0" cellpadding="0">
    <tr>
        <td id="a1" onclick="changeColor(this.id);"></td>
        <td id="a2" onclick="changeColor(this.id);"></td>
        <td id="a3" onclick="changeColor(this.id);"></td>
        <td id="a4" onclick="changeColor(this.id);"></td>
        <td id="a5" onclick="changeColor(this.id);"></td>
    </tr>

    <tr>
        <td id="b1" onclick="changeColor(this.id);"></td>
        <td id="b2" onclick="changeColor(this.id);"></td>
        <td id="b3" onclick="changeColor(this.id);"></td>
        <td id="before" onclick="changeColor(this.id);"></td>
        <td id="b5" onclick="changeColor(this.id);"></td>
    </tr>

    <tr>
        <td id="c1" onclick="changeColor(this.id);"></td>
        <td id="c2" onclick="changeColor(this.id);"></td>
        <td id="c3" onclick="changeColor(this.id);"></td>
        <td id="c4" onclick="changeColor(this.id);"></td>
        <td id="c5" onclick="changeColor(this.id);"></td>
    </tr>

    <tr>
        <td id="d1" onclick="changeColor(this.id);"></td>
        <td id="d2" onclick="changeColor(this.id);"></td>
        <td id="d3" onclick="changeColor(this.id);"></td>
        <td id="d4" onclick="changeColor(this.id);"></td>
        <td id="d5" onclick="changeColor(this.id);"></td>
    </tr>

    <tr>
        <td id="e1" onclick="changeColor(this.id);"></td>
        <td id="e2" onclick="changeColor(this.id);"></td>
        <td id="e3" onclick="changeColor(this.id);"></td>
        <td id="e4" onclick="changeColor(this.id);"></td>
        <td id="e5" onclick="changeColor(this.id);"></td>
    </tr>
</table>

</body>
  1. <style type="text/css">
  2. td{width:100px; height:100px;background:#ff0000;}
  3. </style>
  4. </head>
  5. <body>
  6. <table border="0" cellspacing="0" cellpadding="0">
  7.     <tr>
  8.         <td id="a1" onclick="changeColor(this.id);"></td>
  9.         <td id="a2" onclick="changeColor(this.id);"></td>
  10.         <td id="a3" onclick="changeColor(this.id);"></td>
  11.         <td id="a4" onclick="changeColor(this.id);"></td>
  12.         <td id="a5" onclick="changeColor(this.id);"></td>
  13.     </tr>
  14.     <tr>
  15.         <td id="b1" onclick="changeColor(this.id);"></td>
  16.         <td id="b2" onclick="changeColor(this.id);"></td>
  17.         <td id="b3" onclick="changeColor(this.id);"></td>
  18.         <td id="before" onclick="changeColor(this.id);"></td>
  19.         <td id="b5" onclick="changeColor(this.id);"></td>
  20.     </tr>
  21.     <tr>
  22.         <td id="c1" onclick="changeColor(this.id);"></td>
  23.         <td id="c2" onclick="changeColor(this.id);"></td>
  24.         <td id="c3" onclick="changeColor(this.id);"></td>
  25.         <td id="c4" onclick="changeColor(this.id);"></td>
  26.         <td id="c5" onclick="changeColor(this.id);"></td>
  27.     </tr>
  28.     <tr>
  29.         <td id="d1" onclick="changeColor(this.id);"></td>
  30.         <td id="d2" onclick="changeColor(this.id);"></td>
  31.         <td id="d3" onclick="changeColor(this.id);"></td>
  32.         <td id="d4" onclick="changeColor(this.id);"></td>
  33.         <td id="d5" onclick="changeColor(this.id);"></td>
  34.     </tr>
  35.     <tr>
  36.         <td id="e1" onclick="changeColor(this.id);"></td>
  37.         <td id="e2" onclick="changeColor(this.id);"></td>
  38.         <td id="e3" onclick="changeColor(this.id);"></td>
  39.         <td id="e4" onclick="changeColor(this.id);"></td>
  40.         <td id="e5" onclick="changeColor(this.id);"></td>
  41.     </tr>
  42. </table>
  43. </body>


Basically giving IDs to each td & assigning the changeColor(this.id) function to each of them.

I used the generic css just for example sake, you probably don't want every td to be 100X100px with a bg of red.
you could change that to,
Code: [ Select ]
td#a1,td#a2,td#a3,td#a4,td#a5,td#b1,ect...{width:50,ect..}


This works with the length of the colors array, it will update itself according to the number of colors in it.
  • milesdavis
  • Newbie
  • Newbie
  • milesdavis
  • Posts: 5

Post 3+ Months Ago

Thanks for that joebert.

Now I've got to find a way to store all the colors selected into an array so I can put it into a mysql db.

You wouldn't be able to point me in the right direction for that as well would you? :)

Thanks again for your help.

Miles
  • milesdavis
  • Newbie
  • Newbie
  • milesdavis
  • Posts: 5

Post 3+ Months Ago

BTW, this script is great. I really appreciate you taking the time to help me out.

Kind Regards,
Miles
  • milesdavis
  • Newbie
  • Newbie
  • milesdavis
  • Posts: 5

Post 3+ Months Ago

Would it be possible to grab the color value and put it into a hidden input field?

Example:

<td id="a1" onclick="changeColor(this.id);"><input type=hidden name=a1 value=COLOR></td>

where COLOR would be the currently assigned color of the cell background.

Would also be nice if it were possible to assign a value to COLOR so that when the td cell is shadded Red the hidden input value would be 1. If it were Blue then the value would be 2. And so forth.

If you can help out on this I would be grateful.

Thanks again.

Miles
  • joebert
  • Fart Bubbles
  • Genius
  • User avatar
  • Posts: 13503
  • Loc: Florida

Post 3+ Months Ago

Setup a hidden field,
Code: [ Select ]
<td id="a1" onclick="changeColor(this.id);"><input type="hidden" id="a1b" name="a1" value="test"/></td>

add a statement to change the value of hidden field building the id from the existing target param,
Code: [ Select ]
     /* set the background */
     document.getElementById(target).style.background = colors[xx];

    /* change value of hidden field */
     document.getElementById(target+"b").value = xx;
  1.      /* set the background */
  2.      document.getElementById(target).style.background = colors[xx];
  3.     /* change value of hidden field */
  4.      document.getElementById(target+"b").value = xx;

modify the default clause so the first click will change the hidden value as well,
Code: [ Select ]
  /* if no match was found then assign a default value */
  set ? null : (document.getElementById(target).style.background = colors[1], document.getElementById(target+"b").value = 1);
  1.   /* if no match was found then assign a default value */
  2.   set ? null : (document.getElementById(target).style.background = colors[1], document.getElementById(target+"b").value = 1);


That should take care of the hidden form field, I assume you plan on using thoose fields for the database ?
  • milesdavis
  • Newbie
  • Newbie
  • milesdavis
  • Posts: 5

Post 3+ Months Ago

Hi joebert,

That works great. Yeah, the values will be stored in the db for later use.

I really appreciate all your help.

Regards,
Miles
  • joebert
  • Fart Bubbles
  • Genius
  • User avatar
  • Posts: 13503
  • Loc: Florida

Post 3+ Months Ago

Quote:
I would also like to be able to add up all the squares that someone has clicked, and times that number by a number. How could I do this?

Thanks a lot,

Andrew


If each square increases the click counter every time it's clicked, altering the beginning of the function deffinition in the script section is a start,
Code: [ Select ]
// Track clicks
var clicks = 0;

function changeColor(target){
  clicks++;
  1. // Track clicks
  2. var clicks = 0;
  3. function changeColor(target){
  4.   clicks++;


If each square should only count as a single click, then the alteration could look like this,
Code: [ Select ]
// Keep track of what's been clicked
var beenClicked = '|';

// Track clicks
var clicks = 0;

function changeColor(target){

// Track clicks
  var clickTest = new RegExp('|' + target + '|', 'i');
  if( ! clickTest.test(beenClicked) ) {
   clicks++;
   beenClicked += (target + '|')
  }
  1. // Keep track of what's been clicked
  2. var beenClicked = '|';
  3. // Track clicks
  4. var clicks = 0;
  5. function changeColor(target){
  6. // Track clicks
  7.   var clickTest = new RegExp('|' + target + '|', 'i');
  8.   if( ! clickTest.test(beenClicked) ) {
  9.    clicks++;
  10.    beenClicked += (target + '|')
  11.   }


In either case, the variable clicks would be available to a multiplier function you can call whenever for whatever.

Code: [ Select ]
function multiplyClicks(factor){
  return (clicks * factor);
}
  1. function multiplyClicks(factor){
  2.   return (clicks * factor);
  3. }


So, if this was a form & you wanted to place the result of the multiplication in a hidden form variable, you could alter your forms submit handler to modify the hidden fields value somthing like this.
Code: [ Select ]
// This would set the value of a hidden form input field to ( 5 * clicks)

document.getElementById("clicktracker").value = multiplyClicks(5);
  1. // This would set the value of a hidden form input field to ( 5 * clicks)
  2. document.getElementById("clicktracker").value = multiplyClicks(5);
  • Garibaldi
  • Newbie
  • Newbie
  • User avatar
  • Posts: 13
  • Loc: Wisconsin

Post 3+ Months Ago

Thanks for the fast reply! I added
Code: [ Select ]
// Keep track of what's been clicked

var beenClicked = '|';

// Track clicks

var clicks = 0;

function changeColor(target){
  1. // Keep track of what's been clicked
  2. var beenClicked = '|';
  3. // Track clicks
  4. var clicks = 0;
  5. function changeColor(target){

like this:
Code: [ Select ]
<script language="javascript">

/* First we setup out colors in the order they will be used using an array */

colors = ["#ff0000", "#00ff00", "#0000ff", "#ffff00",
// Track clicks

  var clickTest = new RegExp('|' + target + '|', 'i');

  if( ! clickTest.test(beenClicked) ) {

   clicks++;

   beenClicked += (target + '|')

  }
  1. <script language="javascript">
  2. /* First we setup out colors in the order they will be used using an array */
  3. colors = ["#ff0000", "#00ff00", "#0000ff", "#ffff00",
  4. // Track clicks
  5.   var clickTest = new RegExp('|' + target + '|', 'i');
  6.   if( ! clickTest.test(beenClicked) ) {
  7.    clicks++;
  8.    beenClicked += (target + '|')
  9.   }


To the function. How can I just have it display the number on the page, not putting it into a database or hidden field?
Thanks
  • joebert
  • Fart Bubbles
  • Genius
  • User avatar
  • Posts: 13503
  • Loc: Florida

Post 3+ Months Ago

A simple way, would be to use the same method you would for a hidden form element, only with a text input instead of the hidden field for this portion.

Code: [ Select ]
// This would set the value of a hidden form input field to ( 5 * clicks)
document.getElementById("clicktracker").value = clicks * 5;
  1. // This would set the value of a hidden form input field to ( 5 * clicks)
  2. document.getElementById("clicktracker").value = clicks * 5;


So, the HTML it targeted may look like this
Code: [ Select ]
<input type="text" id="clicktracker" value="0" />
  • Garibaldi
  • Newbie
  • Newbie
  • User avatar
  • Posts: 13
  • Loc: Wisconsin

Post 3+ Months Ago

I tried implementing that, by adding
Quote:
// This would set the value of a hidden form input field to ( 5 * clicks)

document.getElementById("clicktracker").value = clicks * 5;


Here:
Quote:
/* target paramater will be passed (this.id) from the td onclick events */

function changeColor(target){

// Track clicks

var clickTest = new RegExp('|' + target + '|', 'i');

if( ! clickTest.test(beenClicked) ) {

clicks++;

beenClicked += (target + '|')

}
// This would set the value of a hidden form input field to ( 5 * clicks)

document.getElementById("clicktracker").value = clicks * 5;

/* This checks if the browser is an MSIE browser, if it is it converts the hex value that will be returned from checking the targets background into an rgb string, if not MSIE it uses the value as is, the result from either is assigned to the local variable "swapper" */

And several other places but the input still never changed when I clicked the squares. Here's the page I'm using it on:
http://www.racewaytile.com/index.php?op ... &Itemid=15

Thanks
  • Garibaldi
  • Newbie
  • Newbie
  • User avatar
  • Posts: 13
  • Loc: Wisconsin

Post 3+ Months Ago

I've been working with this script a bit more and decided to refine a bit what I would like it to do. The squares are working well now, but I would like it to display the following things at the top as you click and make changes:
- Number of squares total (times a number, the multiplier from above, it still is giving me trouble)
- Number of squares of each color


How would this be possible? Thanks again for your help!
  • b_zilla
  • Novice
  • Novice
  • b_zilla
  • Posts: 15
  • Loc: Seattle, WA

Post 3+ Months Ago

Hi...pretty new to javascript and hoping someone can answer a question I have on this not-so-current thread.

First, thank you (joebert), for such a cool effect.

What I'd like to do is include a background image in every td (or div) that would undergo a color change using this script. The background image would have transparent areas to allow the color shift to show through. Also, to greater effect, I might wish to use a single, large bground image so a grid of tds or divs would share a single bground image.

I'm pretty certain the script would have to let the background image value pass through on every color change b/c I've tried to include a background image and it will only show it initially.

Is this do-able? Thank you so much for any help!

B
  • Garibaldi
  • Newbie
  • Newbie
  • User avatar
  • Posts: 13
  • Loc: Wisconsin

Post 3+ Months Ago

Do you want to have the same background image on all the cells or different ones for different cells?
  • b_zilla
  • Novice
  • Novice
  • b_zilla
  • Posts: 15
  • Loc: Seattle, WA

Post 3+ Months Ago

It would be great to have the option to do either. :)
  • Garibaldi
  • Newbie
  • Newbie
  • User avatar
  • Posts: 13
  • Loc: Wisconsin

Post 3+ Months Ago

Having the same background image would be easier because all you'd need to do is find where the script generates the code for each <td> and insert a background image:
Code: [ Select ]
<td style="background-image: url(background.jpg);">


Now if you want to get specific about the images, you could use a javascript variable which you can increment each time a <td> is generated. You'd then set up your background images in that sequence, e.g. background0.jpg, background1.jpg.... So for instance the code could look something like this:
Code: [ Select ]
var bgimg = 0;

for (var i = 0; i < 10; i++, bgimg++)
document.write("<td style=\"background-image: url(background" + bgimg + ".jpg);\">");
  1. var bgimg = 0;
  2. for (var i = 0; i < 10; i++, bgimg++)
  3. document.write("<td style=\"background-image: url(background" + bgimg + ".jpg);\">");

Obviously an optimization above would just use the for loop's iterator as the variable but since I don't know how the script does its iteration exactly it would be best to use your own iterator variable
  • b_zilla
  • Novice
  • Novice
  • b_zilla
  • Posts: 15
  • Loc: Seattle, WA

Post 3+ Months Ago

Thanks so much, I'm going to try to work this in.

I may prefer a single large bg image and use bg positioning to allow it to show in all divs properly, but I assume the script wouldn't care what the positioning style was.

Cheers!
  • Garibaldi
  • Newbie
  • Newbie
  • User avatar
  • Posts: 13
  • Loc: Wisconsin

Post 3+ Months Ago

Sure, glad to help! If you're looking to use a single image and positioning, here's a great tutorial on CSS Sprites:
http://alistapart.com/articles/sprites
  • b_zilla
  • Novice
  • Novice
  • b_zilla
  • Posts: 15
  • Loc: Seattle, WA

Post 3+ Months Ago

Thanks again G...however I tried an approach similar to your first example and the problem is that the background will show initially, but won't stick around once onclick or onrollover is actuated.

I'd love the script to be able to pass thru any background image I assign to any given div, but unfortunately I've not been able to get anything to work, including your second suggestion. Any ideas?

Thanks and best regards...
b
  • Garibaldi
  • Newbie
  • Newbie
  • User avatar
  • Posts: 13
  • Loc: Wisconsin

Post 3+ Months Ago

Sure, can you send me a link to your page? I'd like to take a look in Firebug to see what your setup is more specifically
  • b_zilla
  • Novice
  • Novice
  • b_zilla
  • Posts: 15
  • Loc: Seattle, WA

Post 3+ Months Ago

Hi...thanks so much for the fast reply.

Here's a crude prototype that includes 3 obvious background images:

http://theclutch.com/rollover.htm

You can see that I've tweaked it to cycle through colors via a rollover, and the backgrounds are visible initially (but not for long). :)

It would be wonderful if the script could sustain any background image written into a given div.

Grazie!!
  • Garibaldi
  • Newbie
  • Newbie
  • User avatar
  • Posts: 13
  • Loc: Wisconsin

Post 3+ Months Ago

Ok I think this should work. Find:
document.getElementById(target).style.background = colors[xx];

And after add:
document.getElementById(target).style.background-image = "url(" + target + ".gif)";

Now, rename your background image so each image name is the same as the div id so e.g. for the first one, your background image should be a1.gif. See how this works
  • b_zilla
  • Novice
  • Novice
  • b_zilla
  • Posts: 15
  • Loc: Seattle, WA

Post 3+ Months Ago

Thanks for your generous follow up...unfortunately though it breaks the rollover function.

http://theclutch.com/rollover2.htm

Post Information

  • Total Posts in this topic: 23 posts
  • Users browsing this forum: No registered users and 117 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.