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

Add custom v-model modifiers #3666

Closed
ecmel opened this Issue Sep 13, 2016 · 33 comments

Comments

Projects
None yet
@ecmel

ecmel commented Sep 13, 2016

We have .lazy, .number, .trim and .undef is on the way.

Apart from .lazy they all work like two-way filters.

Since 2.0 does not support 2 way filters, may be there should be a new api to add custom v-model modifiers to fulfill the same need.

@franciscolourenco

This comment has been minimized.

Contributor

franciscolourenco commented Sep 13, 2016

@posva computed properties are not reusable.

@posva

This comment has been minimized.

Member

posva commented Sep 13, 2016

Almost everything is reusable through a mixin.
You can use a function that generates a mixin. This way you can bind a the
computed property dynamically. I cannot put that example on a fiddle now
but I would do it ASAP.
However, I agree it's a very common use case for inputs to have
transformations applied. A proper api or at least an explanation on the
guide is necessary

On Tue, 13 Sep 2016, 18:48 Francisco Lourenço, notifications@github.com
wrote:

@posva https://github.com/posva computed properties are not reusable.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#3666 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAoicf33lCvETQc9LBQ5GGZ93ExPcLS_ks5qptPegaJpZM4J7vQ0
.

@franciscolourenco

This comment has been minimized.

Contributor

franciscolourenco commented Sep 13, 2016

Almost everything is reusable through a mixin.
You can use a function that generates a mixin. This way you can bind a the
computed property dynamically. I cannot put that example on a fiddle now
but I would do it ASAP.
However, I agree it's a very common use case for inputs to have
transformations applied. A proper api or at least an explanation on the
guide is necessary

Put in another way, computed properties are not reusable. You can use factory functions + mixins as a work around, but the usability and readability doesn't compare.

@ecmel

This comment has been minimized.

ecmel commented Sep 26, 2016

For my project, I badly needed this feature so I used the recommended custom input approach:

InputCustom.js

define(function () {
  return Vue.extend({
    data: function () {
      return {
        focused: false
      };
    },
    template: '<input @focus="onFocus" @blur="onBlur" @input="onInput" @change="setDisplayValue">',
    props: ['value'],
    watch: {
      value: function () {
        if (!this.focused) {
          this.setDisplayValue();
        }
      }
    },
    mounted: function () {
      this.setDisplayValue();
    },
    methods: {
      onInput: function () {
        this.$emit('input', this.parse(this.$el.value));
      },
      onFocus: function () {
        this.focused = true;
      },
      onBlur: function () {
        this.focused = false;
        this.setDisplayValue();
      },
      setDisplayValue: function () {
        this.$el.value = this.format(this.value);
      }
    }
  });
});

InputText.js

define(['js/InputCustom'], function (InputCustom) {
  return InputCustom.extend({
    methods: {
      parse: function (val) {
        val = val.trim();
        return val === '' ? null : val;
      },
      format: function (val) {
        return val === null ? '' : val;
      }
    }
  });
});

In my opinion, this approach is very convenient and I decided not to use any v-model modifiers at all including .lazy.

@yyx990803

This comment has been minimized.

Member

yyx990803 commented Nov 1, 2016

For more customized use cases that built-in modifiers cannot support, what @ecmel mentioned is the recommended approach. We will document that in more details in the official guide.

@yyx990803 yyx990803 closed this Nov 1, 2016

@franciscolourenco

This comment has been minimized.

Contributor

franciscolourenco commented Nov 1, 2016

The idea of this feature proposal is to take advantage of the existing v-model directive, which already works with every input element. To save the work of writing InputCustom.js in every project, because that has been done already in v-model, having only to write the equivalent of InputText.js in a custom modifier, which contains all the logic which needs to be modified most of the times. The fact that v-model already ships with modifiers proves that it is an intuitive and desirable pattern. It is only natural to facilitate the creation of custom modifiers, to save the work of creating custom elements and having to implement dom/model binding manually.

If it makes sense from the API perspective, would be interesting to know what are the technical limitations which are driving the decision of not implementing this feature.

@restoreddev

This comment has been minimized.

restoreddev commented Feb 20, 2017

Any chance we can get this issue reopened? A common use case for me is the need to automatically format data in a field as it's being typed in. Something like taking '101216' and turning it into '10/12/16'. Being able to create a custom v-model modifier would greatly simplify my code since I could write v-model.date instead of having to build a custom input component with props and events.

@ecmel

This comment has been minimized.

ecmel commented Feb 21, 2017

After using vue js for a while now in my project, I think this issue should indeed be reopened.

At least we need an undef modifier.

@rhyek

This comment has been minimized.

rhyek commented Mar 24, 2017

I agree that this issue should be reopened. Not sure what undef was supposed to do, but I would like a v-model modifier that sets my variable to null in case the input's trimmed value is an empty string.

I'd love to be able to do that myself in a straightforward way.

@franciscolourenco

This comment has been minimized.

Contributor

franciscolourenco commented Mar 24, 2017

Functionality more redundant than this has been added for example with #5194 . From the outside, Vue appears to slowly be compromising some of its principles in favour of conventions and practices promoted by the react community. Slightly deviating from the qualities which made it stand out in the first place. Would be interesting to know if this is a conscious decision with the intention to make migration from react easier, or just coincidence.

@ecmel

This comment has been minimized.

ecmel commented Mar 24, 2017

