13

Two-way binding with Vue.js using an <input> element doesn't work when jQuery datepicker and/or timepicker updates the <input> value. The binding only happens when a user types inside the <input>.

I need the two-way binding to happen when the <input> is updated via datepicker or timepicker.

I am using Vue.js and jQuery in the most simple way -- importing them from within my html file via <script src=""></script> tags.

This issue is known and has solutions, but for more complex situations than mine. I'm having trouble figuring out how to adapt the solutions I've found to my basic use case (i.e., I'm not using custom directives, components, or event templates).

Here is a codepen of my working code.

And here are the main parts of my static code:

<form>
  <input v-model="title" name="title" type="text">
  <input v-model="shortDesc" name="shortDesc" type="text">
  <input v-model="date" name="date" type="text">
  <input v-model="time" name="time" type="text">
</form>

<script>
  var elm = new Vue({
    el: '#preview',
    data: {
      title: '',
      shortDesc: '',
      date: '',
      time: ''
    }
  })

  $(function(){
    $("input[name=date]" ).datepicker({
      dateFormat: 'DD, MM dd'
    });
  });


  $('input[name=time]').timepicker({'scrollDefault': 'now'});
</script>

2 Answers 2

18

I am not able to find a pure vue way to do it, but you can do this by using onSelect callback of datapicker, you can set value of date variable in this callback.

See working codepen here.

I have added an mounted block in your vue instance:

var elm = new Vue({
  ...
  ...
  mounted () {
    var vm = this
    $('#datedate').datepicker({
      onSelect: function(dateText) { 
        vm.date = dateText
      }
   })
})

and added in id attribute in your date input:

<input v-model="date" name="date" class="block col-12 mb1 field" type="text"  id="datedate">

EDIT

Since timepicker doesn't have the onSelect option that datepicker does, a solution is to use the changeTime event which is shown in action in the "Event Example" in the timepicker demo docs.

The code below provides the updated Vue script with solutions for both jQuery datepicker and timepicker:

var elm = new Vue({
  ...
  ...
  mounted() {
    var vm = this
    $('input[name=date]').datepicker({
      dateFormat: 'DD, MM dd',
      onSelect: function(dateText) {
        vm.date = dateText
      }
    }),
    $('input[name=time]').timepicker({'scrollDefault': 'now'}).on('changeTime', function() {
      vm.time = $('input[name=time]').val();
    })
  }
})

And here is a new codepen verifying both @saurabh's datepicker solution and @BrianZ's timepicker solution.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks @saurabh, your datepicker code works for me! I was able to adapt your code to a solution to the similar but different timepicker issue. I will create an answer that shows both solutions in the same file.
@BrianZ Great it helped, You can edit this answer as well to make it complete.
What is the reason that direct binding doesn't work in the first place?
4

This approach allows vue to pick up on the change rather than manually setting the value on vm in the select callback as in other answers.

$('#datedate').datepicker({
  onSelect: function(dateText) { 
    $(this)[0].dispatchEvent(new Event('input', { 'bubbles': true }))
  }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.