Hone logo
Hone
Problems

Implement Dynamic Pagination in an Angular Component

This challenge requires you to build a reusable Angular component that handles pagination for a list of items. Effective pagination is crucial for improving user experience when dealing with large datasets, allowing users to navigate through information without overwhelming them.

Problem Description

Your task is to create an Angular component, PaginationComponent, that displays pagination controls for a given total number of items and a specified number of items per page. This component should:

  • Display Page Numbers: Show a series of clickable page numbers.
  • Navigate Pages: Allow users to click on page numbers to select a different page.
  • Indicate Current Page: Visually highlight the currently active page.
  • Control Items Per Page: Potentially offer a way (though not strictly required for the core challenge) for users to change the number of items displayed per page. For this challenge, assume a fixed itemsPerPage is provided.
  • Handle First/Last/Previous/Next Navigation: Include buttons for navigating to the first page, previous page, next page, and last page.
  • Manage Total Pages: Dynamically calculate the total number of pages based on the totalItems and itemsPerPage.
  • Emit Page Change Events: Notify the parent component when the user selects a new page, providing the newly selected page number.

Key Requirements:

  1. Component Structure: Create a standalone Angular component (PaginationComponent).
  2. Inputs: The component should accept the following inputs:
    • totalItems: A number representing the total count of items to be paginated.
    • itemsPerPage: A number representing how many items should be displayed on each page.
    • currentPage: A number representing the currently active page (zero-based or one-based, be consistent and document it). Let's assume one-based for this challenge.
  3. Outputs: The component should emit an output event:
    • pageChanged: An EventEmitter<number> that emits the new page number whenever the user navigates to a different page.
  4. Behavior:
    • Calculate totalPages as Math.ceil(totalItems / itemsPerPage).
    • Render page numbers from 1 up to totalPages.
    • The "Previous" button should be disabled if currentPage is 1.
    • The "Next" button should be disabled if currentPage is equal to totalPages.
    • The "First" button should be disabled if currentPage is 1.
    • The "Last" button should be disabled if currentPage is equal to totalPages.
    • The currently selected page number should have a distinct visual style (e.g., a different background color or font weight).
  5. Edge Cases:
    • totalItems is 0.
    • itemsPerPage is 0 (or invalid). Handle gracefully, perhaps by displaying no pagination or an error. Assume itemsPerPage will be a positive integer for this challenge.
    • totalItems is less than itemsPerPage.
    • A large number of totalPages might require "ellipsis" (...) to represent omitted page numbers, though for this challenge, displaying all page numbers is sufficient if totalPages is reasonably small (e.g., <= 10).

Examples

Example 1:

Input to PaginationComponent:
@Input() totalItems = 100;
@Input() itemsPerPage = 10;
@Input() currentPage = 1;

Expected UI Output (Simplified representation):
First | Prev | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Next | Last
(Page 1 is highlighted)

Example 2:

Input to PaginationComponent:
@Input() totalItems = 35;
@Input() itemsPerPage = 5;
@Input() currentPage = 4;

Expected UI Output (Simplified representation):
First | Prev | 1 | 2 | 3 | 4 | 5 | 6 | 7 | Next | Last
(Page 4 is highlighted)

Example 3: Edge Case - No items

Input to PaginationComponent:
@Input() totalItems = 0;
@Input() itemsPerPage = 10;
@Input() currentPage = 1;

Expected UI Output:
(No pagination controls displayed)

Example 4: Edge Case - All items on one page

Input to PaginationComponent:
@Input() totalItems = 8;
@Input() itemsPerPage = 10;
@Input() currentPage = 1;

Expected UI Output (Simplified representation):
First | Prev | 1 | Next | Last
(Page 1 is highlighted)

Constraints

  • The pagination component must be implemented using Angular (version 12+ recommended).
  • Use TypeScript for the component logic.
  • The styling for the pagination controls can be basic CSS, but it should clearly indicate the current page.
  • The currentPage input will always be a valid page number between 1 and totalPages (inclusive), or 1 if totalItems is 0.
  • totalItems and itemsPerPage will be non-negative integers.
  • Assume a reasonable maximum number of totalPages (e.g., <= 20) for simplicity in displaying page numbers; you don't need to implement complex ellipsis for this core challenge.

Notes

  • Consider how you will generate the list of page numbers to display. A simple *ngFor loop is a good starting point.
  • Think about the logic for handling clicks on page numbers, "First," "Prev," "Next," and "Last" buttons. Ensure these actions correctly update the currentPage and emit the pageChanged event.
  • Remember to handle the disabled state of navigation buttons based on the currentPage and totalPages.
  • You'll need to define CSS classes or styles to visually distinguish the active page.
  • Consider the zero-based vs. one-based indexing for currentPage. For this challenge, we've specified one-based. Ensure your internal logic and emitted values are consistent.
Loading editor...
typescript