SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Guru mwolfe's Avatar
    Join Date
    Mar 2005
    Posts
    912
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Can't click checkbox this way

    Alright i was able to do all of the things i wanted with my table so far.. or so i thought. What i did was this: I made a table that as its moused over the fields get highlighted.. There is a checkbox in the header used to check all boxes (and also unchecks all). THen i had it set so that if a checkbox was selected, the rows containing them would be highlighted. I then figured well if i have the rows being hilighted as they are moused over, the user should be able to click anywhere in that row to select the checkbox in that row.. so i came up with this script:

    Code:
    function toggle_selected(inputTagReference) {
       var is_checked = inputTagReference.firstChild.firstChild.checked;
       
       if (is_checked) {
    
       	inputTagReference.firstChild.firstChild.checked = false;
          inputTagReference.style.backgroundColor="";
       } else {
          inputTagReference.firstChild.firstChild.checked = true;
          inputTagReference.style.backgroundColor="#A7D2FE";
       }
    It gets called like this
    PHP Code:
    echo "<tr class=\"$class\" onmouseover=\"this.className='highlighted'\" onmouseout=\"this.className='$class'\" onClick=\"toggle_selected(this)\" >"
    So the problem now is that I can't click the actual checkbox because it must first check the checkbox, then it runs this script which looks and sees its already checked, and unchecks it.. although its not like i can see all that but i'm pretty sure thats what is happening.. Anyone have any ideas for getting around this?

  2. #2
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Edit:

    You can put an onclick event hander in the <tr> which toggles the checkbox and changes the highlighting. One problem: if you are mousing over, and you change the highlighting to off in response to a click, the mouseover effect will disappear. To solve that problem, instead of using onclick to immediately change the highlighting, you can use onclick to set a variable that onmouseout reads, e.g.
    Code:
    <tr onmouseout = "set_effect(this)">....</tr>
    Code:
    var mouseoutEffect = "";
    
    function set_effect(trRef);
    {
         trRef.style.backgroundColor = mouseoutEffect;
    }
    
    function tr_onclick(trRef)
    {
        //toggle the checkbox
        
        if(trRef.firstChild.firstChild.checked == true) mouseoutEffect = "yellow";
        else mouseEffect = "";
       
    }
    Last edited by 7stud; Apr 7, 2005 at 03:29.

  3. #3
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There's still a problem if you get the above to work--when you click on the input tag, it's onclick event fires and the checkbox is toggled, but since the checkbox is inside the <tr>, the <tr>'s onclick event also fires, and the <tr>'s onclick event toggles the checkbox back, so the net result is the checkbox won't change at all--making it impossible to check. To solve that, you have to cancel event "bubbling", which has cross browser issues. I'll have to take a look at it some more later.

  4. #4
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    what if you disable the check/uncheck ability of the checkbox and just use the TR handler to set it:

    <input type="checkbox" onclick="return false;">

  5. #5
    SitePoint Guru mwolfe's Avatar
    Join Date
    Mar 2005
    Posts
    912
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    this didnt work for some reason:
    <input type="checkbox" onclick="return false;">
    it didnt do anything..
    however i tried this which did almost what i wanted:
    <td align='center'><input type='checkbox' name='index[]' value='$row[$index_column]' onClick=\"this.checked=false;\"/></td>";

    hoewver the problem is that you can't uncheck the box when clicking it now.. i tried to write a function that basically toggle the checkbox opposite how it is supposed to work but that did nothing..

  6. #6
    SitePoint Guru mwolfe's Avatar
    Join Date
    Mar 2005
    Posts
    912
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    any other ideas?

  7. #7
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here:

    Code:
    <html>
    <head>
    <script language="JavaScript">
    function checkMe(thing) {
    	if( thing.tagName.toLowerCase() == "tr" ) {
    		checkbox = thing.firstChild.firstChild;
    		tr = thing;
    		checkbox.checked = !checkbox.checked;
    	} else {
    		checkbox = thing;
    		tr = thing.parentNode.parentNode;
    	}
    	
    	if( checkbox.checked ) {
    		tr.style.backgroundColor = "#00FF00";
    	} else {
    		tr.style.backgroundColor = "";
    	}
    }
    </script>
    </head>
    <body>
    <table>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>1</td></tr>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>2</td></tr>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>3</td></tr>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>4</td></tr>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>5</td></tr>
    </table>
    </body>
    </html>

  8. #8
    SitePoint Guru mwolfe's Avatar
    Join Date
    Mar 2005
    Posts
    912
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    this almost works.. does the same thing as when i added an onlick event to the checkbox : onClick="this.checked=false".. i believe thats what i had.. Everything works, except unchecking by clicking the checkbox.. i'll see if i can add the logic to this version though to fix this.. if anyone see's an obvious solution let me know. Thanks for all your help

    edit..
    actually this doesnt work for checking or unchecking by clicking the actual checkbox.. the only reason why it was working the first time was because i had accidently left my old onclick reference for the checkbox.. I changed everything and it still wouldn't work.. and also tried just testing the code by itself with the same results.. no javascript errors come up. i'm wondering if something isnt backwards though..

  9. #9
    SitePoint Guru mwolfe's Avatar
    Join Date
    Mar 2005
    Posts
    912
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    alright sorry about that.. i did figure it out.. the above code is missing one simple line and everything works perfect..

    HTML Code:
     <html>
    <head>
    <script language="JavaScript">
    function checkMe(thing) {
    	if( thing.tagName.toLowerCase() == "tr" ) {
    		checkbox = thing.firstChild.firstChild;
    		tr = thing;
    		checkbox.checked = !checkbox.checked;
    	} else {
    		checkbox = thing;
    		tr = thing.parentNode.parentNode;
    checkbox.checked = !checkbox.checked;
    	}
    	
    	if( checkbox.checked ) {
    		tr.style.backgroundColor = "#00FF00";
    	} else {
    		tr.style.backgroundColor = "";
    	}
    }
    </script>
    </head>
    <body>
    <table>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>1</td></tr>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>2</td></tr>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>3</td></tr>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>4</td></tr>
    <tr onclick="checkMe(this);"><td><input type="checkbox" onclick="checkMe(this);"></td><td>5</td></tr>
    </table>
    </body>
    </html>

  10. #10
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's a clever solution jim fraser w/ mwolfe modification. It essentially cancels bubbling for for the checkbox: if the user clicks the checkbox to put a check in it, the checkbox's onclick function unchecks it, and then when the event bubbles up to the <tr>, the <tr>'s onclick function checks the checkbox. There are also properties of the event object that you can set to cancel bubbling.

    Great variable and function names as well--it makes it very easy to read the code.

    Here are a few comments I have:

    1)Be aware that in Mozilla, this won't work:

    checkbox = thing.firstChild.firstChild;

    unless the html for the <tr>'s is all on one line. For instance, if you do this
    Code:
    <tr onclick="checkMe(this);">
    <td><input type="checkbox" onclick="checkMe(this);"></td>
    <td>3</td>
    </tr>
    the newlines create invisible textNodes, which mess up the position of the checkbox, and it won't be found at thing.firstChild.firstChild. That can be solved by using:

    checkbox = thing.getElementsByTagName("input")[0];

    where getElementsByTagName("input") gets an array of all the <input> elements in 'thing', and [0] fetches the first one.

    2)There is no reason you have to go to all the trouble of adding onclick event handlers in all the html elements, especially if you have hundreds of them. You can assign them programmatically like this:
    Code:
    window.onload=function()
    {
    	var checkboxes = document.getElementById("my_table").getElementsByTagName("input")
    	for(var j = 0, len = checkboxes.length; j < len; j++)
    	{
    		checkboxes[j].onclick = checkMe;
    	}
    };
    That format has two other advantages: 1) it serves to separate the html and js, which is good programming practice, and 2) inside the event handler functions, the 'this' keyword will automatically refer to the element that was clicked or moused over, so you don't have to pass a 'this' reference to the function. With functions that aren't assigned to event handlers like that, 'this' will refer to the window.

    4)A minor point, but I don't see any reason to make 'checkbox' and 'tr' global variables. Instead, you can do this:
    Code:
    function checkMe(thing) {
    	var checkbox, tr;
    
    	if( thing.tagName.toLowerCase() == "tr" ) {
    		checkbox = thing.firstChild.firstChild;
    		tr = thing;
    		checkbox.checked = !checkbox.checked;
    	} else {
    		checkbox = thing;
    		tr = thing.parentNode.parentNode;
    	}
    	
    	if( checkbox.checked ) {
    		tr.style.backgroundColor = "#00FF00";
    	} else {
    		tr.style.backgroundColor = "";
    	}
    }
    5) <script language="JavaScript"> ----><script type="text/javascript">

    mwolfe,

    Were you able to integrate that script with your onmouseover and your check all checkbox? In my script, I found integrating all the events to be very tricky.
    Last edited by 7stud; Apr 8, 2005 at 03:31.


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
  •