CSS class definition doesn't work inside <g:HTML> element - gwt

Could you guys tell me why css class definition doesn't work in following example ?
I'm using GWT 2.4 + Chrome 17.
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:style>
div.test {
color: red;
}
</ui:style>
<g:HTML>
<div class="test">I should be red but I'm not</div>
</g:HTML>
</ui:UiBinder>

CSS classes listed in the <ui:style> will be obfuscated, going from test to GKYSKJX (or something similar).
Update your div to this:
<div class="{style.test}">Now I'm red :)</div>
Alternatively, you could choose to force your style to NOT obfuscate by doing this:
#external .test;
div.test {
color: red;
}
Unless you have a good reason, I recommend sticking with the first method.
See more at Declarative Layout with UiBinder - Hello Stylish World.

Related

How to use buttons with GWT's UiBinder?

In MyPanel.ui.xml:
<button class="btn" ui:field="myButton">Save</button>
In MyPanel.java:
public class MyPanel extends Composite {
...
#UiField ButtonElement myButtonUi;
...
public MyScreen() {
final HTMLPanel panel = uiBinder.createAndBindUi(this);
initWidget(panel);
Button myButton = Button.wrap(myButtonUi);
In MyEntryPoint.java:
if (....)
RootPanel.get().add(new MyPanel());
So I think I don't really understand how to use UiBinder.
It's my intention to use HTML with ui:field=".." so that the web-designer can set things like class="xx" on the UI fields. Most of the GWT documentation assumes you've got a Button not a ButtonElement. But if I use a Button I need to have a <g:Button> in the HTML document which means my web-designer can't set the class? I mean the point of UiBinder is to allow one to use normal HTML and integrate it with the GWT code?
When I do the above, on the wrap line, I get a NullPointerException in development mode from:
public static Button wrap(com.google.gwt.dom.client.Element element) {
// Assert that the element is attached.
assert Document.get().getBody().isOrHasChild(element);
In production mode it seems to work OK. In the debugger of development mode in Eclipse, when I right-click and "Inspect" the expression "Document.get().getBody()" Eclipse says "Cannot send a static message to a non class type object".
What should I do? Is the null pointer exception happening because I need to attach the element first? If so, how? (I am already calling createAndBindUi and the element passed to wrap is non-null).
So finally, here's the answer. I Edited it and deleted useless comments.
You can't use HTML in your ui.xml if your plan is to use UiBinder to wire a component from the ui.xml to your view's Java code. Instead of
<button class="btn" ui:field="myButton">Save</button>
use
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<g:Button styleName="btn" text="Save" ui:field="myButton"/>
Then in your view -java code- simply type
#UiField com.google.gwt.user.client.ui.Button myButton;
public MyScreen() {
final HTMLPanel panel = uiBinder.createAndBindUi(this);
initWidget(panel);
}
That's it.
The "styleName" attribute is enough for your designer to hook a CSS class. This other post might interest you. Designers will have to learn about what attributes are available on which components. Using UiBinder is not as straighforward as using HTML.
UiBinder is not for writing HTML but to write XML that can be understood by GWT and compiled to javascript (which in turn will produce the page's HTML). It's not like the JSP mechanism where you can insert plain HTML right away.
UiBinder is most helpful when you have to wire ui elements (widgets or composites from the ui.xml) with your Java view code (i.e. using the #UiField or #UiHandler annotations).
You can use HTML. The only restriction is that g:Button must be inside a container like g:HTMLPanel.
The good thing about g:HTMLPanel is that it can render HTML.
See the example below:
<g:HTMLPanel>
<div>
test
</div>
<table border="1">
<th>
button
</th>
<tr>
<td>
<g:Button styleName="{style.important}" ui:field="button"/>
</td>
</tr>
</table>
<div>
test
</div>
</g:HTMLPanel>

Applying just one property from a CSS class to an element

I'm working with a number of large interchangeable style sheets. I need to use the border colour from one of the classes as the border for a div. The class in question has a number of properties, I only want the border.
Is there any way of doing this with CSS? I'd be happy with a CSS3 solution if it degrades nicely.
Of course I can use JS to do it, I know how with JQuery. But I was hoping to avoid that.
Lyle
Update: As I feared not possible, why hasn't CSS3 provided a solution to this? As I said I'm working with a number of large interchangeable style sheets, the re-factoring suggestions simply aren't workable and they'd not only be a large job in themselves, but have far reaching implications :( I'll just have to do it with JQuery.
JQuery solution (JQuery.css doesn't like shorthand, like border or border-color):
var border = $('.class').css('border-top-color');
$('div').css('border-color', border);
This is simply not possible in CSS alone, unless you alter the way the CSS declarations work.
For example:
.class1 {
background: green;
}
.class1, .class2 {
border: 1px solid red;
}
...and the HTML:
<div class="class1"></div>
<div class="class2"></div>
Or:
.class1 {
background: green;
}
.class2 {
border: 1px solid red;
}
...and then in your HTML:
<div class="class1 class2"></div>
<div class="class2"></div>
Nope. Try to refactor your stylesheets. You can add multiple classes to one element.
<div id="mydiv" class="borders black"></div>

Grid + UiBinder : Setting row level styles

...........
.........
<g:row styleName="OddNumberRow">
....
....
</g:row>
<g:row styleName="EvenNumberRow">
....
....
</g:row>
...........
...........
The above approach is not working. In other words, the "tr" elements in the generated html do not have any class names at all. A back up option would be to inject styles into these rows from the UiBinder's constructors (using getRowFormatter.addStyleName) but
I do not want to take that route for now.(I wanna try to reserve the code that goes into the UiBinder java class for event handling purposes only. )
Any thoughts/pointers would be much appreciated.
Note: Cross posted at https://groups.google.com/forum/?fromgroups#!topic/google-web-toolkit/yGRUkpcpBzU
thanks
You are right, this does not work. I have also tried adding the style to g:customCell, which does not work either.
The only way I can think of is using a SimplePanel to wrap your content in:
<g:row>
<g:customCell>
<g:SimplePanel width="100%" height="100%" styleName="OddNumberRow">
<g:Label>Content</g:Label>
</g:SimplePanel>
</g:customCell>
</g:row>
<g:row>
<g:customCell>
<g:SimplePanel width="100%" height="100%" styleName="EvenNumberRow">
<g:Label>Content</g:Label>
</g:SimplePanel>
</g:customCell>
</g:row>
It looks like GWT has been updated to understand styleName=foo directly on <gwt:cell> and <gwt:row> elements.
Your example code should now do what you expect :)

GWT UI Binder using pure HTML

Is there a way to work with pure HTML in GWT UIBinder.
The problem I am seeing is more of where we have to wrap the style in curly braces. Any link /article/book handling UIBinder in detail would be helpful.
I have already seen the articles in GST website
The style name (CSS class name) must be put in curly braces, e.g. <div class="{style.example}">...</div>, when the name is obfuscated by GWT. GWT does this, when you use a CssResource. This is also the case, when you declare it in a <ui:style> block in your .ui.xml file:
<ui:UiBinder ...>
<ui:style>
.example {
...
}
</ui:style>
<div class="{style.example}">
...
</div>
</ui:UiBinder>
In contrast, when you declare your CSS class in a plain CSS file (which you directly reference form you HTML host page), then you don't put the name in curly braces. In that case, you just use it like
<ui:UiBinder ...>
<div class="example">...</div>
</ui:UiBinder>
You can use it this way which is close to pure HTML:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
ui:generateFormat='com.google.gwt.i18n.rebind.format.PropertiesFormat'
ui:generateKeys="com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator"
ui:generateLocales="default"
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:style>
... CSS ...
</ui:style>
<g:HTMLPanel>
... HTML and GWT controls ...
</g:HTMLPanel>
</ui:UiBinder>
I've been looking for the answer to this question via google and landed here.
I've found the solution that worked for me here:
http://blog.sortedset.com/googles-app-engine-java/gwt-uibinder-helloworld-with-html/
The essentials:
Use
interface MyUiBinder extends UiBinder<Element, MobileUI>
instead of
interface MyUiBinder extends UiBinder<Widget, MobileUI>
Use
setElement(uiBinder.createAndBindUi(this));
instead of
initWidget(uiBinder.createAndBindUi(this));
Use
RootPanel.getBodyElement().appendChild(myUiBinder.getElement());
instead of
RootPanel.get().add(myUiBinder);

GWT forced height HTMLPanel

I'm developing a GWT project, and I encountered a problematic cross-browsering problem.
When using firefox, there are problems with the display of all the pages. I found the reason why :
In UIBinder, each of my pages are wrapped by a "g:HTMLPanel" : at start and at the end of the xml file, to wrap the content of all the pages
When doing this, the generated code of the panel goes like this :
div style="width: 100%; height: 100%; ....
The problem is that "height : 100%". If I remove it with firebug, the display is perfect.
So my goal is to programatically remove that generated 100% height.. But no way to do it !
I tried everything : setHeight, setSize, working on the Element itself with getElement().methods()... I tried to do things like style.clear(), everything that could have a chance to work.. But in the generated code that "height: 100%" will ALWAYS be there. If I set it's height to "50%" or "50px" it has no effect at all.
I even tried to give it an ID, then with pure javascript to change it's style, but no solution either..
Note : I'm sure that I'm working on the right element : adding a styleName, for example, works well.
Any idea ?
Your help would be really appreciated, I have no clue of how to remove this bit of generated code, and I've been looking for hours already :(:(:(:(
Best regards,
Nils
I just inspected some of the code generated by GWT from my uibinders in firebug and < g:HTMLPanel > isn't adding any width or height styling.
I don't have < g:HTMLPanel > as the root element in my uibinder though, I have my own class.
<a:FormPanel ui:field="form">
<g:HTMLPanel>
<input type="hidden" ui:field="discoveryId" />
<table cellpadding="2" cellspacing="0" class="{widgets.gridPanel}">
<tr>
<td>Name:*</td>
What about using say FlowPanel as your root uibinder class instead, then HTMLPanel?
Failing that you could always use the !important css rule to override the ones assigned on the div.
.myHTMLPanel {
width: auto !important;
height: auto !important;
}
This can be due to the fact that an HTMLPanel is wrapped into a DeckPanel. A DeckPanel adds "height: 100%" and "width: 100%" to the elements.
After showing the widget, add the following code:
deckPanel.add(widget);
deckPanel.showWidget(0);
Element e = DOM.getParent(widget.getElement());
DOM.setStyleAttribute(e, "height", "");
DOM.setStyleAttribute(e, "width", "");
widget.setHeight("");
widget.gwtContainer.setWidth("");