Question

I need to change in CustomPagingPanel DropDownChoice where I collect information about paging like [1-50], [51-100], to ListView.So I have a code:

// Ajax DropDownChoice used as Page navigator
    pagingDropDownChoice = new DropDownChoice("pagesDropDown", new PropertyModel(this, "currentPage"), new PropertyModel(this, "pages"), new ChoiceRenderer("period", "pageNum"));
    pagingDropDownChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {

        @Override
        protected void onUpdate(AjaxRequestTarget target) {

            criteria.setPageNum((int)currentPage.getPageNum());
            updatePagingList(target);
            setLinkVisibility();                
            target.add(pagingSizeLabel);
            target.add(pagingDropDownChoice);
            target.add(nextLink);
            target.add(previousLink);
        }
    });
    add(pagingDropDownChoice.setOutputMarkupId(true));

The problem is DropDownChoice in Wicket generates <select> tags, I need <ul><li> tags in HTML markups.

Was it helpful?

Solution

I'm still a bit confused about what you are trying to achieve here, but I'll take a stab in the dark.

If I understand correctly, you want to move away from DropDownChoice, as it has to be applied to a <select> tag, and change it into a ListView, as it is what deals with lists. My assumption is that you simply want a component that would generate choices the same way your dropdown did (i.e. the items in the list would be the same as they were on the dropdown).

The first step would be re-creating a ListView, that would render the same information as the dropdown did. That is, if you had a

<select>
    <option>1-50</option>
    <option>51-100</option>
</select>

Then what you want to get, I assume, is:

<ul>
    <li>1-50</li>
    <li>51-100</li>
</ul>

The way ListView works is that it repeats the tag you have attached it to several times, giving you the option of customising the content of it each time. So the way you would have to do this would be something like this

<ul>
    <li wicket:id="your-list-view"></li>        
</ul>

Once you attach the ListView with ID your-list-view, your ListView will repeat the tag as many times as there are items in the model of your ListView, giving you a chance to configure the inside of the tag each time. Now I'm not quite sure what you want the contents to be in order for it to do what you want to do, but I assume it will either be:

  • a Label component with an ajax onClick behaviour attached
  • a Link component

Regardless of which way you choose, the following has to be the same. Since the markup will be repeated, you want to have a link/label in every one of those. So an example markup would be (assuming you are populating the list with labels)

<ul>
    <li wicket:id="your-list-view"><span wicket:id="label"></span></li>        
</ul>

That's the markup for it. In the background, you have to create a ListView, whose model would be a model from which you can infer the information about the display of each row in the <ul>, so converting a DropDownChoice to a ListView I believe the model for the ListView should be the model you used as the model of all available choices on the dropdown, so something like:

ListView yourListView = new ListView("your-list-view", new PropertyModel(this, "pages")){
            @Override
            protected void populateItem(ListItem item) {
                //TODO
            }
        };

I assume the "pages" property is a list of whatever you determine the available pages from.

The way you display each list should now be done in the populateItem method of the ListView. Since the example I used was with a Label, you would have to configure the label the same way your renderer rendered the choices. I'm not sure how that was being done, so I'll just assume it's the model toStringed (since you don't seem to provide classes of models..)

ListView yourListView = new ListView("your-list-view", new PropertyModel(this, "pages")){
            @Override
            protected void populateItem(ListItem item) {
                item.add(new Label("label", item.toString()));
            }
        };

The last part that you need to do is add the "onClick" behaviour that you want. Now this part is somewhat freeform. You can either add an AjaxEventBehavior and do what you want on the events of that behavior, or you can instead use AjaxLink components instead of labels and then do the same in the onClick() method of the link. It's your choice, but that is fairly straightforward. Comment if you need elaboration on that.

OTHER TIPS

@DomasPoliakas Thanks a lot, your response was so helpful, and to be clear there are my Java code:

public abstract class AjaxPagingPanel extends Panel{
private Criteria criteria;
private List<Page> pages; 
private Page currentPage;    
private long listSize;
private int pagesCount;
private DropDownChoice pagingDropDownChoice;
private Label pagingSizeLabel;
private AjaxLink previousLink;
private AjaxLink nextLink;

public AjaxPagingPanel(String id, Criteria pagingCriteria) {
    super(id);

    criteria = pagingCriteria;
    listSize = criteria.getResultSize();
    pagesCount = (int) Math.ceil((double) listSize / criteria.getPageSize());

    long pageSize = pagingCriteria.getPageSize();
    currentPage = new Page(pagingCriteria.getPageNum(), (pagingCriteria.getPageNum() - 1) * pageSize + 1, Math.min( pagingCriteria.getPageNum() * pageSize, pagingCriteria.getResultSize()) ); // Model for DropDownChoice

    pages = new ArrayList(pagesCount);
    for (int i = 0; i < pagesCount; i++) {
        pages.add(new Page(i + 1, i * pageSize + 1, Math.min((i + 1) * pageSize, pagingCriteria.getResultSize()) ));            
    }

    // Label updated by ajax to render listSize
    pagingSizeLabel = new Label("pageSize", new PropertyModel(this, "listSize"));
    add(pagingSizeLabel.setOutputMarkupId(true));

    // Ajax DropDownChoice used as Page navigator
    pagingDropDownChoice = new DropDownChoice("pagesDropDown", new PropertyModel(this, "currentPage"), new PropertyModel(this, "pages"), new ChoiceRenderer("period", "pageNum"));
    pagingDropDownChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {

        @Override
        protected void onUpdate(AjaxRequestTarget target) {

            criteria.setPageNum((int)currentPage.getPageNum());
            updatePagingList(target);
            setLinkVisibility();                
            target.add(pagingSizeLabel);
            target.add(pagingDropDownChoice);
            target.add(nextLink);
            target.add(previousLink);
        }
    });
    add(pagingDropDownChoice.setOutputMarkupId(true));

