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

Reconcile input element causes cursor to move #47

Closed
dave opened this issue Jun 23, 2016 · 10 comments
Closed

Reconcile input element causes cursor to move #47

dave opened this issue Jun 23, 2016 · 10 comments

Comments

@dave
Copy link
Contributor

dave commented Jun 23, 2016

If a textbox has focus, then the Reconcile method results in the cursor moving to the end of the text. The cursor moves when we set the "value" property, here.

I've worked around the problem in my fork by not updating the value property if the element has focus, but this isn't a universal solution. If the value is updated without input from the user, the textbox won't be updated if it has focus.

This seems to be quite a common problem in the React world. I was wondering if anyone had any good solutions or ideas?

@neelance
Copy link
Contributor

Yes, this occurs when setting the value property. The solution is to make sure that it only gets set when it has actually changed. Maybe we should go back to something similar to

if name == "value" {
    oldValue = e.node.Get("value").String()
}
if value != oldValue {

I can't remember exactly in which situation this solution failed... Needs some investigation.

@dave
Copy link
Contributor Author

dave commented Jun 23, 2016

Yes that's the first method I tried, but it wasn't perfect. My component fires the re-render if the value of the textbox hasn't changed 50ms after the last keyup. This worked fine until you start typing fast, at which point the cursor would start jumping.

I also tried saving and re-setting the selectionStart and selectionEnd points of the textbox... This worked rather better, but with some keyboard mashing, the cursor would start moving around.

Perhaps these problems can be solved. I'll continue playing with it.

@dave
Copy link
Contributor Author

dave commented Jun 23, 2016

Here's an interesting idea... If we only update the value if the old value from the model matches the current value from the element, then we still get updates if the user isn't entering text, but it prevents it if the text is being entered...

@slimsag
Copy link
Member

slimsag commented Jun 25, 2016

@davelondon do you have any code on-hand that can reproduce the issue? I'd be curious to play around with potential solutions.

I also have some very old code which attempted to save/restore cursor selection, and it didn't have any drawbacks except one minor thing (when using shift+arrow keys to select text, it had potential to reverse the direction of your selection, i.e. swapping the origin of your selection with the current destination / cursor position). It might be adaptable if your interesting idea above doesn't pan out.

@neelance
Copy link
Contributor

I can only repeat: The golden solution here is to not set the value property unless the content is actually being modified by some code. That way, the browser has no reason to discard the state of the selection, etc.

@dave
Copy link
Contributor Author

dave commented Jun 26, 2016

I don't have a simple test case... I'll see if I can come up with one today and we can all have a play.

@dave
Copy link
Contributor Author

dave commented Jun 26, 2016

If I'm not very much mistaken, the problem manifests itself in the todomvc example... Simply enter some text, reposition the cursor to the start of the entered text and add some more. The cursor immediately jumps to the end. I've pushed a couple of branches to my fork to show the issue and the fix, but perhaps it'll be easier to set it up yourself:

https://github.com/davelondon/vecty/tree/input
https://github.com/davelondon/vecty/tree/inputfixed

@dave
Copy link
Contributor Author

dave commented Jun 26, 2016

I've also added a red div to the bottom of the page. Mouse over this to add a character to the end of the textbox without losing focus... This is important for testing the use-case where the value is updated without the user entering text.

@dave
Copy link
Contributor Author

dave commented Jun 26, 2016

Hmmm @neelance it seems the simple solution you first proposed works fine in this example. I'l go back to my more complex code and work out why it's not working. It's possible I've made a mistake somewhere..

@dave
Copy link
Contributor Author

dave commented Jun 26, 2016

OK I've worked it out. Your simple code works fine. This was actually the first method I tried last week, but at the time my event handlers were dispatching an action containing the actual value, like this. This didn't work.

Since then I've updated it to pass a function that returns the current value, like this. This seems to work fine with your code.

I'll do a PR. We can discuss preserving the cursor position and selection in a different issue.

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

No branches or pull requests

3 participants