Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue js apply filter on v-model in an input field

Hope someone can help me! I have made a directive wrapping the Jasny Bootstrap Plugin more specifically the input-mask thing and everything goes well!

Now I have made a custom filter supported by moment to format the date field!

The date format that I receive from my backend application is YYY-MM-DD and I must show on the view as DD/MM/YYYY... I've tried v-model="date | myDate" but it didn't work properly!

JS

Vue.directive('input-mask', {   params: ['mask'],    bind: function() {     $(this.el).inputmask({       mask: this.params.mask     });    }, });  Vue.filter('my-date', function(value, formatString) {    if (value != undefined)     return '';    if (formatString != undefined)     return moment(value).format(formatString);    return moment(value).format('DD/MM/YYYY');  });  var vm = new Vue({   el: 'body',   data: {     date: '2015-06-26',   } }); 

HTML

<label>Date</label> <input type="text" class="form-control" v-input-mask mask="99/99/9999" v-model="date"> <p>{{ date | myDate 'dd/mm/yyyy' }}</p> 

There is the JSBin if somebody's interested!

Thanks in advance!

EDIT: Explaining better what I expect =)

When the page first load the input receive the value of 2015-06-26 and I would like to show that value as DD/MM/YYYY so 26/06/2015! It works properly only after I start typing something!

like image 456
Gustavo Bissolli Avatar asked Apr 07 '16 21:04

Gustavo Bissolli


People also ask

Where can Vue filter be applied?

Going off number 2, because VueJS filters are meant for text transformations, they can only be used in two places: mustache interpolations (the curly braces in your template) and in v-bind expressions.

What is @input in VUE JS?

It provides two-way data binding by binding the input text element and the value binded to a variable assigned.

How do I get input value from Vue?

To get an input value in Vue, we can use the v-model directive to set up a two-way binding between the value and a variable. Every time the user changes the text in the input field, the text variable will be updated automatically. We can then use this variable to perform an action or display information.


2 Answers

I understand what you are trying to do, however, because of the two way binding when using v-model, it may be better to just format the date as you receive it from the server, and then, use it with the desired format in your front-end app ('DD/MM/YYYY').

When sending the data back to the back-end, you just format it back to the desired server format ('YYYY-MM-DD').

In your Vue app, the work flow would be something like this:

 new Vue({     el: 'body',     data: {       date: null,     },     methods: {         getDataFromServer: function() {                 // Ajax call to get data from server                  // Let's pretend the received date data was saved in a variable (serverDate)                 // We will hardcode it for this ex.                 var serverDate = '2015-06-26';                  // Format it and save to vue data property                 this.date = this.frontEndDateFormat(serverDate);         },         saveDataToServer: function() {             // Format data first before sending it back to server             var serverDate = this.backEndDateFormat(this.date);              // Ajax call sending formatted data (serverDate)         },         frontEndDateFormat: function(date) {             return moment(date, 'YYYY-MM-DD').format('DD/MM/YYYY');         },         backEndDateFormat: function(date) {             return moment(date, 'DD/MM/YYYY').format('YYYY-MM-DD');         }     }   }); 

This works well for me, hope it helps.

Here is a fiddle for it:

https://jsfiddle.net/crabbly/xoLwkog9/

Syntax UPDATE:

    ...     methods: {         getDataFromServer() {                 // Ajax call to get data from server                  // Let's pretend the received date data was saved in a variable (serverDate)                 // We will hardcode it for this ex.                 const serverDate = '2015-06-26'                  // Format it and save to vue data property                 this.date = this.frontEndDateFormat(serverDate)         },         saveDataToServer() {             // Format data first before sending it back to server             const serverDate = this.backEndDateFormat(this.date)              // Ajax call sending formatted data (serverDate)         },         frontEndDateFormat(date) {             return moment(date, 'YYYY-MM-DD').format('DD/MM/YYYY')         },         backEndDateFormat(date) {             return moment(date, 'DD/MM/YYYY').format('YYYY-MM-DD')         }     }   }) 
like image 118
crabbly Avatar answered Sep 17 '22 08:09

crabbly


I had a similar problem when I wanted to uppercase an input value.

This is what I ended up doing:

// create a directive to transform the model value Vue.directive('uppercase', {   twoWay: true, // this transformation applies back to the vm   bind: function () {     this.handler = function () {       this.set(this.el.value.toUpperCase());     }.bind(this);     this.el.addEventListener('input', this.handler);   },   unbind: function () {     this.el.removeEventListener('input', this.handler);   } }); 

Then I can use this directive on the input field with a v-model.

<input type="text" v-model="someData" v-uppercase="someData"> 

Now, whenever I type into this field or change someData, the value is transformed to uppercase.

This essentially did the same thing as I hoped v-model="someData | uppercase" would do. But of course, you can't do that.

In summation: make a directive that transforms the data, not a filter.

like image 27
james2doyle Avatar answered Sep 20 '22 08:09

james2doyle