title: How to generate Ajax Paging Navigation in Wicket with ListView?
body: <p>I have a HTML markup for Ajax Paging Navigation like:</p>
  
  <pre><code>&lt;div class="btn-group"&gt;
                  &lt;a href="#" class="btn btn-default"&gt;
                      &lt;i class="ico ico-prev"&gt;&lt;/i&gt;
                  &lt;/a&gt;
                  &lt;div class="dropdown2 inline"&gt;
                      &lt;a href="#" class="btn btn-default btn-shorter"&gt;
                          &lt;strong&gt;1-8&lt;/strong&gt;
                      &lt;/a&gt;
                      &lt;ul class="dropdown-menu spec_width"&gt;
                              &lt;li&gt;&lt;a data-ico="1" href="#"&gt;10-30&lt;/a&gt;&lt;/li&gt;
                              &lt;li&gt;&lt;a href="#"&gt;30-40&lt;/a&gt;&lt;/li&gt;
                              &lt;li&gt;&lt;a href="#"&gt;40-50&lt;/a&gt;&lt;/li&gt;
                              &lt;li&gt;&lt;a href="#"&gt;50-60&lt;/a&gt;&lt;/li&gt;
                      &lt;/ul&gt;
                  &lt;/div&gt;
                  &lt;a href="#" class="btn btn-default"&gt;
                      &lt;i class="ico ico-next"&gt;&lt;/i&gt;
                  &lt;/a&gt;
  </code></pre>
  
  <p>when user choose interval of pages (10-30, 30-40 etc) the data is changing (Ajax). 
  How I can implement it with ListView in wicket? I think that it should be smth like:</p>
  
  <pre><code>ListView yourListView = new ListView("your-list-view", new PropertyModel(this, "pages")){
          @Override
          protected void populateItem(ListItem item) {
              item.add(new Label("label", item.toString()));
          }
      };
  </code></pre>
  
  <p>and markup:</p>
  
  <pre><code>&lt;ul&gt;&lt;li wicket:id="your-list-view"&gt;&lt;span wicket:id="label"&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
  </code></pre>
  
  <p>I exactly know, how to do it with DropDownChoice, but it isn't suitable in my case, because I have to generate <code>&lt;ul&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt;</code> instead of <code>&lt;select&gt;&lt;option&gt;&lt;/option&gt;&lt;/select&gt;</code> tags.<br><br>
  p/s: sample how to do it with <b>DropDownChoice</b>:</p>
  
  <pre><code>public abstract class AjaxPagingPanel extends Panel{
  private Criteria criteria;
  private List&lt;Page&gt; 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 &lt; 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() &gt; 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() &lt; 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 &lt; 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 &gt;&gt;&gt; 32));
          return hash;
      }
  
  }
  </code></pre>