javascriptvuejs2pickadate

Cant update vuejs2 v-model from native javascript change event


I'm trying to figure out how to fire native javascript events on an input given that I want to update a data attribute inside my vue instance.

I'm searched a bit on the matter (and that's how I got to the part that suggests the solution is a native javascript event) due to this post https://github.com/vuejs/vue/issues/96#issuecomment-37870300

So I have this input:

<input type="text" name="occurred" id="occurred" class="form-control" required="" v-model="occurred">

And through javascript I'm attempting to figure it's native event so that vue can update v-model="occurred" (I'm using pickadate.js)

$('#occurred').pickadate({
  format: 'dddd, dd mmm, yyyy',
  formatSubmit: 'dd-mm-yyyy',
  hiddenPrefix: 'prefix__',
  hiddenSuffix: '__suffix'  
});

var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', true, true);

var el = document.getElementById("occurred");
el.dispatchEvent(evt);

I've tried a couple different ways but I can't seem to fully understand how it works.

I would be super glad if you could explain to me the solution rather than just give it as I want to comprehend it.

I've created a fiddle to help explain: https://jsfiddle.net/c1askwj2/5/

edit: A solution is to do what I don't want to do. Basically "expose" your view object:

var vueFoo = new Vue({ ... });

This way you can access it through varFoo.thedate and set it:

$('#thedate').pickadate({
  onSet: function(value) {
    var date = new Date(value.select);
    vueFoo.thedate = date.getDate() + '-' + date.getMonth() + 1 + '-' + date.getFullYear();
  }
});

This to me is a very ugly solution as I like to keep my vue objects unavailable...


Solution

  • You need to handle the on change event on the input to update the view model and set the date picker's value by watching the view model. This would be a lot easier if you abstracted the date picker into its own component but there is a working example based on your code below.

    Read more about watching here: https://v2.vuejs.org/v2/api/#watch

    // Init Vue
    new Vue({
        el: '#vueDate',
      data: {
        thedate: '00-00-0000',
        thedate_counter: 0,
        picker: null
      },
      mounted: function() {     
        var el = $('#thedate')
        this.picker = el.pickadate().pickadate('picker')
        var vm = this
        el.on('change', function() {
                vm.thedate = this.value
            })
      },
      watch: {
        thedate: function(value) {
            this.picker.set('select', value)
        }
      }
    });