I\'m trying to grab an arbitrary element using a CSS selector (eg. \"#someId .className a\") in GWT.
I\'m building a JS widget that can live on a 3rd party website a
Inspire by Asfand Yar Qazi answer.
With JSNI you can just define this method and enjoy it when you web app is running in modern browsers.
public final native NodeList<Element> querySelectorAll(String selectors) /*-{
return $doc.querySelectorAll(selectors);
}-*/;
There's the DOM class, that provides many wrapper methods for accessing the DOM tree. There's no function that takes a CSS selector jQuery style that I'm aware of - GWT just encourages/enforces accessing DOM elements through Widgets (and such), not directly - though I understand that in your case such "low-level" approach might be needed. The only way I see pulling that off through pure Java GWT methods is via lots and lots of (probably horrible) chaining/invocations of the DOM
class. It'd be easier if all you had to do was access some id
- for that there's RootPanel.get(id) (and DOM.getElementById(id), they differ in what type of objects they return).
However, like you already suggested, JSNI might offer a better solution - try returning, for example, $wnd.$("#someId .className a")
from JSNI as an Element
- actually, you can return anything as anything from JSNI, GWT will just crap up the second you try to use, say an int as a DOM element or something.
PS: while the GQuery project does seem dead/inactive, it might be worth checking how they wrapped the jQuery calls (such as $
) so that they could be used seemingly in GWT.
You could use querySelector() and querySelectorAll(), available for newer browsers...
http://www.javascriptkit.com/dhtmltutors/css_selectors_api.shtml
...in terms of browser support, querySelector() and querySelectorAll() is supported in Firefox 3.1+, IE8+ (only in IE8 standards mode), and Safari 3.1+
Here's an example using the GWT Element and Node classes to find a single nested element with a given class name. This is not as open ended and powerful as a literal CSS selector, but can be modified as needed for your specific use case:
static public Element findFirstChildElementByClassName( Widget w, String className ){
return findFirstChildElementByClassName( w.getElement(), className );
}
static private Element findFirstChildElementByClassName( Element e, String className ){
for( int i=0; i != e.getChildCount(); ++i ){
Node childNode = e.getChild(i);
if( childNode.getNodeType() == Node.ELEMENT_NODE ){
Element childElement = (Element)childNode;
if( childElement.getClassName().equalsIgnoreCase( className ) )
return childElement;
else if( childElement.hasChildNodes() ){
Element grandChildElement =
findFirstChildElementByClassName(
childElement, className );
if( grandChildElement != null ) return grandChildElement;
}
}
}
return null;
}
Use GwtQuery, is updated to GWT 2.4: http://code.google.com/p/gwtquery/
Selector examples :
//select an element having id equals to 'container'
GQuery myElement = $("#container");
//select all elements having 'article' as css class
GQuery allArticles = $(".article");
/select all cells of tables
GQuery allCells = $("table > tr > td");
//find the ul elements being inside a element with class 'article' itself inside a element with id 'container'
GQuery articleUls = $("#container .article ul");
http://code.google.com/p/gwtquery/wiki/GettingStarted