0

Have to have fulfill for a tabPanel fire from a viewModel that sets the selected tab in Java?

asked 2012-10-05 13:30:34 +0800

rickcr gravatar image rickcr
704 7

updated 2012-10-05 15:54:53 +0800

Consider three tab panels:

<tabpanel fulfill="tab1.onSelect">
    <include id="page1"  src="/page1.zul" ></include>
</tabpanel>
<tabpanel fulfill="tab2.onSelect">
    <include id="page2"  src="/page2.zul" ></include>
</tabpanel>
<tabpanel fulfill="tab3.onSelect">
    <include id="page3"  src="/pages3.zul" ></include>
</tabpanel>	

The above zul is backed by a ViewModel (MVVM pattern.)

page2's ViewModel can fire off a global command "openTab3." The tabbox's view model responds to that global command and then can open up tab 3...

this.selectedTab = 2;

This issue however is that page3.zul is not rendered when I try to load the tab up like this via Java. I want page3 to rendered deferred just as if you had manually clicked on the tab and triggered the fulfill, but I'm not sure how to do this?

(Note, if I remove the fulfill on tab3, it renders fine, but of course it's not deferred which is bad since I only want tab3's content to be initialized if it's truly needed.)

There must be something simple I'm missing?

delete flag offensive retag edit

9 Replies

Sort by ยป oldest newest

answered 2012-10-05 21:07:47 +0800

rickcr gravatar image rickcr
704 7

updated 2012-10-05 21:09:46 +0800

Is there maybe some kind of "onOpen" type of behavior I can listen for to signal the loading of the page? Surely what I'm trying to accomplish can be done programmatically some how?

I also should have noted in the initial post the tabbox is bound to the selectedTab property of its view model:

<tabbox id="myTabBox" selectedIndex="@bind(myBuilder.selectedTab)" >


But like I mentioned in the initial post, this doesn't trigger the 'fufill' in the same way manually clicking on the tab does.

link publish delete flag offensive edit

answered 2012-10-05 21:27:58 +0800

terrytornado gravatar image terrytornado flag of Germany
9373 3 7 16
http://www.oxitec.de/

Can this code help you?

	/**
	 * When the tab 'tabCallList' is selected.<br>
	 * Loads the zul-file into the tab.
	 * 
	 * @param event
	 * @throws IOException
	 */
	public void onSelect$tabCallList(Event event) throws IOException {

		// Check if the tabpanel is already loaded
		if (tabPanelCallList.getFirstChild() != null) {
			tabCallList.setSelected(true);

			return;
		}

		// Check if tab is not created than create and select them
		if (tabPanelCallList != null) {
                       
                       // calls Executions.createComponents...
			FHGuiUtils.createTabPanelContent(tabPanelCallList, this, "ModuleMainController", "/WEB-INF/pages/XXXXXXXXX/call/callList.zul");
			tabCallList.setSelected(true);
		}

	}

link publish delete flag offensive edit

answered 2012-10-06 01:37:02 +0800

rickcr gravatar image rickcr
704 7

Thanks Terry. I'm still a bit new and using a ViewModel approach and have some trouble following your code exactly (never mind that I'd need to know how your FHGuiUtils class is creating the content.)

Regardless the idea should be that my view model should be pretty clean. It's frustrating because the code is fine if users click on the tabs, there has to be some way to trigger the "onSelected" of the tabPanel and have it fire what "fulfill" is doing in the code below:

<tabbox id="myTabBox" selectedIndex="@bind(vm.selectedTab)" >
	<tabs visible="true">
		<tab id="tab1" label="Tab 1"  />
		<tab id="tab2" label="Tab 2"  />
		<tab id="tab3" label="Tab 3" />
	</tabs>					
	<tabpanels>						
		<tabpanel fulfill="tab1.onSelect">
			<include id="page1"  src="/page1.zul" ></include>
		</tabpanel>
		<tabpanel fulfill="tab2.onSelect">
			<include id="page2"  src="/page2.zul" ></include>
		</tabpanel>
		<tabpanel fulfill="tab3.onSelect">
			<include id="page3"  src="/pages3.zul" ></include>
		</tabpanel>
	</tabpanels>					
</tabbox>

if the tab box view model's property "selectedTab" changes it's value, the tab is correctly switched to, but the included zul is never initialized.

I guess rather than set the selectedTab, I could try to do something like you're doing Terry and programmatically set the tab's content. I'm just not sure how to do this within a View Model or if it's even the correct approach to take.

