JS & buttons

JavaScript and client side scripting.

Moderator: General Moderators

Post Reply
al3xandar
Forum Newbie
Posts: 15
Joined: Tue Dec 16, 2008 3:05 pm

JS & buttons

Post by al3xandar »

I'm developing a new on-line questionnaire, and I have several problems concerning HTML, CSS & JS interaction. I'm trying to put up several buttons in a table row, with stylish CSS :hover pseudoclass, hence make those buttons capable of changing colour with "onclick" event. I figured out that this can ONLY be done through JavaScript, because of CSS-JS conflict.
I want to make users able to give an answer to some question by clicking on the button, and for feedback purposes, when they click on that button, it changes colour e.g. to blue (default colour: gray). If they click on the another button in the same row, that button changes colour (blue), while the other buttons switch to default gray. Currently I mannaged to write JS script that changes button colour with onmouseover and onmouseout event - similar to :hover pseudoclass in CSS, and also with onclick event. Suppose that a button is gray when mouse is out (default), green when mouse is over, and blue on click. The problem is: on button click, colour changes to blue, on mouse out colour switches to default, and while hovering, it's green. Complete madness!!!
I would like to retain that clicked-blue colour!!! How?!?

I reckon that I've confused you a bit, but what I want to do is quite simple: write a JavaScript function(s) that make(s) buttons gray by default (mouseover), green while hovering, and blue on click. If a user clicks another button, it becomes blue, the others switch to default (gray), and green hover colour remains while moving mouse over the buttons.

In order to present you the problem(s) I'm struggling with, I'll post HTML, CSS and JavaScript codes, respectively. Here goes:

HTML code:

Code: Select all

 
<html>
<body>
<div>
<table>
<tr>
<td><input type = "button" id = "button11" class = "button" value = "one" 
onmouseover = "btClick('button11','#B4DB6F')" 
onmouseout = "btClick('button11','#BFBFBF')" 
onclick = "btClick('button11','#0788C3')"><td>
<td><input type = "button" id = "button12" class = "button" value = "two" 
onmouseover = "btClick('button11','#B4DB6F')" 
onmouseout = "btClick('button11','#BFBFBF')" 
onclick = "btClick('button12','#0788C3')"><td>
<td><input type = "button" id = "button13" class = "button" value = "three" 
onmouseover = "btClick('button11','#B4DB6F')" 
onmouseout = "btClick('button11','#BFBFBF')" 
onclick = "btClick('button13','#0788C3')"><td>
</tr>
<tr>
<td><input type = "button" id = "button21" class = "button" value = "four" 
onmouseover = "btClick('button11','#B4DB6F')" 
onmouseout = "btClick('button11','#BFBFBF')" 
onclick = "btClick('button21','#0788C3')"><td>
<td><input type = "button" id = "button22" class = "button" value = "five" 
onmouseover = "btClick('button11','#B4DB6F')" 
onmouseout = "btClick('button11','#BFBFBF')" 
onclick = "btClick('button22','#0788C3')"><td>
<td><input type = "button" id = "button23" class = "button" value = "six" 
onmouseover = "btClick('button11','#B4DB6F')" 
onmouseout = "btClick('button11','#BFBFBF')" 
onclick = "btClick('button23','#0788C3')"><td>
</tr>
</table>
</div>
<body>
<html>
 
CSS code:

Code: Select all

 
input.button{
color:white;
background-color:#BFBFBF;
width:60px;
height:25px;
border:0px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
}
 
JavaScript code:

Code: Select all

 
function btClick(idbut, col) {
    var butt = document.getElementById(idbut);
    butt.style.backgroundColor = col;
}
 
User avatar
kaszu
Forum Regular
Posts: 749
Joined: Wed Jul 19, 2006 7:29 am

Re: JS & buttons

Post by kaszu »

Instead I would use CSS classes to define colors, in javascript just changing classNames.

Code: Select all

<table id="myTable">
<tr>
    <td><input class="button" type="button" /></td><td><input class="button" type="button" /></td><td><input class="button" type="button" /></td>
