Components: [Paginator] Allow 'All' option

Created on 31 Oct 2017  路  24Comments  路  Source: angular/components

Feature request

What is the expected behavior?

Ability to provide "ALL" as page size option.[5,10,50, All]

What is the current behavior?

Page size options are fixed numbers.[5,10,50]

What is the use-case or motivation for changing an existing behavior?

Most paginators offer this function, therefore user expects it.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

All

P5 materiapaginator feature

Most helpful comment

+1
I need this feature as well. Using an ugly workaround for now.

All 24 comments

@andrewseguin When are you planning to implement this functionality and are there any solutions?

Its on our roadmap but we haven't yet planned it for implementation.

This works, but isn't great:
<mat-paginator [pageSizeOptions]="getPageSizeOptions()"></mat-paginator>

then in code:

getPageSizeOptions(): number[] {
  return [5, 10, 20, myTableDataSourceArray.length];
}

Labels for the entries would be nice, something like

[pageSizeOptions]="[5, 10, 20, 57]"  
[pageSizeLabels]="[5, 10, 20, ALL]"

I've implemented a solution locally, but I've never actually contributed to Material2 before. I've read through the CONTRIBUTING.md file and it says to search for existing issues. Doing so resulted in finding this issue so I would assume I should not create a new issue for my contribution. What are the appropriate next steps? Should I simply attach my contribution here for review? Thanks

@jeff-a-andersen

  1. Fork this repo
  2. Clone your fork into your local machine
  3. Checkout a new branch in your clone
  4. Do the required changes in the new branch
  5. Commit and push to your fork
  6. Submit a pull request

Further details in the contributing guide

Is this still planned?

I'm still planning to make the change, just keep getting pulled away for my daily work..

+1

+1
I need this feature as well. Using an ugly workaround for now.

Has this been implemented yet?

I did make the changes to my copy of the material2 repository about a year ago. I didn't have time to jump through the hoops to get it released at the time. Since then, we've moved to using PrimeNG so my changes sat dormant because it was less of a priority for me. If you're interested in taking this up, you can see what I changed in the following commits:

https://github.com/jeff-a-andersen/material2/commit/5b185510f28c98d97b39f254c95ad5125b3f8c26
https://github.com/jeff-a-andersen/material2/commit/4b7f10fb102745eb2fd9fe587a25922d213dd1ba

If I can ever find time to jump back into it, I will.

+1
I need this feature as well. Using an ugly workaround for now.

What kind of workaround are you using?

+1
I need this feature as well. Using an ugly workaround for now.

What kind of workaround are you using?
@dilyandimitrov
I'm using a very large number to mean "all" e.g. [5, 10, 20, 1000]
Obviously this is not clean, nice or safe. Have you seen the proposed solution by @rramsey above? To be honest, his workaround looks better than mine.

Hey, guys... no update here yet?

I used a solution from stackoverflow:
https://stackoverflow.com/questions/47588162/how-to-add-all-option-for-angular-material-paginator
It's similar to @rramsey 's solution, but the styling part was missing.

To make the solution work I needed to add encapsulation: ViewEncapsulation.None inside of @Component decorator.
The only problem I got is that through ViewEncapsulation.None the "All" Option appears in every component. Yes, that's what ViewEncapsulation.None is made for.
Does anybody have another solution to make he "All" thing work in a specific component without using ViewEncapsulation.None?

Hey, @KevCanon . I did it, but not in a pretty good way, it worked tho. So, I changed directly the DOM by manipulating a high number (because I needed it to be translated according to the culture) and I used the pageEvent:

```
this.textALL = this.translate.instant('All');
addOptionAllToPaginator(): void {
const element: NodeListOf = this.window.document.querySelectorAll('[role="option"]');

    if (element !== null && element !== undefined) {
        for (let i = 0; i < element.length; i++) {
            const optText = element[i].getElementsByClassName('mat-option-text');

            if (optText !== null && optText !== undefined && optText.length === 1) {
                const text: HTMLSpanElement = optText[0] as HTMLSpanElement;
                const textWithoutSpace = text.innerText.replace(/\s/g, '');
                if (Number(textWithoutSpace) && textWithoutSpace === '9999') {
                    text.innerHTML = this.textALL;
                }
            }
        }
    }
}

pageEventChanged(pageEvent: PageEvent): void {
    if (this.previousPageSize !== pageEvent.pageSize) {
        const ariaLabelTranslated: string = this.paginator._intl.itemsPerPageLabel;
        const element: NodeListOf<Element> = this.window.document.querySelectorAll(`[aria-label="${ariaLabelTranslated}"]`);

        if (element !== null && element !== undefined) {
            for (let i = 0; i < element.length; i++) {
                const optText: HTMLCollectionOf<Element> = element[i].getElementsByClassName('mat-select-value-text');

                if (optText !== null && optText !== undefined && optText.length === 1) {
                    const text: HTMLSpanElement = optText[0] as HTMLSpanElement;

                    if (Number(text.innerText) && pageEvent.pageSize === 9999) {
                        text.innerHTML = this.textALL;
                    } else {
                        text.innerHTML = pageEvent.pageSize.toString();
                    }
                }
            }
        }

        this.previousPageSize = pageEvent.pageSize;
    }
}

getPageSizeOptions(): number[] {
    const pageSizeOptions: number[] = [5, 10, 25];

    if (this.templates !== null && this.templates.length > 0) {
        pageSizeOptions.push(9999);
        this.addOptionAllToPaginator();
    }

    return pageSizeOptions;
}```

