Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

Should bind to native input event rather than rely on componentUpdated #64

Open
tmorehouse opened this issue Oct 13, 2017 · 3 comments
Open

Comments

@tmorehouse
Copy link

Changing the approach to how this directive is implemented may make it work better with custom input components.

Rather than reply on the v-model (and firing input events, which may not always be the event used in a custom component), binding to the elements native input event, grabbing the current value via evt.target.value and formatting it, then setting the value via evt.target.valuemight make this directive more robust.

One can check if they are on a custom component by checking if el has the el.__vue__ property, and if so, then trigger the 'vue' input event el.__vue__.$emit('input', evt.target.value).

Adding a modifier to the direction to set which event is fired would be good as well (i.e. input or change)

@probil
Copy link
Owner

probil commented Jan 31, 2018

Hi, @tmorehouse
Thanks for pointing this.
The version prior to v1.1.0 was implemented similar way. But it was really buggy. If you can create minimum valuable working example, I would like to take a look

@rulrok
Copy link

rulrok commented May 7, 2019

@tmorehouse @probil
Hi,

If I understand the problem here, it is the same I'm having with custom components:

I'm using a custom input component from Quasar framework.
They have a q-input which hides a native input element underneath its template.

I have seen that the directive code just assumes it is being used directly on a native input element.

I was trying to use as:

<q-input type="text" float-label="Data de nascimento" maxlength="15" v-model="birthDay" v-mask="'##/##/####'"/>

But the directive was only getting a reference to a div instead of an input element.

Here is the current code for the directive receiving el as the top element where it has been used (<q-input/> in my case)

var directive = {
  bind: function bind(el, _ref) {
    var value = _ref.value;

    updateMask(el, value);
    updateValue(el);
  },
  componentUpdated: function componentUpdated(el, _ref2) {
    var value = _ref2.value,
        oldValue = _ref2.oldValue;

    var isMaskChanged = value !== oldValue;

    if (isMaskChanged) {
      updateMask(el, value);
    }

    updateValue(el, isMaskChanged);
  }
};

I think I have a easier solution for the problem. Or at least for my own problem :b

Just verify if el is an HTMLInputElement or use querySelector('input') to find the native input.

The code would become: (notice the getNativeInput method)

function getNativeInput(el){
  if(el instanceof HTMLInputElement)
    return el;
  
  return el.querySelector('input');
}

var directive = {
  bind: function bind(el, _ref) {
    el = getNativeInput(el);
    var value = _ref.value;

    updateMask(el, value);
    updateValue(el);
  },
  componentUpdated: function componentUpdated(el, _ref2) {
    el = getNativeInput(el);
    var value = _ref2.value,
        oldValue = _ref2.oldValue;

    var isMaskChanged = value !== oldValue;

    if (isMaskChanged) {
      updateMask(el, value);
    }

    updateValue(el, isMaskChanged);
  }
};

@rulrok
Copy link

rulrok commented May 7, 2019

I've created a PR draft #384

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

No branches or pull requests

3 participants