prikhi/paginate/3.0.0

NOTE: this package is not compatible with Elm 0.19.1

Paginate

Paginate is used for querying & paginating API responses. Paginate will handle fetching new pages of data, and caches already fetched data.

TODO: Eventually:

  • examples
  • fetchRequest per-args cache?
    • toString on args to get a (Dict String (Dict PageNumber Chunk))?

Model

type Paginated a b

The Paginated type is responsible for storing the fetched items, current page number, total count, and additional data to pass to the fetch command..

initial : Config a b -> b -> Int -> Int -> ( Paginated a b, Cmd (Msg a) )

Get an initial Pagination & Fetch Commands from a Config, list of Filters, & Page Number.

Config

type Config a b

The Config type is used to build a Fetch Request, given the Paginated's Request Data, a Page Number, & the Items per Page.

type alias FetchResponse a =
{ items : List a
, totalCount : Int
}

The result type of a Paginated Fetch Request. At the minimum, your API needs to return the items & a total count of all items.

makeConfig : (b -> Int -> Int -> Request (FetchResponse a)) -> Config a b

Make a Config from a function that takes a list of Parameters & a Page Number.

Retrieving Data

getCurrent : Paginated a b -> List a

Get the current list of items.

getPage : Paginated a b -> Int

Get the current page number.

getPerPage : Paginated a b -> Int

Get the number of items to show per page.

getTotalPages : Paginated a b -> Int

Get the total number of pages.

getTotalItems : Paginated a b -> Int

Get the total item count.

getError : Paginated a b -> Maybe Error

Return the current page's fetch request's error if it has one.

getData : Paginated a b -> b

Return the Extra Request Data for the current Paginated.

Rendering

getPagerSections : Int -> Int -> Paginated a b -> List (List ( Int, Bool ))

Generate sections of pages to show for a Pager. Depending on the current page & total number of pages, the sections may either be a single section, a beginning & end section, or a beginning, middle, & end section.

Each section's page is a tuple of (pageNumber, isCurrentPage).

The sections are defined by the initial arguments, the first is the number of pages to show at the end sections, while the second is the number of pages to show around the current page if it is in the middle section.

Some example of Pagers generated with 2 end & middle pages, with the current page marked by *:

*1*|2|3|4|5|6


*1*|2|3|4|5|...|49|50


1|2|3|4|*5*|...|49|50


1|2|...|4|5|*6*|7|8|...|49|50


1|2|...|9|10|*11*|12|13|...|49|50


1|2|...|*46*|47|48|49|50

No split is made if there are not enough pages to show a middle section. When at an end section, enough pages are shown that there must be something hidden before splitting off the middle section.

(Int -> List (Attribute msg))
-> Int
-> Int
-> Paginated a b
-> List (Html msg)

Render a split Pager with the standard Bootstrap4 classes.

It takes a function that takes a page number & generates attributes for an item's a element, the number of pages to show at the ends of the pagination, the number of middle pages to show in the middles of the pagination, and a pagination.

It will split out a list of li elements for each page that should be shown, with disabled dots(...) between each section. A list is returned so that you can add previous/next buttons if you want them.

See the docs for getPagerSections to see how the splitting works.

Querying Status

isLoading : Paginated a b -> Bool

Is the current page's fetch request still loading?

hasNone : Paginated a b -> Bool

Did the current page load successfully but return no items?

isFirst : Paginated a b -> Bool

Is the current page the first page?

isLast : Paginated a b -> Bool

Is the current page the last page?

hasPrevious : Paginated a b -> Bool

Are there page's before the current one?

hasNext : Paginated a b -> Bool

Are there page's after the current one?

Modifying Pagination

moveNext : Config a b -> Paginated a b -> ( Paginated a b, Cmd (Msg a) )

Move to the next page. TODO: re-implement as call to jumpTo?

movePrevious : Config a b -> Paginated a b -> ( Paginated a b, Cmd (Msg a) )

Move to the previous page. TODO: re-implement as call to jumpTo?

jumpTo : Config a b -> Int -> Paginated a b -> ( Paginated a b, Cmd (Msg a) )

Move to a specific page.

updateData : Config a b -> Paginated a b -> b -> ( Paginated a b, Cmd (Msg a) )

Replace the current Extra Request Data, jumping to page 1 & performing new fetch requests. Does nothing if the Data is equal to existing Data.

updatePerPage : Config a b -> Paginated a b -> Int -> ( Paginated a b, Cmd (Msg a) )

Update the items per page, jumping to page 1 & performing new fetch requests. Does nothing if the new value is the same as the current items per page.

Updating / Messages

type Msg a

Wrap an Http Response for a Page, to be handled in the update function.

Config a b
-> Msg a
-> Paginated a b
-> ( Paginated a b, Cmd (Msg a) )

Update the Paginated Model on Fetch Completion.

If the Page Number of the Returned Model is Different than the Given Model, We Were On a Page That Didn't Exist, So We Changed to the Last Page.

You Should Handle this Special Case in your Update Function, so that You can Modify the Page URL.