Wrox Programmer Forums

Need to download code?

View our list of code downloads.

| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
BOOK: Beginning JavaScript and CSS Development with jQuery
This is the forum to discuss the Wrox book Beginning JavaScript and CSS Development with jQuery by Richard York; ISBN: 9780470227794
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Beginning JavaScript and CSS Development with jQuery section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old May 14th, 2010, 06:33 PM
Friend of Wrox
 
Join Date: Dec 2008
Location: , , .
Posts: 238
Thanks: 2
Thanked 20 Times in 19 Posts
Default IE 7/jquery 1.4.2 checkbox issue

We have a web page that contains a set of check boxes that represent different taxes. There is logic between those taxes, for example, if you charge tax1, you must also charge tax2, etc., and we use check/uncheck related checkboxes. Please see the end of this post for the javascript.

By looking at the code, there is no way for anyone to turn on both gstCheckbox and bulkCheckbox, but one of my colleague managed to do so in IE7. I tried in FF and wasn't able to repeat this issue there.

Can anyone spot anything obvious or have run into similar situation (with IE 7 and jquery)?

Code:
$(document).ready(function() {
    var hstEnabled = $("#ctl00_ContentPlaceHolder_Hst").attr("value");
    if (hstEnabled == "1") {
        $('label[for="ctl00_ContentPlaceHolder_pstCheckBox"]').html("harmonized sales tax");
        $('label[for="ctl00_ContentPlaceHolder_gstCheckBox"]').html("federal sales tax only");
        $("#ctl00_ContentPlaceHolder_lstCheckBox").parent().parent().remove();
        $("#ctl00_ContentPlaceHolder_pstCheckBox").click(function() {
            //enableTaxSection(false);
            if (!$("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked")) {
                $("#ctl00_ContentPlaceHolder_fntCheckBox").attr("checked", false);
                $("#ctl00_ContentPlaceHolder_bulkCheckBox").attr("checked", false);
                turnOffTabacoo();
            } else {
                $("#ctl00_ContentPlaceHolder_gstCheckBox").attr("checked", false);
            }
            //enableTaxSection(true);
        });
        $("#ctl00_ContentPlaceHolder_gstCheckBox").click(function() {
            //enableTaxSection(false);
            if ($("#ctl00_ContentPlaceHolder_gstCheckBox").attr("checked")) {
                $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", false);
                $("#ctl00_ContentPlaceHolder_fntCheckBox").attr("checked", false);
                $("#ctl00_ContentPlaceHolder_bulkCheckBox").attr("checked", false);
                turnOffTabacoo();
            }
            //enableTaxSection(true);
        });
        $("#ctl00_ContentPlaceHolder_fntCheckBox").click(function() {
            //enableTaxSection(false);
            if ($("#ctl00_ContentPlaceHolder_fntCheckBox").attr("checked")) {
                $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", true);
                $("#ctl00_ContentPlaceHolder_gstCheckBox").attr("checked", false);
            } else {
                turnOffTabacoo();
            }
            //enableTaxSection(true);
        });
        $("#ctl00_ContentPlaceHolder_bulkCheckBox").click(function() {
            //enableTaxSection(false);
            if ($("#ctl00_ContentPlaceHolder_bulkCheckBox").attr("checked")) {
                $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", true);
                $("#ctl00_ContentPlaceHolder_gstCheckBox").attr("checked", false);
            }
            //enableTaxSection(true);
        });
        $("#ctl00_ContentPlaceHolder_itemTypeDropDownList").change(function() {
            //enableTaxSection(false);
            if ($("#ctl00_ContentPlaceHolder_itemTypeDropDownList").val() == "18" || $("#ctl00_ContentPlaceHolder_itemTypeDropDownList").val() == "19") {
                $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", true);
                $("#ctl00_ContentPlaceHolder_fntCheckBox").attr("checked", true);
                $("#ctl00_ContentPlaceHolder_gstCheckBox").attr("checked", false);
            }
            //enableTaxSection(true);
        });
    }
});
Reply With Quote
  #2 (permalink)  
Old May 14th, 2010, 09:34 PM
richard.york's Avatar
Wrox Author
Points: 5,506, Level: 31
Points: 5,506, Level: 31 Points: 5,506, Level: 31 Points: 5,506, Level: 31
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Camby, IN, USA.
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
Default

The "checked" attribute is not a boolean value.

Code:
if ($("#ctl00_ContentPlaceHolder_fntCheckBox").attr("checked") == "checked") {
  $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", "checked");
  $("#ctl00_ContentPlaceHolder_gstCheckBox").removeAttr("checked");
}
Reply With Quote
  #3 (permalink)  
Old May 14th, 2010, 09:46 PM
richard.york's Avatar
Wrox Author
Points: 5,506, Level: 31
Points: 5,506, Level: 31 Points: 5,506, Level: 31 Points: 5,506, Level: 31
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Camby, IN, USA.
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
Default

By the way, if you had your heart set on the DOM way, this is how you'd do it:

