Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text cursor jumps to last position for [:input] fields #79

Closed
jonase opened this issue Dec 14, 2014 · 9 comments · Fixed by #126
Closed

Text cursor jumps to last position for [:input] fields #79

jonase opened this issue Dec 14, 2014 · 9 comments · Fixed by #126

Comments

@jonase
Copy link
Contributor

jonase commented Dec 14, 2014

The following minimal example

(defn my-input [on-change text]
  [:div [:input {:type "text"
                 :value (.toUpperCase text)
                 :on-change #(on-change (-> % .-target .-value))}]])

(def text (reagent/atom "foo"))

(defn main-page []
  [my-input #(reset! text %) @text])

will cause the cursor to jump to the last position after each key stroke (try to insert a character in the middle of the string). If I replace (.toUpperCase text) with text the cursor stays at the correct position.

@mike-thompson-day8
Copy link
Member

This is no answer, just an observation: if you enter numeric chars or upper case alpha, then the cursor does not move to the end as you type. Only lower case alpha chars cause the behaviour you describe.

To put it another way: this issue only occurs when a new char means (not= text (.toUpperCase text))

Also note: Jonase's blog post on the subject:
http://jonase.github.io/nil-recur/posts/14-12-2014-controlled-input.html

@holmsand
Copy link
Contributor

Reagent behaves just like "normal" React in this regard – both Reagent and React just set the value of the input field to the specified value, and leaves it up to the browser to decide where the cursor should go.

The only difference between React and Reagent with respect to controlled inputs is that Reagent resets the input a little bit later (i.e. at the next async rendering). Also, Reagent never sets the value if it doesn't have to.

Keeping the cursor in the "right" place generally would be quite tricky, since you can do arbitrary transformations in your code. In my mind, using controlled inputs are mostly useful for either resetting form elements to some original value, or for disallowing certain inputs (say, allowing only digits), and I think the current model works quite well for that.

What is the use-case for transforming the input to uppercase?

@dmohs
Copy link

dmohs commented Jan 21, 2015

This might be one of those cases where doing the right thing, UI-wise, is tough. I don't think you can modify the event, so your only option might be to check the character on keypress and, if it is lowercase, prevent the event and fire a new keypress event with the uppercase character instead. I'm not certain that would work, but I think it has a chance.

In any case, if this is a bug, it is a bug in React or the browser. I think it's important for Reagent to remain bug-for-bug compatible with React to the extent possible, so I would recommend closing this issue.

@holmsand holmsand closed this as completed Feb 2, 2015
@gtrak
Copy link

gtrak commented Feb 2, 2015

Similar issue in Om for reference: omcljs/om#295

@mike-thompson-day8
Copy link
Member

Keeping the cursor in the "right" place generally would be quite tricky

It was :-) but #126 seems to work perfectly in all the corner cases tested.

@marcloyal3
Copy link

@mike-thompson-day8 CC: @yogthos

Mike,

Please articulate why you think @holmsand is wrong in his statement that:

"Reagent behaves just like "normal" React in this regard – both Reagent and React just set the value of the input field to the specified value, and leaves it up to the browser to decide where the cursor should go."

Also, your solution hard codes the HTMLElement tags, which is problematic with respect to the new feature in web browsers known as "Custom Elements" a la Document.registerElement()

Marc

@mike-thompson-day8
Copy link
Member

@marcloyal Eh? Dan is 100% right. That is indeed what causes this problem. The proposed patch FIXES that problem.

@marcloyal3
Copy link

You can also use "text-transform: uppercase" for this particular case. In other words, this case is fixable with CSS.

I have a working example I'll post on the github issue

@yogthos
Copy link
Member

yogthos commented May 11, 2015

I think if the issue is addressed by CSS then that would be the preferred method in any case as it's not a good practice to bake styling into content.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants