Open tplk opened 7 years ago
@t-p-l-k I don't really get the use case, could you be more specific? When external paging is enabled the page size is automatically calculated, so I don't get the need to expose this.
@mvhecke How can we control automatic calculation of the pageSize. Because it forcing to miscalculate the number pages.
Please refer the issue "Issue with Number of pages" #804
@mvhecke here's an example:
Pager displays 5 pages and it's okay when you only have pagination in the footer. But what if we need extra information there?
Well, it seems logical to reduce pager's width so it doesn't take 1/3 of footer's width.
Another use case is a mobile layout where viewport width causes default pager to wrap.
Last use case can be solved with css media queries but anyway.
Aah, a very good example. Now I get why you would want this, should be pretty easy to expose this.
Offtopic: @mvhecke btw, I don't understand how can I change row limit dynamically. You've mentioned somewhere that datatable uses OnPush change detection strategy but it doesn't work with limit value (works for pager maxSize without any extra work, I just switched constant maxSize with an input variable). Should I create a new issue to solve this?
Oh, I think I figured it out: https://plnkr.co/edit/wRWlit
@t-p-l-k do you mind explaining how you went about finding your solution? I modified it to work for a drop-down menu to choose the number of items per page, but I don't fully understand what's going on code wise.
@t-p-l-k I am little curious to know how could we get selection box in the footer to allow changing the pageSize. Please see the highlighted section in image.
I'd tried to achieve it however could not make it work. I've seen you got good hold on this code, could you please help me out achieve this.
Thanks. Rahul
Adding to my query :
@mvhecke Would it be a good idea to have this feature [allow to change page size from footer] OOTB !
@rahul-winner sure, here's working example: https://plnkr.co/edit/ym689j You can create custom footer template and move select element there:
<ngx-datatable-footer>
<ng-template
ngx-datatable-footer-template
let-rowCount="rowCount"
let-pageSize="pageSize"
let-selectedCount="selectedCount"
let-curPage="curPage"
let-offset="offset"
>
<div class="datatable-footer_pagination">
<datatable-pager
[page]="curPage"
[size]="pageSize"
[count]="rowCount"
[hidden]="false"
(change)="table.onFooterPage($event)">
</datatable-pager>
<div class="page-limit-container">
<select (change)="onLimitChange($event.target.value)" class="page-limit">
<option
*ngFor="let option of pageLimitOptions"
[value]="option.value"
[selected]="option.value == currentPageLimit"
>
{{option.value}} per page
</option>
</select>
</div>
</div>
</ng-template>
</ngx-datatable-footer>
@dylandrollut well, basically @ViewChild(DatatableComponent) private table: DatatableComponent;
gives you a pointer to the table. DatatableComponent has limit
attribute which defines number of rows per page. In my example I change it directly but you can probably do the same by binding a variable in the template:
<ngx-datatable
[rows]='rows'
[limit]='pageLimit'
[columns]='[{name:"Name"},{name:"Gender"},{name:"Company"}]'
[columnMode]='"force"'
[headerHeight]='50'
[footerHeight]='50'
[rowHeight]='"auto"'>
</ngx-datatable>
I thought that it doesn't matter since you still need a pointer to the table so you can call recalculate()
method.
setTimeout(() => {
if (this.table.bodyComponent.temp.length <= 0) {
this.table.offset = Math.floor((this.table.rowCount - 1) / this.table.limit);
}
});
This is a hackish way to switch active page to the last one available.
this.table.bodyComponent.temp
is an array of currently visible rows if you're using pagination.
When you have 100 items total and 5 items per page then you have 20 pages.
If you go to the 20th page and switch page limit to 50 items per page then you'll only have 2 pages.
this.table.offset = Math.floor((this.table.rowCount - 1) / this.table.limit);
changes active page to the last page available (2 in this example).
This was only tested with client-side pagination and I have no idea what's going to happen if you use it with server-side. You can just change offset to 0 so when you change page limit your paging will reset. It will give protection from navigating to unexisting page and will work with server-side pagination I think.
Thank you for the reply @t-p-l-k. I actually did bind it to a variable for the drop-down menu. Any idea on how to do that but with two drop-downs and two tables on the same page?
@dylandrollut move it to a separate component?
I think is can be a valuable feature, especially for large datasets. But it shouldn't be enabled by default as most applications don't allow you to do this.
Was the original feature request ever looked into? I was interested in displaying a much smaller number of pages in the paginator to avoid overflowing.
@irco I've implemented it in my project, I can share my code here but I don't have time to test everything and create a PR.
Possibly related. https://github.com/swimlane/ngx-datatable/issues/963
I fixed a bug that didn't allow you to bind the limit
and it was only allowed to be set once without a workaround. It now updates when you change `limit' from the template.
I'm assuming you want a more customizable pager though.
@t-p-l-k would love to see what you did. I might have the time to do a pr if this is something desired.
@t-p-l-k could you share your css for for this pagination ?
Hello, I think it would help to can set the maximun of custom number of pages. Currently it's hardcoded to display 5 pages always.
const maxSize = 5;
Looks messy for mobile.
You can prevent that using styles. I just fixed using this:
@media (max-width: 560px) { .ngx-datatable .datatable-footer .datatable-pager .pager li.pages { display: none !important; } }
@t-p-l-k : Not sure if you're still checking this page, but would love to know how you were able to override the 'const maxSize = 5' statement. I really need to set it to 3 due to limited horizontal space at lower resolutions (as you illustrated previously with your screenshots above) but can't figure out how to accomplish that since the calcPages() function only has one parameter (not the one I need) as well as maxSize is set as a constant.
@cole-paciano hello!
I don't use ngx-datatable anymore really, I usually implement my own data grids based on angular/cdk DataTable.
But I found my old implementation and updated it to work with current version of ngx-datatable, here you go: https://stackblitz.com/edit/tplk-angular-ngx-datatable-custom-paginator
There are two dropdowns to change rows per page and visible pages in paginator. Custom paginator is basically ngx-datatable's paginator with additional visiblePagesCount
input and updated calcPages
method.
It can definitely be improved, it's just a really quick example. Hope it helps!
@duard Hi! I'm sorry for such late reply. I don't know if you still need this and I don't have time to clean it up, but here's what I've got:
@import '~@swimlane/ngx-datatable/release/index.css';
@import '~@swimlane/ngx-datatable/release/themes/material.css';
@import '~@swimlane/ngx-datatable/release/assets/icons.css';
@import './shared/variables';
@import './shared/breakpoints';
// Component styles are so messed up that it's impossible
// to override them without breaking style guide.
/* stylelint-disable */
.ngx-datatable.material.single-selection .datatable-body-row.active,
.ngx-datatable.material.single-selection .datatable-body-row.active .datatable-row-group,
.ngx-datatable.material.multi-selection .datatable-body-row.active,
.ngx-datatable.material.multi-selection .datatable-body-row.active .datatable-row-group,
.ngx-datatable.material.multi-click-selection .datatable-body-row.active,
.ngx-datatable.material.multi-click-selection .datatable-body-row.active .datatable-row-group {
background-color: #54af3b;
color: #fff;
&:hover {
background-color: #55b93c;
color: #fff;
}
}
.ngx-datatable.material {
.progress-linear {
position: fixed !important;
bottom: 0px;
}
.datatable-footer_scroll-to-top {
margin: 1em;
.scroll-to-top-button {
padding: 0.5em 1em;
color: #fff;
background-color: #4d87ea;
}
}
.datatable-header {
background-color: #383a3c;
}
.datatable-header-cell-label {
color: #fff;
cursor: pointer;
}
.datatable-body-cell-label {
cursor: default;
}
.datatable-footer {
font-size: 1em;
.datatable-footer_pagination {
width: 100%;
padding: 0.5em 1em;
display: flex;
justify-content: space-between;
align-items: center;
}
}
.glp-datatable-pager {
flex: none;
margin-right: 1em;
margin-left: 0;
text-align: initial;
ul {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
li {
width: 2.5em;
height: 2.5em;
margin-right: 0.3em;
cursor: pointer;
&.active {
font-weight: bold;
}
&.disabled {
opacity: 0.6;
}
&.nav {
background-color: #e68628;
color: #fff;
a {
font-size: 1.5em;
}
}
&.pages {
background-color: #e6e6e6;
display: none;
@include gt-xs {
display: inherit;
}
}
}
a {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
}
.datatable-footer__page-limit {
padding: 0.4em;
font-size: 1.2em;
width: 10em;
}
&.scroll-vertical {
max-height: 90vh;
min-height: 20em;
}
::-webkit-scrollbar {
width: 0.35em;
height: 0.35em;
}
::-webkit-scrollbar-thumb {
background-color: transparent;
}
::-webkit-scrollbar-thumb:vertical {
border-left: 0.1em solid $scrollbar-background-color;
}
::-webkit-scrollbar-thumb:horizontal {
border-top: 0.1em solid $scrollbar-background-color;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
}
Related HTML:
<ngx-datatable-footer>
<ng-template
let-rowCount="rowCount"
let-pageSize="pageSize"
let-selectedCount="selectedCount"
let-curPage="curPage"
let-offset="offset"
ngx-datatable-footer-template
>
<div class="datatable-footer_pagination">
<glp-datatable-pager
[page]="curPage"
[visiblePagesCount]="3"
[size]="pageSize"
[count]="rowCount"
[hidden]="false"
(change)="table.onFooterPage($event)">
</glp-datatable-pager>
<div class="datatable-footer__page-limit-container">
<select (change)="onLimitChange($event.target.value)" class="datatable-footer__page-limit">
<option
*ngFor="let option of pageLimitOptions"
[value]="option.value"
[selected]="option.value == currentPageLimit"
>
{{option.value}} {{ 'COMPONENTS.DATATABLE.PER_PAGE' | translate }}
</option>
</select>
</div>
</div>
</ng-template>
</ngx-datatable-footer>
@t-p-l-k Thank you so much for taking the time to put that example together! That did the trick. So basically, you overwrote the existing pager.component.ts file with a modified version that allows for setting the amount of pager buttons to be viewed. I wonder if I should be concerned for any potential conflicts if/when future updates are made to the original file by swimlane down the road? In any event, thanks again for your quick and helpful response!
@cole-paciano I guess I'll put a PR together later this week if I have spare time. Yeah, on upgrade you should check if there are any major changes in Paginator to keep it up to date. Also, since in my example it extends default paginator, you can remove any methods/vars which you don't want to override from custom paginator.
Make an extension.ts and import that in component
import 'app/...../xxx-datatable-pager.extensions'; //Import this one time and it will effect everywhere in project.
import { DataTablePagerComponent } from "@swimlane/ngx-datatable";
declare module '@swimlane/ngx-datatable/release/components/footer/pager.component' {
}
DataTablePagerComponent.prototype.calcPages = function (page) {
console.log('DataTablePagerComponent.prototype.calcPages');
var pages = [];
var startPage = 1;
var endPage = this.totalPages;
var maxSize = 3;
var isMaxSized = maxSize < this.totalPages;
page = page || this.page;
if (isMaxSized) {
startPage = page - Math.floor(maxSize / 2);
endPage = page + Math.floor(maxSize / 2);
if (startPage < 1) {
startPage = 1;
endPage = Math.min(startPage + maxSize - 1, this.totalPages);
}
else if (endPage > this.totalPages) {
startPage = Math.max(this.totalPages - maxSize + 1, 1);
endPage = this.totalPages;
}
}
for (var num = startPage; num <= endPage; num++) {
pages.push({
number: num,
text: num
});
}
return pages;
};
need left alignment who can i ?
angular 8
i already play with scss but not working
need left alignment who can i ?
<ngx-datatable class="bootstrap" [rows]="rows" [columnMode]="'force'" [headerHeight]="50" [footerHeight]="50" [rowHeight]="'auto'" [limit]="10" [sorts]="[{prop: 'submiteddate', dir: 'desc'}]"> <ngx-datatable-column name="Submited Date"> <ng-template let-row="row" ngx-datatable-cell-template> {{row.submiteddate}} </ng-template> </ngx-datatable-column> <ngx-datatable-column name="Currency"> <ng-template let-row="row" ngx-datatable-cell-template> {{row.currency}} </ng-template> </ngx-datatable-column> <ngx-datatable-column name="Address"> <ng-template let-row="row" ngx-datatable-cell-template> {{row.address}} </ng-template> </ngx-datatable-column> <ngx-datatable-column name="Amount"> <ng-template let-row="row" ngx-datatable-cell-template> {{row.amount}} </ng-template> </ngx-datatable-column> <ngx-datatable-column name="Snap Amount"> <ng-template let-row="row" ngx-datatable-cell-template> {{row.snapamount}} </ng-template> </ngx-datatable-column> <ngx-datatable-column name="Status"> <ng-template let-row="row" ngx-datatable-cell-template> {{row.status}} </ng-template> </ngx-datatable-column> <ngx-datatable-column name="Hash"> <ng-template let-row="row" ngx-datatable-cell-template> {{row.hash}} </ng-template> </ngx-datatable-column> </ngx-datatable> </div>
I'm submitting a ... (check one with "x")
Current behavior DataTablePagerComponent can't be configured to display custom number of pages. Currently it's hardcoded to display 5 pages always.
Expected behavior User should be able to set a custom number of elements to be displayed which fits his project requirements.
I already implemented it in my current project by adding a variable which can be passed from the template. If anyone interested I can create a pull request.