Search code examples
wicketwicket-7

Update a label which used multiple times


I have a label which is used mutiple times in my page. It works fine, until I try to update the label per ajax. Result: only the first label gets updated. Is it a known issue? I'm not sure, since I can't open the JIRA page: https://issues.apache.org/jira/browse/wicket (Get throbber all time). I'm using wicket version 7.3.0


    To reproduce this issue:
    1. Add an label on your page (java part):
    private final Label label;
    ..
    label = new Label("yourLabel", "Your Text");
    label.setOutputMarkupId(true);
    add(label);
    ...
    1. Add your label multiple time (for e.g. 4 times) in your page (html part):
    ...
    <span wicket:id="yourLabel"/>
    <span wicket:id="yourLabel"/>
    <span wicket:id="yourLabel"/>
    <span wicket:id="yourLabel"/>
    ...
    2. Add event handler for e.g. the ajax event is UpdateEvent in your page (java part)
    ...
        @Override
        public void onEvent(IEventevent) {
            if (event.getPayload() instanceof UpdateEvent) {
              //update your label
              label.setDefaultModelObject("new Text");
              target.add(label);

            }
        }

=> only the first label gets updated. I have a workaround for this by adding 4 different instances of label with the same text content.


Solution

  • The root of the problem is that Wicket components are not supposed to be used multiple times - a Component represents an individual item on the page. Adding four different Label objects (your workaround) is correct.

    If the four labels will always have the same content, but that content sometimes changes, you can make this clear by having the four Labels share a single writable string Model. Here's some pseudocode:

    IModel<String> labelModel = new Model<String>("Your Text");
    
    label1 = new Label("label1", labelModel);
    label1.setOutputMarkupId(true);
    add(label1);
    
    label2 = new Label("label2", labelModel);
    label2.setOutputMarkupId(true);
    add(label2);
    
    ...
    
    @Override
    public void onEvent(IEventevent) {
        if (event.getPayload() instanceof UpdateEvent) {
          //update your label
          labelModel.setObject("new Text");
          target.add(label1);
          target.add(label2);
        }
    }
    

    Alternatively, you could encapsulate things even further by making a subclass of Label that implements the onEvent method itself and adjusts its own text.