bestguy / sveltestrap

Bootstrap 4 & 5 components for Svelte
https://sveltestrap.js.org
MIT License
1.31k stars 183 forks source link

Suggestion for Pagination (with code example) #353

Open nstuyvesant opened 3 years ago

nstuyvesant commented 3 years ago

There are a number of Svelte pagers out there of varying quality (svelte-paginate being one that doesn't use Bootstrap). Perhaps it would make sense to have similar capability in SvelteStrap?

Would submit this as a PR but day job is getting in the way of me writing tests.

This code I use for my Paginator.svelte component could be modified to use Pagination, PaginationItem, and PaginationLink easily...

<script lang="ts">
  // $lib/Paginator.svelte
  import { Icon } from 'sveltestrap'

  export let totalItems = 0
  export let pageSize = 10
  export let currentPage = 1
  export let clickFunction: Function

  let pageButtons: number[]

  $: totalPages = Math.ceil(totalItems / pageSize)

  $: {
    pageButtons = []
    for (let val = 1; val <= totalPages; ++val) {
      // Put in -1's where the ellipsis will go
     const pageNumberValue = Math.abs(currentPage - val) < 2 || val == 1 || val == totalPages ? val : -1
     pageButtons.push(pageNumberValue)
    }
    // Get rid of duplicate -1s which represent an ellipsis
    pageButtons = pageButtons.filter((val,index) => pageButtons[index-1] !== val)
  }
</script>

{#if totalPages > 1}
    <nav aria-label="Record navigation">
        <ul class="pagination">
            <li class="page-item" class:disabled={currentPage == 1}>
                <a class="page-link" href={'#'} on:click|preventDefault={() => clickFunction(currentPage-1)} aria-label="Previous"><Icon name="chevron-left"/></a>
            </li>
            {#each pageButtons as pageNumber}
                <li class="page-item" class:active={pageNumber == currentPage} class:disabled={pageNumber == -1}>
                    <a class="page-link" href={'#'} aria-label="Page {pageNumber}" on:click|preventDefault={() => clickFunction(pageNumber)}>{pageNumber !== -1 ? pageNumber : '...'}</a>
                </li>
            {/each}
            <li class="page-item" class:disabled={currentPage == totalPages}>
                <a class="page-link" href={'#'} on:click|preventDefault={() => clickFunction(currentPage+1)} aria-label="Next"><Icon name="chevron-right"/></a>
            </li>
        </ul>
    </nav>
{/if}

Using it...

<script lang="ts">
  import Paginator from '$lib/Paginator.svelte'

  let totalItems = 99
  let currentPage = 1
  let pageSize = 10
  const toPageNumber = (page: number) => currentPage = page
</script>
<Paginator {totalItems} {pageSize} {currentPage} clickFunction={(pageNumber) => toPageNumber(pageNumber)}/>
bestguy commented 3 years ago

Great thanks! Seems a good idea, let me take a look.