ThinkAlexandria/elm-drag-locations/3.0.0

NOTE: the latest version is 3.1.0

Drag

This package allows you to make multiple elements draggable simultaneously.

How it works

  1. You create a single type to represent every possible interaction location.
type InteractionLocation
    = GraphNode Int
    | Label Int
  1. In your view functions, add an attribute to each element you want to make draggable
viewGraphNode: Int -> Node -> Html Msg
viewGraphNode key node =
    div
        [ Drag.onMouseDownWithOptions
            { stopPropogation = False, preventDefault = False }
            (GraphNode key)
        -- ...
        ]
        [ text <| "Graph Node " ++ (String.fromInt key) ]
  1. In your update, handle the start, movement, and end of a drag as well as clicks on an interaction location.
    (Drag.Start location currentMousePosition) as dragMsg ->
        { model | dragState = Drag.update dragMsg model.dragState }

    (Drag.Moved location currentMousePosition) as dragMsg ->
        let
            (dx, dy) = Drag.delta dragMsg model.dragState
            updatedModel =
                { model | dragState = Drag.update dragMsg model.dragState }
        in
            case location of
                GraphNode key ->
                    -- Handle the drag of the node ...

                Label key ->
                    -- Handle the drag of a label ...

    (Drag.End location currentMousePosition) as dragMsg ->
        { model | dragState = Drag.update dragMsg model.dragState }

    (Drag.Click location currentMousePosition) as dragMsg ->
        { model | dragState = Drag.update dragMsg model.dragState }
    
  1. Add this library's subscriptions to your subscriptions.
subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.batch
        [ Drag.subscriptions
        --, ... your subscriptions
        ]
type State interactionLocation
type Msg interactionLocation
= Start interactionLocation Position
| Moved interactionLocation Position
| End interactionLocation Position
| Click interactionLocation Position
{ stopPropagation : Bool
, preventDefault : Bool
}
-> location
-> Attribute (Msg location)
subscriptions : State interactionLocation -> Sub (Msg interactionLocation)
Msg interactionLocation
-> State interactionLocation
-> State interactionLocation
init : State interactionLocation
Msg interactionLocation
-> State interactionLocation
-> ( Int, Int )