vecty icon indicating copy to clipboard operation
vecty copied to clipboard

Preserve selection range across element replacements

Open dave opened this issue 8 years ago • 3 comments

As a follow-on from https://github.com/gopherjs/vecty/issues/47 - we can preserve the cursor position by recording and replacing the selectionStart and selectionEnd properties:

start := e.node.Get("selectionStart").Int()
end := e.node.Get("selectionEnd").Int()
e.node.Set(name, value)
e.node.Call("setSelectionRange", start, end)

This isn't ideal - if text is added to the start of the textbox, the cursor position / selected text changes. Is this is better than moving the cursor to the end of the textbox?

Perhaps we could check to see if the selected text would change?

if name == "value" {
    start := e.node.Get("selectionStart").Int()
    end := e.node.Get("selectionEnd").Int()

    if end != start {
        // we have a selected block. Only preserve the selection
        // if the selected text is unchanged.
        if oldValue.(string)[start:end] != value.(string)[start:end] {
            // if the selected text would change, we should
            // place the cursor without a selection at the
            // position of the start of the selection.
            end = start
        }
    }

    e.node.Set(name, value)
    e.node.Call("setSelectionRange", start, end)

} else {
    e.node.Set(name, value)
}

You can see this in action here. It isn't ideal. The cursor position still moves backwards if it's after inserted text. I fear simple universal solution is impossible.

Perhaps this is a solution to a problem that doesn't exist. If the text in a textbox changes, moving the cursor to the end of the text might not be the end of the world.

However, quite a common use-case I can see is validation where the entry of certain characters is forbidden... preserving the cursor position in that case would be essential...

dave avatar Jun 26 '16 11:06 dave

Perhaps this is a solution to a problem that doesn't exist. If the text in a textbox changes, moving the cursor to the end of the text might not be the end of the world.

I've been thinking about this recently, and while I don't have a full conclusion here, I am considering: what other things in browsers might break arbitrarily by only copying the selection range? For example, there are Input Method Editors (IMEs) for non-English languages that might be affected somehow (I'm not sure how yet, though). I'm just spitballing ideas here, not saying any of this is true.

However, quite a common use-case I can see is validation where the entry of certain characters is forbidden... preserving the cursor position in that case would be essential...

If I understand correctly, you're saying for example an input component which only allows entering a phone number. When the user types a non-number, the value of the input needs to be replaced and thus the cursor would be moved to the end of the input. Is that correct?

slimsag avatar Jul 03 '16 04:07 slimsag

When the user types a non-number, the value of the input needs to be replaced and thus the cursor would be moved to the end of the input. Is that correct?

Yup - that's what I had in mind.

For example, there are Input Method Editors (IMEs) for non-English languages that might be affected somehow

You're probably right.

There's a good cursor jumping discussion in the Facebook react repo here: https://github.com/facebook/react/issues/955

dave avatar Jul 14 '16 08:07 dave

I'm going to mark this as WontFix -- but leave the issue open.

I currently think that it is not possible to implement this in a way that truly works properly (without screwing up the selection flow of the user, or breaking IMEs etc.) But I'd like to acknowledge that this is a real issue for users -- including for React users today -- but that it probably isn't solvable with the APIs that browsers expose today. I'm very open to being proven wrong, or seeing a future selection API solve this problem :)

slimsag avatar Jan 07 '17 21:01 slimsag