Как создать Ajax Paging Navigation в Wicket с ListView?

У меня есть HTML-разметка для Ajax Paging Navigation, например:

<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>

когда пользователь выбирает интервал страниц (10-30, 30-40 и т. д.), данные меняются (Ajax). Как я могу реализовать это с ListView в калитке? Я думаю, что это должно быть что-то вроде:

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

и разметка:

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

Я точно знаю, как это сделать с DropDownChoice, но это не подходит в моем случае, потому что я должен генерировать <ul><li></li></ul> вместо <select><option></option></select> теги.

p / s: пример того, как сделать это с DropDownChoice:

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;
    }

}

1 ответ

Решение

Вместо того, чтобы использовать простой ListView и пытаясь создать свою собственную поддержку подкачки, вы, вероятно, хотите PageableListView и прикрепленный AjaxPagingNavigator,

PageableListView продолжается ListView добавить поддержку подкачки и AjaxPagingNavigator предоставляет навигационный интерфейс для подкачки.

Есть и другие ретрансляторы, которые можно использовать для поддержки пейджинга, но это наиболее близко к тому, что вы сейчас делаете.

Если вы используете Hibernate для доступа к вашей базе данных, вы можете посмотреть на DataView для хорошей поддержки подкачки.

Другие вопросы по тегам