nathanreyes / v-calendar

An elegant calendar and datepicker plugin for Vue.
https://vcalendar.io
MIT License
4.32k stars 841 forks source link

Input value doesn't update after a manual change of the date #389

Open ligiab opened 4 years ago

ligiab commented 4 years ago

I have created a simple v-date-picker. Once I change the date manually, selecting a new date using the mouse is not triggering the update of the input value anymore.

<v-date-picker mode='single' v-model='selectedValue'> </v-date-picker>

PS. I have seen that with Version 0.9.7 this thing was working.

cwilby commented 4 years ago

Experiencing this too, hard to debug as there are no error messages. Thinking it has something to do with the updateValue function disabling input format when the input event occurs.

https://github.com/nathanreyes/v-calendar/blob/26922cd5fb9f480b2e824b490ce5d815d2d8c049/src/components/DatePicker.vue#L443-L478

najuste commented 4 years ago

I finally figured,, that if wishing to update the value manually (so I have buttons for the next and previous day), one needs in v-date-picker pass the updateValue as prop in the slot-scope.

Provide a default slot for v-date-picker. Be sure to extract out the following props by using slot-scope:

  • updateValue | Function | Call to update the value at the time of your choosing.

But what is not written in the docs, that this function (as in comment line 451) expects either a string(!) that is going to be replaced as input Value, or a date object but as date object needs to be parsed, one needs to pass a configuration object as second argument with a key: formatInput = true

updateValue(new Date(newDate), { formatInput: true });

mathias22osterhagen22 commented 4 years ago

In my case, I have a 'range' type. I set up the start and end value by code but I don't know what to do to refresh the input, currently looking.

quaidesbalises commented 4 years ago

@mathias22osterhagen22 Did you find a solution ? Currently in the same case

najuste commented 4 years ago

I haven't tried with a range, but maybe the same solution - passing an option object to format the value would work ?

-- html

<v-date-picker v-model='range'>
 <div slot-scope='{ inputValue, updateValue, hidePopover }'>
<b-input :value='inputValue'> </b-input>
 <button @click="updateRange(updateValue); hidePopover()">
</div>
</v-date-picker>

---js

//definition from v-calendar
range: {
        start: new Date(2018, 0, 16), // Jan 16th, 2018
        end: new Date(2018, 0, 19)    // Jan 19th, 2018
      }

updateRangeDayPeriod(updateValue){
// set a new range
this.range {
        start: new Date(2020, 0, 1),
        end: new Date()
      }
// call a passed function with obj and formatInput
updateValue(this.range, {
            formatInput: true,
        });
}
karipeltola commented 3 years ago

For me setting formatInput did not work with a range, I only got to update it by converting both the start and end date to strings.

burhanahmeed commented 3 years ago

Experiencing this too. I ended up using value from computed / pass the value to computed first.

 <v-date-picker 
        :columns="$screens({ default: 1, lg: 2 })" 
        is-range 
        :value="dateRange"
        :attributes="attrs"
        :max-date='new Date()'
        v-model="dateRange"
      />
computed: {
 dateRange: {
      set (val) {
         // action after date change here
      },
      get () {
        let range = {
          start: new Date(moment().subtract(7, 'day').format('YYYY-MM-DD')), 
          end: new Date(moment().format('YYYY-MM-DD'))
        }
        // action after receives date from props
        return range
      }
    }
}

Previously I used value from data() and it didnt work, but when value comes from props it works and also works on props change

andrewalc commented 2 years ago

Experiencing this too. I ended up using value from computed / pass the value to computed first.

 <v-date-picker 
        :columns="$screens({ default: 1, lg: 2 })" 
        is-range 
        :value="dateRange"
        :attributes="attrs"
        :max-date='new Date()'
        v-model="dateRange"
      />
computed: {
 dateRange: {
      set (val) {
         // action after date change here
      },
      get () {
        let range = {
          start: new Date(moment().subtract(7, 'day').format('YYYY-MM-DD')), 
          end: new Date(moment().format('YYYY-MM-DD'))
        }
        // action after receives date from props
        return range
      }
    }
}

Previously I used value from data() and it didnt work, but when value comes from props it works and also works on props change

can confirm this still does the trick, thank you!

LasithaPrabodha commented 2 years ago

Experiencing this too. I ended up using value from computed / pass the value to computed first.

 <v-date-picker 
        :columns="$screens({ default: 1, lg: 2 })" 
        is-range 
        :value="dateRange"
        :attributes="attrs"
        :max-date='new Date()'
        v-model="dateRange"
      />
computed: {
 dateRange: {
      set (val) {
         // action after date change here
      },
      get () {
        let range = {
          start: new Date(moment().subtract(7, 'day').format('YYYY-MM-DD')), 
          end: new Date(moment().format('YYYY-MM-DD'))
        }
        // action after receives date from props
        return range
      }
    }
}

Previously I used value from data() and it didnt work, but when value comes from props it works and also works on props change

If you set value for dateRange manually, inside a method lets say. This will trigger which I don't want to happen.

parthjani7 commented 2 years ago

This is how I did, In case someone encounter the same problem:

<vc-date-picker
  v-model="range"
  mode="date"
  is-range
  :max-date="new Date()"
>
<template v-slot="{ inputValue, inputEvents, updateValue }">
....
<button @click="updateValue(quickFilter(30, 'days'))">
...
</template>
</vc-date-picker>

Here, quickFilter returns object containing start and end properties.

quickFilter(amount, time) {
  return {
      start: this.$moment().subtract(amount, time).toDate(),
      end: new Date()
  };
},
dapobelieve commented 2 years ago

call this.$forceUpdate()

ataldev commented 2 years ago

If you still can't fix it. This must work. If you update the range data using a method it will not re-render the Date-Picker component. So an easy fix is to add a key to the Date-Picker component and change the key every time you change the date from the method.

<Date-Picker
  :key="datePickerKey"
  v-model="range"
  is-range
/>
data(){
    datePickerKey: 0,
}

methods: {
    resetRange() {
      this.range.start = null  //or a date
      this.range.end = null // or a date
      this.calendarKey++;
    },
}
kokiok3 commented 1 year ago

@parthjani7 this answer is awesome! Thank you

GicaGashy commented 1 year ago

If you still can't fix it. This must work. If you update the range data using a method it will not re-render the Date-Picker component. So an easy fix is to add a key to the Date-Picker component and change the key every time you change the date from the method.

<Date-Picker
  :key="datePickerKey"
  v-model="range"
  is-range
/>
data(){
    datePickerKey: 0,
}

methods: {
    resetRange() {
      this.range.start = null  //or a date
      this.range.end = null // or a date
      this.calendarKey++;
    },
}

Yes definitely did the trick. However I do not like the fact that it is not updating automatically.

ddelilah commented 1 year ago

Has anyone found a solution for updating the date picker selection after the model in changed in the code? I am using version 2.4.1 and nothing seems to help for resetting a range input. @najuste's version works if I pass in some dates to update, but not if I try to reset (so the dates would be null).

ataldev commented 1 year ago

Did you try adding a key to the DatePicker component, and updating it, when the data changes in the model?

ddelilah commented 1 year ago

Yes, but it doesn't even render the datepicker from the slot (I have a button from where I am toggling the date picker). The updateValue function does indeed trigger the update of the model, but that doesn't work with null dates and I can't find a fix for resetting the dates after a range was selected.

ataldev commented 1 year ago

Can you create a JSFiddle for your problem? I think that's the only way I can help.

Lehren commented 3 months ago

Having same issue