Code:
if ($("#ctl00_ContentPlaceHolder_fntCheckBox").get(0).checked) {
  $("#ctl00_ContentPlaceHolder_pstCheckBox").get(0).checked = true;
  $("#ctl00_ContentPlaceHolder_gstCheckBox").get(0).checked = false;
}
Since everything in jQuery is an array, the get(0) method retrieves the first match of the query as the DOM node.

You have to retrieve the DOM node in order to set the checked property to a boolean value as you would in plain JavaScript, whereas jQuery's attr() and removeAttr() are used modify the markup attributes using the same attribute values you'd use in markup, e.g., checked="checked".
Reply With Quote
  #4 (permalink)  
Old May 15th, 2010, 02:13 PM
Friend of Wrox
 
Join Date: Dec 2008
Location: , , .
Posts: 238
Thanks: 2
Thanked 20 Times in 19 Posts
Default

Richard thanks for your reply.

I knew that some people dealing with checkboxes your way, but the way in the original post is correct. You can verify that by running the following, and it worked fine for me in IE7, IE8, Firefox, Opera, Chrome and Safari on PC. The issue with the original code is more subtle...
Code:
<head>
	<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.js" type="text/javascript"></script>   
	<script>
		$(document).ready (function () {
			$("#c1").click(function() {
				alert($("#c1").attr("checked"));
				if ($("#c1").attr("checked"))
				{
					$("#c2").attr("checked", true);
					$("#c3").attr("checked", false);
				} else {
					$("#c2").attr("checked", false);
					$("#c3").attr("checked", true);
				}
			});
		});
	</script>
</head>
<body>
<form>
<input type="checkbox" id="c1">
<input type="checkbox" id="c2">
<input type="checkbox" id="c3">
</form>
</body>
</html>

Last edited by PeterPeiGuo; May 15th, 2010 at 02:25 PM..
Reply With Quote
  #5 (permalink)  
Old May 15th, 2010, 02:29 PM
Friend of Wrox
 
Join Date: Dec 2008
Location: , , .
Posts: 238
Thanks: 2
Thanked 20 Times in 19 Posts
Default

If you change that alert statement in my demo code to the following, you can observe the type of the return value, and it is straight boolean in all major browsers (IE7, IE8, Opera, Firefox, Chrome, Safari):
Code:
alert(typeof($("#c1").attr("checked")));
Reply With Quote
  #6 (permalink)  
Old May 15th, 2010, 02:49 PM
richard.york's Avatar
Wrox Author
Points: 5,506, Level: 31
Points: 5,506, Level: 31 Points: 5,506, Level: 31 Points: 5,506, Level: 31
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Camby, IN, USA.
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
Default

I'll have to take your word for it, but when I tested that way of doing it, it did not work. But then again, that was a year and half, two years ago. Perhaps they have changed that in the newer versions of jQuery, and I did not realize it. It definitely used to be the case that it had to match the XHTML way. ;-D

This is another way to look for a checked value:

Code:
if ($("#ctl00_ContentPlaceHolder_fntCheckBox:checked").length)
Reply With Quote
The Following User Says Thank You to richard.york For This Useful Post:
PeterPeiGuo (May 16th, 2010)
  #7 (permalink)  
Old May 16th, 2010, 10:33 AM
Friend of Wrox
 
Join Date: Dec 2008
Location: , , .
Posts: 238
Thanks: 2
Thanked 20 Times in 19 Posts
Default

I thought to double check whether attr("checked") would return string if checked attribute is preset to a string, like "checked", "foo" or "bar", so I tried the following. The good news is that the return value is consistent, and is always boolean. The return value is true as long as checked attribute is set, even if you set it to "" or "false". (Testing was only done with IE 8)
Code:
<!DOCTYPE html>
<html>
<head>
	<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.js" type="text/javascript"></script>   
	<script>
		$(document).ready (function () {
			$("#c1").click(function() {
				alert(typeof($("#c1").attr("checked")));
				if ($("#c1").attr("checked"))
				{
					$("#c2").attr("checked", true);
					$("#c3").attr("checked", false);
				} else {
					$("#c2").attr("checked", false);
					$("#c3").attr("checked", true);
				}
			});
		});
	</script>
</head>
<body>
<form>
<input type="checkbox" id="c1" checked="">
<input type="checkbox" id="c2">
<input type="checkbox" id="c3">
</form>
</body>
</html>

Last edited by PeterPeiGuo; May 16th, 2010 at 10:38 AM..
Reply With Quote
  #8 (permalink)  
Old May 16th, 2010, 12:20 PM
richard.york's Avatar
Wrox Author
Points: 5,506, Level: 31
Points: 5,506, Level: 31 Points: 5,506, Level: 31 Points: 5,506, Level: 31
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Camby, IN, USA.
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
Default

OK, did my own tests, and it seems both methods work with regards to setting a checked attribute.
Code:
  $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", "checked");
  $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", true);
Which makes sense, "checked" simply evaluates to true, which also has the desired result. That is what I originally tested many moons ago when I was trying to figure out how that worked, but you are correct; it is technically a boolean. Sorry for the disinformation there. I recall there being something to why I did it that way, but it's been so long ago and a few versions of jQuery ago, and I can't find anything pointing to that now.

