How to properly model subviews with Wicket?

I have a panel (see BasePanel below) that has a list of items and an "action" -bar where the buttons are located. Clicking these buttons makes changes to the items in the list using models.

Now I want the same panel, but with slightly different buttons (see CustomPanelA and CustomPanelB below). I have three configurations for panel buttons.

How can I simulate this? I thought to use wicket:child

, but since the buttons are inside another gate component that didn't work.

BasePanel.java

class BasePanel extends Panel {
    public BasePanel(String id) {
        super(id);

        // note: I need this container for refreshing using AJAX
        WebMarkupContainer outer = new WebMarkupContainer("outerContainer");
        outer.setOutputMarkupId(true);
        add(outer);

        // ... create listview
        outer.add(new ListView("items") { /* implementation of listview */ };

        // This container is necessary to show/hide the buttons
        WebMarkupContainer actionbar =  new WebMarkupContainer("outerContainer");
        actionbar.setOutputMarkupId(true);

        // ... create default buttons
        actionbar.add(new Link("add") { /* implementation of link */ );
    }
}

      

BasePanel.html

<html>
<wicket:panel>
    <div wicket:id="outerContainer">
         <div wicket:id="actionbar" >
               <a wicket:id="add">Add</a>
         </div>
         <div wicket:id="items">
               <!-- ... markup for items is here -->
         </div>
    </div>
</wicket:panel>
</html>

      

CustomPanelA.java

class CustomPanelA extends BasePanel {
    public CustomPanelA (String id) {
        super(id);

        // add additional buttons only
        actionbar.add(new Link("actionA1") { /* implementation of link */ );
        actionbar.add(new Link("actionA2") { /* implementation of link */ );
    }
}

      

CustomPanelA.html

<html>
<wicket:extend>
     <a wicket:id="actionA1">ActionA1</a>
     <a wicket:id="actionA2">ActionA2</a>
</wicket:extend>
</html>

      

CustomPanelB.java

class CustomPanelB extends BasePanel {
    public CustomPanelB (String id) {
        super(id);

        // add additional buttons only
        actionbar.add(new Link("action_b1") { /* implementation of link */ );
        actionbar.add(new Link("action_b2") { /* implementation of link */ );
    }
}

      

CustomPanelB.html

<html>
<wicket:extend>
     <a wicket:id="action_b1">Action b1</a>
     <a wicket:id="action_b2">Action b2</a>
</wicket:extend>
</html>

      

+3


source to share


2 answers


There are many solutions to your problem. I'll show you one of them.

As you mentioned with an approach based <wicket:child/>

, then I will describe my solution. Yours BasePanel

will be an abstract class that will contain all of your components that are already in it, with the exception of the action references. It will provide one abstract method called for example addActionLinks

:

class abstract BasePanel extends Panel {
    public BasePanel(String id) {
        super(id);

        //...your code.
        WebMarkupContainer actionBar = ...;

        //call this abstract method to add links in actionBar.
        addActionLinks( actionBar );
    }

    public abstract void addActionLinks( WebMarkupContainer container );
}

      

HTML:

<wicket:panel>
    ...
     <div wicket:id="actionbar" >
        <wicket:child/>
     </div>
    ...
</wicket:panel>

      

And for other panels, you just implement the method addActionLinks

:

class CustomPanelA extends BasePanel {
    public CustomPanelA (String id) {
        super(id);
    }

    protected void addChildren ( WebMarkupContainer container )
    {
        actionbar.add(new Link("actionA1") { /* implementation of link */ );
        actionbar.add(new Link("actionA2") { /* implementation of link */ );
    }
}

      



And HTML:

<wicket:extend>
    <a wicket:id="actionA1">ActionA1</a>
    <a wicket:id="actionA2">ActionA2</a>
</wicket:extend>

      

Of course, you need to implement another panel with a link for the action BasePanel

removed from my implementation (create a class for example DefaultBasePanel

).

In addition, you can create another link ListView

for actions in yours BasePanel

, as well as extract them from one method, override subclasses.

Also, maybe using snippets can solve your problem as well. You can take a look here to read more about snippets.

I think there are more approaches, but somehow it crossed my mind. Hope this helps.

+2


source


I think a much better solution is to use RepeatingViews. This way you don't even need to have html for subviews.

BasePanel.java

class BasePanel extends Panel {

protected final RepeatingView actionbar;

public BasePanel(String id) {
    super(id);

    // note: I need this container for refreshing using AJAX
    WebMarkupContainer outer = new WebMarkupContainer("outerContainer");
    outer.setOutputMarkupId(true);
    add(outer);

    // ... create listview
    outer.add(new ListView("items") { /* implementation of listview */ };

    // This container is necessary to show/hide the buttons
    actionbar =  new RepeatingView("action");

    // ... create default buttons
    actionbar.add(new Link("add") { /* implementation of link */ }.
       setBody(Model.of("Add"));
}
}

      

BasePanel.html

<html>
<wicket:panel>
<div wicket:id="outerContainer">
     <div class="actions">
           <a wicket:id="action"></a>
     </div>
     <div wicket:id="items">
           <!-- ... markup for items is here -->
     </div>
</div>
</wicket:panel>
</html>

      



CustomPanelA.java

class CustomPanelA extends BasePanel {
public CustomPanelA (String id) {
    super(id);

    // add additional buttons only
    actionbar.add(new Link("actionA1") { /* implementation of link */ );
    actionbar.add(new Link("actionA2") { /* implementation of link */ );
}
}

      

CustomPanelB.java

class CustomPanelB extends BasePanel {
public CustomPanelB (String id) {
    super(id);

    // add additional buttons only
    actionbar.add(new Link("action_b1") { /* implementation of link */ );
    actionbar.add(new Link("action_b2") { /* implementation of link */ );
}
}

      

Note: inside the RepeatingView you can add any component that inherits the markup of the RepeatingView component. Just make sure you don't add the same component ID twice and you should be fine.

+4


source







All Articles