Possible fix of cursor jumping at the end of the input field

Recently there was a discussion in Slack about this issue, which is a common problem unrelated to Elm.

Browsers move the cursor to the end of the input field when the value of an input field is overwritten with a value different from the present value.

A possible fix is to save and restore the position of the cursor (aka caret) while updating the input field with something like this:

const caretPositionBefore = this.inputNode.selectionStart;
this.inputNode.value = newValue;
this.inputNode.setSelectionRange(caretPositionBefore, caretPositionBefore);

So I created a custom element that does this automatically.

You can find a demo here: https://ellie-app.com/hqgbZ6Qg55Ca1

To use this custom element from Elm is necessary to:

  • Copy the necessary JavaScript available in the Ellie
  • Use Html.node "custom-input" instead of Html.input
  • Use Html.Attributes.attribute when changing certain attributes like value and placeholder instead of changing them directly with Html.Attributes.value and Html.Attributes.placeholder

I’m not an expert on custom elements so probably there are better solutions or possible imrpvements.

Few things are not done yet, for example, proper support of dynamically changing style.

This solution can be probably used also with other frameworks, like React, etc. that suffer from the same issue

Note that changing the value of the input field while the user is typing is, in general, a bad UX. So be sure to assess the quality of the UX. My use case is a date input field with the pattern “YYYY / MM / DD” that gets over imposed to the value.

4 Likes

I tried changing String.toUpper to String.filter Char.isDigit in your Ellie, to achieve a digits-only input: https://ellie-app.com/hr93TWKRwWYa1

It doesn’t seem to work properly in your custom element: When I type digits, non-digits are cleared. When I type non-digits, they end up in the text input where I typed them.

I’ve created digits-only fields – and some other transform-while-you-type things – before, and from that experience I can’t see how a generalized custom element could possibly understand where the cursor should end up in all situations. I might be wrong though.

Here are some old Ellies I’ve created, in case it’s interesting:

Digits only field: https://ellie-app.com/6YfzVxqmtJ3a1
Enhanced version with separators: https://ellie-app.com/fyH8y9N7PC9a1
Same, but with more code in Elm: https://ellie-app.com/fz5cr7SGjSFa1

1 Like

Using a real diff to better reconstruct the cursor position seems to get pretty close, but it still does not feel “right” in all situations to me.

Also it looks like that you can use the builtin property-based value and placeholder attributes if the custom element is defined before Elm renders the page!

https://ellie-app.com/hrgnqR8zcbna1

This Ellie uses jsdiff, but there seem to be other implementations that also allow to specify the edit position to produce better diffs, which might also be worth looking into: fast-diff

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.