1

I have some form which searching result from db. How can I display results from db automatically every x second ? This means submit button every x second. All I found about refreshing is this class:

add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(10)) {
    private static final long serialVersionUID = 1;       
    });

which just refresh page not submit form. Then I wanna inspire from wicket example pages: http://www.wicket-library.com/wicket-examples/ajax/clock?1 but when I click to source code I just see urls which just return: Internal error

UPDATE:

I try to call simple javascript and then submit form from js:

    add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(10)) {
        private static final long serialVersionUID = 1L;

        @Override
        protected void onPostProcessTarget(AjaxRequestTarget target) {
            target.appendJavaScript("alert('hello');");
        }

    });

but with no success

hudi
  • 15,555
  • 47
  • 142
  • 246

3 Answers3

2

You'll need a combination of AbstractAjaxTimerBehaviour to raise an event that triggers an AjaxFormSubmittingBehaviour. I didn't try this but from my wicket experience and the JavaDocs of both behaviours, it should work.

Since there seems to be the need for some demo code...

Disclaimer: This was thrown together in a couple of minutes by Copy'n'Pasting from both mentioned classes. So this isn't good code, tested code or anything I'd put into production without having a solid look at it. But it seems to work.

First you need the combined Behavior:

public abstract class AjaxTimerFormSubmitBehavior extends AbstractAjaxTimerBehavior {

    /**
     * should never be accessed directly (thus the __ cause its overkill to
     * create a super class), instead always use #getForm()
     */
    private Form<?> __form;

    private boolean defaultProcessing = true;

    /**
     * @param updateInterval
     */
    public AjaxTimerFormSubmitBehavior(Duration updateInterval) {
        this(null, updateInterval);
    }

    public AjaxTimerFormSubmitBehavior(Form<?> form, Duration updateInterval) {
        super(updateInterval);
        __form = form;

        if (form != null) {
            form.setOutputMarkupId(true);
        }
    }

    @Override
    protected void onTimer(final AjaxRequestTarget target) {
        getForm().getRootForm().onFormSubmitted(new IFormSubmitter() {
            public Form<?> getForm() {
                return AjaxTimerFormSubmitBehavior.this.getForm();
            }

            public boolean getDefaultFormProcessing() {
                return AjaxTimerFormSubmitBehavior.this.getDefaultProcessing();
            }

            public void onSubmit() {
                AjaxTimerFormSubmitBehavior.this.onSubmit(target);
            }

            public void onError() {
                AjaxTimerFormSubmitBehavior.this.onError(target);
            }
        });
    }

    /**
     * @return Form that will be submitted by this behavior
     */
    public final Form<?> getForm() {
        if (__form == null) {
            __form = findForm();

            if (__form == null) {
                throw new IllegalStateException(
                        "form was not specified in the constructor and cannot "
                                + "be found in the hierarchy of the component this behavior "
                                + "is attached to: Component="
                                + getComponent().toString(false));
            }
        }
        return __form;
    }

    /**
     * @see Button#getDefaultFormProcessing()
     *
     * @return {@code true} for default processing
     */
    public boolean getDefaultProcessing() {
        return defaultProcessing;
    }

    /**
     * Finds form that will be submitted
     *
     * @return form to submit or {@code null} if none found
     */
    protected Form<?> findForm() {
        // try to find form in the hierarchy of owning component
        Component component = getComponent();
        if (component instanceof Form<?>) {
            return (Form<?>) component;
        } else {
            return component.findParent(Form.class);
        }
    }

    /**
     * Listener method that is invoked after the form has been submitted and
     * processed without errors
     *
     * @param target
     */
    protected abstract void onSubmit(AjaxRequestTarget target);

    /**
     * Listener method invoked when the form has been processed and errors
     * occurred
     *
     * @param target
     */
    protected abstract void onError(AjaxRequestTarget target);

}

And then you've got to use it

public class HomePage extends WebPage {
    private static final long serialVersionUID = 1L;

    private Integer counter = 0;

    public HomePage(final PageParameters parameters) {
        final Label label = new Label("counter", new PropertyModel<Integer>(this, "counter"));
        label.setOutputMarkupId(true);
        add(label);
        Form form = new Form("form");
        form.add(new AjaxTimerFormSubmitBehavior(form, Duration.seconds(10)) {

            @Override
            protected void onSubmit(AjaxRequestTarget target) {
                counter++;
                target.add(label);
            }

            @Override
            protected void onError(AjaxRequestTarget target) {
                // TODO Auto-generated method stub

            }
        });
        add(form);
    }

    public Integer getCounter() {
        return counter;
    }

    public void setCounter(Integer counter) {
        this.counter = counter;
    }
}

I hope that'll give you an idea...

Here is a small demo war-file. Just download, toss at your favorite Application Container and watch what it does. It contains the sources too.

Nicktar
  • 5,548
  • 1
  • 28
  • 43
  • hm and can you post here some piece of code how should I combine this two class ? – hudi Jun 27 '12 at 09:53
  • hm interesting example but I dont understand it. What is doing property "counter" ? You just increment it and I cant see that you are using it in code – hudi Jun 28 '12 at 15:00
  • @hudi It's the model of the Label and just used to proof that the form is indeed submitted every 10 seconds as the submit increments the value and the label displays the incremented value. It's just a demo. – Nicktar Jun 28 '12 at 16:35
1

To set an interval an run some code regularly, you could do this using JQuery:

$(document).ready(function(){
    //ajax code here
    myVar = setInterval(someCode, 10000);
});

That what you after?

EDIT

Just realised... set Interval isn't actually a JQuery function.

//use this to stop it    
clearInterval(myVar);
Danny
  • 468
  • 2
  • 7
  • hm but I am using java where should I add this – hudi Jun 26 '12 at 11:38
  • Here `10000` means 10 seconds. `setInterval` function want time in miliseconds. just for help... – shan Jun 26 '12 at 11:39
  • Silly me. Didn't see that. I don't use Java but I have just found this... http://stackoverflow.com/questions/652389/java-equivelant-of-setinterval-in-javascript – Danny Jun 26 '12 at 11:43
  • and I dont use JQuery so I dont think this can help me – hudi Jun 26 '12 at 12:01
  • certainly this is the most easy way to do that and also does not require any time of server processing. – osdamv Jun 26 '12 at 18:35
0

I think you did the right things, I think you attached the behavior to a component that doesn't change itself. You will need to write the update logic in the onPostProcessTarget method and add the component you want to refresh to the ajaxRequestTarget. Have a look at the network tab of Firebug or Chrome to see if the behavior triggers a call to the server.

If it's not the case, it might be that the precondition of the script fails (markup id change could do this)

Cedric Gatay
  • 1,553
  • 3
  • 12
  • 17