The Wayback Machine - https://web.archive.org/web/20200905102824/https://github.com/jschomay/elm-paginate/
Skip to content
master
Go to file
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
Jan 27, 2019
Aug 23, 2018

README.md

elm-pagination

Simple and robust pagination in elm.

Encapsulate your pagination concerns from the rest of your app.

Example usage

Below is a fully featured example (demo | source).

module Example exposing (main)

import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Paginate exposing (..)


type alias Model =
    { things : PaginatedList String
    , reversed : Bool
    , query : String
    , globalId : Int
    }


type Msg
    = Next
    | Prev
    | First
    | Last
    | GoTo Int
    | ChangePageSize String
    | DeleteItem String
    | AddItem
    | Reverse
    | Find String


main : Program () Model Msg
main =
    Browser.sandbox
        { init = init
        , view = filterAndSortThings >> view
        , update = update
        }


init : Model
init =
    let
        things =
            List.map (String.fromInt >> (++) "item ") <| List.range 1 37
    in
    { things = Paginate.fromList 10 things
    , reversed = False
    , query = ""
    , globalId = List.length things
    }


update : Msg -> Model -> Model
update msg model =
    case msg of
        GoTo index ->
            { model | things = Paginate.goTo index model.things }

        Next ->
            { model | things = Paginate.next model.things }

        Prev ->
            { model | things = Paginate.prev model.things }

        First ->
            { model | things = Paginate.first model.things }

        Last ->
            { model | things = Paginate.last model.things }

        ChangePageSize size ->
            let
                sizeAsInt =
                    Maybe.withDefault 10 <| String.toInt size
            in
            { model | things = Paginate.changeItemsPerPage sizeAsInt model.things }

        DeleteItem item ->
            let
                removeItem =
                    List.filter ((/=) item)
            in
            { model | things = Paginate.map removeItem model.things }

        AddItem ->
            let
                newId =
                    model.globalId + 1

                addItem existing =
                    existing ++ [ "new item " ++ String.fromInt newId ]
            in
            { model
                | things = Paginate.map addItem model.things
                , globalId = newId
            }

        Reverse ->
            { model | reversed = not model.reversed }

        Find query ->
            { model | query = query }


filterAndSortThings : Model -> PaginatedList String
filterAndSortThings model =
    let
        sort =
            if model.reversed then
                List.reverse

            else
                identity

        filter =
            if model.query == "" then
                identity

            else
                List.filter (\thing -> String.contains model.query thing)
    in
    Paginate.map (filter >> sort) model.things


view : PaginatedList String -> Html Msg
view filteredSortedThings =
    let
        displayInfoView =
            div []
                [ div []
                    [ text <|
                        String.join " " <|
                            [ "showing"
                            , String.fromInt <| List.length <| Paginate.page filteredSortedThings
                            , "of"
                            , String.fromInt <| Paginate.length filteredSortedThings
                            , "items"
                            ]
                    , u [ onClick <| AddItem, style "cursor" "pointer" ] [ text " (add more!)" ]
                    ]
                , text <|
                    String.join " "
                        [ "page"
                        , String.fromInt <| Paginate.currentPage filteredSortedThings
                        , "of"
                        , String.fromInt <| Paginate.totalPages filteredSortedThings
                        ]
                , div []
                    [ text <|
                        String.join " "
                            [ "including"
                            , Paginate.foldMap
                                (List.filter (String.contains "new item") >> List.length >> String.fromInt)
                                filteredSortedThings
                            , "new items"
                            ]
                    ]
                ]

        itemView item =
            li []
                [ span [] [ text item ]
                , u [ onClick <| DeleteItem item, style "cursor" "pointer" ] [ text " (delete)" ]
                ]

        itemsPerPageSelector =
            div []
                [ text "show"
                , select [ onInput ChangePageSize ]
                    [ option [ value "3" ] [ text "3" ]
                    , option [ value "10", selected True ] [ text "10" ]
                    , option [ value "20" ] [ text "20" ]
                    , option [ value "30" ] [ text "30" ]
                    ]
                , text "items per page"
                ]

        prevButtons =
            [ button [ onClick First, disabled <| Paginate.isFirst filteredSortedThings ] [ text "<<" ]
            , button [ onClick Prev, disabled <| Paginate.isFirst filteredSortedThings ] [ text "<" ]
            ]

        nextButtons =
            [ button [ onClick Next, disabled <| Paginate.isLast filteredSortedThings ] [ text ">" ]
            , button [ onClick Last, disabled <| Paginate.isLast filteredSortedThings ] [ text ">>" ]
            ]

        pagerButtonView index isActive =
            button
                [ style "font-weight"
                    (if isActive then
                        "bold"

                     else
                        "normal"
                    )
                , onClick <| GoTo index
                ]
                [ text <| String.fromInt index ]

        pagerOptions =
            { innerWindow = 1
            , outerWindow = 1
            , pageNumberView = pagerButtonView
            , gapView = text "..."
            }
    in
    div [] <|
        [ displayInfoView
        , itemsPerPageSelector
        , button [ onClick Reverse ] [ text "Reverse list" ]
        , input [ placeholder "Search...", onInput Find ] []
        , ul [] (List.map itemView <| Paginate.page filteredSortedThings)
        ]
            ++ prevButtons
            ++ [ span [] <| Paginate.pager pagerButtonView filteredSortedThings ]
            ++ nextButtons
            ++ [ p [] [ text "Elidied pager (set items per page to 3 to see it elide)" ]
               , span [] <| Paginate.elidedPager pagerOptions filteredSortedThings
               ]
You can’t perform that action at this time.