PDA

View Full Version : DOM Traversing with Ext.select (jQuery -> Ext 4)



mbvana
16 Sep 2011, 5:04 AM
I do not understand how to work with the result Ext.select ?r Ext.query
jQuery:
var e=$('#someID');
var a=e.find(...);
var b=e.find(...);
....
How do I get the this with Ext 4?
Thanks

mberrie
16 Sep 2011, 11:06 PM
Ext.query is just an alias for Ext.select.

If you have an id, better use Ext.get().

Ext.select() will return an array of elements to allow for more than one result. You have to 'traverse the array' (using a for loop or Ext.each) and can do whatever you want with each result item.

On single elements (e.g. as obtained by Ext.get) you can use a variety of select methods directly, e.g. up(), down(), first(), last(), next(), ... and of course select().

The docs for Ext.Element are unfortunately pretty crowded, so I recommend to look at the source file in Ext.Element-traversal.js to get an overview over all available DOM traversal methods:
http://docs.sencha.com/ext-js/4-0/source/Element.traversal.html#Ext-Element-method-select

Why are there so many?

Well, some will return exactly one node (first match), others all (possibly multiple) matches. Some will traverse all elements in one direction (like up() or down()), and some only direct descendants (like child()).

In case of methods that return multiple matches most methods will return a CompositeElement, which makes it easy to operate on all elements at once (e.g. results.setStyle('display', 'hidden');)

mbvana
18 Sep 2011, 12:07 AM
I read the documentation:
select( String/Array selector, , [HTMLElement/String [B]root] ) : CompositeElementLite/CompositeElement
.........
(optional) The root element of the query or id of the root

I'm trying to use the root in the following simple example,

<body>
<div id="ex">
<div>111</div>
<div>222</div>
<div>333</div>
</div>

I need a way of traversing as easy as in jQuery
var parent=$('#ex');
var some = parent.find('div');

I want to get the child elements:

var parent=document.getElementById("ex");
var some = Ext.Element.select('div',document.getElementById("ex"));
alert(some.getCount()); // return 4.

may be i must use some another path?

var parent=Ext.get("ex");
var some = Ext.Element.select('div',parent);
alert(some.getCount()); // return 4

may be i must use this (select : function(selector) {return Ext.Element.select(selector, false, this.dom);)?

var parent=Ext.select("#ex");
var some = parent.select('div');
alert(some.getCount()) // return 1


I've tried a some variations, but did not understand, can just as easily and effectively reuse the results Ext.select to find in him the child elements. Perhaps i can use only this way?

var parent=Ext.query("#ex");
var some = Ext.query('div',parent[0]);
var another=Ext.select(some);
alert(another.getCount()); // return 3

Sorry for the stupid question

damo
18 Sep 2011, 1:01 AM
Given your example above it's just.


var div = Ext.select('#ext div');
div.getCount() // 3

If the HTML is more complex then use the relevant css style selector e.g.


('#ext > div')

mbvana
18 Sep 2011, 3:02 AM
I talk about reuse of result Ext.select operation
<div id="ex">
<div>...<div>
<p>...</p>
</div>

I must call once each time the search #ex???

var parent = Ext.select('#ex'); // first seeking #ex
var div = Ext.select('#ex div'); // second seeking #ex
var p = Ext('#ex p'); // third seeking #ex

I can not do the same way as is done in jQuery??

var parent= $('#ex');
var p= parent.find('p');
var div=parent.find('div');

In Ext so many DOM-traversing methods, but how to make this trivial operation?

mberrie
18 Sep 2011, 3:14 AM
Maybe this helps clear up some of your confusion.



// jquery equivalent
var el = Ext.get('ex');
var result = el.select('div'); // 3 elements as 'CompositeElement'

// do something with all elements at once
result.setStyle('display', 'none');

// iterate elements
result.each(function(element) {
console.log(element.dom.innerHTML);
})



And about your problem of Ext.Element.select returning 4 DIVs instead of just 3:


var parent=Ext.get("ex");
var some = Ext.Element.select('div',parent);
alert(some.getCount()); // return 4

This one was not obvious to me at first!

Problem is that the second method parameter is *not* the root node (parent) but a boolean switch. This is why the select query defaulted to the document body as root and returned all 4 divs.

It should have been:


var some = Ext.Element.select('div', false, 'ex'); // 3 elements! 3rd argument is root node and can be an id or an actual element.


But instead of using Ext.Element.select and passing the root node you'd rather invoke the select method on the root node directly (just as the first example in this post)

mbvana
18 Sep 2011, 3:45 AM
Thank you, Mberrie. The your first examle works. But I was hoping that there is universal Ext.Element method without mixing get/select/query/.... as it is done to jQuery and some other js-frameworks: $(..)
I has not found it

mberrie
18 Sep 2011, 4:11 AM
I can see now that my first answer was actually more confusing than it was helpful. Sorry for that ;) (And it actually also contained two minor errors).

And you are right. It seems that Ext's DOM traversal framework is less flexible than that of JQuery (I'm no expert on neither of them though!).

I toyed around with Ext more and found that it doesn't love chaining of selectors that much.

While in JQuery you can do something like this:



$('li').find('a')


Ext doesn't like chaining 'select' queries:



Ext.select('li').select('a');


Will actually return the result of Ext.select('li'). I guess the philosophy behind it that the CompositeElement is not geared at chaining selects but rather to manipulate the result of a select query, e.g.



Ext.select('li').addClass('xxx').setStyle(...).doMore(); // all operating on the first result set


I can just assume that the main reason is that if you want to chain selects it is far better to use a single CSS select since it will use the browser's native DOM query capabilities and perform much faster:



Ext.select('li a');