Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you dynamically create inputs in Elm?

I want to create a button which, when pressed, adds a new input (or textarea) to the form.

like image 842
Robin Green Avatar asked Dec 01 '12 15:12

Robin Green


2 Answers

If you want a text field to be added each time the button is clicked, that means that you want the number of displayed text fields to be equal to the number of times the button has been clicked. We can create a signal that tells us how often the button has been clicked by using the countIf id on the button's clicked signal¹.

If we have a list of inputs, we can use flow to display them beneath (or besides) each other. It is fairly straight forward to write a function that takes a number n and produces a list containing a button and n text fields.

So now we can just use lift to hook that function up to our signal that counts the number of button clicks, combine that with the flow function, and voilà, we have a button that dynamically creates inputs.

(btn, clicked) = Input.button "Click me!"

-- Count how often the clicked signal is true
clicks = countIf id clicked

main = lift2 flow (constant down) $ lift nInputs clicks

nInputs n =
  let helper n acc =
    if n<=0 then btn : acc
    else
      -- Input.textField returns a pair containing the field as well as a signal
      -- that you can use to access the field's contents. Since I don't actually
      -- ever do anything with the contents, I just ignore the signal here.
      -- In your real code, you'd probably want to keep the signal around as well.
      let (field, _) = Input.textField $ "input " ++ (show n)
      in helper (n-1) $ field : acc
  in helper n []

¹ Just using count would count how often the signal changes. Since each click causes the signal's value to change to true and then right back to false, that would count 2 changes per click. By using countIf id we only count the number of times the signal is true and thus the number of clicks.

like image 83
sepp2k Avatar answered Sep 29 '22 21:09

sepp2k


As of Elm 0.8, this can indeed be done. See the release announcement, the Input Groups section of the online reference and a code example.

like image 24
thSoft Avatar answered Sep 29 '22 23:09

thSoft