6

I've been working on debugging some jQuery on a BlackBerry OS5 device (the 8530). There are a number of problems, but one that I have narrowed down is related to jQuery's .each()

The logic is as such:

$objectArray.each(function(){
   alert('test');
   if(...some logic...){
       $(this).addClass('testClass');
   };
})

In any normal browser I get the alert, click OK, and then see that particular item (in this case, a TD) get an updated class if the logic statement is true. It then repeats through the rest of the items, each getting an alert, me OKing it, and me seeing that particular TD's class get updated.

On the BlackBery 8530, however, I get each alert but the TDs aren't updated one-by-one. Instead, they all get updated at once after the last alert based on the if logic of the last TD only.

Odds are that there are serious JS issues with this particular browser, but I'm wondering if there is a way to get around this. Are there alternatives to using .each() in jQuery?

UPDATE:

A more detailed code example:

$TRs.each(function(){
    var $TR = $(this);
    var $checkBoxTD = $TR.find('td.td3');
    var $checkBox = $checkBoxTD.find('input');

    alert($checkBox.is(':checked'));

    if ($checkBox.is(':checked')!=true){
       $checkBoxTD.addClass('notSelected');
    }
});

I'm looping through each TR of a TABLE. Within each TR is a TD (.td3) that contains a checkbox. I need to check each one. If it's not checked, I need to add a class to the TD.

In good browsers, the alert will show a true or false, and, based on that particular alert, you will see the class being applied appropriately to that row as you dismiss the alert. It then repeats for every row.

In BB OS5's browser, each alert pops up with the proper value, but the classes aren't updated until AFTER the very last alert/loop, so every TD class then used the logic of the last loop only.

UPDATE 2 (fix?):

Thanks to Alex, I did some more playing with this and found a way to get this to work in the stubborn browser.

$TRs.each(function(idx){
    var $TR = $(this);
    var $checkBoxTD = $TR.find('td.td3');
    var $checkBox = $checkBoxTD.find('input');

    alert($checkBox.is(':checked'));

    if ($checkBox.is(':checked')!=true){
       $TRs.eq(idx).find('td.td3').addClass('notSelected'); // <-- the 'fix'
    }
});

The difference is that I'm going back to the main jQuery object $TRs and specifically grabbing one of the elements from it based on its index.

So based on that, my final question is: Does the above solution have any downsides for the 'good' browsers? Is there a performance hit?

DA.
  • 39,848
  • 49
  • 150
  • 213
  • Is `$objectArray` a real array, or a jQuery object? – Alnitak Aug 01 '11 at 21:37
  • It's a jQuery object. The contents of a `$('td')` selector – DA. Aug 01 '11 at 22:11
  • It sounds like it might be stacking the `alert`s. Can you debug to a div on the page instead and see if that works? – Adam Hopkinson Aug 02 '11 at 15:06
  • UPDATE 2 works with or without the alerts. The rest do not work with or without the alerts. So the alerts don't seem to be a factor in the issue nor the solution. – DA. Aug 02 '11 at 15:08

1 Answers1

2

Try this:

$objectArray.each(function(idx, element){
   alert('test');
   if(...some logic...){
       $(element).addClass('testClass');
   };
})

UPDATE:

Try this, maybe it has less overhead...

var $checkBox = $TRs.find('td.td3 input:not(:checked)');
$checkBox.each(function(){
    $(this).parent().addClass('notSelected');
});
Alex
  • 180
  • 4
  • what does 'idx' represent in that example? – DA. Aug 02 '11 at 13:09
  • alas, that doesn't work. If I replace the alert with `alert(...result of some logic...)` the proper value is returned for each row in each alert, but the classes aren't being updated until after the very last alert, which then updates ALL classes based on the value of the last logic loop. – DA. Aug 02 '11 at 14:03
  • ah...I think I see the issue. In the example above, `element` is being passed as a DOM object, rather than a jQuery object. Is it possible to pass in the jQuery object instead? – DA. Aug 02 '11 at 14:08
  • idx is the index of current loop iteration (zero based), element is the current DOM element. If you need jQuery object just use $(element). See http://api.jquery.com/each/ – Alex Aug 02 '11 at 14:53
  • Thanks, Alex. FYI, I updated my question with more specific code examples in hopes of better explaining what I'm trying to accomplish. – DA. Aug 02 '11 at 14:54