</tr>
<tr>
    <td><input class="button" type="button" /></td><td><input class="button" type="button" /></td><td><input class="button" type="button" /></td>
</tr>
...
</table>

Code: Select all

 
input.button{
    color:white;
    background-color:#BFBFBF;
    width:60px;
    height:25px;
    border:0px;
    -moz-border-radius:5px;
    -webkit-border-radius:5px;
}
input.selected {
    background-color: blue;
}
input.hover {
    /* Since .hover has the same 'importance' but it is lower in CSS (line number), then if button has .selected and .hover then background will be green */
    background-color: green;
}
 

Code: Select all

 
//Returns all buttons in the same row
function getAllButtons (button) {
    var nodeTr = button.parentNode.parentNode;  //Get TR element
    var allButtons = nodeTr.getElementsByTagName('INPUT');  //Get all buttons
    return allButtons;
}
 
//Handle onmouseover event
function onMouseOver ()  {
    addClassName(this, 'hover');  //Add class 'hover'
}
 
//Handle onmouseout event
function onMouseOut ()  {
    removeClassName(this, 'hover');  //Remove class 'hover', 
}
 
//Handle onclick event
function onClick ()  {
    var buttons = getAllButtons(this); //Get all buttons, which are on the same row
    for(var i=0,j=buttons.length; i<j; i++) {
        removeClassName(buttons[i], 'selected');  //Remove 'selected' class from all buttons
    }
    addClassName(this, 'selected');  //Add 'selected' to current button
}
function addEvents () {
    var table = document.getElementById('myTable');
    var buttons = table.getElementsByTagName('INPUT');
 
    for(var i=0,j=buttons.length; i<j; i++) {
        buttons[i].onmouseover = onMouseOver;  //on mouse over will add 'hover' class to the button
        buttons[i].onmouseout = onMouseOut;      //on mouse out will remove 'hover' class from the button
        buttons[i].onclick = onClick;    //on click remove 'selected' class from all buttons and add it to the button which was clicked
    }
}
addEvents();  //Add onmouseover, onmouseout and onclick event handlers to the buttons
 
Edit: I didn't included addClassName and removeClassName functions, since they can be easily found on the net (will be good exercise if you decide to write them by yourself) :)
al3xandar
Forum Newbie
Posts: 15
Joined: Tue Dec 16, 2008 3:05 pm

Re: JS & buttons

Post by al3xandar »

Brilliant! This saved me a dozens of headaches... The whole questionnaire thing is based on simple form input, and what I used to do is just putting a radio button within <td> and simulating a button effect - I even wrote a js that selects radio button when you click on the <td> element... Anyway, that was lousy...

Thanks a lot @kaszu! This was sublime!!! Be sure to PM me your mail/site address/contact... when I finish this whole mess with my questionnaire, I would like to make... let's say... a little act of gratitude! Of course, if you agree!
:wink:

However, I get this error in Error Console:
table is null
And I've managed addClassName & removeClassName functions:

Code: Select all

 
//Add class name
function addClassName (objId, className) {
    var obj = document.getElementById(objId);
    obj.className = className;
}
 
//Remove class name
function removeClassName(e,t) {
    if (typeof e == "string") {
        e = xGetElementById(e);
    }
    //code to change and replace strings
    var ec = ' ' + e.className.replace(/^s*|s*$/g,'') + ' ';
    var nc = ec;
    t = t.replace(/^s*|s*$/g,'');
    //check if not already there
    if (ec.indexOf(' '+t+' ') != -1) {
        //found, so lets remove it
        nc = ec.replace(' ' + t.replace(/^s*|s*$/g,'') + ' ',' ');
    }
    //return the changed text!
    e.className = nc.replace(/^s*|s*$/g,''); //trimmed whitespace
    return true;
}
 
