views:

45

answers:

2

I'm not sure if I'm doing something wrong here or not, but I need to base the status of several objects off of the status of another. So I'm basically iterating over the parents, then getting their children and iterating over them to get their children etc. However, I don't know how to add jquery objects on to a jquery result object.

My code looks something like this (where bubbleDown is said result object):

while (i < bubbleDown.length) {
    var curRow = bubbleDown[i];
    child = curRow.getAttribute('class') //etc
    parent = curRow.getAttribute('class') //etc
    bubbleDown.add($('.' + child + ':not(.' + parent.replace(' ', '.') + ')'));
    i++;
}

I've hidden some logic due to it not being applicable to my question. Anyway, it doesn't work, and not because the jquery fails to return objects. Can anyone help?

A: 

you have to do this on a jquery-object item:

var curRow = $(bubbleDown[i]);

or you can use the each() method: (while index holds the current item index)

bubbleDown.each(function(index){
    var child = $(this).attr('class')...
    ...
    bubbleDown.add(...);
});

use var to init your variables to avoid problems with IE for example.

helle
That's not right in this case. `bubbleDown[i]` is returning the DOM element, and the code is calling a native API method against that element in the next two lines.
patrick dw
really? didn't know that. maybe it works using jquery
helle
helle - Your new example should produce the same result as the question, except that you're using `.append()` which is used to add/move an element to a certain point in the DOM. The OP seems to want them added to the same `bubbleDown` jQuery object that is being iterated over.
patrick dw
okay, one moment, i'll change it. *sorry haven't seen that.
helle
helle - Better, but now you're effectively back to the original code, just using jQuery's `.attr()` instead of the native `.getAttribute()`. Not incorrect, but doesn't fix the issues yet. ;o)
patrick dw
+1  A: 

The simplest approach is that .add() takes a selector already, just use that overload and keep updating the reference to the object to use the one .add() returns:

var newBubbleDown = $(bubbleDown);
while (i < bubbleDown.length) {
  var curRow = bubbleDown[i];
  child = curRow.getAttribute('class') //etc
  parent = curRow.getAttribute('class') //etc
  newBubbleDown = newBubbleDown.add('.' + child + ':not(.' + parent.replace(' ', '.') + ')');
  i++;
}
//use newBubbleDown

I can't simplify it any further since I'm not sure of your logic outside, e.g. where i comes from, what child and parent are used for, etc. But just call .add(selector), without feeding it a jQuery object and you're all set.

We're using a new object here since .add() returns a reference to a new jQuery object (one you're not using), so each .add() adds elements, creates a jQuery object containing them, then it's thrown away on the next loop. Instead you need to update the reference so it keeps accumulating elements like you want. I tend to change the .add() implementation to act on the current array in most of my projects because it's more useful that way which would make your original code work, for example).

Note: this will only add elements to the newBubbleDown jQuery object, but your :not() use makes me wonder if this will suit your needs, it wouldn't remove any elements in any case, it'll only find the elements matching that selector and add them to the array. If you need to exclude elements already in the array, you'll need .filter().

Nick Craver
That doesn't seem to add anything to the object.
C Bauer
`.add` does not mutate the jQuery object. It returns a new one.
Roatin Marth
@Roatin - Good point...I actually change `.add()` so it *does* mutate (more useful most of the time IMO), I tend to forget the API doesn't do this by default.
Nick Craver
@Roatin - thanks! Didn't realize that was the issue... misunderstandings like this have been my downfall with certain javascript problems before :)
C Bauer
@Nick: you patch jQuery functions locally?
Roatin Marth
@Roatin - Here's for example what I do to make `.add()` mutable: http://jsfiddle.net/9S76a/ Just run it anytime after jQuery is included.
Nick Craver