0

Refresh of component triggered by different controller

asked 2012-10-05 05:25:17 +0800

starwarsfan gravatar image starwarsfan
36

Hi there

I've defined the following snippet on a zul file:

...
    <borderlayout>
        <north size="80px" flex="true" border="normal" splittable="false" collapsible="false">
            <div apply="org.foo.bar.LoginViewCtrl" id="loginViewCtrl">
                <div id="loginDiv">
                    Name: <textbox id="txtBoxUsername" />
                    Password: <textbox id="txtBoxPassword" type="password" />
                    <button id="btnConfirm" label="Login" />
                </div>
                <label id="lblMessage" />
                <div id="logoutDiv">
                    <button id="btnLogout" label="Logout" />
                </div>
            </div>
        </north>

        <west title="Navigation" size="20%" flex="true" splittable="true" collapsible="true"
            apply="org.foo.bar.NavigationTreeForwardComposer">
            <tree id="navigationTree" />
        </west>
...

NavigationTreeForwardComposer handles all the navigation and what's visible there, loads new navigation entries depending on state of current user and so on. The question is, how to refresh/update/redraw the navigation tree triggered by LoginViewCtrl!? If someone is logging in, the navigation tree should be updated.

I achieve this at the moment only via a redirect after a login. But this redirect reloads the whole page.

LoginViewCtrl is defined like this:

...
public class LoginViewCtrl extends GenericForwardComposer {

    @Wire
    private Textbox txtBoxPassword;
    @Wire
    private Textbox txtBoxUsername;
    @Wire
    private Label lblMessage;
    @Wire
    private Div loginDiv;
    @Wire
    private Div logoutDiv;
    @Wire
    private Button btnConfirm;
    @Wire
    private Button btnLogout;
    @Wire
    private Window mainWindow;

    public void onOK$txtBoxPassword() {
        onClick$btnConfirm();
    }

