0

I'm not sure if this is possible, but I'm trying to trigger html events with chained union types. I have the two union types below:

type DialogOf =
    SearchItems
    | SearchingItems String
    | None

type Msg = 
    Start
    | ShowDialog DialogOf
    | CancelDialog

I handle the model update as follows, which works fine.

        ShowDialog dialogOf ->
            case dialogOf of
                SearchItems ->
                    ( { model | dialogOf = SearchItems }, Cmd.none)
                SearchingItems filter -> 
                    ( {model | context = CurrentContext filter }, Cmd.none )
                None -> (model ,Cmd.none)

Now when I fire the events, I want to fire SearchingItems with the filter (String) which can be done using the onClick for a button:

let searchWordButton item = 
    div [] [ 
        button [ onClick (ShowDialog (SearchingItems item))] [text item]
    ]

Now I want to fire the onInput for the text box to filter on text input but I can't find any way to do this with the implicitly passed value - I'm trying to do something like this (not working):

div [] [ input [ 
    value model.context.filter, onInput (ShowDialog SearchingItems) ] [] 
]

I realise there may be other better ways of handling this (like sub modules), but I'd like to know if there is a way to implicitly pass the string value with the onInput event using the chained union types above?

Thanks

onemorecupofcoffee
  • 2,237
  • 1
  • 15
  • 21
  • What feature are you trying to add to your application that led you down this path? – Dwayne Crooks Jul 04 '18 at 11:12
  • I need to add multiple dialogs to an already busy form, and I though it might be a good way to simplify the Msg / update instead of having a lot of Msg types. I think I'll have to use sub modules instead. – onemorecupofcoffee Jul 04 '18 at 16:10
  • Maybe you should step back and rethink the user experience. Redesign the interface to reduce the noise on the form and remove the need for multiple dialogs. It's possible it's not a problem that needs fixing with code. – Dwayne Crooks Jul 04 '18 at 16:17

1 Answers1

1

It won't work since ShowDialogue is of type

(DialogueOf -> Msg)

but onInput expect an argument of type

(String -> Msg)

In other words onInput is passing the String to the message (ShowDialogue) and not to the constructor SearchingItems.

I don't believe there is a way to just access the string (which would then allow you to pass it to SearchingItems directly). If you want to go more in-depth you can look into making a custom event listener using on (http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html-Events#on) but I don't think it will work, and it seems a bit of an overkill.

You might be better off having two different messages to to capture the different uses:

type Msg 
    = Start
    | ShowDialog DialogOf
    | ShowDialogWithString String
    | CancelDialog

update function:

    ShowDialog dialogOf ->
        ( { model | dialogOf = SearchItems }, Cmd.none)

    ShowDialogWithString filter -> 
        ( {model | context = CurrentContext filter }, Cmd.none )

view

div [] 
    [ input 
        [ value model.context.filter, onInput ShowDialogWithString ] [] 
    ]
Jolanda
  • 173
  • 6