TabbedPanel with AjaxSelfUpdatingTimerBehavior

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

TabbedPanel with AjaxSelfUpdatingTimerBehavior

Decebal Suiu-4
Hello

I use AjaxSelfUpdatingTimerBehavior on one tab and when switching to
another tab I want to stop it.
The AjaxSelfUpdatingTimerBehavior will be active only if this tab is
selected (start timer behavior when select the tab and stop it when
select other tab).
Any help is welcome.

Thanks,
Decebal

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Decebal Suiu
When I switch to other tab I received a PageExpiredException:
org.apache.wicket.protocol.http.PageExpiredException: No behavior listener found with behaviorId 0; Component: [MarkupContainer [Component id = panel]]

Any idea how can I remove/stop the AjaxSelfUpdatingTimerBehavior?
I created a visitor (in TabbedPanel.newLink) that visit all children components and for each component if I found that a behavior is an instance of AjaxSelfUpdatingTimerBehavior call stop method and remove the behavior but the exception appears again on tab switch.
Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Ernesto Reinaldo Barreiro-4
Why not "put" the behavior "outside" the tab and just do something if
you are on the wight tab?

Ernesto

On Mon, Jun 7, 2010 at 3:07 PM, Decebal Suiu <[hidden email]> wrote:

>
> When I switch to other tab I received a PageExpiredException:
> org.apache.wicket.protocol.http.PageExpiredException: No behavior listener
> found with behaviorId 0; Component: [MarkupContainer [Component id = panel]]
>
> Any idea how can I remove/stop the AjaxSelfUpdatingTimerBehavior?
> I created a visitor (in TabbedPanel.newLink) that visit all children
> components and for each component if I found that a behavior is an instance
> of AjaxSelfUpdatingTimerBehavior call stop method and remove the behavior
> but the exception appears again on tab switch.
> --
> View this message in context: http://apache-wicket.1842946.n4.nabble.com/TabbedPanel-with-AjaxSelfUpdatingTimerBehavior-tp2243691p2245915.html
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Ernesto Reinaldo Barreiro-4
I meant "right tab"

On Mon, Jun 7, 2010 at 3:54 PM, Ernesto Reinaldo Barreiro
<[hidden email]> wrote:

> Why not "put" the behavior "outside" the tab and just do something if
> you are on the wight tab?
>
> Ernesto
>
> On Mon, Jun 7, 2010 at 3:07 PM, Decebal Suiu <[hidden email]> wrote:
>>
>> When I switch to other tab I received a PageExpiredException:
>> org.apache.wicket.protocol.http.PageExpiredException: No behavior listener
>> found with behaviorId 0; Component: [MarkupContainer [Component id = panel]]
>>
>> Any idea how can I remove/stop the AjaxSelfUpdatingTimerBehavior?
>> I created a visitor (in TabbedPanel.newLink) that visit all children
>> components and for each component if I found that a behavior is an instance
>> of AjaxSelfUpdatingTimerBehavior call stop method and remove the behavior
>> but the exception appears again on tab switch.
>> --
>> View this message in context: http://apache-wicket.1842946.n4.nabble.com/TabbedPanel-with-AjaxSelfUpdatingTimerBehavior-tp2243691p2245915.html
>> Sent from the Wicket - User mailing list archive at Nabble.com.
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Decebal Suiu
In reply to this post by Ernesto Reinaldo Barreiro-4
Thanks, I will try. The problem with your approach is that in our application each tab is a "section" that can be added using spring framework (modular architecture). For example the dashboards tab has many widget panels, each widget panel is auto refreshable (different time for different widget). Also each tab supports contributors (you can add panels, fragments that can be auto refreshable). I think that will be better to stop/remove behaviors automatically on tab switch and not to force each contributor to do it.
What's mean for you "outside" the tab?
Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Ernesto Reinaldo Barreiro-4
I mean to have the timer attached to a component that is a sibling of
the tab. You could register component as listener of this behavior and
have the timer ask the components if the have changes to "repaint".

I´m not sure but the problem you have might happen as follows:

1-When you switch tabs you stop the behavior at server side.
2-On client side there is a queued AJAX request (timer) asking to
refresh a component.
3-When tab is switched the component the "timer" is trying to address
is no longer on the path  specified by the request.

