Search code examples
vue.jswatchtimepickerbuefy

Buefy timepicker does not clear input


I have a project where I need to use Buefy timepicker. There is an input which contains the value selected in the picker. Everything works well except the input element which I thing should be cleared if the model is set to null. The code looks like:

<b-field>
    <b-timepicker
        v-model="newTimeFrom"
        editable
        trap-focus
        icon="clock"
        :incrementMinutes="5"
        :placeholder="Set time from"
        class="mb-2"
    >
    </b-timepicker>
    <b-timepicker
        v-model="newTimeTo"
        editable
        trap-focus
        icon="clock"
        :incrementMinutes="5"
        :placeholder="Set time to"
        class="mb-2"
    >
    </b-timepicker>
</b-field>

and there are some watchers which should get the value from model variables and then set model variables to null.

data() {
    return {
        newTimeFrom: null,
        newTimeTo: null,
        times: [],
    };
},
watch: {
    newTimeFrom(newTimeFrom) {
        if( !this.newTimeTo ) return;
        this.times.push([newTimeFrom, this.newTimeTo]);
        this.newTimeFrom = this.newTimeTo = null;
    },
    newTimeTo(newTimeTo) {
        if( !this.newTimeFrom ) return;
        this.times.push([this.newTimeFrom, newTimeTo]);
        this.newTimeFrom = this.newTimeTo = null;
    }
},

Can somebody tell me what is wrong with this code?


Solution

  • Looks like there is a timing issue. The value of the properties haven't been propagated to the DOM. Try $nextTick() which waits until after the next round of UI updates to execute the callback.

    this.$nextTick(function() {  
      this.newTimeFrom = this.newTimeTo = null;
    });
    

    Working Demo :

    const example = {
        data() {
            return {
                minutesGranularity: 15,
                newTimeFrom: null,
                newTimeTo: null,
                times: []
            }
        },
        watch: {
          newTimeFrom(newTimeFrom) {
            if( !this.newTimeTo ) return;
            this.times.push([newTimeFrom, this.newTimeTo]);
            this.$nextTick(function() {  
              this.newTimeFrom = this.newTimeTo = null;
            });
          },
          newTimeTo(newTimeTo) {
            if( !this.newTimeFrom ) return;
            this.times.push([this.newTimeFrom, newTimeTo]);
            this.$nextTick(function() {
              this.newTimeFrom = this.newTimeTo = null;
            });
          }
        }
    }
    
      const app = new Vue(example)
      app.$mount('#app')
                
    <script src="https://unpkg.com/vue@2/dist/vue.min.js"></script>
    <script src="https://unpkg.com/buefy/dist/buefy.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/buefy/dist/buefy.min.css"/>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css"/>
    <div id="app" class="container">
        
        <b-field label="Select timepicker">
            <b-timepicker
                placeholder="Click to select"
                icon="clock"
                :editable="true"
                :incrementMinutes="minutesGranularity"
                v-model="newTimeFrom"
                >
            </b-timepicker>
          <b-timepicker
                placeholder="Click to select"
                icon="clock"
                :incrementMinutes="minutesGranularity"
      v-model="newTimeTo"
                >
            </b-timepicker>
        </b-field>
    
    </div>