Grid + UiBinder : Setting row level styles - gwt

...........
.........
<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 :)

Related

Hide <g:customCell styleName="width:15%;">

I have a customcell in my xml file, It contains vertical panel which I have hide, But it cause some UI design issue as CustomCell is not hidde. Can anyone tell me how I can hide my customcell?. Thanks in advance.
<g:customCell styleName="width:15%;" ui:field="parentCell"
visible="false">
<g:VerticalPanel visible="false" ui:field="SortVPanel">
<g:Grid width="100%">
<g:row>
<g:customCell >
<g:Label styleName="float-left" wordWrap="false" width="65px" >
<ui:msg key="lblSort"> Sort By </ui:msg></g:Label>
</g:customCell>
<g:customCell styleName="cell-width83">
<c:ComboBoxComponent />
</g:customCell>
</g:row>
</g:Grid>
</g:VerticalPanel>
</g:customCell>
I want to hide the above customcell, which UiField value is ui:field="parentCell"
The g:customCell tag isnt a dom element, but a marker for the g:Grid tag to know which items are cells vs rows. This means you can't add html attributes to it. You also can't give it a ui:field, since it isn't an object at all.
Instead, you put these on the child Widget which lives inside the g:customCell tag, or from your Java code, you can call grid.getCellFormatter() and use the methods there to further format the cell which wraps the widget.

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>

Defining GWT CellTables with UiBinder

If I define my CellTable in MyView.ui.xml UiBinder file like this:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:c="urn:import:com.google.gwt.user.cellview.client"
ui:generateFormat='com.google.gwt.i18n.rebind.format.PropertiesFormat'
ui:generateKeys='com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator'
ui:generateLocales='default' xmlns:p1="urn:import:com.google.gwt.user.cellview.client">
...
<g:HTMLPanel>
<c:CellTable
addStyleNames='{style.cellTable}'
pageSize='15'
ui:field='cellTable' width="100%">
</c:CellTable>
</g:HTMLPanel>
and then programmaticaly add the columns to the CellTable, everything works fine.
But in an attempt to reduce boilerplate code I would like to define also the table columns in my UiBinder file. I've tried this:
...
<g:HTMLPanel>
<c:CellTable
addStyleNames='{style.cellTable}'
pageSize='15'
ui:field='cellTable' width="100%">
<c:TextColumn
addStyleNames='{style.titleColumn}'
ui:field="titleColumn"/>
</c:CellTable>
</g:HTMLPanel>
But it produces the following error:
[ERROR] [dialective] - Found unexpected child element Element addStyleNames='{style.titleColumn}'ui:field='titleColumn'> (:33)
How could I define the whole CellTable using UiBinder?
Evidently, in the second listing you're trying to add a column as a child object. Cell table doesn't accept children directly (meaning there is no addChild(...) method).
If you have fixed number of columns and want to use UIBinder consider using mere HTML table. In that case you will have all columns in the XML file, but the table will become harder to work with - HtmlElement not Widget.
<table ui:field="table">
<col ui:field="firstColumn" class="{style.firstColumn}">
<col ui:field="secondColumn" class="{style.secondColumn}">
...
</table>
And the code might look like the following
...
#UiField
private TableColElement firstColumn;
#UiField
private TableColElement secondColumn;
But all other operations with the table will be via DOM. Like table.appentChild(rowElement). I think doing like this doesn't worth it.

Is it possible to set the column width of a grid in GWT using uibinder?

I'm trying to use the GWT grid component in uibinder. It works fine until I want to set the width of the columns. The following is what I've tried to do but it doesn't seem to work.
<g:Grid width="100%">
<g:row>
<g:customCell width="20%">
<g:FlowPanel width="">
</g:FlowPanel>
</g:customCell>
<g:customCell width="80%">
<g:FlowPanel width="">
</g:FlowPanel>
</g:customCell>
</g:row>
</g:Grid>
You can write some java code in order to do that, example:
grid.getColumnFormatter().setWidth(0, "10%");
grid.getColumnFormatter().setWidth(1, "10%");
Only styleName is taken into account on g:row, g:cell and g:customCell elements.
If you can (i.e. if your grid content is mostly static), avoid using Grid and prefer an HTMLPanel containing an HTML <table>, this gives you much more flexibility.
http://code.google.com/p/google-web-toolkit/source/browse/tags/2.4.0/user/src/com/google/gwt/uibinder/elementparsers/GridParser.java

How to use UIBinder dynamacally?

I am using gwt 2.3.I am using UI binder in this. I want to create grid in this by using UIBinder. For this I have written this code.
<g:Grid ui:field='mygrid' addStyleNames='{style.panel}'
cellSpacing='10'>
<g:row>
<g:customCell>
<g:Label text="11" styleName="{style.label}" />
</g:customCell>
<g:customCell>
<g:Label text="22" styleName="{style.label}" />
</g:customCell>
</g:row>
<g:row>
<g:customCell>
<g:Label text="33" styleName="{style.label}" />
</g:customCell>
<g:customCell>
<g:Label text="44" styleName="{style.label}" />
</g:customCell>
</g:row>
</g:Grid>
Now here my data of grid is static.Now In case if my data comes from server side & depending on that data I want to create a Grid using UIbinder. How can this possible ??
One another case.There is form.In that from number of controls comes from data base.
So How can UIBider support to create this form.As number of control may vary each time
So I want to know is it possible to use UIBinder in case to create User Interface depending on run time data.
Any suggestions or example appreciated.
UiBinder is "cross compiled" to JavaScript and HTML code. Once that is done you cant modify it. There is now way to do something like send your XML syntax to client and then it creates a grid.
However it is possible that you add new Rows in your "code behind".
For your second question: I have no Idea what you mean :P
Yes, you can add data into UIBinder from Java. When you created UIBinder in Eclipse it also created .java file for this XML. Edit this corresponding java file and add something like this:
public class MyGridSample extends Composite {
// uiBinder interface declaration...
private static MyGridSampleUiBinderUiBinder uiBinder = GWT.create(MyGridSampleUiBinder.class);
interface MyGridSampleUiBinder extends UiBinder<Widget, MyGridSample > {
}
// annotation to get ui-field into code
#UiField
Grid mygrid;
public MyGridSample () {
setWidget(uiBinder.createAndBindUi(this));
// sets cell 0,0 with label
mygrid.setWidget(0, 0, new Label("cell 0"));
}
}
GWT is client side framework and UIBinder is precompiled as javascript files - they are served as static files. You should make a Webservice call to get data into this template.