    add(previousLink = new IndicatingAjaxLink("previousLink"){

            @Override
            public void onClick(AjaxRequestTarget target) {
                if (criteria.getPageNum() > 1) {                    
                    criteria.setPageNum(criteria.getPageNum() - 1);
                    int index = pages.indexOf(currentPage);
                    currentPage = pages.get(index - 1);       
                    updatePagingList(target);
                    setLinkVisibility();
                    target.add(pagingSizeLabel);
                    target.add(pagingDropDownChoice);
                    target.add(nextLink);
                    target.add(previousLink);
                }
            }
    });
    previousLink.setOutputMarkupPlaceholderTag(true);


    // Next link of Page navigator
    add(nextLink = new IndicatingAjaxLink("nextLink"){

            @Override
            public void onClick(AjaxRequestTarget target) {
                if (criteria.getPageNum() < pagesCount) { 

                    criteria.setPageNum(criteria.getPageNum() + 1);     
                    int index = pages.indexOf(currentPage);
                    currentPage = pages.get(index + 1);
                    updatePagingList(target);
                    setLinkVisibility();
                    target.add(pagingSizeLabel);
                    target.add(pagingDropDownChoice);
                    target.add(nextLink);
                    target.add(previousLink);
                }
            }
    });
    nextLink.setOutputMarkupPlaceholderTag(true);

    setLinkVisibility();
}

public Page getCurrentPage() {
    return currentPage;
}

public void setCurrentPage(Page currentPage) {
    this.currentPage = currentPage;
}

public final void setLinkVisibility() {
    if (criteria.getPageNum() == 1) {
        previousLink.setVisible(false);
    } else {
        previousLink.setVisible(true);
    }

    if (criteria.getPageNum() == pagesCount || pagesCount == 0) {
        nextLink.setVisible(false);
    } else {
        nextLink.setVisible(true);
    }
}

// Method must be overrided by a class which is using AjaxPagingPanel
public abstract void updatePagingList(AjaxRequestTarget target);

// Method to refresh the AjaxPagingPanel, for example after Ajax search
public void refresh(Criteria pagingCriteria, AjaxRequestTarget target) {
    criteria = pagingCriteria;
    listSize = criteria.getResultSize();
    pagesCount = (int) Math.ceil((double) listSize / criteria.getPageSize());

    long pageSize = pagingCriteria.getPageSize();
    currentPage = new Page(pagingCriteria.getPageNum(), (pagingCriteria.getPageNum() - 1) * pageSize + 1, Math.min( pagingCriteria.getPageNum() * pageSize, pagingCriteria.getResultSize()) ); 

    pages.clear();
    for (int i = 0; i < pagesCount; i++) {
        pages.add(new Page(i + 1, i * pageSize + 1, Math.min((i + 1) * pageSize, pagingCriteria.getResultSize()) ));            
    }

    pagingDropDownChoice.modelChanged();
    setLinkVisibility();
    target.add(pagingSizeLabel);
    target.add(pagingDropDownChoice);
    target.add(nextLink);
    target.add(previousLink);
}

/**
 * This class is used as a model class in DropDownChoice component and
 * provides list of page as [1-50] [51-100] [101-150] [151-200]...
 */
public class Page implements Serializable{
    private long pageNum;
    private long firstPage;
    private long lastPage;

    public Page(long pageNum, long firstPage, long lastPage) {
        this.pageNum = pageNum;
        this.firstPage = firstPage;
        this.lastPage = lastPage;
    }

    public long getPageNum() {
        return pageNum;
    }

    public void setPageNum(long pageNum) {
        this.pageNum = pageNum;
    }

    public String getPeriod() {
        return Long.toString(firstPage) + "-" + Long.toString(lastPage);
    }

    @Override
    public boolean equals(Object obj) {
        if(!(obj instanceof Page)){
            return false;
        }
        return this.pageNum == ((Page)obj).pageNum;

    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + (int) (this.pageNum ^ (this.pageNum >>> 32));
        return hash;
    }

}

}

My Old Html Markup: `

    <table cellpadding="0" cellspacing="3" border="0">
        <tr>
            <td>
                <span class="td2">&nbsp;<wicket:message key="selected"/>: </span>
                <span class="td1" wicket:id="pageSize"/>&nbsp;&nbsp;-&nbsp;&nbsp;
                <a wicket:id="previousLink" class="listLink">&lt;&lt;<wicket:message key="previousPage"/>&nbsp;</a>
                <select wicket:id="pagesDropDown" class="input"/>
                <a wicket:id="nextLink" class="listLink">&nbsp;<wicket:message key="nextPage"/>&gt;&gt;</a>
            </td>
        </tr>
    </table>
</wicket:panel>

`

And I need to change the part with DropDown, where contains page navigation:

<div class="pull-right"> <div class="btn-group"> <a href="#" class="btn btn-default"> <i class="ico ico-prev"></i> </a> <div class="dropdown2 inline"> <a href="#" class="btn btn-default btn-shorter"> <strong>1-8</strong> </a> <ul class="dropdown-menu spec_width"> <li><a data-ico="1" href="#">10-30</a></li> <li><a href="#">30-40</a></li> <li><a href="#">40-50</a></li> <li><a href="#">50-60</a></li> </ul> </div> <a href="#" class="btn btn-default"> <i class="ico ico-next"></i> </a> </div> <span class="page-title">из <strong>45</strong></span> </div>

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top