If timer is on a sibling f the tab this will not happen.

Ernesto

On Mon, Jun 7, 2010 at 9:16 PM, Decebal Suiu <[hidden email]> wrote:

>
> Thanks, I will try. The problem with your approach is that in our application
> each tab is a "section" that can be added using spring framework (modular
> architecture). For example the dashboards tab has many widget panels, each
> widget panel is auto refreshable (different time for different widget). Also
> each tab supports contributors (you can add panels, fragments that can be
> auto refreshable). I think that will be better to stop/remove behaviors
> automatically on tab switch and not to force each contributor to do it.
> What's mean for you "outside" the tab?
> --
> View this message in context: http://apache-wicket.1842946.n4.nabble.com/TabbedPanel-with-AjaxSelfUpdatingTimerBehavior-tp2243691p2246419.html
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Decebal Suiu
I tried your advice and I keep the timer behavior "outside" the tab, in MyTabbedPanel. In the refreshable panel  I register a listener with MyApplication.get().addRefreshableComponent(Duration,Component). When I select the tab with the refreshable panel all works fine but when I switch the tab I received the same "PageExpiredException: No behavior listener found with behaviorId".
Did I do something wrong or I misunderstood you?

Below is the java code:

public class MyTabbedPanel extends AjaxTabbedPanel {

        private static final long serialVersionUID = 1L;
       
        private List<AbstractAjaxTimerBehavior> ajaxTimerBehaviors;
               
        public ImageTabbedPanel(String id, List<ITab> tabs) {
                super(id, tabs);

                ajaxTimerBehaviors = new ArrayList<AbstractAjaxTimerBehavior>();
        }

        @Override
        protected WebMarkupContainer newLink(String linkId, final int index) {
                List<? extends ITab> tabs = getTabs();
               
                // check for usage of our custom class, if it is not our class,
                // add as image empty container - this way you can use image only in tabs you want
                ITab currentTab = tabs.get(index);
                if (currentTab instanceof ImageTab) {
                        final ImageTab imageTab = (ImageTab) currentTab;
                        return new ImageTabLink(linkId, imageTab.getImage()) {
                               
                                private static final long serialVersionUID = 1L;

                                @Override
                                public void onClick(AjaxRequestTarget target) {
                                        removeAjaxTimerBehaviors();
                                        clearRefreshableComponents();
                                       
                                        setSelectedTab(index);
                                       
                                        createAjaxTimerBehaviors();
                                        addAjaxTimerBehaviors();
                                        target.addComponent(MyTabbedPanel.this);
                                }
                               
                        };
                } else {
                        WebMarkupContainer link = super.newLink(linkId, index);
                        link.add(new WebMarkupContainer("image").setVisible(false));
                       
                        return link;
                }
        }
       
    private Map<Duration, List<Component>> getRefreshableComponents() {
    return MyApplication.get().getRefreshableComponents();
    }
   
    private void clearRefreshableComponents() {
    getRefreshableComponents().clear();
    }
   
        private void createAjaxTimerBehaviors() {
                final Map<Duration, List<Component>> refreshableComponents = getRefreshableComponents();
                Set<Duration> durations = getRefreshableComponents().keySet();
                for (final Duration duration : durations) {
                        AbstractAjaxTimerBehavior behavior = new AbstractAjaxTimerBehavior(duration) {

                                private static final long serialVersionUID = 1L;

                                @Override
                                protected void onTimer(AjaxRequestTarget target) {
                                        List<Component> components = refreshableComponents.get(duration);
                                        for (Component component : components) {
                                                target.addComponent(component);
                                        }
                                }
                               
                        };
                        ajaxTimerBehaviors.add(behavior);
                }
        }
       
        private void addAjaxTimerBehaviors() {
                for (IBehavior behavior : ajaxTimerBehaviors) {
                        add(behavior);
                }
        }
       
        private void removeAjaxTimerBehaviors() {
                for (AbstractAjaxTimerBehavior behavior : ajaxTimerBehaviors) {
                        behavior.stop();
                        remove(behavior);
                }
               
                ajaxTimerBehaviors.clear();
        }
       
}
Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Ernesto Reinaldo Barreiro-4
What I meant was to have a unique timer behavior attached to something like

MyTimerTabbedPanel

