Dennis Anderson
Dennis Anderson

Reputation: 1396

Wicket - Ajax PropertyListView

I got some data going into my propertyListview, got a container around it but when i want to update it with Ajax it aint doing nothing ! How do i update my PropertyListview with Ajax?

EDIT in the background im using JSON Parse to parse data from a weatherstation, that data can change alot, so i want to update the data in the propertyListview

public class WeerPanel extends Panel {

public WeerPanel(String id) throws IOException {
    super(id);

    final WeerService weerService = new WeerServiceImpl();

    PropertyListView<Weer> newview = new PropertyListView<Weer>("weer", weerService.getWeer()) {

        @Override
        protected void populateItem(ListItem<Weer> item) {
            item.add(new Label("temperatuur"));
            item.add(new StaticImage("type", String.format("images/%s.png", item.getModelObject().getType())));
            item.add(new Label("omschrijving"));
        }
    };

    final WeerVoorspellingService weerVoorspellingService = new WeerVoorspellingServiceImpl();

    PropertyListView<WeerVoorspelling> hateView = new PropertyListView<WeerVoorspelling>("weersvoorspelling", weerVoorspellingService.getWeerVoorspelling()) {

        @Override
        protected void populateItem(ListItem<WeerVoorspelling> item) {
            item.add(new Label("dag"));
            item.add(new StaticImage("typeVoorspelling", String.format("images/%s.png", item.getModelObject().getType())));
            item.add(new Label("minTemperatuur"));
            item.add(new Label("maxTemperatuur"));
        }
    };

    final WebMarkupContainer containerWeer = new WebMarkupContainer("containerWeer");
    containerWeer.setOutputMarkupId(true);
    containerWeer.add(hateView);
    containerWeer.add(newview);
    add(containerWeer);

    add(new AbstractAjaxTimerBehavior(Duration.seconds(10)) {

        @Override
        protected final void onTimer(AjaxRequestTarget target) {
            target.add(containerWeer);
        }
    });
}

}

This is some code i do in the background, its a dummy that changes the temp of the weather by a random number each time.

                Random r = new Random();
            int randomInt = r.nextInt(100);
            weer.add(new Weer("rain", "Mooi bewolkt", randomInt, v.getVoorspellingen()));

The dummy code is fine, but STILL there is nothing of a change to see at my page.... as if my the list isnt getting any new data..

FIXED here is the code for people that will find this handy

public class WeerPanel extends Panel {

    public WeerPanel(String id) {

        super(id);

        add(createContainer());

        add(new AbstractAjaxTimerBehavior(Duration.seconds(10)) {
            @Override
            protected final void onTimer(AjaxRequestTarget target) {
                target.add(createContainer());
            }
        });
    }

    private final WebMarkupContainer createContainer() {
        final WeerService weerService = new WeerServiceImpl();

        PropertyListView<Weer> newview = null;
        try {
            newview = new PropertyListView<Weer>("weer", weerService.getWeer()) {

                @Override
                protected void populateItem(ListItem<Weer> item) {
                    item.add(new Label("temperatuur"));
                    item.add(new StaticImage("type", String.format("images/%s.png", item.getModelObject().getType())));
                    item.add(new Label("omschrijving"));
                }
            };
        } catch (Exception e) {
            e.printStackTrace();
        }

        WeerVoorspellingService weerVoorspellingService = new WeerVoorspellingServiceImpl();

        PropertyListView<WeerVoorspelling> hateView = null;
        try {
            hateView = new PropertyListView<WeerVoorspelling>("weersvoorspelling", weerVoorspellingService.getWeerVoorspelling()) {

                @Override
                protected void populateItem(ListItem<WeerVoorspelling> item) {
                    item.add(new Label("dag"));
                    item.add(new StaticImage("typeVoorspelling", String.format("images/%s.png", item.getModelObject().getType())));
                    item.add(new Label("minTemperatuur"));
                    item.add(new Label("maxTemperatuur"));
                }
            };
        } catch (Exception e) {
            e.printStackTrace();
        }

        WebMarkupContainer containerWeer = new WebMarkupContainer("containerWeer");
        containerWeer.setOutputMarkupId(true);
        containerWeer.add(hateView);
        containerWeer.add(newview);
        addOrReplace(containerWeer);

        return containerWeer;
    }
}

