Fork me on GitHub
#re-frame
<
2022-03-02
>
fadrian14:03:41

I want to create a component that is la text input that would use an integer as a model and allow only an integer to be entered. I've used the re-com input-text component as the basis of the same, and using the following code, I've gotten it to work:

[input-text
 :model  (-> @(rf/subscribe [:integer-state id]) str)
 :on-change #(rf/dispatch [:on-integer-change id (js/parseInt %)])
 :change-on-blur? true
 :validation-regex #"[+-]?[0-9]*"]
This works fine, when :change-on-blur? is true. However, it leads to broken editing when :change-on-blur? is false, as one can get into intermediate editing states that cannot be parsed as an integer (think of a single - sign, for example). My question is whether there's a good way to disable the :change-on-blur? attribute, preferably either ignoring it or throwing a re-com error when it's attempted to be set to false?

p-himik15:03:07

Just wrap input-text in something that drops that attribute. Regarding invalid inputs - you can have an internal ratom that stores the current, possibly invalid, state, and only call the :on-change function once the value is valid. It'll prevent any issues that you see with entering - and whatnot. It's similar how re-com itself has ratoms for internal and external models that it keeps in sync: https://github.com/day8/re-com/blob/master/src/re_com/input_text.cljs#L97-L99

p-himik15:03:49

Also, maybe it'll work without an extra ratom if you simply start calling rf/dispatch conditionally - only when the number is a proper integer.

fadrian19:03:00

Thanks. I'll try some of those.

👍 1