Search code examples
gwtuibinder

Widget with internal uiBinder code


I would like to create widget where you can inject some part of uiBinder code. For instance

<c:MyWidget title="Title text" type="SOME_TYPE">
    <g:Button ... />
    <g:HTMLPanel ... > ... </g:HTMLPanel>   
</c:MyWidget>

I addition MyWidget has itself uiBinder code like bellow:

<g:HTMLPanel>
    <g:HTMLPanel styleName="...">SOME HEADER</g:HTMLPanel>
    <g:HTMLPanel ui:field="mainBody"/>
    <g:HTMLPanel styleName="...">SOME FOOTER</g:HTMLPanel>
</g:HTMLPanel>

and into main body I would like to inject code which is wrapped via

What I did so far is :

public class MyWidget extends Composite implements HasSafeHtml {
...
    private static MyWidgetUiBinder uiBinder = GWT.create(MyWidgetUiBinder.class);
    interface MyWidgetUiBinder extends UiBinder<Widget, MyWidget> {}

...

@Override
public void setHTML(String html) {
    modalBody.getElement().setInnerHTML(html);
    this.innerContent = html;
}

but it doesn't parse generated code like buttons or htmlPanels I can only insert pure html.

also I did sth like above

public class MyWidget extends HTMLPanel {
private static MyWidgetUiBinder uiBinder = GWT.create(MyWidgetUiBinder.class);
interface MyWidgetUiBinder extends UiBinder<Widget, MyWidget> {}

@UiConstructor
public ModalWindow(Type type, String title, String html) {
    super(html);
...

but I even don't know how to capture code form from first code listing in this question. I'm getting error "missing required attribute(s): html:"

Does somebody has some idea how to build such component ?


Solution

  • You just need to implement HasWidgets interface. In the add() method insert widgets to mainBody panel.

    public class MyWidget extends Composite implements HasWidgets {
    
        private static MyWidgetUiBinder uiBinder = GWT.create(MyWidgetUiBinder.class);
    
        interface MyWidgetUiBinder extends UiBinder<Widget, MyWidget> {}
    
        @UiField
        HTMLPanel mainBody;
    
        public MyWidget() {
            initWidget(uiBinder.createAndBindUi(this));
        }
    
        @Override
        public void add(Widget w) {
            mainBody.add(w);
        }
    
        @Override
        public void clear() {
            mainBody.clear();
        }
    
        @Override
        public Iterator<Widget> iterator() {
            return mainBody.iterator();
        }
    
        @Override
        public boolean remove(Widget w) {
            return mainBody.remove(w);
        }
    }
    

    Tested, it works.