PDA

View Full Version : jQuery checkboxes



bigalo
03-09-2010, 09:31 PM
Hello,

I hope someone can help. I have some jQuery code to add and remove a class to toggle an image. It works for one but now I want it to work if I add other checkboxes. Currently all the checkboxes change the 1st div. I would like to make it toggle it's respective div. Any help would be great!


Thanks in advance!



<html>
<head>
<title>jquery to Show/Hide a Div</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){

$("input").removeAttr("checked");


$("input").click(function(){


if ($(this).is(":checked"))
{
$("#action").addClass("clipped");
}
else
{
$("#action").removeClass("clipped");
}


});

});
</script>
<style type="text/css">
#checkme { float:left;}
#action { float:left;}
.clip {
background:transparent url(http://download3.coupons.com/7/19/7125/1450/print.coupons.com/CouponWeb/Themes/CM_BigBlue/_images/clip.gif) no-repeat scroll 0 0;height:24px;margin:0;text-indent:-9999px;width:75px;}
.clipped {background-position:0 -24px;}
</style>
</head>
<body>
<form>
<div style="width:196px;">
<input id="checkme" type="checkbox" /><div id="action" class="clip"></div>
<input id="checkme" type="checkbox" /><div id="action" class="clip"></div>
<input id="checkme" type="checkbox" /><div id="action" class="clip"></div>
<input id="checkme" type="checkbox" /><div id="action" class="clip"></div>
</div>
</form>
</body>
</html>

jscheuer1
03-10-2010, 04:39 AM
According to standards, only one element per page is allowed to have any given id. But that's not critical to solving this issue. What you appear to need is a way of distinguishing among the various sets of elements you are targeting with your functions:



if ($(this).is(":checked"))
{
$("#action").addClass("clipped");
}
else
{
$("#action").removeClass("clipped");
}

If you address (include) all elements with the id action (it should be a class, but that won't change what happens enough to fix this), you will get them all (if sticking with id, you will either get an error or just the first one).

So, as I was saying, we need a way to distinguish which elements we include in the response (highlighted in the above), so as to only pull in those we want to change.

Give this version a shot:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>jQuery to Position Background Sprite</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
.checkme, .clip {
float: left;
}
.clip {
background-image: url('http://download3.coupons.com/7/19/7125/1450/print.coupons.com/CouponWeb/Themes/CM_BigBlue/_images/clip.gif');
height: 24px;
width: 75px;
}
.clipped {
background-position: 0 -24px;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function($){
$('.checkme').attr('checked', false).click(function(){
if(this.checked){
$(this).next().addClass('clipped');
} else {
$(this).next().removeClass('clipped');
}
});
$('.clip').click(function(){
var p = this.previousSibling;
p.checked = !p.checked;
$(p).click();
p.checked = !p.checked;
});
});
</script>
</head>
<body>
<form action="#">
<div style="width:196px;">
<input class="checkme" type="checkbox"><div class="clip"></div>
<input class="checkme" type="checkbox"><div class="clip"></div>
<input class="checkme" type="checkbox"><div class="clip"></div>
<input class="checkme" type="checkbox"><div class="clip"></div>
</div>
</form>
</body>
</html>

Or even (more precise, compact, and jQuery-ish):


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>jQuery Sprite Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
.clips {
width: 196px;
}
.checkme, .clip {
float: left;
}
.clip {
background-image: url('http://download3.coupons.com/7/19/7125/1450/print.coupons.com/CouponWeb/Themes/CM_BigBlue/_images/clip.gif');
height: 24px;
width: 75px;
}
.clipped {
background-position: 0 -24px;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function($){
function togAttr(index, attr){return !attr;}
$('input.checkme').removeAttr('checked').click(function(){
$(this).next('div.clip')[this.checked? 'addClass' : 'removeClass']('clipped');
});
$('div.clip').click(function(){
$(this).prev('input.checkme').attr('checked', togAttr).click().attr('checked', togAttr);
});
});
</script>
</head>
<body>
<form action="#">
<div class="clips">
<input class="checkme" type="checkbox"><div class="clip"></div>
<input class="checkme" type="checkbox"><div class="clip"></div>
<input class="checkme" type="checkbox"><div class="clip"></div>
<input class="checkme" type="checkbox"><div class="clip"></div>
</div>
</form>
</body>
</html>

bigalo
03-10-2010, 02:06 PM
Thanks John! this is exactly what I was looking for. Works perfectly! I actually found a shorter solution.



<script type="text/javascript">
$(document).ready(function(){

$("input").removeAttr("checked");


$("input").click(function(){


if ($(this).is(":checked"))
{
$(this).next('div').addClass("clipped");
}
else
{
$(this).next('div').removeClass("clipped");
}


});

});
</script>





<input id="checkme" type="checkbox" /><div class="clip"></div>
<input id="checkme" type="checkbox" /><div class="clip"></div>
<input id="checkme" type="checkbox" /><div class="clip"></div>
<input id="checkme" type="checkbox" /><div class="clip"></div>



Cheers!

jscheuer1
03-10-2010, 02:54 PM
Ah, but you still have non-standard markup. My second version is actually shorter:


jQuery(function($){
$('input.checkme').removeAttr('checked').click(function(){
$(this).next('div.clip')[this.checked? 'addClass' : 'removeClass']('clipped');
});
});

These bits:


function togAttr(index, attr){return !attr;}

and:


$('div.clip').click(function(){
$(this).prev('input.checkme').attr('checked', togAttr).click().attr('checked', togAttr);
});

are only required for increased functionality. With them clicking on the divisions also changes the checked state of the checkboxes and adds or removes the class clipped from the divisions.

Where you do:


$("input").removeAttr("checked");


$("input").click(function(){


if ($(this).is(":checked"))
{
$(this).next('div').addClass("clipped");
}
else
{
$(this).next('div').removeClass("clipped");
}

You are creating a jQuery for 'this' twice for each click, and a jQuery for 'input' twice. I have:


$('input.checkme').removeAttr('checked').click(function(){
$(this).next('div.clip')[this.checked? 'addClass' : 'removeClass']('clipped');
});

Only one for each. This may seem like a small difference, but in longer code it will add up, increasing execution time. The reason I use 'input.checkme' and 'div.clip' instead of just 'input' and 'div' is that your markup likely will grow to include other inputs possibly followed by other divs that shouldn't receive this treatment.

bigalo
03-10-2010, 03:40 PM
Very nice!!! Thanks so much!