Dynamic textfields

118 views
Skip to first unread message

James Parker

unread,
Feb 26, 2014, 3:06:37 PM2/26/14
to elm-d...@googlegroups.com
Hi,

I was wondering if it's possible to create a dynamic textfield that is dependent on the value of that textfield using Elm. For example, can I take the output string behavior of a textfield, parse the string into a color behavior, and then set the textfield's color based on this color behavior? 

Thanks!

JP

Max Goldstein

unread,
Feb 26, 2014, 7:30:24 PM2/26/14
to elm-d...@googlegroups.com
No, to my knowledge there is not a way to do that at this time.

There's actually a much more reasonable use-case, which is form validation. Checking or greying out checkboxes depending on what selections are made, or populating dropdown 1 based on what's selected in dropdown 0.

James Parker

unread,
Feb 26, 2014, 8:10:35 PM2/26/14
to elm-d...@googlegroups.com
Hmm ok. Thanks for the reply. I guess this limitation is due to the fact that the dependency graph must be acyclic? I suppose there might be ways around this though. 

Evan Czaplicki

unread,
Feb 26, 2014, 8:13:52 PM2/26/14
to elm-d...@googlegroups.com
Unless I am misunderstanding, this is definitely possible. The thread on the new Graphics.Input library is about how it will work in the next release. Would you prefer an example of how it works in 0.11 or how it will work with the improved API?


On Wed, Feb 26, 2014 at 8:10 PM, James Parker <j...@jamesparker.me> wrote:
Hmm ok. Thanks for the reply. I guess this limitation is due to the fact that the dependency graph must be acyclic? I suppose there might be ways around this though. 

--
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 elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

John Mayer

unread,
Feb 26, 2014, 8:16:23 PM2/26/14
to elm-d...@googlegroups.com
I'd like to see that example.

James Parker

unread,
Feb 26, 2014, 8:17:04 PM2/26/14
to elm-d...@googlegroups.com
I'm more familiar with the older API, but either would work. 

Evan Czaplicki

unread,
Feb 26, 2014, 8:31:18 PM2/26/14
to elm-d...@googlegroups.com
This example shows a text field that just shows what you type. The content of a text field must be set programmatically to keep the field function pure. This means you pipe the content of the field through to the view.

This is an example where keepIf is used to only accept input that is all numbers.

Instead of using keepIf, you would want to use some parsing code that gives a color and use that to set the background. I've actually been wanting to make something like this for a really long time!

The remaining task before the next release is to give more style options for fields (borders, padding, and fonts). Also, sorry for being snappy in my email. This is a topic that I have never explained well on the internet, and since I worked on the new library so recently I sort of forgot that the old API is really hard to use. To do the same thing but with 0.11, you'd want to use the Graphics.Input.fields function. This appears in the TodoFRP example, but I'd say it's not a super clear presentation because the API is weird.

Evan Czaplicki

unread,
Feb 26, 2014, 8:34:43 PM2/26/14
to elm-d...@googlegroups.com
The new API is shown here. I have a flight on Saturday, so I am hoping that will give me time to get the dev branch ready for a list-only release. From there I'll write lots of documentation and examples about how to do exactly the kind of extremely practical thing you'd like to do!

Max Goldstein

unread,
Feb 26, 2014, 9:22:35 PM2/26/14
to elm-d...@googlegroups.com
One of us is mistaken, and given that you claim something is possible which I don't think is possible, I would love to be mistaken one. The question was not about setting the background color (an independent element further down the signal DAG - James's cyclical observation is spot-on). Rather it is, can some attribute of the text field itself be changed? The difficulty in implementing the RGB/HEX converter you link to is not in setting the background but in setting and reseting the text fields. It may be possible with some cleverness (with lift and partial application)? but it's not obvious to me.

John Mayer