@andrewseguin I've been waiting for this implementation for 2 years, when the update?))

I submitted #20367 based on @jeff-a-andersen's solution... fingers crossed!

I submitted a more focus solution: #20397.

@Lavdaft I'm using a similar approach but it broke somehow after upgrading angular 8 to 11.
We are now facing an issue when the default value is already "All".
Did you manage to make your solution work in this scenario?

When the default is already "All", we show 9999 in the text selected.

And if we force the selected text to "All", it never gets back to a number even after further selections.

My solution does work as expected even when you start with a length that is equal to your page size (with label "All"). For example: in my typescript I set the following properties:

  length = 100;
  pageSize = 100;
  pageIndex = 0;
  pageSizeOptions: {[key: string]: string} = {5: '5', 10: '10', 25: '25,' 100: 'All'};

And in my HTML:

  <mat-paginator #paginator
                 (page)="handlePageEvent($event)"
                 [length]="length"
                 [pageSize]="pageSize"
                 [pageSizeOptions]="showPageSizeOptions ? pageSizeOptions : {}"
                 [pageIndex]="pageIndex">
  </mat-paginator>

In this scenario, the page size will be defaulted to "All", and I can successfully change it to 5, 10 or 25.

I developed the solution on Angular 10.

My solution does work as expected even when you start with a length that is equal to your page size (with label "All"). For example: in my typescript I set the following properties:

  length = 100;
  pageSize = 100;
  pageIndex = 0;
  pageSizeOptions: {[key: string]: string} = {5: '5', 10: '10', 25: '25,' 100: 'All'};

And in my HTML:

  <mat-paginator #paginator
                 (page)="handlePageEvent($event)"
                 [length]="length"
                 [pageSize]="pageSize"
                 [pageSizeOptions]="showPageSizeOptions ? pageSizeOptions : {}"
                 [pageIndex]="pageIndex">
  </mat-paginator>

In this scenario, the page size will be defaulted to "All", and I can successfully change it to 5, 10 or 25.

I developed the solution on Angular 10.

What is "showPageSizeOptions"? Can you show its code?

showPageSizeOptions is simply a boolean property found in dev-app contained in the the Angular Material components source code.

You can download the source code and run dev-app to see demos of the components with the ability to adjust various options on the fly. In the case of mat-paginator, the `showPageSizeOptions in the paginator-demo.ts file supports a toggle in the paginator demo page that allows you to show/hide the dropdown list of page size options.

dbgod, thank you, I viewed this document. I need to do label for page size option, that shows all elements. I can do it with variable that shows number on front-end, but I need to show label "All".

Your decision - "pageSizeOptions: {[key: string]: string} = {5: '5', 10: '10', 25: '25', 100: 'All'};" looks good and this is that what I looked for. But it doesn't work with my code. I work with Angular 11, not sure that it's matter in this case.

Here is my code, maybe you can see and tell what is wrong:

HTML:

<mat-paginator
            (page)="pageEvent = $event; onPaginateChange($event)"
            [length]="numberPatientTests"
            [pageSize]="defaultTestsPerPage"
            [disabled]="disabled"
            [showFirstLastButtons]="showFirstLastButtons"
            [pageSizeOptions]="showPageSizeOptions ? pageSizeOptions : {}"
            [hidePageSize]="hidePageSize"
            [pageIndex]="pageIndex">
</mat-paginator>

TS:

numberPatientTests = this.tests.length;
  defaultTestsPerPage: any = 5;
  filteredTests: any[] = [];
  pageSizeOptions: {[key: string]: string} = {5: '5', 10: '10', 25: '25', 100: '100', 1000: 'All'};
  pageIndex = 0;
  pageEvent: PageEvent;
  hidePageSize = false;
  showPageSizeOptions = true;
  showFirstLastButtons = true;
  disabled = false;

onPaginateChange(data: PageEvent) {
    this.filteredTests = this.tests.slice(data.pageIndex*data.pageSize, data.pageIndex*data.pageSize + data.pageSize);
  }
Was this page helpful?
0 / 5 - 0 ratings