views:

112

answers:

2

Following DOM structure:

<ul>
  <li class="item">yes</li>
  <li>no</li>
  <li class="item">yes</li>
  <li>
    <ul>
      <li class="item">no</li>
    </ul>
  </li>
</ul>

Assuming I have the outer <ul> in $ul. How do I get the two immediate children which have the item-class?

In jQuery I would write something like this:

$ul.children().filter(".item")
$ul.children(".item")
$ul.find("> .item")

How do I to this with Prototype?

I tried the following ...

$ul.select("> .item") //WRONG

... but it does does exactly the opposite and returns the one inner <li>

+1  A: 

if your ul has an id of Foo you could do this:

var els = $$('#foo>.item').each(function(s,i) { alert(s.innerText); });

Oddly enough, none of these work..

$('foo').getElementsBySelector('>.item').each(function(s,i) { alert(s.innerText); });
// As you say it returns the 'no' list item. Taking off the '>' doesn't work either.

$('foo').getElementsBySelector('.item').each(function(s,i) { alert(s.innerText); });
// returns all three

$('foo').up().getElementsBySelector('>.item').each(function(s,i) { alert(s.innerText); });
// returns all three

getElementsBySelector is supposed to be the equivalent of $$(), but clearly it's not. Seems like a bug in Prototype to me...

This works, but seems of little value...

$('foo').up().getElementsBySelector('#foo>.item').each(function(s,i) { alert(s.innerText); });
Matthew Smith
It's not a bug. You can't use `>` this way in Prototype, see my answer. And getElementsBySelector is deprecated in favor of Element#select.
Alsciende
+2  A: 

You would do something very similar, functionally, to jQuery (1st example), although Prototype doesn't have a filter method, it has two more generic methods: findAll and grep. Here, you can use both. grep as explained here:

var items = ul.childElements().grep(new Selector('li.item'));

or findAll:

var items = ul.childElements().findAll(function (elt) {
  return elt.match('li.item');
});

And here is an example: http://jsfiddle.net/RuBzq/.

What you tried (ul.select("> .item")) doesn't work because the selector only tests descendants of ul. Since ul is unknown to the selector, > doesn't start from ul but from elements under it. So everything that is not an immediate descendant of ul will match ul.select('> *') for example. And that's why ul.select('> .item') only matches .items that are descendants of something inside the set. If jQuery works differently, that's a bummer.

Alsciende
Sounds good, I'll try out the grep-solution. Thanks!
naltatis