angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.39k stars 6.76k forks source link

[Paginator] Add jump-to-page functionality #7615

Open dushkostanoeski opened 7 years ago

dushkostanoeski commented 7 years ago

Bug, feature request, or proposal:

Feature request

What is the expected behavior?

To be able to jump to a specific page using a dropdown populated with page numbers. The dropdown should be next in line after the Items per page dropdown, so you can choose the page size and then the page number you want to go to.

Don't know if the following part is smart, but in use cases where the page number is large, a step input can be implemented. If the total number of pages is 500, and the step is 5, the Page number dropdown would hold only pages 1, 5, 10, 15, 20 .... so the user can get to the desired page in as little scrolling and as few clicks as possible.

What is the current behavior?

To get to a specific page you have to go page by page

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

In my case, I have a 100 item per page list, that has 3500 total items sorted by date and the users land at the last page. If the users wants to check the items that were added at the beginning of the year, they know that they should be looking at items from 1 to at least 300, so that is 32 clicks to get to the desired items. As the total page count gets bigger, the harder it is to get to the last pages (first pages in my case).

willshowell commented 7 years ago

Maybe something like this will help in the mean time

https://stackblitz.com/edit/material2-beta12-fpf2ka?file=app%2Fapp.component.ts

dushkostanoeski commented 7 years ago

I have a working component that wraps around the paginator, adds the dropdown and all the events are bound to the same function so you don't need to have separate event handlers.

A paginator component should let you get to a specific page easily. I'd make a PR if the idea is considered acceptable.

dushkostanoeski commented 7 years ago

@andrewseguin will this get in on the next beta?

andrewseguin commented 7 years ago

@dushkostanoeski We haven't started work on something like this, especially since its out of the spec and we'd have to really consider how the UX would play out here

Chris2011 commented 6 years ago

button for firstPage and lastPage is also needed, should I create a new ticket? Couldn't find a ticket until now for such functionality.

Asad-Islam commented 6 years ago

I think it's possible using the existing API. You can try like this...

 this.paginator.pageIndex = pageNumber, // number of the page you want to jump.
 this.paginator.page.next({      
      pageIndex: pageNumber,
      pageSize: this.paginator.pageSize,
      length: this.paginator.length
    });

where this.paginator is

@Input()
paginator: MatPaginator;

For jumping to a specific page you can add an input box or select box and execute that piece of code and for jumping to previous or last page two button could be added which could use that too.

dushkostanoeski commented 6 years ago

Extending the current paginator isn't a problem, the thing is that a paginator should have a jump to page functionality.

Asad-Islam commented 6 years ago

@dushkostanoeski yes you're right. It would've been a useful functionality.

dushkostanoeski commented 6 years ago

@andrewseguin I can make a PR about this, if that's OK

andrewseguin commented 6 years ago

You're welcome to open a PR but it may be worth discussing what the UX would look like. Do you have suggestions on how the UI would appear?

dushkostanoeski commented 6 years ago

The field would be optional and I was thinking of adding it after the Items per page field. The label would say Jump to page: followed by a dropdown populated with the page numbers. That way the user can choose the page size and then jump to the desired page.

willshowell commented 6 years ago

What would the select options text be? Page numbers or item ranges? Configurable via MatPaginatorIntl?

dushkostanoeski commented 6 years ago

The Jump to page label makes you think of page numbers, but being able to choose between item ranges and page numbers, or even both, something like Jump to page: 2 (11 - 20) is even better.

Should the label change depending on what the dropdown is populated with?

AntonisFK commented 6 years ago

Can it look the same like in https://github.com/daniel-nagy/md-data-table

dushkostanoeski commented 6 years ago

That's pretty much the idea

mzernetsch commented 6 years ago

How about converting the .mat-paginator-range-label to a mat-select so a user can choose the range directly.

Would look like this: image

throne1986 commented 6 years ago

hii

https://stackoverflow.com/questions/51542796/table-angular-material-pagination-does-not-work-as-expected

was this solved at all? can some check this thread related to this too ?

alex-osman commented 6 years ago

+1 this would be super useful

piyushgupta1 commented 6 years ago

+1

sumigoma commented 6 years ago

How about a UI like something like what @shlomiassaf has in his table demos? It feels very natural to put the current page index between the next and prev buttons.

image

bastian-f commented 5 years ago

How about a UI like something like what @shlomiassaf has in his table demos? It feels very natural to put the current page index between the next and prev buttons.

image

Could please provide a link to this demo? Thank you!

parys commented 5 years ago

@bastian-f https://shlomiassaf.github.io/table-demo/table-demo#/extensions/pagination

azamanaza commented 4 years ago

Any chances this gets implemented this year? Doesn't look like the suggestions took traction.

sameerthekhans commented 4 years ago

I have created a mat-paginator-goto component over mat-paginator, this works same as original mat-paginator but also has option of goTo/jumpTo specific page.

