module Comp.MappingForm exposing ( FormData , Model , Msg , ViewOpts , init , update , view ) import Comp.FixedDropdown import Dict exposing (Dict) import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (onClick) import Util.Maybe type alias FormData = Dict String String type alias Model = { leftDropdown : Comp.FixedDropdown.Model String , rightDropdown : Comp.FixedDropdown.Model String , leftSelect : Maybe String , rightSelect : Maybe String } type Msg = AddPair FormData | DeleteItem FormData String | EditItem String String | LeftMsg (Comp.FixedDropdown.Msg String) | RightMsg (Comp.FixedDropdown.Msg String) init : List String -> List String -> Model init leftSel rightSel = { leftDropdown = Comp.FixedDropdown.initString leftSel , rightDropdown = Comp.FixedDropdown.initString rightSel , leftSelect = Nothing , rightSelect = Nothing } --- Update update : Msg -> Model -> ( Model, Maybe FormData ) update msg model = case msg of AddPair data -> case ( model.leftSelect, model.rightSelect ) of ( Just l, Just r ) -> ( { model | leftSelect = Nothing , rightSelect = Nothing } , Just (Dict.insert l r data) ) _ -> ( model, Nothing ) DeleteItem data k -> ( model, Just (Dict.remove k data) ) EditItem k v -> ( { model | leftSelect = Just k , rightSelect = Just v } , Nothing ) LeftMsg lm -> let ( m_, la ) = Comp.FixedDropdown.update lm model.leftDropdown in ( { model | leftDropdown = m_ , leftSelect = Util.Maybe.withDefault model.leftSelect la } , Nothing ) RightMsg lm -> let ( m_, la ) = Comp.FixedDropdown.update lm model.rightDropdown in ( { model | rightDropdown = m_ , rightSelect = Util.Maybe.withDefault model.rightSelect la } , Nothing ) --- View type alias ViewOpts = { renderItem : ( String, String ) -> Html Msg , label : String , description : Maybe String } view : FormData -> ViewOpts -> Model -> Html Msg view data opts model = div [ class "field" ] [ label [] [ text opts.label ] , div [ class "fields" ] [ div [ class "inline field" ] [ Html.map LeftMsg (Comp.FixedDropdown.viewString model.leftSelect model.leftDropdown ) ] , div [ class "inline field" ] [ Html.map RightMsg (Comp.FixedDropdown.viewString model.rightSelect model.rightDropdown ) ] , button [ class "ui icon button" , onClick (AddPair data) , href "#" ] [ i [ class "add icon" ] [] ] ] , renderFormData opts data , span [ classList [ ( "small-info", True ) , ( "invisible hidden", opts.description == Nothing ) ] ] [ Maybe.withDefault "" opts.description |> text ] ] renderFormData : ViewOpts -> FormData -> Html Msg renderFormData opts data = let values = Dict.toList data renderItem ( k, v ) = div [ class "item" ] [ a [ class "link icon" , href "#" , onClick (DeleteItem data k) ] [ i [ class "trash icon" ] [] ] , a [ class "link icon" , href "#" , onClick (EditItem k v) ] [ i [ class "edit icon" ] [] ] , opts.renderItem ( k, v ) ] in div [ class "ui list" ] (List.map renderItem values)