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

Caret position gets reset to 0 when the same variable is bound to multiple element instances #62

Open
michalsukupcak opened this issue May 18, 2016 · 2 comments

Comments

@michalsukupcak
Copy link

Description

When the same variable is bound to multiple element instances, eg.:

<gold-phone-input label="Input 1" value="{{phoneNumber}}"></gold-phone-input>
<gold-phone-input label="Input 2" value="{{phoneNumber}}"></gold-phone-input>

Then usage of PaperInputBehavior.updateValueAndPreserveCaret inside _onValueChanged observer causes after any user input the caret to bug and reset its position always back to beginning (start) of the input, so user effectively types in RTL direction.

IMHO the issue is caused by the fact that change in value of one input triggers change in the other input, which triggers change back. The subsequent changes detect no caret positions (this.$.input.selectionStart equals to 0) and therefore the position resets back to the beginning of the input.

Quick workaround that prevents the issue from happening is adding a check at the beginning of the _onValueChanged observer for input focus (this.focused === true), therefore preventing the observer code from being executed unless user actually has focus on the input and is typing in the specific element instance.

Issue occurs in Chrome (50) on Linux (Ubuntu 16.04), doesn't occur under Firefox (46) on the same OS.

Expected outcome

Caret position follows user input naturally.

Actual outcome

Caret gets reset to initial position (start of the input).

Steps to reproduce

  1. Put 2 gold-email-input elements into the page.
  2. Bind the same variable to both inputs.
  3. Start typing into one of the elements.
@notwaldorf
Copy link
Contributor

Argh, yeah, this looks like a bug: http://jsbin.com/gaceku/edit?html,output

If we do what you say, and skip _onValueChanged if the element isn't focused, then won't something like `someInput.value = '12345678' stop working?

@michalsukupcak
Copy link
Author

Unfortunately yes, you are correct - that will allow setting a value, but validation won't be triggered.

I did my own paper-input implementation (heavily inspired by gold-phone-input) with the same caret position resetting issue (as I only modified the code to specific formatting requirements), and this is a fix that is working for me for the validation problem when value is set imperatively:

    _onValueChanged: function (value, oldValue) {
      if (value !== oldValue && value !== '' && value !== null && value !== undefined) {

        value = value ? value.toString() : '';
        var start = this.$.input.selectionStart;
        // Input formatting similar to gold-phone-input is here,
        // removed to shorten the sample as it is irrelevant ...

        // Update caret position only when input is focused
        if (this.focused) {
          var updatedSpacesBeforeCaret = formattedValue.substr(0, start).split(' ').length - 1;
          var spacesDifference = updatedSpacesBeforeCaret - initialSpacesBeforeCaret;
          this.updateValueAndPreserveCaret(formattedValue.trim());
          this.$.input.selectionStart = this.$.input.selectionEnd = start + spacesDifference;
        } else { // Otherwise (input not focused), simply just update the internal value
          this.value = formattedValue.trim();
        }

        this._handleAutoValidate();

      }

    },

I removed the focus condition from the beginning of the function and only wrapped the piece of code handling caret position and added simple this.value update when input isn't focused. Result:

  • caret position continues to work correctly (doesn't reset on user input),
  • input validation works even if the value is set imperatively in code (input is marked as invalid).

Can't say if it is the best or correct solution (is it ok to set this.value inside _onValueChanged?), but at least it seems to work. :)

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

No branches or pull requests

2 participants