Paginate
is used for querying & paginating API responses. Paginate will
handle fetching new pages of data, and caches already fetched data.
TODO: Eventually:
The Paginated
type is responsible for storing the fetched items, current
page number, total count, and additional data to pass to the fetch command..
The a
type refers to the data that is paginated, b
refers to any additional
data you need to make the API request, and c
is any additional data you want
to pull out of the API response.
initial : Config a b c -> b -> Basics.Int -> Basics.Int -> ( Paginated a b c, Platform.Cmd.Cmd (Msg a c) )
Get an initial Pagination & Fetch Commands from a Config
, list of Filters,
& Page Number.
The Config
type is used to build a Fetch Request, given the Paginated's
Request Data, a Page Number, & the Items per Page.
{ items : List a
, totalCount : Basics.Int
, extraData : Maybe c
}
The result type of a Paginated Fetch Request. At the minimum, your API needs to return the items & a total count of all items.
If any additional data is returned that you would like to have access to, you
can decode it to the extraData
field and use getResponseData
to pull it
out of a Paginated
.
makeConfig : (b -> Basics.Int -> Basics.Int -> Platform.Cmd.Cmd (RemoteData.WebData (FetchResponse a c))) -> Config a b c
Make a Config
from a function that takes a list of Parameters & a Page Number.
getCurrent : Paginated a b c -> List a
Get the current list of items.
getPage : Paginated a b c -> Basics.Int
Get the current page number.
getPerPage : Paginated a b c -> Basics.Int
Get the number of items to show per page.
getTotalPages : Paginated a b c -> Basics.Int
Get the total number of pages.
getTotalItems : Paginated a b c -> Basics.Int
Get the total item count.
getError : Paginated a b c -> Maybe Http.Error
Return the current page's fetch request's error if it has one.
getRequestData : Paginated a b c -> b
Return the Extra Request Data for the current Paginated.
getResponseData : Paginated a b c -> Maybe c
Return any Extra Response Data for the current Paginated.
getRemoteData : Paginated a b c -> RemoteData.WebData (List a)
Return the raw WebData
for the current page.
getPagerSections : Basics.Int -> Basics.Int -> Paginated a b c -> List (List ( Basics.Int, Basics.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.
bootstrapPager : (Basics.Int -> List (Html.Attribute msg)) -> Basics.Int -> Basics.Int -> Paginated a b c -> 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.
isLoading : Paginated a b c -> Basics.Bool
Is the current page's fetch request still loading?
hasNone : Paginated a b c -> Basics.Bool
Did the current page load successfully but return no items?
isFirst : Paginated a b c -> Basics.Bool
Is the current page the first page?
isLast : Paginated a b c -> Basics.Bool
Is the current page the last page?
hasPrevious : Paginated a b c -> Basics.Bool
Are there page's before the current one?
hasNext : Paginated a b c -> Basics.Bool
Are there page's after the current one?
moveNext : Config a b c -> Paginated a b c -> ( Paginated a b c, Platform.Cmd.Cmd (Msg a c) )
Move to the next page.
TODO: re-implement as call to jumpTo
?
movePrevious : Config a b c -> Paginated a b c -> ( Paginated a b c, Platform.Cmd.Cmd (Msg a c) )
Move to the previous page.
TODO: re-implement as call to jumpTo
?
jumpTo : Config a b c -> Basics.Int -> Paginated a b c -> ( Paginated a b c, Platform.Cmd.Cmd (Msg a c) )
Move to a specific page.
updateData : Config a b c -> b -> Paginated a b c -> ( Paginated a b c, Platform.Cmd.Cmd (Msg a c) )
Replace the current Extra Request Data, jumping to page 1 & performing new fetch requests. Does nothing if the Data is equal to existing Data.
updateAndResetData : Config a b c -> b -> Paginated a b c -> ( Paginated a b c, Platform.Cmd.Cmd (Msg a c) )
Similar to the updateData
function, but this will also reset the
ResponseData
.
Which you should pick depends on how the new request data affects your response
data. E.g., if the slug of the pagination container changes, you should reset
the response data as well, but if you're only changing the sorting order of the
results, you can just use the updateData
function.
updatePerPage : Config a b c -> Basics.Int -> Paginated a b c -> ( Paginated a b c, Platform.Cmd.Cmd (Msg a c) )
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.
Wrap an Http Response for a Page, to be handled in the update
function.
update : Config a b c -> Msg a c -> Paginated a b c -> ( Paginated a b c, Platform.Cmd.Cmd (Msg a c) )
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.