I realize this doesn't answer your original question though. Things are slightly more verbose in your script than they have to be. In your events, you can use the "this" keyword to refer to the node that the event is attached to, and that will work universally, even in IE, and that will save you additional performance penalties for having to look up those nodes again.

Code:
$(document).ready(function() {
    var hstEnabled = $("#ctl00_ContentPlaceHolder_Hst").attr("value");
    if (hstEnabled == "1") {
        $('label[for="ctl00_ContentPlaceHolder_pstCheckBox"]').html("harmonized sales tax");
        $('label[for="ctl00_ContentPlaceHolder_gstCheckBox"]').html("federal sales tax only");
        $("#ctl00_ContentPlaceHolder_lstCheckBox").parent().parent().remove();
        $("#ctl00_ContentPlaceHolder_pstCheckBox").click(function() {
            //enableTaxSection(false);
            if (!this.checked) {
                $("#ctl00_ContentPlaceHolder_fntCheckBox").attr("checked", false);
                $("#ctl00_ContentPlaceHolder_bulkCheckBox").attr("checked", false);
                turnOffTabacoo();
            } else {
                $("#ctl00_ContentPlaceHolder_gstCheckBox").attr("checked", false);
            }
            //enableTaxSection(true);
        });
        $("#ctl00_ContentPlaceHolder_gstCheckBox").click(function() {
            //enableTaxSection(false);
            if (this.checked) {
                $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", false);
                $("#ctl00_ContentPlaceHolder_fntCheckBox").attr("checked", false);
                $("#ctl00_ContentPlaceHolder_bulkCheckBox").attr("checked", false);
                turnOffTabacoo();
            }
            //enableTaxSection(true);
        });
        $("#ctl00_ContentPlaceHolder_fntCheckBox").click(function() {
            //enableTaxSection(false);
            if (this.checked) {
                $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", true);
                $("#ctl00_ContentPlaceHolder_gstCheckBox").attr("checked", false);
            } else {
                turnOffTabacoo();
            }
            //enableTaxSection(true);
        });
        $("#ctl00_ContentPlaceHolder_bulkCheckBox").click(function() {
            //enableTaxSection(false);
            if (this.checked) {
                $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", true);
                $("#ctl00_ContentPlaceHolder_gstCheckBox").attr("checked", false);
            }
            //enableTaxSection(true);
        });
        $("#ctl00_ContentPlaceHolder_itemTypeDropDownList").change(function() {
            //enableTaxSection(false);
            if (this.value == "18" || this.value == "19") {
                $("#ctl00_ContentPlaceHolder_pstCheckBox").attr("checked", true);
                $("#ctl00_ContentPlaceHolder_fntCheckBox").attr("checked", true);
                $("#ctl00_ContentPlaceHolder_gstCheckBox").attr("checked", false);
            }
            //enableTaxSection(true);
        });
    }
});
Thinking through your logic, it doesn't look like it's possible to have both of those checked at the same time. Are there any JavaScript errors that come up? What specific things did your colleague do to arrive at that result? Are you able to reproduce this result?

Another suggestion would be to hand off the setting of your checkboxes to a function instead of doing the setting of your checkboxes directly in the event callback, and then have all of the on/off logic for all possible scenarios laid out in that function. The advantage of doing that is that you are checking the status of every checkbox every time you want to check or uncheck something and there's no way for something to fall through the cracks. For example, if you want one checkbox to be unchecked whenever another is checked, presently, you're looking for that to happen when the checkbox is clicked on, but you aren't applying the same code when you manually set the checkbox through the DOM; you're reimplementing your logic multiple times, which wides the possibility for something to happen in one place, but not in another. Does that make sense?
Reply With Quote
The Following User Says Thank You to richard.york For This Useful Post:
PeterPeiGuo (May 16th, 2010)
  #9 (permalink)  
Old May 16th, 2010, 04:05 PM
Friend of Wrox
 
Join Date: Dec 2008
Location: , , .
Posts: 238
Thanks: 2
Thanked 20 Times in 19 Posts
Default

Thanks for your detailed reply, Richard!

True, I should have used 'this', otherwise the node is looked up again and it is bad for performance.

Talking about the logic, this is actually a typical application of a state machine. At one point, I actually thought of making the code a lot more generic, and detach it from the tax codes entirely. I think that I will do that when I have some spare time, and it could be made into a plugin.

My colleague did capture a screen shot of the issue, and I will check tomorrow whether there is a "script error" icon showing. Don't have access at this point.
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Please I need some help on jquery on usercontrols, thanks... ysfkay ASP.NET 3.5 Professionals 8 August 27th, 2010 09:30 AM
Jquery issue FileFound Javascript How-To 0 December 28th, 2009 07:00 AM
JavaScript vs JQuery skijor ASP.NET 3.5 Basics 4 August 7th, 2009 10:21 AM
XML AND JQUERY pallone BOOK: Beginning JavaScript and CSS Development with jQuery 10 July 10th, 2009 10:08 AM
DGV CheckBox Click Issue obrienkev C# 2005 1 December 17th, 2007 06:04 AM



All times are GMT -4. The time now is 08:53 PM.


Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.