    public void onClick$btnConfirm() {
        final UserCredentialManager mgmt = UserCredentialManager.getInstance(Sessions.getCurrent());
        mgmt.login(txtBoxUsername.getValue(), txtBoxPassword.getValue());
        if (mgmt.isAuthenticated()) {
            setLoginDivVisible(false);
            lblMessage.setValue("Welcome " + mgmt.getUser().getFirstname());
//            mainWindow.getFellow("navigationTree").invalidate();
            execution.sendRedirect("index.zul");
        } else {
            setLoginDivVisible(true);
            lblMessage.setValue("Your User Name or Password is invalid!");
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public void doAfterCompose(final Component comp) throws Exception {
        super.doAfterCompose(comp);
        final UserCredentialManager mgmt = UserCredentialManager.getInstance(Sessions.getCurrent());
        boolean loginDivVisible = true;
        if (mgmt.isAuthenticated()) {
            lblMessage.setValue("Welcome " + mgmt.getUser().getFirstname());
            loginDivVisible = false;
//            execution.sendRedirect("index.zul");
        }
        setLoginDivVisible(loginDivVisible);
        txtBoxUsername.setFocus(true);
    }
...

If I activate the redirect on doAfterCompose(...), the page get's reloaded all the thime. Not so good. With the redirect on onClick$btnConfirm() it's working but with a reload of the whole page. Even the usage of .invalidate() doesn't solve the problem.

Then I tried to use an EventListener on doAfterCompose():

...
    @Wire
    private Tree navigationTree;
...
    public void doAfterCompose(final Component comp) throws Exception {
        super.doAfterCompose(comp);
        final UserCredentialManager mgmt = UserCredentialManager.getInstance(Sessions.getCurrent());
        boolean loginDivVisible = true;
        if (mgmt.isAuthenticated()) {
            lblMessage.setValue("Welcome " + mgmt.getUser().getFirstname());
            loginDivVisible = false;
//            execution.sendRedirect("index.zul");
        }
        btnConfirm.addEventListener(Events.ON_CLICK, new EventListener() {

            @Override
            public void onEvent(final Event event) throws Exception {
//                navigationTree.invalidate();
//                navigationTree.redraw(new java.io.StringWriter());
//                navigationTree.notify();
//                final Component navigation = mainWindow.getFellow("navigationTree");
//                navigation.invalidate();
            }
        });
        setLoginDivVisible(loginDivVisible);
        txtBoxUsername.setFocus(true);
    }
...

But whatever I try, the navigation tree is not refreshed. So where is my mistake? What is the procedure to let different controllers interact?

Many thanks in advance and kind regards,
Yves

delete flag offensive retag edit

5 Replies

Sort by ยป oldest newest

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

aros54 gravatar image aros54
66

You should use a postEvent command to post a ON_USER event to the Div to refresh. Look at these (trivial) code snippets that toggle the display of two Divs:

	<div id="div0" apply="Div0Composer">
		<div id="div1">
			<vbox>
				<label value="This is a div"/>
				<button id="div1btn" label="Toggle"/>
			</vbox>
   		</div>
   		<div id="div2" visible="false">
			<vbox>
				<label value="This is another div"/>
				<button id="div2btn" label="Toggle"/>
			</vbox>
   		</div>
	</div>

 
public class Div0Composer extends GenericForwardComposer {

	private static final long serialVersionUID = 1L;
	
	private Div div1;
	private Div div2;
	private Button div1btn;
	private Button div2btn;

	private void toggleDiv() {
		div1.setVisible(!div1.isVisible());
		div2.setVisible(!div2.isVisible());
	}
	
	public void onClick$div1btn() {
		Events.postEvent(Events.ON_USER, div1, null);
	}
	
	public void onClick$div2btn() {
		Events.postEvent(Events.ON_USER, div2, null);
	}

	public void onUser$div1() {
		toggleDiv();
	}

	public void onUser$div2() {
		toggleDiv();
	}
}

/Adriano

link publish delete flag offensive edit

answered 2012-10-05 18:49:30 +0800

starwarsfan gravatar image starwarsfan
36

updated 2012-10-05 18:50:27 +0800

Hi Adriano

Thx for your response. Unfortunately it's not working. Please note, I'm using two different Controllers, maybe that's the tricky part?

I tried it the following two ways but as I said, the navigation tree is not refreshed:

...
    @Wire
    private Tree navigationTree;
...
    public void onClick$btnConfirm() {
        ...
//        Events.postEvent(Events.ON_USER, navigationTree, null);
//        Events.postEvent(Events.ON_USER, mainWindow.getFellow("navigationTree"), null);
    }

If I hit F5 to reload the page, then the navigation tree shows the correct content. Any other ideas please?

Kind regards,
Yves

link publish delete flag offensive edit

answered 2012-10-05 19:08:49 +0800

starwarsfan gravatar image starwarsfan
36

updated 2012-10-05 19:09:23 +0800

Hi again

I'm a small step closer to the desired functionality. :-) After registering an EventListener on the NavigationTreeForwardComposer like this:

...
    public void doAfterCompose(final Component comp) throws Exception {
        super.doAfterCompose(comp);

        navigationTree.setItemRenderer(new NavigationTreeRenderer());

        navigationTreeModel = new NavigationTreeModel();
        navigationTree.setModel(navigationTreeModel);

        navigationTree.addEventListener(Events.ON_USER, new EventListener() {

            @Override
            public void onEvent(final Event event) throws Exception {
                logger.info("onEvent(...) called");
                navigationTree.invalidate();
//                navigationTree.redraw(new java.io.StringWriter());
            }
        });

        logger.debug("Created navigation tree");
    }
...

I see the log output if clicking the login button on the page. So the event from my login controller is properly forwarded to the NavigationTreeForwardComposer. But the content of the navigation tree is still not updated on the page. As stated above, I tried invalidate() and redraw(...) but without success.

Any idea or hint into the right direction would be much appreciated.

Thx a lot and kind regards,
Yves

link publish delete flag offensive edit

answered 2012-10-05 21:23:03 +0800

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

Have you read about EventQueue ? It works like a global listener. Defined in moduleA you can reach it from moduleB moduleC... publish/subscribe

best
Stephan

link publish delete flag offensive edit

answered 2012-10-08 05:27:01 +0800

starwarsfan gravatar image starwarsfan
36

Hi all together

Thx a lot for all the tips and hints. Nearly everything works as expected. The odd thing is: I figured out, that something is wrong on my navigation tree component (or I didn't implement all neccessary parts?). I think to start a separate thread for this problem.

Kind regards,
Yves

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 05:25:17 +0800

Seen: 180 times

Last updated: Oct 08 '12

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More