The list of available pages for goTo have been calculated based on length and pageSize.

To Integrate in your angular/material project follow below steps

Step 1: Goto mat-paginator-with-goto (Stackblitz)

Step 2: Copy folder(mat-paginator-goto) and paste into you project

Step 3: Import in your module

import { MatPaginatorGotoComponent } from './mat-paginator-goto/mat-paginator-goto.component';

@NgModule({
  declarations: [ ...MatPaginatorGotoComponent ],
})

Step 4: Use it same as original mat-paginator

<mat-paginator-goto [length]="100" [pageSize]="10" [pageSizeOptions]="[5, 10, 25, 100]"
        (page)="paginationChange($event)"></mat-paginator-goto>

Note: Update import paths and styles accordingly

crisbeto commented 3 years ago

We may want to accommodate a design like the one mentioned in https://github.com/angular/components/issues/22361#issue-843300077.

112833501-df95b280-90a7-11eb-95b8-12c503039e9e

hardikhari96 commented 2 years ago

We may want to accommodate a design like the one mentioned in #22361 (comment).

112833501-df95b280-90a7-11eb-95b8-12c503039e9e

I liked that design

Doyalle commented 2 years ago

Great, but in this design, 1 and 100 is the same that first and last page. We don't need the two sign at the end. The number is better cause we have the gain of the information.

We loose the gain of the proximity of the two arrows two (less moove of the mouse). It will be great to have a reflexion of the good practice to have the less click to go to a page (like a page 75 and a page 25 ?

Something like this

image

image

image

image

Khelthos commented 2 years ago

How about converting the .mat-paginator-range-label to a mat-select so a user can choose the range directly.

Would look like this: image

Hi, did you have a working example of this? Thank you.

alvipeo commented 2 years ago

So, it's been 5 (FIVE) years? Are you going to make it or now? If not, just say so.

nishchay7pixels commented 1 year ago

Anyone working on it?

image Just like Items Per Page, Got page dropdown will also be controlled by a boolean flag which if enabled will display it as part of paginator and if disabled will hide it.

KostaProsenikov commented 1 year ago

So no Go To page functionality for the Angular material even though so much requests are made ? This is ridiculous. @mgechev shall this functionality be implemented some day in the future, please ?

timeoutguy commented 1 year ago

Next month, 6 years will have passed 🥳

CharlyDucrocq commented 5 months ago

I put this here. Not perfect but fine enough.

import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  ComponentRef,
  Directive,
  ElementRef,
  EventEmitter,
  Input,
  Output,
  ViewContainerRef,
} from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatInputModule } from '@angular/material/input';

@Directive({
  standalone: true,
  selector: '[selectablePaginator]',
})
export default class SelectablePaginatorDirective implements AfterViewInit {
  selectPageComp: ComponentRef<SelectPageComponent>;

  constructor(
    private el: ElementRef,
    private paginator: MatPaginator,
    private viewContainerRef: ViewContainerRef,
  ) {
    this.selectPageComp = this.viewContainerRef.createComponent(SelectPageComponent);

    this.paginator.page.subscribe(() => {
      this.selectPageComp.setInput('page', this.paginator.pageIndex);
    });

    this.selectPageComp.instance.pageChange.subscribe((page) => {
      let prev = this.paginator.pageIndex;
      this.paginator.pageIndex = page;
      this.paginator.page.emit({
        pageIndex: page,
        previousPageIndex: prev,
        pageSize: this.paginator.pageSize,
        length: this.paginator.length,
      });
    });
  }

  @Input()
  set pageIndex(pageIndex: number | undefined) {
    this.selectPageComp.setInput('page', this.paginator.pageIndex);
  }

  ngAfterViewInit(): void {
    // place page selector after previous-page-button
    (this.el.nativeElement as HTMLElement)
      .querySelector('.mat-mdc-paginator-navigation-previous')!
      .after(this.selectPageComp.location.nativeElement);
  }
}

@Component({
  selector: 'selectable-paginator-page-select',
  standalone: true,
  imports: [MatInputModule],
  template: `<input
    (change)="emitChange($event)"
    [value]="page"
    matInput
    min="0"
    type="number" />`,
  changeDetection: ChangeDetectionStrategy.OnPush,
  styles: `
    // remove arrow on input[type='number']
    input::-webkit-outer-spin-button,
    input::-webkit-inner-spin-button {
      -webkit-appearance: none;
      margin: 0;
    }
    input[type='number'] {
      width: 2.5rem;
      text-align: center;
      -moz-appearance: textfield;
    }
  `,
})
export class SelectPageComponent {
  @Input() page: number = 0;
  @Output() pageChange: EventEmitter<number> = new EventEmitter<number>();

  emitChange(event: any) {
    this.pageChange.emit(event.target.value);
  }
}