com.premiumminds.webapp.wicket.bootstrap.BootstrapPaginator Maven / Gradle / Ivy
/**
* Copyright (C) 2016 Premium Minds.
*
* This file is part of pm-wicket-utils.
*
* pm-wicket-utils is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* pm-wicket-utils is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with pm-wicket-utils. If not, see .
*/
package com.premiumminds.webapp.wicket.bootstrap;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.FormComponentPanel;
import org.apache.wicket.markup.html.list.Loop;
import org.apache.wicket.markup.html.list.LoopItem;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
/**
* This component creates a paginator component using the bootstrap pagination element.
*
*
* Example:
*
*
* <nav>
* <ul wicket:id="paginator" class="pagination"></ul>
* </nav>
*
*
*
* The related Java code:
*
*
* new BootstrapPaginator("paginator", Model.of(2000)) {
* public void onPageChange(AjaxRequestTarget target, IModel<Integer> page) {
* ...
* }
* }
*
*
* @author acamilo
* @see bootstrap pagination
*/
public abstract class BootstrapPaginator extends FormComponentPanel {
private static final long serialVersionUID = -5991811031611368885L;
/*booleans to control if the component should be showned*/
private boolean showFirstButton = true;
private boolean showLastButton = true;
private boolean showNextButton = true;
private boolean showPreviousButton = true;
private boolean showMorePagesInformation = false;
/*booleans to control if the component should be hidden in specific cases*/
private boolean hiddenFirstButton = false;
private boolean hiddenLastButton = false;
private boolean hiddenPreviousButton = false;
private boolean hiddenNextButton = false;
private int pagesToShow = 5;
private IModel totalResults;
private int numberResultsPerPage;
/**
* Creates a paginator with 20 results per page by default
*
* @param id component id
* @param totalResults model for total results
*/
public BootstrapPaginator(String id, IModel totalResults){
this(id, totalResults, 20);
}
/**
* Creates a paginator
*
* @param id component id
* @param totalResults model for total results
* @param resultsPerPage number of results per page
*/
@SuppressWarnings("serial")
public BootstrapPaginator(String id, IModel totalResults, int resultsPerPage){
super(id, Model.of(0));
setOutputMarkupId(true);
this.totalResults = totalResults;
this.numberResultsPerPage = resultsPerPage;
add(new SquaresContainer("first"){
@Override
protected void onConfigure() {
super.onConfigure();
setEnabled(getModelObject()>0);
setVisible(showFirstButton && (!hiddenFirstButton || getThreshold()>0));
}
}.add(new AjaxLink("link"){
@Override
public void onClick(AjaxRequestTarget target) {
BootstrapPaginator.this.setModelObject(0);
target.add(BootstrapPaginator.this);
onPageChange(target, BootstrapPaginator.this.getModel());
}
}));
add(new SquaresContainer("previous"){
@Override
protected void onConfigure() {
super.onConfigure();
setEnabled(BootstrapPaginator.this.getModelObject()>0);
setVisible(showPreviousButton && (!hiddenPreviousButton || BootstrapPaginator.this.getModelObject()>0));
}
}.add(new AjaxLink("link"){
@Override
public void onClick(AjaxRequestTarget target) {
BootstrapPaginator.this.setModelObject(BootstrapPaginator.this.getModelObject()-1);
target.add(BootstrapPaginator.this);
onPageChange(target, BootstrapPaginator.this.getModel());
}
}));
add(new SquaresContainer("next"){
@Override
protected void onConfigure() {
super.onConfigure();
setEnabled(BootstrapPaginator.this.getModelObject()("link"){
@Override
public void onClick(AjaxRequestTarget target) {
BootstrapPaginator.this.setModelObject(BootstrapPaginator.this.getModelObject()+1);
target.add(BootstrapPaginator.this);
onPageChange(target, BootstrapPaginator.this.getModel());
}
}));
add(new SquaresContainer("last"){
@Override
protected void onConfigure() {
super.onConfigure();
setEnabled(BootstrapPaginator.this.getModelObject()("link"){
@Override
public void onClick(AjaxRequestTarget target) {
BootstrapPaginator.this.setModelObject(getTotalPages()-1);
target.add(BootstrapPaginator.this);
onPageChange(target, BootstrapPaginator.this.getModel());
}
}));
add(new WebMarkupContainer("previousPages"){
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(showMorePagesInformation && getThreshold()>0);
}
});
add(new WebMarkupContainer("nextPages"){
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(showMorePagesInformation && getThreshold()<(getTotalPages()-pagesToShow));
}
});
IModel pages = new LoadableDetachableModel() {
@Override
protected Integer load() {
return Math.min(getTotalPages(), pagesToShow);
}
};
add(new Loop("page", pages) {
@Override
protected void populateItem(final LoopItem item) {
final int threshold = getThreshold();
item.add(AttributeModifier.append("class", new LoadableDetachableModel() {
@Override
protected String load() {
return item.getIndex()+getThreshold()==BootstrapPaginator.this.getModelObject() ? "active" : "";
}
}));
item.add(new AjaxLink("link") {
@Override
protected void onConfigure() {
super.onConfigure();
};
@Override
public void onClick(AjaxRequestTarget target) {
BootstrapPaginator.this.setModelObject(item.getIndex()+threshold);
target.add(BootstrapPaginator.this);
onPageChange(target, BootstrapPaginator.this.getModel());
}
}.add(new Label("label", new LoadableDetachableModel() {
@Override
protected Integer load() {
return item.getIndex()+threshold+1;
}
})));
}
});
}
private int getThreshold(){
if(getTotalPages()<=getModelObject()) setModelObject(0);
if(getModelObject()>pagesToShow-2) return (int) Math.max(Math.min(getModelObject()-(Math.floor(pagesToShow/2)), getTotalPages()-pagesToShow), 0);
if(getModelObject()>getTotalPages()-pagesToShow) return Math.max(getTotalPages()-pagesToShow, 0);
return 0;
}
@SuppressWarnings("serial")
private class SquaresContainer extends WebMarkupContainer {
public SquaresContainer(String id) {
super(id);
add(AttributeModifier.append("class", new LoadableDetachableModel() {
private static final long serialVersionUID = 4330457477794180592L;
@Override
protected String load() {
return isEnabled() ? "" : "disabled";
}
}));
}
}
/**
* Return if the goto first page button is shown
*
* @return true if the goto first page button is shown
*/
public boolean isShowFirstButton() {
return showFirstButton;
}
/**
* Sets whether to show the goto first page option
*
* @param showFirstButton whether to show the goto first page option
*/
public void setShowFirstButton(boolean showFirstButton) {
this.showFirstButton = showFirstButton;
}
/**
* Return if the goto last page button is shown
*
* @return true if the goto last page button is shown
*/
public boolean isShowLastButton() {
return showLastButton;
}
/**
* Sets whether to show the goto last page option
*
* @param showLastButton if true show the goto last page option
*/
public void setShowLastButton(boolean showLastButton) {
this.showLastButton = showLastButton;
}
/**
* Return if the goto next page button is shown
*
* @return true if the goto next page button is shown
*/
public boolean isShowNextButton() {
return showNextButton;
}
/**
* Sets whether to show the goto next page option
*
* @param showNextButton whether to show the goto next page option
*/
public void setShowNextButton(boolean showNextButton) {
this.showNextButton = showNextButton;
}
/**
* Return if the goto previous page button is shown
*
* @return true if the goto previous page button is shown
*/
public boolean isShowPreviousButton() {
return showPreviousButton;
}
/**
* Sets whether to show the goto previous page option
*
* @param showPreviousButton whether to show the goto previous page option
*/
public void setShowPreviousButton(boolean showPreviousButton) {
this.showPreviousButton = showPreviousButton;
}
/**
* Return the number of pages to show on the pagination component
*
* @return integer with the number of pages to show on the pagination component
*/
public int getPagesToShow() {
return pagesToShow;
}
/**
* Sets the number of pages to show on the pagination component
*
* @param pagesToShow number of pages to show on the pagination component
*/
public void setPagesToShow(int pagesToShow) {
this.pagesToShow = pagesToShow;
}
/**
* Get the total of pages shown
*
* @return totalResults / numberOfResultsPerPage
*/
public int getTotalPages() {
return (int) Math.ceil(totalResults.getObject()/ (double) numberResultsPerPage);
}
/**
* Return if the goto first page button is hidden when it's not needed
*
* @return true if the goto first page button is hidden when it's not needed
*/
public boolean isHiddenFirstButton() {
return hiddenFirstButton;
}
/**
* Sets if the goto first page button should be hidden when it's not needed
*
* @param hiddenFirstButton if the goto first page button should be hidden when it's not needed
*/
public void setHiddenFirstButton(boolean hiddenFirstButton) {
this.hiddenFirstButton = hiddenFirstButton;
}
/**
* Return if the goto last page button is hidden when it's not needed
*
* @return true if the goto last page button is hidden when it's not needed
*/
public boolean isHiddenLastButton() {
return hiddenLastButton;
}
/**
* Sets if the goto last page button should be hidden when it's not needed
*
* @param hiddenLastButton if the goto last page button should be hidden when it's not needed
*/
public void setHiddenLastButton(boolean hiddenLastButton) {
this.hiddenLastButton = hiddenLastButton;
}
/**
* Return if the goto previous page button is hidden when it's not needed
*
* @return true if the goto previous page button is hidden when it's not needed
*/
public boolean isHiddenPreviousButton() {
return hiddenPreviousButton;
}
/**
* Sets if the goto previous page button should be hidden when it's not needed
*
* @param hiddenPreviousButton if the goto previous page button should be hidden when it's not needed
*/
public void setHiddenPreviousButton(boolean hiddenPreviousButton) {
this.hiddenPreviousButton = hiddenPreviousButton;
}
/**
* Return if the goto next page button is hidden when it's not needed
*
* @return true if the goto next page button is hidden when it's not needed
*/
public boolean isHiddenNextButton() {
return hiddenNextButton;
}
/**
* Sets if the goto next page button should be hidden when it's not needed
*
* @param hiddenNextButton if the goto next page button should be hidden when it's not needed
*/
public void setHiddenNextButton(boolean hiddenNextButton) {
this.hiddenNextButton = hiddenNextButton;
}
/**
* This method is called every time the current page changes
*
* @param target ajax target (paginator was already added)
* @param page the new current page
*/
public abstract void onPageChange(AjaxRequestTarget target, IModel page);
/**
* Get the model with the total number of results
*
* @return model with number of results
*/
public IModel getTotalResults() {
return totalResults;
}
/**
* Set the model with the total number of results
*
* @param totalResults model with the number of results
*/
public void setTotalResults(IModel totalResults) {
this.totalResults = totalResults;
}
/**
* Get the number of results per page that the paginator uses to calculate how many pages should exist
*
* @return number of results per page
*/
public int getNumberResultsPerPage() {
return numberResultsPerPage;
}
/**
* Set the number of results per page that the paginator uses to calculate how many pages should exist
*
* @param numberResultsPerPage number of results per page
*/
public void setNumberResultsPerPage(int numberResultsPerPage) {
this.numberResultsPerPage = numberResultsPerPage;
}
/**
* Get the first first index for the current page
*
* @return page * numberOfResultsPerPage
*/
public int getCurrentIndex(){
return getModelObject() * numberResultsPerPage;
}
}