unread,
Feb 26, 2014, 9:40:38 PM2/26/14
to elm-d...@googlegroups.com
It should be possible; when you create an Input, it's signal can be arbitrarily high up the DAG, such that you could build an element with a configuration derived from it's own value. We really need a working example on something like share-elm rather than a code snippet.


On Wed, Feb 26, 2014 at 9:22 PM, Max Goldstein <maxgol...@gmail.com> wrote:
One of us is mistaken, and given that you claim something is possible which I don't think is possible, I would love to be mistaken one. The question was not about setting the background color (an independent element further down the signal DAG - James's cyclical observation is spot-on). Rather it is, can some attribute of the text field itself be changed? The difficulty in implementing the RGB/HEX converter you link to is not in setting the background but in setting and reseting the text fields. It may be possible with some cleverness (with lift and partial application)? but it's not obvious to me.

--

Max Goldstein

unread,
Feb 26, 2014, 11:38:59 PM2/26/14
to elm-d...@googlegroups.com, john.p....@gmail.com
Okay, I'm eating my words. Sorry it's not share-elm, because that doesn't have dev.

import String
import Graphics.Input (..)

str1 : Input FieldContent
str1 = input noContent
str2 = input noContent

field1_base : FieldContent -> Element
field1_base = field str1.handle id "This field is"
field2_base = field str2.handle id "reversed into this one"

reverseContent : FieldContent -> FieldContent
reverseContent fc = FieldContent (String.reverse fc.string) (Selection 0 0 Forward)

field1_sig : Signal FieldContent
field1_sig = merge str1.signal <| lift reverseContent str2.signal
field2_sig = merge str2.signal <| lift reverseContent str1.signal

main = flow down <~ combine [ lift field1_base field1_sig
                            , lift field2_base field2_sig
                            ]

Navigating among these fields is messed up* but the reversing of two fields into each other, mutually recursively, is totally working. This opens up a lot of new ground in terms of being able to style the resulting elements based on feedback. That's part of a larger, more general update, but as part of that I'd like to see grey-out-able HTML inputs.

* In case the behavior is browser/OS dependent, I cannot use the mouse to select the second text field. I can get to it with tab, but once I enter once character, it goes back to the top field. Typing in the top field is fine. Replacing the merged, reversed signals in main with str[1-2].signal removes the issue.

Evan Czaplicki

unread,
Feb 27, 2014, 11:40:36 AM2/27/14
to elm-d...@googlegroups.com, John Mayer
I'm planning to make a bunch of examples of these kinds of things, but yeah, the Input should be at the top of the signal graph. The UI will report events to the Input via its handle. I don't really think of this as a loop in the graph because values flowing through the graph are never propagated upwards. The thing displayed to the user may generate new events, and those come in through an Input (just like other input nodes such as Mouse.position)

Max, That example is pretty awesome :D I think the reason the second text field cannot be selected is that the definition of reverseContent always sets the selection to zero zero. It could be cool to make the selections mirror each other, so (Selection 1 3 Forward) would become (Selection (length fc.str - 3) (length fc.str - 1) Backward) or something like that :)

This is one of the more interactive-ish examples I have done, but it's not as fancy as yours :)


--

Max Goldstein

unread,
Feb 27, 2014, 1:25:06 PM2/27/14
to elm-d...@googlegroups.com, John Mayer
Aww, thanks Evan! Unfortunately that doesn't seem to be the problem. (We can fork this debugging conversation if you like.) Implementing reverseContent as below (which is not necessarily correct) doesn't change the behavior, and moreover, cutting it out entirely with field1_sig = merge str1.signal str2.signal doesn't seem to help either. Nor does it look like a merge biasing problem.


reverseContent : FieldContent -> FieldContent
reverseContent fc = let
    reverseDirection d = case d of
        Forward -> Backward
        Backward -> Forward
                    in
    FieldContent (String.reverse fc.string) <|
        Selection (String.length fc.string - fc.selection.end)
                  (String.length fc.string - fc.selection.start)
                  (reverseDirection fc.selection.direction)