Writing custom components is fine but if you want to use a 3rd party custom component like https://github.com/text-mask/text-mask/tree/master/vue#readme there is no straight forward way to sanitize the masked input to model values except using computed properties.

@tobei

This comment has been minimized.

tobei commented May 2, 2017

So, I just want to use an HTML standard input[type=date] field to edit a date type in my model and this wonderfully powerfull and extensible framework can't do that out of the box? Can't read the date into the field, overwrite my date with a string in my data after I select a date. This solution could be written in two lines with two-way filters or with modifier.

But the best solution at all would be to just support it natively as they do for checkbox and other standard input field, why is "date" a special thing?

@newms87

This comment has been minimized.

newms87 commented May 28, 2017

+1 for custom modifiers. Seems like a no brainer, unless there is a good reason not to?

Masking input and parsing the value for application use is a very common practice, and making some "syntatic sugar" like v-model.lazy.currency="amount" would be amazing!

@Chalkin

This comment has been minimized.

Chalkin commented Jun 25, 2017

1+ for custom modifiers.
I have a simple radio input with true|false values which evaluate to strings - But I need them as an boolean - computed properties will not be smart in this case since I need to reimplement a computed property for every radio input. E.g. Having 100 radio inputs will result in 100 computed properties

@maxapps

This comment has been minimized.

maxapps commented Jul 6, 2017

+1 for custom modifiers but I agree with tobei -- input[type=date] should work automagically.

@mahesh29

This comment has been minimized.

mahesh29 commented Aug 16, 2017

+1 for custom modifiers.

I come from an Angular background, and just started with vue, and saw this thread.

I feel it would really help having something like Angular's parsers and formatters, in Vue too. If I could do something like v-model.dateFormat and result in something like mm/dd/yyyy, it would be really cool.

EDIT: looks like it reiterated on what @restored18 said. +1 to you too

@coderjz

This comment has been minimized.

coderjz commented Sep 20, 2017

+1 for custom v-model modifiers.

In my case I loop over a few nested objects retrieved in JSON, and use a single HTML template (rather than a template per object). In this case I believe computed properties don't work?

I'm currently putting in custom conversion methods between the server format and v-model format when fetching and sending data, but would love for something just "built-in" that I could pass the functions to.

@johnleider

This comment has been minimized.

johnleider commented Nov 6, 2017

+1 to this. It used to be available before 2.2. You could access the property through,

this.$vnode.data.directives

It was removed with the addition of custom model input values, but was a very useful feature and should be back in the framework.

@matthew-inamdar

This comment has been minimized.

matthew-inamdar commented Nov 21, 2017

+1 for this.

Custom v-model modifiers would be great!

@webnoob

This comment has been minimized.

webnoob commented Jan 11, 2018

+1 in 2018 as well ...

@Mushr0000m

This comment has been minimized.

Mushr0000m commented Jan 11, 2018

+1 It's a necessary feature for DRY code in my opinion. Right now I have to create 10 watchers that does the same thing for a form with a lot of input. A custom modifier would solve everything.

@emadgh

This comment has been minimized.

emadgh commented Mar 30, 2018

+1 I just started vue and already need these type of two way filters ...

@samayo

This comment has been minimized.

Contributor

samayo commented Mar 31, 2018

+1 definitely needed

@mt89vein

This comment has been minimized.

mt89vein commented Apr 20, 2018

+1

@nickmessing

This comment has been minimized.

Member

nickmessing commented Apr 20, 2018

You can build helpers like this for most use-cases IMO

@bbugh

This comment has been minimized.

bbugh commented May 8, 2018

@nickmessing that doesn't cover the (really useful) use case being described here, which is in-place modification of the input text. If you have an input box that you want to always be formatted like a phone, you'd have <input v-model.phone="some_data">. When the user entered text, it would automatically format it.

This seems like such a basic feature and it's more difficult than it should be right now. The behavior already exists in the framework, but for some reason it's restricted to framework-only code. We want to be able to add a custom modifier that would do this, which is reusable across components and projects, just like filters and directives are right now.

@phoet

This comment has been minimized.

phoet commented Jun 21, 2018

@bbugh totally agree, i'm having a similar case with formatting IBANs and it would be such a nice and declerative way to simply put v-model.iban="payment.iban" in there...

@franciscolourenco maybe someone could put some reasoning behind why this should not be supported by the framework so that it becomes more obvious.

@IharKrasnik

This comment has been minimized.

IharKrasnik commented Sep 24, 2018

+1 for custom modifiers, there are plenty of use-cases that could be accomplished with this feature

In our application there are few different inputs to format currencies, we always store cents amount in model, but display nicely formatted dollars amounts in inputs (so 123456 in model shown as $1,234.56) <input v-model.dollars="cents" />

Other use-case is sanitizing and unescaping html fields in order to prevent XSS atacks (Model stores "A &amp; B" while input shows "A & B") <input v-model.html="text" />

@orangevinz

This comment has been minimized.

orangevinz commented Oct 1, 2018

+1

1 similar comment
@krychu90

This comment has been minimized.

krychu90 commented Oct 13, 2018

+1

@iStyx

This comment has been minimized.

iStyx commented Oct 24, 2018

+1 for custom modifiers.
I was really surprised that I can't do something like v-model.trim.uppercase=...

@magisters-org

This comment has been minimized.

magisters-org commented Nov 1, 2018

+1

1 similar comment
@rkingon

This comment has been minimized.

rkingon commented Nov 14, 2018

+1

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