Setting a Conditional Breakpoint in Firefox with Firebug

Every once in a while I click randomly on something and realize that I’ve been an idiot. OK, sometimes it doesn’t require clicking on anything.

First off, if you’re working on client side code and you aren’t using Firefox with the Firebug add on, you should be. It gives you all the debugging capability that you need to win. (Some others swear by Chrome, but I’ve been developing with Firefox for a long time.)


Everyone else has probably known this for millennia, but I just figured out today that I can set a conditional breakpoint in Firebug. If you right click on a line where you’ve set a breakpoint (this was my random click), you get a syntax menu that looks something like this:

Firebug Breakpoint Context Menu

By selecting Edit Breakpoint Condition… you can add any valid JavaScript condition. Here’s one I used to break when I was processing row 55 in a loop:

Firebug Conditional BreakpointSetting a condition like this is really useful, especially when you know that item 55 out of 4645 is causing an error and you just want to step through your script for that item.

There’s more to conditional breakpoints in Firebug [I know now], as you can read in the Firebug Tip: Conditional Breakpoints post on the Firebug blog.

Perhaps because I’m old school, while I’ve truly wanted to be able to set conditional breakpoints like this I’ve simply changed my indices or put in conditional debugging statements. I’ve gotten by just fine, but I’m going to be a lot more efficient now. If you didn’t know about this little trick, then hopefully you’ll be more efficient now, too.

Or maybe I’m just an idiot.

Attribute Change Detection for SharePoint 2010 Row Selection

SharePoint 2010 has some quirky architecture to handle row selection in list views. We’re all familiar with this from navigating around lists. In the list views, we have a few choices on how we select rows to work with (depending on the list view settings):

  • Clicking the checkbox to the left of each item
  • Clicking on the row itself to highlight and select/deselect it
  • Clicking on the checkbox in the title row to toggle ”’Select or deselect all items’

List View Row SelectionThe are times when we’d like to be able to intercept those actions so that we can manage other content in the page. It’s not so simple if you’d like it to work across browsers.

In this example, we were building a performance review capability into My Sites. Each person would set goals by adding items to the Goals list and then they and others could comment on those goals in a Comments list. It was more complicated than this, but you get the idea.

One of the complexities was that we didn’t want to allow comments on draft goals, and there were several other limiting circumstances as well. Suffice it to say that we needed to catch any of the events above so that we could count up various characteristics of the selected goals and change the behavior of other list views and links on the page. Trust me when I say that simple old Web Part Connections didn’t hack it; we needed some custom script to tie it all together.

For this post, please consider all of the code snippets examples, as your environment may well vary. (I shouldn’t need to say this, but I get a lot of “this didn’t work for me when I copy/pasted it into my page” comments.)

Getting this to work in Internet Explorer was relatively simple.

// You'd use your unique Web Part id here
var goalsWP = $("#WebPartWPQ2");
var goalCheckboxes = $("input.s4-itm-cbx");
var goalRows = $("");
var goalSelectAll = goalsWP.find("input[title='Select or deselect all items']");