<wicket:panel>
  <div wicket:id="timerContext"></div>
 <div wicket:id="tabs"></div>
</wicket:panel>

and you attach your timer to timerContext. Then you create an interface like

ITimerListener {
  boolean hasChnaged();
  Component getComponentToRepaint();
}

Then the (timer) components on the tabs implement this interface and
register themselves on a list of  ITimerListener you keep on
MyTimerTabbedPanel.  Then on the timer event you go through this list
and ask the (visible) components if they have to repaint themselves.
This way you timer will be always attached to the panel.

This is just an idea... that might work;-) Can you create a quickstart
(simplified project) for this?

Best,

Ernesto

On Tue, Jun 8, 2010 at 2:44 PM, Decebal Suiu <[hidden email]> wrote:

>
> I tried your advice and I keep the timer behavior "outside" the tab, in
> MyTabbedPanel. In the refreshable panel  I register a listener with
> MyApplication.get().addRefreshableComponent(Duration,Component). When I
> select the tab with the refreshable panel all works fine but when I switch
> the tab I received the same "PageExpiredException: No behavior listener
> found with behaviorId".
> Did I do something wrong or I misunderstood you?
>
> Below is the java code:
>
> public class MyTabbedPanel extends AjaxTabbedPanel {
>
>        private static final long serialVersionUID = 1L;
>
>        private List<AbstractAjaxTimerBehavior> ajaxTimerBehaviors;
>
>        public ImageTabbedPanel(String id, List<ITab> tabs) {
>                super(id, tabs);
>
>                ajaxTimerBehaviors = new ArrayList<AbstractAjaxTimerBehavior>();
>        }
>
>        @Override
>        protected WebMarkupContainer newLink(String linkId, final int index) {
>                List<? extends ITab> tabs = getTabs();
>
>                // check for usage of our custom class, if it is not our class,
>                // add as image empty container - this way you can use image only in tabs
> you want
>                ITab currentTab = tabs.get(index);
>                if (currentTab instanceof ImageTab) {
>                        final ImageTab imageTab = (ImageTab) currentTab;
>                        return new ImageTabLink(linkId, imageTab.getImage()) {
>
>                                private static final long serialVersionUID = 1L;
>
>                                @Override
>                                public void onClick(AjaxRequestTarget target) {
>                                        removeAjaxTimerBehaviors();
>                                        clearRefreshableComponents();
>
>                                        setSelectedTab(index);
>
>                                        createAjaxTimerBehaviors();
>                                        addAjaxTimerBehaviors();
>                                        target.addComponent(MyTabbedPanel.this);
>                                }
>
>                        };
>                } else {
>                        WebMarkupContainer link = super.newLink(linkId, index);
>                        link.add(new WebMarkupContainer("image").setVisible(false));
>
>                        return link;
>                }
>        }
>
>    private Map<Duration, List<Component>> getRefreshableComponents() {
>        return MyApplication.get().getRefreshableComponents();
>    }
>
>    private void clearRefreshableComponents() {
>        getRefreshableComponents().clear();
>    }
>
>        private void createAjaxTimerBehaviors() {
>                final Map<Duration, List<Component>> refreshableComponents =
> getRefreshableComponents();
>                Set<Duration> durations = getRefreshableComponents().keySet();
>                for (final Duration duration : durations) {
>                        AbstractAjaxTimerBehavior behavior = new
> AbstractAjaxTimerBehavior(duration) {
>
>                                private static final long serialVersionUID = 1L;
>
>                                @Override
>                                protected void onTimer(AjaxRequestTarget target) {
>                                        List<Component> components = refreshableComponents.get(duration);
>                                        for (Component component : components) {
>                                                target.addComponent(component);
>                                        }
>                                }
>
>                        };
>                        ajaxTimerBehaviors.add(behavior);
>                }
>        }
>
>        private void addAjaxTimerBehaviors() {
>                for (IBehavior behavior : ajaxTimerBehaviors) {
>                        add(behavior);
>                }
>        }
>
>        private void removeAjaxTimerBehaviors() {
>                for (AbstractAjaxTimerBehavior behavior : ajaxTimerBehaviors) {
>                        behavior.stop();
>                        remove(behavior);
>                }
>
>                ajaxTimerBehaviors.clear();
>        }
>
> }
>
> --
> View this message in context: http://apache-wicket.1842946.n4.nabble.com/TabbedPanel-with-AjaxSelfUpdatingTimerBehavior-tp2243691p2247320.html
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Decebal Suiu
Hello Ernesto

