adopted-ember-addons / ember-inputmask

Ember wrapper around Inputmask.js
https://adopted-ember-addons.github.io/ember-inputmask/
MIT License
68 stars 45 forks source link

EmberInputMask does not play well with multiple masks property #143

Open brunoocasali opened 3 years ago

brunoocasali commented 3 years ago

Hello!!

In my app I have a field with two kinds of masks:

<OneWayInputMask
  @mask={{array '999.999.999-99' '99.999.999/9999-99'}}
  @value={{this.value}}
  {{!-- @update={{this.update}} --}}
  @options={{hash oncomplete=(action this.onMaskFinished)}}
/>

The idea is simple, when any of the masks is complete I just want to call a function (covered in inputmask.js) to do some business logic there.

The problem is: The input does not allow more typing after the first mask is complete! I've checked if is a inputmask bug but I think is not, because everything works when I remove @update part (of course with bunch of console errors because @update is required by the component).

I've tried to reproduce this behaviour in tests right here in this repo, as placed in: https://github.com/brandynbennett/ember-inputmask/issues/144

brunoocasali commented 3 years ago

To workaround this i've implemented a really simple version:

import Component from '@glimmer/component';
import Inputmask from 'inputmask';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';

const DEFAULT_OPTIONS = {
  rightAlign: false,
};

// TODO: must be tested or replaced by ember-input-mask version when this issue was closed
// https://github.com/brandynbennett/ember-inputmask/issues/143
export default class FormsInputMaskComponent extends Component {
  @tracked inputmask;

  @action setupMask(element) {
    let options = { ...DEFAULT_OPTIONS, ...this.args.options };

    this.inputmask = new Inputmask(this.args.mask, options);
    this.inputmask.mask(element);
  }

  @action processNewValue({ target }) {
    let cursorStart = target.selectionStart;
    let cursorEnd = target.selectionEnd;

    this.sendUpdate(target.inputmask.unmaskedvalue(), target.value);

    target.setSelectionRange(cursorStart, cursorEnd);
  }

  sendUpdate(unmaskedValue, value) {
    this.args.update && this.args.update(unmaskedValue, value);
  }

  willDestroy() {
    this.inputmask.remove();
  }
}
<Input
  ...attributes
  type="text"
  {{on "input" (action this.processNewValue)}}
  {{did-insert this.setupMask}}
/>