FabienHenon/elm-infinite-scroll/1.0.0

NOTE: this package is not compatible with Elm 0.19.1

InfiniteScroll

Infinite scroll allows you to load more content for the user as he scrolls (up or down).

The infinite scroll must be bound to an Html element and will execute your own Cmd when the user scrolled to the bottom (or top) of the element.

The Cmd can be anything you want from local data fetching or complex requests on remote APIs. All it has to do is to return a Cmd msg and call stopLoading once fetching is finished so that the infinite scroll can continue asking for more content.

Definitions

type alias LoadMoreCmd msg =
Direction -> Cmd msg

Definition of the function you must provide to the API. This function will be called as soon as new content is required

loadMore : InfiniteScroll.Direction -> Cmd Msg
loadMore dir =
    Task.perform OnLoadMore <| Task.succeed dir


InfiniteScroll.init loadMore
= Top
| Bottom

Scroll direction.

  • Top means new content will be asked when the user scrolls to the top of the element
  • Bottom means new content will be asked when the user scrolls to the bottom of the element

Initialization

init : LoadMoreCmd msg -> Model msg

Creates a new Model. This function needs a LoadMoreCmd that will be called when new data is required.

type Msg
    = OnLoadMore InfiniteScroll.Direction


type alias Model =
    { infiniteScroll : InfiniteScroll.Model Msg }


loadMore : InfiniteScroll.Direction -> Cmd Msg
loadMore dir =
    Task.perform OnLoadMore <| Task.succeed dir


initModel : Model
initModel =
    { infiniteScroll = InfiniteScroll.init loadMore }
timeout : Time -> Model msg -> Model msg

Sets a different timeout value (default is 5 seconds)

When timeout is exceeded stopLoading will be automatically called so that infinite scroll can continue asking more content event when previous request did not finished.

init loadMore
    |> timeout 10 * second
offset : Int -> Model msg -> Model msg

Sets a different offset (default 50).

Offset is the number of pixels from top or bottom (depending on Direction value) from which infinite scroll will detect it needs more content.

For instance with offset set to 50 and direction to Top. Once scroll position is 50 pixels or less from the top of the element it will require new content. The same applies with a direction set to Bottom except it will check for the distance with the bottom of the element.

init loadMore
    |> offset 100
direction : Direction -> Model msg -> Model msg

Sets a different direction (default to Bottom).

A direction set to Bottom will check distance of the scroll bar from the bottom of the element, whereas a direction set to Top will check distance of the scroll bar from the top of the element.

init loadMore
    |> direction Top

Update

update : (Msg -> msg) -> Msg -> Model msg -> ( Model msg, Cmd msg )

The update function must be called in your own update function. It will return an updated Model and commands to execute.

type Msg =
    InfiniteScrollMsg InfiniteScroll.Msg


type alias Model =
    { infiniteScroll : InfiniteScroll.Model Msg }


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        InfiniteScrollMsg msg_ ->
            let
                ( infiniteScroll, cmd ) =
                    InfiniteScroll.update InfiniteScrollMsg msg_ model.infiniteScroll
            in
                ( { model | infiniteScroll = infiniteScroll }, cmd )

Scroll

infiniteScroll : (Msg -> msg) -> Attribute msg

Function used to bind the infinite scroll on an element.

The element's height must be explicitly set, otherwise scroll event won't be triggered

type Msg
    = InfiniteScrollMsg InfiniteScroll.Msg


view : Model -> Html Msg
view _ =
    let
        styles =
            [ ( "height", "300px" ) ]
    in
        div [ infiniteScroll InfiniteScrollMsg, Attributes.style styles ]
            [ -- Here will be my long list -- ]
stopLoading : Model msg -> Model msg

Stops loading. You should call this function when you have finished fetching new data. This tells infinite scroll that it can continue asking you more content.

If you forget to call this function or if your data fetching is too long, you will be asked to retrieve more content after timeout has expired.

startLoading : Model msg -> Model msg

Starts loading more data. You should never have to use this function has it is automatically called when new content is required and your loadMore command is executed.

Types

type alias Model msg =
{ direction : Direction
, offset : Int
, loadMoreFunc : LoadMoreCmd msg
, isLoading : Bool
, timeout : Time
, lastRequest : Time
}

Model of the infinite scroll module. You need to create a new one using init function.

type Msg

Infinite scroll messages you have to give to the update function.