I understood now. I single AbstractAjaxTimerBehavior on "timerContext" component and onTimer I will iterate  through all visible components from TabbedPanel that implements ITimerListener. One problem is that DashboardsTab (for example) contains many auto refreshable widget panels with various durations (panel1 at 5 seconds, panel2 at 15 seconds, etc). What duration may I put in the single timer on "timerContext"? (the min duration).
And I don't see the role of the hasChnaged() from ITimerListener in my case. I want to do an auto refresh on some panels at some interval and in this case hasChnaged() returns always true (or for example if I want to refresh the component after 30 seconds and the unique timer has duration 10 seconds I will ignore 2 calls?)

Thnaks,
decebal
Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Ernesto Reinaldo Barreiro-4
Hi Decebal,

Was just an idea you will have to adapt it to your needs... It would
be interesting to see why your original setting is not working: as I
only was guessing an explanation which might be wrong.

Best,

Ernesto

On Tue, Jun 8, 2010 at 3:57 PM, Decebal Suiu <[hidden email]> wrote:

>
> Hello Ernesto
>
> I understood now. I single AbstractAjaxTimerBehavior on "timerContext"
> component and onTimer I will iterate  through all visible components from
> TabbedPanel that implements ITimerListener. One problem is that
> DashboardsTab (for example) contains many auto refreshable widget panels
> with various durations (panel1 at 5 seconds, panel2 at 15 seconds, etc).
> What duration may I put in the single timer on "timerContext"? (the min
> duration).
> And I don't see the role of the hasChnaged() from ITimerListener in my case.
> I want to do an auto refresh on some panels at some interval and in this
> case hasChnaged() returns always true (or for example if I want to refresh
> the component after 30 seconds and the unique timer has duration 10 seconds
> I will ignore 2 calls?)
>
> Thnaks,
> decebal
> --
> View this message in context: http://apache-wicket.1842946.n4.nabble.com/TabbedPanel-with-AjaxSelfUpdatingTimerBehavior-tp2243691p2247422.html
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Decebal Suiu
Hello Ernesto,

I resolved the problem. The AjaxSelfUpdatingTimerBehavior was added by me on the panel returned by the ITab.getPanel() method. I put the behavior on a child of the tab panel and it works.
Do you have an explanation why I retrieve "PageExpiredException: No behavior listener found with behaviorId" in the first case (behavior on the tab panel)?
Is it something that keeps by the role of onlyTargetActivePage() method? In the second case, the ajax was stopped because of precondition check (ignore if not active) but in the first case (with the error) the condition with active page is not true.

Thanks,
Decebal
Reply | Threaded
Open this post in threaded view
|

Re: TabbedPanel with AjaxSelfUpdatingTimerBehavior

Ernesto Reinaldo Barreiro-4
Decebal,

I think TabbedPanel works by replacing the active panel with the
result of ITab.getPanel: see method setSelectedTab(int index). So,
when you click on a tab the previous one is removed form the component
tree (and therefore TimerAjaxCallBacks are not able to find the
component). Have you considered using JavaScript based tabs (as the
ones proc=vided by jquery)? That way your component tree will be
always consistent.

Best,

Ernesto

On Thu, Jun 10, 2010 at 3:02 PM, Decebal Suiu <[hidden email]> wrote:

>
> Hello Ernesto,
>
> I resolved the problem. The AjaxSelfUpdatingTimerBehavior was added by me on
> the panel returned by the ITab.getPanel() method. I put the behavior on a
> child of the tab panel and it works.
> Do you have an explanation why I retrieve "PageExpiredException: No behavior
> listener found with behaviorId" in the first case (behavior on the tab
> panel)?
> Is it something that keeps by the role of onlyTargetActivePage() method? In
> the second case, the ajax was stopped because of precondition check (ignore
> if not active) but in the first case (with the error) the condition with
> active page is not true.
>
> Thanks,
> Decebal
> --
> View this message in context: http://apache-wicket.1842946.n4.nabble.com/TabbedPanel-with-AjaxSelfUpdatingTimerBehavior-tp2243691p2250376.html
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]