Any idea why this is happening?! JS cannot get a table ID...
:(
User avatar
kaszu
Forum Regular
Posts: 749
Joined: Wed Jul 19, 2006 7:29 am

Re: JS & buttons

Post by kaszu »

A little critique: both functions (addClassName / removeClassName) should accept same arguments for consistency. For example addClassName as first argument expects string and won't work with html node, while removeClassName can handle both.

Your addClassName will replace className, not add :(

Code: Select all

function addClassName (objId, className) {
    var obj = objId;
    if (typeof obj == 'string') {
        obj = document.getElementById(objId);
    }
    if (obj.className.length) {
        obj.className += ' ' + className; //Add
    } else {
        obj.className = className; //It's empty, so we can replace it
    }
}
Recheck if table ID matches what is in getElementById (case is important)!
al3xandar
Forum Newbie
Posts: 15
Joined: Tue Dec 16, 2008 3:05 pm

Re: JS & buttons

Post by al3xandar »

Thanks for critiques... and I've figured out that I can fix all this mess by just assigning 2 classes to buttons, while each class has one pseudoclass assigned to it... for example:

Code: Select all

 
.normal{
color:black;
background-color:E5E5E5;
}
 
.normal:hover{
color:white;
background-color:#BFBFBF;
}
 
.selected{
color:white;
background-color:#0788C3;
}
 
.selected.hover{
color:white;
background-color:#B4DB6F;
}
 
I'll try to write those functions by myself... I really need more practice in JS, since I consider myself primarily a PHP "programmer"...
Thanks once again!!!
al3xandar
Forum Newbie
Posts: 15
Joined: Tue Dec 16, 2008 3:05 pm

Re: JS & buttons

Post by al3xandar »

I've managed to do it... very raw & simple code, IMHO, but it works!
Here goes:

Code: Select all

 
<html>
<head>
<script type="text/javascript">
<!--
 
function switchIt(objId, rId, cId) {
    var thisOne = objId + rId + cId;
    var rowBut = objId + rId;
    var but = document.getElementById(thisOne);
    
    
    for(i = 1; i <= 5; i++) {
        var foo = rowBut + i;
        var foos = document.getElementById(foo)
        foos.className = 'normal';
    }
    
    but.className = 'selected';
    
}
 
// -->
</script>
<style type = "text/css">
 
body{
margin-top:20%; 
margin-bottom:25%;
margin-left:25%;
margin-right:25%;
}
 
input{
width:50px; 
height:50px;
-moz-border-radius:10px;
}
 
 
.normal{
color:black;
background-color:E5E5E5;
}
 
.normal:hover{
color:white;
background-color:#BFBFBF;
}
 
.selected{
color:white;
background-color:#0788C3;
}
 
.selected:hover{
color:white;
background-color:#B4DB6F;
}
 
button::-moz-focus-inner,
input[type="reset"]::-moz-focus-inner,
input[type="button"]::-moz-focus-inner,
input[type="submit"]::-moz-focus-inner,
input[type="file"] > input[type="button"]::-moz-focus-inner {
    border: none;
}
 
* {
outline: 0;
}
 
</style>
</head>
<body>
<center>
<table>
    <tr>
        <td><input type = "button" class = "normal" id = "but11" onclick = "switchIt('but',1,1)"></td>
        <td><input type = "button" class = "normal" id = "but12" onclick = "switchIt('but',1,2)"></td>
        <td><input type = "button" class = "normal" id = "but13" onclick = "switchIt('but',1,3)"></td>
        <td><input type = "button" class = "normal" id = "but14" onclick = "switchIt('but',1,4)"></td>
        <td><input type = "button" class = "normal" id = "but15" onclick = "switchIt('but',1,5)"></td>
    </tr>
    <tr>
        <td><input type = "button" class = "normal" id = "but21" onclick = "switchIt('but',2,1)"></td>
        <td><input type = "button" class = "normal" id = "but22" onclick = "switchIt('but',2,2)"></td>
        <td><input type = "button" class = "normal" id = "but23" onclick = "switchIt('but',2,3)"></td>
        <td><input type = "button" class = "normal" id = "but24" onclick = "switchIt('but',2,4)"></td>
        <td><input type = "button" class = "normal" id = "but25" onclick = "switchIt('but',2,5)"></td>
    </tr>
</table>
</center>
</body>
</html>
 
Post Reply