annaghi/dnd-list/3.0.0

NOTE: the latest version is 6.0.1

DnDList

While dragging a list item, the mouse events and the list reordering are handled internally by this module.

First you need to create a System object which holds the information and functions related to the drag operation. Using this object you can wire up the internal model, subscriptions, commands, and update into your model, subscriptions, commands, and update respectively. Also you can get access to the drag and drop events as well as the dragged position styles in your view functions.

Finally you need to wrap up the internal messages into your message, and pass them along with your sortable list to the update function within your update funcion. The update will return back with a tuple of the updated Draggable and the reordered list.

System

A System represents the information about the drag operation and the drag related functions.

type alias System m a =
{ draggable : Draggable
, subscriptions : Draggable -> Sub m
, commands : Draggable -> Cmd m
, update : Msg -> Draggable -> List a -> ( Draggable, List a )
, dragEvents : Int -> String -> List (Attribute m)
, dropEvents : Int -> List (Attribute m)
, draggedStyles : Draggable -> List (Attribute m)
, dragIndex : Draggable -> Maybe Int
}

A System encapsulates a Draggable which represents the information about the drag operation and the drag related functions.

For the details, see System Fields

create : Config m -> System m a

Creates a System parametrized with your configuration.

Having a list of fruits:

type alias Fruit =
    String


data : List Fruit
data =
    [ "Apples", "Bananas", "Cherries", "Dates" ]

The system is a wrapper type of your message and list item types:

system : DnDList.System Msg Fruit
system =
    DnDList.create config
type alias Config m =
{ message : Msg -> m
, movement : Movement
}

Represents the System configuration.

  • message: your message wrapper

  • movement: the kind of the Movement. It can be Free, Horizontal, or Vertical.

Example configuration:

config : DnDList.Config Msg
config =
    { message = DnDMsg
    , movement = DnDList.Free
    }


...


type Msg
    = DnDMsg DnDList.Msg
= Free
| Horizontal
| Vertical

Represents the mouse dragging movement. Dragging can be restricted to vertical or horizontal axis only, or it can be free.

System Fields

draggable

A Draggable represents the information about the current drag operation. It should be set in your model and can be initialized through the System's draggable field.

type alias Model =
    { draggable : DnDList.Draggable
    , items : List Fruit
    }


initialModel : Model
initialModel =
    { draggable = system.draggable
    , items = data
    }

subscriptions

subscriptions is a function to access browser events during the drag.

subscriptions : Model -> Sub Msg
subscriptions model =
    system.subscriptions model.draggable

commands

commands is a function to access the DOM for the dragged element x, y, width and height information.

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        DnDMsg message ->
            let
                updatedModel = ...
            in
            ( updatedModel
            , system.commands model.draggable
            )

update

update is a function which returns an updated Draggable and the reordered list for your model.

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        DnDMsg message ->
            let
                ( draggable, items ) =
                    system.update message model.draggable model.items
            in
            ( { model | draggable = draggable, items = items }
            , system.commands model.draggable
            )

dragEvents

dragEvents is a function which wraps all the events for draggable elements.

model.items
    |> List.indexedMap
        (\index item ->
            let
                itemId : String
                itemId =
                    "id-" ++ item
            in
            Html.div
                (Html.Attributes.id itemId :: system.dragEvents index itemId)
                [ Html.text item ]
        )
    |> Html.div []

dropEvents

dropEvents is a function which wraps all the events for droppable elements.

model.items
    |> List.indexedMap
        (\index item ->
            Html.div
                (system.dropEvents index)
                [ Html.text item ]
        )
    |> Html.div []

draggedStyles

draggedStyles is a helper to set the current position of the dragged element.

Html.div
    (system.draggedStyles model.draggable)
    [ Html.text item ]

dragIndex

dragIndex is a helper which returns the index of the dragged element.

maybeDragIndex : Maybe Int
maybeDragIndex =
    system.dragIndex model.draggable

Message

type Msg

Internal message type. You should wrap it within your message constructor.

type Msg
    = DnDMsg DnDList.Msg