Check out this new solution: https://jsfiddle.net/ghLmnm2c/483/
After further consideration, I decided to revisit an older approach that was initially mentioned when I first attempted to assist you. I removed the computed properties as they may have been affecting the component rendering process. Instead, I replicated the functionality using the plugin's event emitters and added a watcher on the interval plugin to achieve the same functionality.
Below is what the HTML structure looks like:
Start Date: <date-picker v-model="startDate" :config="config" @dp-change="updateEndDateInterval"></date-picker>
End Date: <date-picker v-model="endDate" :config="config" @dp-update="updateInterval"></date-picker>
Interval: <input class="form-control" type="text" v-model="interval" @keyup="updateEndDate">
It was determined that only the start date and the interval inputs would affect the end date.
Here are the methods used:
methods: {
updateEndDateInterval: function() {
this.updateEndDate(); // this automatically triggers updateInterval due to @dp-change="updateInterval" on the end date component
},
updateEndDate: function() {
this.endDate = moment(this.startDate).add(this.interval * this.periods, 'days');
},
updateInterval: function(v) {
if (this.periods > 0) {
var dateVal = "";
if (v.target) {
dateVal = v.target.value;
} else {
dateVal = v;
}
this.interval = (moment(dateVal).diff(this.startDate, 'days')+1) / this.periods;
}
}
}
The updateInterval function accepts a 'v' parameter, which will receive the moment object passed from updateEndDateInterval or the event object when changing the interval value. Passing in this.endDate from the interval textbox would create a circular reference, causing the interval to update the end date and vice versa indefinitely.
Moreover, it is necessary to ensure that the endDate property is reactive:
data: {
interval: 7,
startDate: moment(),
endDate: '' // keep this property empty
}
Upon loading the component, update the endDate property to match the start date value (as defined in updateEndDate):
mounted: function(){
this.updateEndDate();
}
After verifying all functionalities against your previous fiddle and checking for reactivity, it appears that this strategy, utilizing the recommended plugin methods, is preferable. There were no indications of computed properties being used in the examples, making the implementation more modular and allowing for easier adjustments without inadvertently affecting other components.
Initially, I considered using a Vue watcher on the interval textbox triggering the updateEndDate function in this manner:
// do not do this
watch: {
interval: function() {
this.updateEndDate()
}
}
This approach is not viable due to the circular reference issue, leading to a crash in your browser. Hence, I opted for the @keyup event to prevent interference with date selections, ensuring that the updateEndDate function is only triggered by key inputs when altering the interval.
(FIXED)
Addressing the root issue. The problem at hand has been resolved. It was discovered that when solely using computed properties, the underlying issue remained unnoticed, hindering the proper editing of the interval.
When modifying only the end date, the interval calculation formula functions correctly since only the interval is being altered. However, adjusting the start date impacts both the end date and the interval.
Updating the end date first becomes challenging as the interval value becomes outdated, resulting in an incorrect end date calculation. Conversely, reversing the order makes the end date value outdated, rendering the interval value incorrect.
// stale this.interval value as it isn't updated beforehand
this.endDate = moment(this.startDate).add(this.interval * this.periods, 'days').format('DD MMM YYYY');
// utilizing the incorrect this.endDate to compute the incorrect this.interval
this.interval = (moment(this.endDate).diff(this.startDate, 'days')+1) / this.periods;
Attempting to switch the execution order leads to a similar predicament where the stale this.endDate prevents an accurate interval value. Subsequently, using the incorrect interval value results in an incorrect end date.
// stale this.endDate value as it isn't updated beforehand
this.interval = (moment(this.endDate).diff(this.startDate, 'days')+1) / this.periods;
// utilizing the incorrect this.interval to deduce the incorrect this.endDate
this.endDate = moment(this.startDate).add(this.interval * this.periods, 'days').format('DD MMM YYYY');