How do I mix HTMLPanel and VerticalPanel using GWT 2.4? - gwt

I'm trying to add in a verticalPanel to an HTMLPanel I'm getting errors trying to add this into the html code.
What I'm trying to do is create a panel that has a border around my widgets and as it's more of a vertical alignment pattern, I chose to use verticalPanel.
I get compile errors when I try to add in outside of my html table, tr, or td tags, but that is what I thought I wanted to do in order to show a border.
Here is a code snippet:
<g:HTMLPanel ui:field="mainPanel" >
//Putting verticalPanel here causes a compile error
<table width="100%">
//Putting verticalPanel here causes a compile error
<tr>
//Putting verticalPanel here causes a compile error
<td>
<g:Label ui:field="title"></g:Label>
</td>
</tr>
Is this a good approach and if so, how do I do this, or is there a better way?

You need to read the javadoc of a widget.
if a widget implements HasText, you can place text between its tags
if it implements HasHTML, you can place HTML between its tags
otherwise (since all widgets implements HasWidgets), you can only place widgets between its tags.
some widgets have configurative subtags, where the subtag names start in lowercase.
some widgets allow only one child widget. These are extensions of SimplePanel.
So, if you try to put HTML tags in between a VerticalPanel, you will encounter errors because VerticalPanel does not implement hasText or hasHtml.
HTMLPanel does not implement HasHTML, BUT you are allowed to place a mix of widgets and HTML, because its content parser is specially designed to recognise HTML placed inside its tags. That is why it is called HTMLPanel.
The following is not acceptable and results in compilation error:
<g:HTMLPanel>
<g:VerticalPanel>
<TABLE><TR><TD>Hello</TD></TR></TABLE>
</g:VerticalPanel>
</g:HTMLPanel>
because the HTML sits inside the VerticalPanel tags.

Related

How can i vertical-align & horizontal-align components inside a FlowPanel?

As stated in http://www.gwtproject.org/doc/latest/DevGuideUiPanels.html, Google said we should not use HorizontalPanel & VerticalPanel to make layouts since it can have some browser incompatibility problems. Google suggests to use FlowPanel instead.
VerticalPanel can usually be replaced by a simple FlowPanel (since block-level elements will naturally stack up vertically).
HorizontalPanel is a bit trickier. In some cases, you can simply replace it with a DockLayoutPanel, but that requires that you specify its childrens' widths explicitly. The most common alternative is to use FlowPanel, and to use the float: left; CSS property on its children. And of course, you can continue to use HorizontalPanel itself, as long as you take the caveats above into account.
However, we now run into another problem.
How to vertical-align & horizontal-align components inside a FlowPanel?
This doesn't work.
<g:FlowPanel height="100%" addStyleNames="{res.css.alignMiddle}">
.alignMiddle{
vertical-align:middle;
}
I tried myFlowPanel.getElement().getStyle().setVerticalAlign(VerticalAlign.MIDDLE); but it also doesn't work.
Also, another approach is to use <table> html tag inside a HTMLPanel, but some people said different browsers may render gui differently the widgets inside <table> causing some quirks. Google doesn't suggest to use <table> inside a HTMLPanel, so we shouldn't use.
But, then:
How to vertical-align & horizontal-align components inside a FlowPanel?
i found a solution
<g:FlowPanel addStyleNames="{res.css.outer}">
<g:FlowPanel addStyleNames="{res.css.alignMiddle}">
more widget here....
</g:FlowPanel>
</g:FlowPanel>
.outer {
display: table;
height: 100%;
width: 100%;
}
.alignMiddle{
display: table-cell;
vertical-align: middle;
text-align:center;
}

How to set Widget as Anchor content in GWT instead of the usual String?

I'm in a situation where I want a whole Widget to be a link to another page. Both Anchor and Hyperlink only accept Strings or SafeHTML as visual representation. However, I need e.g. a <div>...</div> to be a link.
This would be similar to:
<div><p>This whole thing is a link</p></div>
Is there a way to do this withou custom coding my own SafeHTML? To be more concrete, I want a GXT HBoxLayoutContainer to be clickable and bookmarkable.
The easiest solution would be using UiBinder:
<ui:UiBinder
xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:container="urn:import:com.sencha.gxt.widget.core.client.container">
...
<g:HTMLPanel>
<a href="somesite">
<container:HBoxLayoutContainer>...</container:HBoxLayoutContainer>
</a>
</g:HTMLPanel>

anchor element click event