Upvotes: 3

Views: 1510

Answers (4)

svenmeier
svenmeier

Reputation: 5681

You're getting the "WeerVoorspelling" once only:

PropertyListView<WeerVoorspelling> hateView
  = new PropertyListView<WeerVoorspelling>("weersvoorspelling",
         weerVoorspellingService.getWeerVoorspelling()) { .. }

So regardless how the weather forecasts change, your listView still looks at the original list. You should introduce an indirection:

IModel<List<WeerVoorspelling>> weerVoorspelling = new AbstractReadOnlyModel<List<WeerVoorspelling>> {
  public List<WeerVoorspelling> getObject() {
    return weerVoorspellingService.getWeerVoorspelling();
  }
}

PropertyListView<WeerVoorspelling> hateView
  = new PropertyListView<WeerVoorspelling>("weersvoorspelling",
         weerVoorspelling) { .. }

Upvotes: 1

Raystorm
Raystorm

Reputation: 6538

in Your onTimer you're adding the object to itself with out changing it. I would suggest moving the view/container regeneration into a new method.

Then redifine onTimer like so:

add(new AbstractAjaxTimerBehavior(Duration.seconds(10)) 
{
    @Override
    protected final void onTimer(AjaxRequestTarget target) 
    {   //createContainer() generates the views and container.
        target.add(createContainer()); 
    }
}

EDIT:
I would define createContainer() like so:

private WebMarkupContainer createContainer()
{
  final WeerService weerService = new WeerServiceImpl();

  PropertyListView<Weer> newview = new PropertyListView<Weer>("weer", weerService.getWeer()) 
  {

    @Override
    protected void populateItem(ListItem<Weer> item) 
    {
        item.add(new Label("temperatuur"));
        item.add(new StaticImage("type", String.format("images/%s.png", item.getModelObject().getType())));
        item.add(new Label("omschrijving"));
    }
  };

  WeerVoorspellingService weerVoorspellingService = new WeerVoorspellingServiceImpl();

  PropertyListView<WeerVoorspelling> hateView = new PropertyListView<WeerVoorspelling>("weersvoorspelling", weerVoorspellingService.getWeerVoorspelling()) 
  {

    @Override
    protected void populateItem(ListItem<WeerVoorspelling> item) 
    {
        item.add(new Label("dag"));
        item.add(new StaticImage("typeVoorspelling", String.format("images/%s.png", item.getModelObject().getType())));
        item.add(new Label("minTemperatuur"));
        item.add(new Label("maxTemperatuur"));
    }
  };

  WebMarkupContainer containerWeer = new WebMarkupContainer("containerWeer");
  containerWeer.setOutputMarkupId(true);
  containerWeer.add(hateView);
  containerWeer.add(newview);
  add(containerWeer);

  return containerWeer;
}

Edited to match final solution

Then define your Panel constructor like so:

public WeerPanel(String id) throws IOException 
{
  super(id);

  final WebMarkupContainer container = createContainer();

  add(new AbstractAjaxTimerBehavior(Duration.seconds(10)) 
  {
    @Override
    protected final void onTimer(AjaxRequestTarget target) 
    {   //createContainer() generates the views and container.
        container.addOrReplace(createContainer());
    }
  }
}

Upvotes: 1

kgrad
kgrad

Reputation: 4792

According to the Docs AjaxSelfUpdatingTimerBehavior has a method onTimer(). You need to implement this method and add the view you wish to update to the AjaxRequestTarget. This will refresh the component that you wish to update. The ajax event is currently doing nothing at all, which is why you see nothing happening.

Basically, from a high level standpoint, you want to update the backing model object that controls the listView, then when the ajax timer fires, you want to refresh that list to show the latest data.

The code would look something like this:

containerWeer.add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(5)){
  @Override
  protected final void onTimer(AjaxRequestTarget target) {
    target.addComponent(/The component you wish to refresh/);
  }
});

Upvotes: 0

Daniel
Daniel

Reputation: 41

Please have a look at the output in the wicket ajax console, it's probably saying something that a listview cannot be updated directly. Also, can you add the code where you are updating the Listview?

Upvotes: 0

Related Questions