Something like this can be made to work, if you don't care about relaxing 
the type safety which is provided by your current approach:


initialModel = 
    { form : Dict.fromList
        [ ("applicant",
            { label = "Applicant name"
            , selected = True
            , value = ""
            })
        , ("year",
            { label = "Year"
            , selected = True
            , value = ""
            })
        , ("state",
            { label = "State"
            , selected = True
            , value = ""
            })
        …
        ]
    …
    } 


type Msg
    = Update String String


update msg model =
    case msg of
        Update fieldName query ->
            let
                entry =
                    Dict.get fieldName model.form

                newEntry =
                    { entry | value = query }

                form = Dict.insert fieldName newEntry model.form
            in
                ( { model | form = form }, Cmd.none )


You should make it safer by including run-time checks that the first string 
argument (fieldName) is one of your 20 possibilities, before doing the 
above replacement, and if it isn't then you should specify what to do 
(maybe ignore it).

On Monday, September 12, 2016 at 12:08:25 PM UTC-4, Eduardo Cuducos wrote:
>
> Hi all,
>
> I'm writing an application that has a “advanced search” form. In my 
> context it means a form with approx. 20 input fields.
>
> As a newbie the only way I could think of coding this is quite repetitive. 
> I bet that there is a more cleaver and a DRY way to do it, but I couldn't 
> figure out how. Any ideias?
>
> This is the terrible idea I have in mind:
>
> 1. My initial model would have 20 form fields definition like that:
>
> initialModel = 
>     { form :
>         { applicant =
>             { label = "Applicant name"
>             , selected = True
>             , value = ""
>             , msg = UpdateApplicant
>             }
>         , year =
>             { label = "Year"
>             , selected = True
>             , value = ""
>             , msg = UpdateYear
>             }
>         , state =
>             { label = "State"
>             , selected = True
>             , value = ""
>             , msg = UpdateState
>             }
>         …
>         }
>     …
>     }    
>
>
> 2. Consequently my type Msg would have another 20 very similar fields:
>
> type Msg
>     = UpdateApplicant String
>     | UpdateYear String
>     | UpdateState
>     | …
>
> 3. And my update would have 20 very similar cases:
>
> update msg model =
>     case msg of
>         UpdateApplicant query ->
>             let
>                 applicant =
>                     model.form.applicant
>
>                 newApplicant =
>                     { applicant | value = query }
>
>                 currentForm =
>                     model.form
>
>                 form =
>                     { currentForm | applicant = newApplicant }
>             in
>                 ( { model | form = form }, Cmd.none )
>
>         UpdateYear query ->
>             let
>                 year =
>                     model.form.year
>
>                 newYear =
>                     { year | value = query }
>
>                 currentForm =
>                     model.form
>
>                 form =
>                     { currentForm | year = newYear }
>             in
>                 ( { model | form = form }, Cmd.none )
>
>         UpdateState query ->
>             let
>                 state =
>                     model.form.state
>
>                 newState =
>                     { state | value = query }
>
>                 currentForm =
>                     model.form
>
>                 form =
>                     { currentForm | state = newState }
>             in
>                 ( { model | form = form }, Cmd.none )
>
> Many thanks,
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to