I have been using uibinder for a while and got pretty good at it. I know all about the use of HTMLPanel and Anchor for adding click handlers. However, there are cases where this design approach simply doesn't fit the bill.
say I have a unordered list, and each list has some anchor elements.
<ul><li><a ...></li>...</ul>
it is good to make each li as a component (java class) so you can add multiple instances of the component inside the ul. this means inside the ui.xml, you start with li (no other way that I can see). but then there is no way to insert Anchor inside. you can not replace li with HTMLPanel since that would create a div which you don't want.
by leave the anchor as a in this uibinder, there would be no way to detect the anchor click event.
any ideas?
In your HTML, set ID to the anchor :
<a id='testachor'>...</a>
In your GWT code, wrap the anchor into a widget:
Anchor testAnchor = Anchor.wrap(Document.getElementById('testanchor'));
Then add click handler to it:
testAnchor.addDomHandler(new ClickHandler(){...}, ClickEvent.getType());
You can add Anchor widget inside <li> tag:
<g:HTMLPanel>
<ul>
<li>
<g:Anchor ui:field="link" />
</li>
</ul>
</g:HTMLPanel>

GWT UIBinder Tab panel

I want to put some anchor inside the body of tab panel with two tabs. But my anchors are not visible. The code is as follows
<g:TabLayoutPanel ui:field="lhsTabPanel" barUnit="PX" barHeight="60">
<g:tab>
<g:header>Analysis</g:header>
<g:FlowPanel>
<g:Anchor ui:field='personalInformation'>Personal Information</g:Anchor>
</g:FlowPanel>
</g:tab>
<g:tab>
<g:header>Comparison</g:header>
<g:FlowPanel ui:field="comparisonContent"/>
</g:tab>
</g:TabLayoutPanel>
The personal information tab is not visible
TabLayoutPanels must be added to other widgets that implement ProvidesResize. For example, if you are adding this TabLayoutPanel to RootPanel instead of RootLayoutPanel, you won't be able to see the TabLayoutPanel because RootPanel does not implement ProvidesResize.
You can't see the contents of the tabs because the TabLayoutPanel does not know how big it should be. Try adding it to some descendant of a LayoutPanel and setting its size explicitly with the setWidgetLeftRight and related functions.
Check out http://code.google.com/webtoolkit/doc/latest/DevGuideUiPanels.html#LayoutPanels for more information.

Get UiBinder widget to display inline instead of block

I'm trying to get my UiBinder-defined widget to display inline, but I can't. My current code is:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:style>
.section {
border: 1px solid #000000;
width: 330px;
padding: 5px;
display: run-in;
}
</ui:style>
<g:HTMLPanel>
<div class="{style.section}">
<div ui:field="titleSpan" class="{style.title}" />
<div class="{style.contents}">
<g:VerticalPanel ui:field="messagesPanel" />
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
This works fine in terms of how the widget looks internally, but I want to throw a bunch of these widgets into a FlowPanel and have them flow when the window is resized. The HTMLPanel is a div, but I can't get the display attribute to assign. I can't force the style name, since the following throws an error:
<g:HTMLPanel styleNames="{style.section}">
And I can assign an additional style, but it doesn't apply the display setting.
<g:HTMLPanel addStyleNames="{style.section}">
This displays the border and sets the size, as expected, but it doesn't flow. Firebug shows the styles on the div are border, width, and padding, but no display.
Is there a way to make a widget in UiBinder so that it'll display inline instead of block? And if so, can I make it compatible with having a VerticalPanel inside (can I do it without making the entire widget pure HTML without any GWT widgets)?
PS: I saw question 2257924 but it hasn't had any answers lately, and he seems to be focused on getting a tag, not specifically getting inline layout. I don't care directly about , if I can just get the top-level tag for my widget to flow inline, I'm happy.
It seems your problem is caused by using display: run-in instead of the more "standard" display: inline. IE and Firefox don't support run-in and it seems that Firebug prunes the style upon adding.
Try changing the style to display: inline (or inline-block if you want some properties of a block, like width, but beware of the quirks of IE + inline-block).
It should be <g:HTMLPanel styleName="{style.section}">, not <g:HTMLPanel styleNames="{style.section}"> - styleNames is a typo (which appears in the UiBinder docs, so I'm sure that's where you got it from). styleName is the correct thing to use.
Also, Igor Klimer is correct that you should use display: inline or display: inline-block rather than display: run-in.
In general, you can tell the available attribute names by looking for setXXX methods on the UIObject class, and the attribute name is just the XXX. So, UIObject has a setStyleName method, which you access using the attribute called styleName.