// When the user checks a goal's checkbox...
goalCheckboxes.change(function() {
// ...or clicks on the goal's row to select... {
// ...or clicks the 'Select or deselect all items' checkbox...
goalSelectAll.change(function() {

The countSelected() function does all the stuff we need, but the contents of the function don’t really matter for this post.

The problem came when we started looking at things in Firefox and Safari on PCs and Safari on Macs. All of the browsers have slightly different behavior when it comes to bubbling up events. We went through several iterations on this which would fix things in one browser while breaking them in another.

When I looked to the Web for some hints, I found a great post from Darcy Clarke. What we needed was very similar to what Darcy has done in his .watch() jQuery function. In his case, he wanted to detect CSS changes to elements, perhaps the background color changing. In our case, it was more than just a CSS change, but his code formed a good basis. Someone named Frank posted some tweaks to Darcy’s original function that made it work with any element attributes, not just CSS changes.

This is an area where the browsers are fairly different, unfortunately. IE has its unique propertychange event, where the other browsers have their quirks as well, though DOMAttrModified is sometimes supported. The article points out that DOMAttrModified is not universally supported yet, though – perhaps not yet in Chrome and Safari – though the article is a bit dated. The fallback is to attach a check to the element using setInterval. This latter approach is expensive, so it should be the last resort.

In the case of the row selection in SharePoint list views, we can rely on the fact that each tr’s class will change from “ms-itmhover” to “ms-itmhover s4-itm-selected” when the row is selected. All this comes down to the odd way Microsoft has set up the selection behavior using a row click and highlight, which is using table rows rather than divs.

What I ended up with is actually pretty good, and I expect I’ll use it again. This isn’t the first time I’ve wanted to watch a DOM element for *any* change, and not just an event-triggering one. It’s an adapted version of Darcy’s .watch() function, with Frank’s additions, tweaked to use feature detection rather than the deprecated (removed in modern versions) of jQuery’s $.browser function. On top of that, to prevent a ridiculous number of calls to countSelected(), which is doing some reasonably heavy lifting, I added an additional check to make absolutely sure that the class has changed by saving the current class into data on the row element and checking it on each firing. It doesn’t seem as though this should be necessary, but I was seeing .watch() fire quite a few more times that I needed.

Here’s the resulting code to detect the different types of user actions:

// When the user checks a goal's checkbox...
goalCheckboxes.change(function() {
// ...or clicks on the goal's row to select..."class", function() {
  // Make sure the class has actually changed
  if($(this).data("class") !== $(this).attr("class")) {
    $(this).data("class", $(this).attr("class"));
// ...or clicks the 'Select or deselect all items' checkbox...
goalSelectAll.change(function() {

And the revised .watch() function:

$ = function (props, callback, timeout) {
  if (!timeout)
    timeout = 10;
  return this.each(function () {
    var el = $(this),
    func = function () {, el)
    data = {
      props : props.split(","),
      func : callback,
      vals : []
    $.each(data.props, function (i) {
      data.vals[i] = (!el.css(data.props[i]) ? el.attr(data.props[i]) : el.css(data.props[i]));
    if (typeof(this.onpropertychange) == "object") {
      el.bind("propertychange", callback);
    } else if (this.DOMAttrModified) {
      el.bind("DOMAttrModified", callback);
    } else {
      setInterval(func, timeout);
  function __check(el) {
    var data =,
    changed = false,
    temp = "";
    for (var i = 0; i < data.props.length; i++) {
      temp = (!el.css(data.props[i]) ? el.attr(data.props[i]) : el.css(data.props[i]));
      if (data.vals[i] != temp) {
        data.vals[i] = temp;
        changed = true;
    if (changed && data.func) {, data);

But Is jQuery Already Loaded?


JQuery (Photo credit: Wikipedia)

Many end users are taking advantage of all of the goodness that jQuery provides, whether by adding simple effects like a sliding Quick Launch, more sophisticated form enhancements like SPCascadeDropdowns from SPServices, or even writing their own scripts for more complex solutions. More than ever, the distinction between “end user” and “developer” is blurring. IMO, that’s a good thing, but it also introduces complications, of course.

As one of those end users, you owe it to yourself to talk to your SharePoint team to explain what you are doing and to find out if jQuery is already loaded in the environment. In many cases, it will already be loaded in the master page or a page layout so that it is readily available across the Site Collection. The version that is loaded can also have an impact on how plugins function, making some of them effectively useless if there’s a version mismatch.

I know that in some cases, even finding the person who might know what’s loaded in the master page or what the plans may be is well nigh impossible. In those cases, here’s a trick to find out what’s up.

In a Internet Explorer browser window with the page you want to work with open, hit F12 to open the Developer Tools, and go to the Console. The screenshot below is from IE9, where there is a separate Console tab:


If you’re in IE8, the Console is hidden under the Script tab, as below.


If you’re in an older version of IE, well, I don’t have a screenshot for you. You may also not have the Developer Tools available, as it was a separate download with IE7 and below.

In Firefox, you’ll need the firebug add-in. If you have it, you can hit F12 to open Firebug. The Console tab is the first one on the left:


Once you’ve gotten to the Console, wherever it is, type the line I show in each of the screenshots above:


Depending on where you are, you’ll then either hit enter or click on the Run button.

Somewhere on the screen, you’ll see a display like this one, which shows that jQuery version 1.7.1 is loaded…


…or you’ll see something like…


…which tells you that jQuery isn’t loaded at all.

At that point, at least you’ll know what you are dealing with. If the version number isn’t what you need (I sometimes still see jQuery 1.3.2 loaded in a master page, which is ancient) then you’ll need to talk to your SharePoint team about updating it.

Tip ‘o the skimmer to Matt Bramer (@ionline247) for the exact syntax…!/iOnline247/status/200574868524236800

…and @BinaryJam for asking the question in the first place!!/BinaryJam/status/200566890437951488

Enhanced by Zemanta

Problem with jQuery 1.7+ and SPServices

<UPDATE dateTime=”2012-12-04″>

This issue is resolved in v0.7.0+. See this post for more details, including the SPFilterNode function. </UPDATE>

<UPDATE dateTime=”2011-11-15T11:59GMT-1″>

Steve Workman has come up with a much improved way to do the selecting for things like z:row in general – it’s much faster, as Steve’s statistics show – and it also works with jQuery 1.7. I’ve added it to the latest alpha for v1.6.3 (which I will probably rename v0.7.0). More details to come, but this issue is going to be resolved in the upcoming release of SPServices.


Alert reader Dustin Meany pinged me yesterday with a brief email through this blog: — I think you should update the documentation for SPServices…

Ah, if the issue were only as small as his email. The ticket on the jQuery site talks about the fact that the notation that I’ve been recommending to parse through the results of a call to the Web Services, like:

$(xData.responseXML).find("[nodeName='z:row']").each(function() {
  // Do something

is no longer valid in jQuery 1.7.

I’ve confirmed in my main test pages that jQuery 1.7 no longer matches on any z:rows in calls to GetListItems. That breaks the majority of the “value added” functions in SPServices. The [nodeName='z:row'] notation has proved highly useful to ensure cross-browser compatibility, and that was the reason I’ve been recommending it in the first place. Because GetListItems uses the somewhat odd namespace of z:row, not all browsers react the same way. Of course GetListItems is the single most used Web Service operation with SPServices. Most of the other operations, which are used less often, do not use this type of namespace.

So the question is how we as a development community handle this. Based on the suggestion in the jQuery ticket, I could implement a function in SPServices itself that probably will solve the issues for the SPServices value-added functions. There are only ten calls in SPServices at the moment that use the [nodeName='z:row'] notation. However, there are thousands of you out there who have your own custom scripts written on top of SPServices that will break if you move to jQuery 1.7+.

The suggestion of switching to the .find("z\\:row, row") notation may work. I’ve quickly tested it with IE9, Chrome 15, Safari 5.1, and Firefox 7.0, all on my Windows 7 laptop. I don’t trust my cursory test, of course; there’s more work to do.

I hold no sway over the jQuery development team. They make their decisions without any knowledge of my little SPServices library or probably even SharePoint.

This, along with the XSL timeout issue I wrote about yesterday, may prove to be a big blow to those of us who choose to develop in SharePoint’s Middle Tier. As the standard bearer for this little movement, I can only do so much to make noise about how important and useful these development techniques are. When these types of roadblocks are put up, there’s little I can do to change things.

DOM Inspectors for Different Browsers

I’ve been using the Internet Explorer Developer Toolbar for years with Internet Explorer 7 and below.  When Internet Explorer 8 came out, it had these tools baked right in and called the Developer Tools.  (You can activate the Developer tools by hitting F12 in IE8.)

But what if you need to peek into the DOM with Safari or Firefox?  Here are the tools for the Windows platform:


From Safari help:

To examine the resources of a webpage:

  1. Open the website, and then choose Develop > Show Web Inspector. The Web Inspector’s sidebar lists the categories of resources found on the page, such as documents, style sheets, and scripts.

    Note:If the Develop menu does not appear in the menu bar, open Safari preferences, click Advanced, and select “Show Develop menu in menu bar.”



From the Firebug Web Site:

Firebug integrates with Firefox to put a wealth of development tools at your fingertips while you browse. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page.
Visit the Firebug website for documentation, screen shots, and discussion forums: