We use AjaxLazyLoadingPanel, and want to be able to trigger the process of showing the indicator, and requesting the panels contents with a separate Ajax request, after the first complete render has finished. I.e. do the whole process over and over, without having to reload the entire page.

I came up with this, which I was surprised actually worked first try :) gotta love Wicket.

But perhaps there's a better way to do it ? A simpler way? Something I'm missing? I tried simply replacing the lazy loading panel with a new instance of one but that didn't seem to have an effect - I think the magic is in the adding a new AbstractAjaxBehaviour on each request.


import org.apache.wicket.Component;
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
import org.apache.wicket.markup.html.IHeaderResponse;

/**
 * An {...@link AjaxLazyLoadPanel} extension which allows it to
* {...@link #restart(AjaxRequestTarget)} the process of showing the loading
 * indicator, then load it's contents using a separate Ajax request.
 *
 * @author Antony Stubbs
 */
abstract public class ReloadingAjaxLazyPanel extends AjaxLazyLoadPanel {

    private static final long serialVersionUID = 1L;

    public ReloadingAjaxLazyPanel(String id) {
        super( id );
    }

    /**
* Causes the {...@link AjaxLazyLoadPanel} to re-display the loading indicator,
     * then in a seperate ajax request, get it's contents.
     *
     * @param target
     */
    public void restart(AjaxRequestTarget target) {
        target.addComponent( this );

        // replace panel contents with loading icon
        Component loadingComponent = getLoadingComponent( "content" );

        this.replace( loadingComponent );

        // add ajax behaviour to install call back
        loadingComponent.add( new AbstractDefaultAjaxBehavior() {

            private static final long serialVersionUID = 1L;

            @Override
            protected void respond(AjaxRequestTarget target) {
Component component = ReloadingAjaxLazyPanel.this.getLazyLoadComponent( "content" ); ReloadingAjaxLazyPanel .this.replace( component.setRenderBodyOnly( true ) );
                target.addComponent( ReloadingAjaxLazyPanel.this );
                // setState((byte)2);
            }

            @Override
            public void renderHead(IHeaderResponse response) {
                super.renderHead( response );
response.renderOnDomReadyJavascript( getCallbackScript().toString() );
            }

        } );
    }

}

As you can see, there is duplication from AjaxLazyLoadingPanel - which would need re-factoring in order to remove. - no problem there. But also, because the setState method is private, I can't use that state system.

Regards,
Antony Stubbs,
NZ
http://friendfeed.com/astubbs

Reply via email to