gwt.material.design.client.ui.MaterialPager Maven / Gradle / Ivy
/*
* #%L
* GwtMaterial
* %%
* Copyright (C) 2015 - 2017 GwtMaterialDesign
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package gwt.material.design.client.ui;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Event;
import gwt.material.design.client.base.MaterialWidget;
import gwt.material.design.client.constants.CssName;
import gwt.material.design.client.constants.IconPosition;
import gwt.material.design.client.constants.IconType;
import gwt.material.design.client.constants.WavesType;
import gwt.material.design.client.events.PageSelectionEvent;
import gwt.material.design.client.ui.html.ListItem;
import static gwt.material.design.client.events.PageSelectionEvent.PageSelectionHandler;
import static gwt.material.design.client.events.PageSelectionEvent.TYPE;
//@formatter:off
/**
* Material Pager with page event
* UiBinder Usage:
*
* {@code }
*
*
* @author Guaido79
*/
public class MaterialPager extends MaterialWidget {
private int total;
private int pageSize = 10;
private int currentPage = 1;
private int maxPageLinksShown = 10;
private int calcTotalPages;
private int calcShowingPageFrom;
private int calcShowingPageTo;
private boolean enableIndicator;
private boolean calcInitialized;
private String indicatorTemplate = "Page {page} of {total}";
private PagerListItem linkLeft;
private PagerListItem linkRight;
private MaterialChip indicator;
public MaterialPager() {
super(Document.get().createULElement(), CssName.PAGINATION);
setWaves(WavesType.DEFAULT);
removeStyleName(CssName.WAVES_EFFECT);
}
public MaterialPager(int total, int pageSize) {
this();
this.total = total;
this.pageSize = pageSize;
}
public MaterialPager(int total, int pageSize, int currentPage) {
this(total, pageSize);
this.currentPage = currentPage;
}
@Override
protected void onLoad() {
super.onLoad();
load();
}
protected void load() {
if (!calcInitialized) {
calcTotalPages = total / pageSize + (((double) total % (double) pageSize) > 0 ? 1 : 0);
add(getOrCreateLiElementLeft());
moveNextPagesRange();
add(getOrCreateLiElementRight());
if (enableIndicator) {
add(createLiElementIndicator());
}
onPageSelection(1);
calcInitialized = true;
}
}
protected void moveNextPagesRange() {
calcShowingPageFrom = currentPage;
calcShowingPageTo = Math.min(currentPage + maxPageLinksShown - 1, calcTotalPages);
createPageNumberLinks();
}
protected void movePreviousPagesRange() {
calcShowingPageFrom = currentPage - maxPageLinksShown + 1;
calcShowingPageTo = currentPage;
createPageNumberLinks();
}
protected void createPageNumberLinks() {
for (int i = 0; i < getWidgetCount(); i++) {
final PagerListItem widget = (PagerListItem) getWidget(i);
if (!widget.isFixed()) {
Scheduler.get().scheduleDeferred(widget::removeFromParent);
}
}
int insertionIndex = 1;
for (int i = calcShowingPageFrom; i <= calcShowingPageTo; i++) {
final PagerListItem liElementForPage = createLiElementForPage(i);
Scheduler.get().scheduleDeferred(new InsertElementAtPositionCommand(insertionIndex++) {
@Override
public void execute() {
insert(liElementForPage, insertionIndex);
}
});
}
}
protected PagerListItem createLiElementForPage(final int page) {
final PagerListItem pageLiElement = new PagerListItem();
pageLiElement.setFixed(false);
pageLiElement.add(createLinkPage(page));
registerHandler(addPageSelectionHandler(event -> pageLiElement.setActive(event.getPageTo() == page)));
registerHandler(pageLiElement.addHandler(event -> {
onPageSelection(page);
event.preventDefault();
event.stopPropagation();
}, ClickEvent.getType()));
return pageLiElement;
}
protected PagerListItem getOrCreateLiElementLeft() {
linkLeft = new PagerListItem();
linkLeft.setFixed(true);
registerHandler(linkLeft.addHandler(event -> {
if (linkLeft.isEnabled()) {
onPageSelection(currentPage - 1);
}
event.preventDefault();
event.stopPropagation();
}, ClickEvent.getType()));
linkLeft.add(createLinkLeft());
registerHandler(addPageSelectionHandler(event -> MaterialPager.this.linkLeft.setEnabled(event.getPageTo() > 1)));
return linkLeft;
}
protected PagerListItem getOrCreateLiElementRight() {
linkRight = new PagerListItem();
linkRight.setFixed(true);
registerHandler(linkRight.addHandler(event -> {
if (linkRight.isEnabled()) {
onPageSelection(currentPage + 1);
}
event.stopPropagation();
event.preventDefault();
}, ClickEvent.getType()));
linkRight.add(createLinkRight());
registerHandler(addPageSelectionHandler(event -> MaterialPager.this.linkRight.setEnabled(event.getPageTo() < calcTotalPages)));
return linkRight;
}
protected PagerListItem createLiElementIndicator() {
PagerListItem indicatorLi = new PagerListItem(false);
indicatorLi.setFixed(true);
indicatorLi.add(getOrCreateIndicator());
return indicatorLi;
}
protected MaterialChip getOrCreateIndicator() {
indicator = new MaterialChip();
indicator.getElement().getStyle().setBackgroundColor("inherit");
registerHandler(addPageSelectionHandler(event -> indicator.setText(indicatorTemplate
.replaceAll("\\{page\\}", String.valueOf(event.getPageTo()))
.replaceAll("\\{total\\}", String.valueOf(event.getTotalPage()))
)));
return indicator;
}
protected MaterialLink createLinkPage(int page) {
return new MaterialLink(String.valueOf(page));
}
protected MaterialLink createLinkLeft() {
final MaterialLink linkLeft = new MaterialLink(IconType.CHEVRON_LEFT);
linkLeft.setIconPosition(IconPosition.NONE);
return linkLeft;
}
protected MaterialLink createLinkRight() {
final MaterialLink linkRight = new MaterialLink(IconType.CHEVRON_RIGHT);
linkRight.setIconPosition(IconPosition.NONE);
return linkRight;
}
protected void onPageSelection(int page) {
currentPage = page;
if (currentPage > calcShowingPageTo) {
moveNextPagesRange();
}
if (currentPage < calcShowingPageFrom) {
movePreviousPagesRange();
}
PageSelectionEvent event = new PageSelectionEvent();
event.setPageFrom(currentPage);
event.setPageTo(page);
event.setTotalPage(calcTotalPages);
fireEvent(event);
}
public HandlerRegistration addPageSelectionHandler(PageSelectionHandler handler) {
return addHandler(handler, TYPE);
}
public boolean isEnableIndicator() {
return enableIndicator;
}
public void setEnableIndicator(boolean enableIndicator) {
this.enableIndicator = enableIndicator;
}
public int getTotal() {
return total;
}
public void setTotal(final int total) {
boolean needToClear = total != this.total;
this.total = total;
currentPage = 1;
if (calcInitialized && needToClear) {
clear();
load();
}
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getMaxPageLinksShown() {
return maxPageLinksShown;
}
public void setMaxPageLinksShown(int maxPageLinksShown) {
this.maxPageLinksShown = maxPageLinksShown;
}
public String getIndicatorTemplate() {
return indicatorTemplate;
}
/**
* Set the paging indicator label with a custom template
*
* - {page} is the current page
* - {total} is the total page
*
* Example
*
* {@code
* Page {page} of {total}
* }
*/
public void setIndicatorTemplate(String indicatorTemplate) {
this.indicatorTemplate = indicatorTemplate;
}
static abstract class InsertElementAtPositionCommand implements Scheduler.ScheduledCommand {
protected int insertionIndex;
InsertElementAtPositionCommand(int insertionIndex) {
this.insertionIndex = insertionIndex;
}
}
static class PagerListItem extends ListItem {
private boolean fixed;
private boolean enabled;
public PagerListItem() {
this(true);
}
public PagerListItem(boolean clickable) {
if (clickable) {
addStyleName(CssName.WAVES_EFFECT);
sinkEvents(Event.ONCLICK | Event.TOUCHEVENTS);
}
}
public boolean isFixed() {
return fixed;
}
public void setFixed(boolean fixed) {
this.fixed = fixed;
}
public void setActive(boolean active) {
if (active) {
addStyleName(CssName.ACTIVE);
} else {
removeStyleName(CssName.ACTIVE);
}
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public void setEnabled(boolean enabled) {
this.enabled = enabled;
if (!enabled) {
addStyleName(CssName.DISABLED);
} else {
removeStyleName(CssName.DISABLED);
}
}
}
public MaterialChip getIndicator() {
return indicator;
}
}