Ben Bracha
Ben Bracha

Reputation: 1397

Tab container hosting dynamic presenter widgets

I want to show a tab container where each tab hosts a PresenterWidget.

Tabs are dynamic - they can be opened and closed. Moreover, the current selected tab should somehow be persistent in the URL so it can be shared or bookmarked.

I saw that GWTP has TabContainerPresenter, but it is for hosting a Presenter on each tab and not PresenterWidget. You also cannot add tabs dynamically, and the relation to place is (of course) static.

I also saw several discussions on this issue saying that if the tabs are hosting PresenterWidget, no special implementation is needed, so we can use any tab-container out there. For example GWT TabLayoutPanel.

But I don't understand how my PresenterWidget (that is hosted in a tab) life-cycle will be invoked on tab selection, or what should I do to have the life-cycle working (onReveal, onReset...)?

I guess I must build my own tab container that manages visible content through slots?

Any other ideas?

Ben

Upvotes: 1

Views: 1111

Answers (3)

Edwin Bautista
Edwin Bautista

Reputation: 364

Here is the sample UiBinder implementation, this is of course static implementation, you need to make your own dynamic implementation if the number of tabs is determined at runtime.

<g:PopupPanel styleName="{style.popupPanel}" modal="true">
        <g:HTMLPanel>
            <g:HTMLPanel styleName="titleHeader" height="20px">
                <g:Label styleName="titleHeaderCaption" ui:field="titleLabel" />
                <g:Image styleName="titleImage" ui:field="titleCloseImage" url="{images.actionCancel.getURL}"/>
            </g:HTMLPanel>
            <g:CaptionPanel captionText="{lbl.contractDetails}" styleName="captionPanel_popup">
                <g:HTMLPanel ui:field="contractDetail"/>
            </g:CaptionPanel>
            <g:TabLayoutPanel ui:field="tabPanel" barUnit="PX" barHeight="30">
                <g:tab>
                    <g:header size="7"><b>Permit</b></g:header>
                    <g:HTMLPanel ui:field="permit"/>
                </g:tab>
                <g:tab>
                    <g:header size="7"><b>ERP</b></g:header>
                    <g:HTMLPanel ui:field="erp"/>
                </g:tab>
            </g:TabLayoutPanel>
            <g:HTMLPanel styleName="{style.separator}">
                <hr/>
            </g:HTMLPanel>
            <g:HTMLPanel styleName="buttons">
                <g:Button text="{lbl.cancel}" styleName="button" ui:field="btnCancel"/>
                <g:Button text="{lbl.submit}" styleName="button" ui:field="btnSubmit"/>
            </g:HTMLPanel>
        </g:HTMLPanel>
    </g:PopupPanel>

Upvotes: 0

Edwin Bautista
Edwin Bautista

Reputation: 364

Ben, the TabContainerPresenter is only applicable if each tab is a place. As for your problem you just need to set in each tab the same presenter widget. You might want that the presenter widget not to be a singleton if you are injecting them in multiple tabs. This is a sample of setting presenter widgets in slots in the main presenter:

@Override
protected void onBind() {
    super.onBind();
    setInSlot(TYPE_PermitContent, permitPresenter);
    setInSlot(TYPE_ErpMessageContent, orgErpMessagePresenter); 
    setInSlot(TYPE_ContractDetailContent, contractDetailPresenter);
}

Then on the view, on my sample permit and erp are tabs in the TabLayoutPanel:

@Override
    public void setInSlot(Object slot, Widget content) {
        if (content == null) return;

        if (slot == ContractPopupWithTabPresenter.TYPE_PermitContent) {
            permit.clear();
            permit.add(content);
        } else if (slot == ContractPopupWithTabPresenter.TYPE_ErpMessageContent) {
            erp.clear();
            erp.add(content);
        } else if (slot == ContractPopupWithTabPresenter.TYPE_ContractDetailContent) {
            contractDetail.clear();
            contractDetail.add(content);
        } else {
            super.setInSlot(slot, content);
        }
    }

Then add a beforeSelection handler on your TabLayoutPanel which may look something like this:

tabPanel.addBeforeSelectionHandler(new BeforeSelectionHandler<Integer>() {
        @Override
        public void onBeforeSelection(BeforeSelectionEvent<Integer> event) {
            //TODO: Set your presenter widget here with whatever argument it needs to populate itself
        }
    });

Hope this helps.

Upvotes: 1

Edwin Bautista
Edwin Bautista

Reputation: 364

If any selected tab should be persistent in the URL then it is a Place and therefore should be represented by a Presenter and not by a PresenterWidget.

Upvotes: 0

Related Questions