James Parker

unread,
Feb 27, 2014, 1:28:56 PM2/27/14
to elm-d...@googlegroups.com
Ok cool thanks. Just to clarify, the reason this doesn't create a cycle is since the input signal and displayed element are split into distinct objects? 
You received this message because you are subscribed to a topic in the Google Groups "Elm Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elm-discuss/du9x7E9AkDE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elm-discuss...@googlegroups.com.

Evan Czaplicki

unread,
Mar 2, 2014, 5:50:10 PM3/2/14
to elm-d...@googlegroups.com
Max, I just pushed another round of API revisions to give the ability to style text fields. After that I tried to do the field reversal thing and saw the same behavior as you. It seems that the first text field grabs focus immediately. It is essential that I work out this bug for this to be usable!

James, yeah, that's right. You have some signal graph:
Inline image 1
Events flow through from the top. At the bottom is the code for displaying stuff. That will just put a static thing on screen. When the user types or clicks or does any action, that event will be sent to the top of the graph.

When I say "you can't have cycles within the graph" it means that a single event cannot loop through the graph many times.

Alex Neslusan

unread,
Mar 2, 2014, 7:52:06 PM3/2/14
to elm-d...@googlegroups.com
These graphs remind me of programming in Max/MSP

Max Goldstein

unread,
Mar 2, 2014, 9:53:48 PM3/2/14
to elm-d...@googlegroups.com
That looks like a very detailed library, and I'm sure docs and even quickstart guides will spring up around it. Glad you could replicate the bug and are convinced of its seriousness. I left a few nitpicks on GitHub; feel free to prioritize them downward if there are still big changes in the works.

Evan Czaplicki

unread,
Mar 4, 2014, 1:05:23 PM3/4/14
to elm-d...@googlegroups.com
Okay, just pushed the fix for the field focus thing Max and I have seen. I think the library should be pretty much ready to go at this point!


On Mon, Mar 3, 2014 at 2:53 AM, Max Goldstein <maxgol...@gmail.com> wrote:
That looks like a very detailed library, and I'm sure docs and even quickstart guides will spring up around it. Glad you could replicate the bug and are convinced of its seriousness. I left a few nitpicks on GitHub; feel free to prioritize them downward if there are still big changes in the works.

--

Max Goldstein

unread,
Mar 4, 2014, 3:22:49 PM3/4/14
to elm-d...@googlegroups.com
I can confirm the field switching problem is gone in dev/HEAD. (Yay!) I tried implementing selection like Evan recommended, but selecting in either field doesn't cause selection in another field. This may be a language bug, a bug in my Elm, or a limitation HTML inputs.

Other than that, the API (but not the docs) look good.

As for the selection bug, the code I'm using for reverse is below.


import String
import Graphics.Input (..)
import Graphics.Input.Field (..)

str1 : Input Content
str1 = input noContent
str2 = input noContent

field1_base : Content -> Element
field1_base = field str1.handle id defaultStyle "This field is"
field2_base = field str2.handle id defaultStyle "reversed into this one"

reverseContent : Content -> Content
reverseContent fc = let
    reverseDirection d = case d of
        Forward -> Backward
        Backward -> Forward
                    in
    Content (String.reverse fc.string) <|
        Selection (String.length fc.string - fc.selection.end)
                  (String.length fc.string - fc.selection.start)
                  (reverseDirection fc.selection.direction)

field1_sig : Signal Content

Evan Czaplicki

unread,
Mar 5, 2014, 12:12:12 AM3/5/14
to elm-d...@googlegroups.com
Showing a field selection implicitly means the field has focus. Browsers (rightly) only allow one thing to have focus at a time.

There should be some other API for handling focus for arbitrary inputs. I have thought about an alternate approach where Selection can determine focus, but it seems much clumsier. Or at least a problem for a later te.
--
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 elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


--
Sent from Gmail Mobile
Reply all
Reply to author
Forward
0 new messages