link publish delete flag offensive edit

answered 2012-10-08 05:44:44 +0800

rickcr gravatar image rickcr
704 7

Terrytornado, I might be stuck having to do something like you are showing. ( A real shame in my opinion since the concept of "fulfill' is there via a true select of the tab through a button click so you wouldn't think, through Java, I could get it to fire.)

But anyway, do you have some example how I could handle what your doing in a view model?

Right now my tabbox view model has some global listeners like...

//myVM
@GlobalCommand 
public void showFooBar(){
      this.selectedTab = FOO_BAR_TAB_INDEX;
 }

//my zul
<tabbox id="myTabBox" selectedIndex="@bind(myVM.selectedTab)" > 

I'd somehow inside of MyVM in showFooBar need to create the fooBar.zul and add it to the correct tabPanel, just not sure how to do all this within a ViewModel. At this point I don't even care about polluting the view model. (Although I do wish someone from the support team could help with this since there should be a way to get the separation of concerns working to accomplish this.) [I tend to think what the framework should handle is when something is bound to selectedIndex of a tabbox , the fulfill of a tablpanel that is set to onSelect should still fire. ]

Thanks again for any pointers

link publish delete flag offensive edit

answered 2012-10-08 06:15:40 +0800

hawk gravatar image hawk
2018 1 5
http://hawkphoenix.blogsp... ZK Team

Hi, rickcr

on-demand evaluation might solve your problem.
http://books.zkoss.org/wiki/ZK%20Developer's%20Reference/UI%20Composing/ZUML/On-demand%20Evaluation

link publish delete flag offensive edit

answered 2012-10-08 13:34:30 +0800

rickcr gravatar image rickcr
704 7

Hawk that was the first link I looked at, but it doesn't help with the issue I'm having (other than possibly the first link on that page which mentions http://books.zkoss.org/wiki/ZK_Developer%27s_Reference/UI_Composing/ZUML/Load_ZUML_in_Java)

All the examples on the link you posted only seem to work if binding fulfill on the tabbox to things the user could actually click on. Fulfill is never called when the selected tab is triggered by some other means (like I described above. )

Also, I though about binding all the clicks that could trigger the tab change but I can't seem to get that to work when your trying to bind to a click event on a tab that hasn't been rendered yet.

//TRIED
<tabpanel fulfill="tab3.onSelect, page2.someId.onClick"/>
<tabpanel fulfill="tab3.onSelect, tab2.page2.someId.onClick"/>
 

The problem is no matter what I try above I get null pointers.. probably because page2 is deferred so I can't even bing to an onClick on that page.

link publish delete flag offensive edit

answered 2012-10-09 01:49:22 +0800

hawk gravatar image hawk
2018 1 5
http://hawkphoenix.blogsp... ZK Team

Hi rickcr:
The "fulfill" you set is triggered by event, so if you change selection through data binding (MVVM approach). It won't trigger an event to the tab, thus the Tabpanel won't be dynamically created.

You can send an "onSelect" event to tab2 with:

Events.sendEvent("onSelect",tab2,null);

This will trigger "fulfill" work as expected.

But I suggest you to use MVC approach because the feature you want needs fine-grained component and event control. The fine-grained component control is not proper under MVVM approach.

link publish delete flag offensive edit

answered 2012-10-09 05:59:18 +0800

rickcr gravatar image rickcr
704 7

Thanks so much Hawk!

Created a SelectorComposer for my Tabbox and it listens for some global events that could fire from the ViewModels. Not sure if I'm using the most eloquent approach but it's working now...

@Subscribe("builderTabBoxSelectionQueue")
public void showBuilderTab(Event event) {
		Tab tab = null;
		if(event instanceof GlobalCommandEvent) {
			String command = ((GlobalCommandEvent)event).getCommand();
			if("buyerGroupPage".equals(command)){ 
				tab = buildingBlocks;
			} else if ("productsPage".equals(command)) { 
				tab = products;
			}
		}
		Events.sendEvent("onSelect", tab, null);
		tab.setSelected(true);
}

link publish delete flag offensive edit

answered 2017-05-10 10:41:12 +0800

hawk gravatar image hawk
2018 1 5
http://hawkphoenix.blogsp... ZK Team

A better solution.

<tabpanel fulfill="self.linkedTab.onSelect"> </tabpanel>

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2012-10-05 13:30:34 +0800

Seen: 352 times

Last updated: May 10