【发布时间】:2019-08-03 08:26:03
【问题描述】:
我正在尝试解决 Vue JS 申请表的支付频率<select> 的问题。为了稍微解释一下我所拥有的,我将在此处添加一些上下文。
有一个申请表,带有一个<select> 框,其中包含一些选项供用户选择下一次付款的时间,例如:每月最后一个工作日、每周、每两周、每月最后一个星期一,每个月的最后一个星期二等,我将在下面列出可用的选项。
用户选择适当的<option> 并自动计算他们的下一个和下一个付款日期,例如:下一个付款:30/08/2019,下一个付款:27/09/2019。如果愿意,用户可以选择编辑这些字段。
下一个付款日期有 3 个输入字段,下一个付款日期有 3 个输入字段,(DD/MM/YYYY) 字段。
我遇到的问题与每个月的最后周的支付频率选项有关,例如:每月的最后一个星期一,每月的最后一个星期二,一直到到星期五。问题是,例如,如果我在本月的最后一个星期四,假设日期是 29/08/2019,然后我选择选项本月的最后一个星期一,而不是自动将 1 个月添加到月份字段,它停留在当前月份,这是不正确的,因为您不能有过去的下一个付款日期。
我正在使用 Moment JS,版本 2.24.0,并使用 Vue JS 版本 2.6.10,还有包 vee-validate 用于已设置的验证。
我有一些方法可以确定用户的下一个和下一个支付日期,下面列出的payFrequencyChange 方法计算用户可以从中选择的每个可用支付频率选项。我试过检查代码,它似乎应该根据日期正确计算 month 字段,但不是。
这是有问题的代码:
new Vue({
el: '#application-form',
data: {
frequency: [{ value: 0, name: 'Last working day of month' }, { value: 1, name: 'Weekly' }, { value: 2, name: 'Four weekly' }, { value: 10, name: 'Specific Date' }, { value: 3, name: 'Bi-Weekly' }, { value: 9, name: 'Last Friday of month' }, { value: 5, name: 'Last Monday of month' }, { value: 6, name: 'Last Tuesday of month' }, { value: 7, name: 'Last Wednesday of month' }, { value: 8, name: 'Last Thursday of month' }],
NextPaydateError: false,
FollowingPaydateError: false,
formData: {
EmpPayFrequency: '',
NextPaydate: '',
FollowingPaydate: '',
NextPaydateDay: '',
NextPaydateMonth: '',
NextPaydateYear: '',
FollowingPaydateDay: '',
FollowingPaydateMonth: '',
FollowingPaydateYear: ''
}
},
methods: {
/**
* Switch fields
*/
switchToField(fieldSwitchName, fieldValue, fieldLength) {
if (String(fieldValue).length >= fieldLength) {
this.$refs[fieldSwitchName].focus();
}
},
/**
* Leading Zero
* @param {int} input
* @param {bool} years
*/
leadingZeros: function leadingZeros(input, years = false) {
if (!years) {
if (String(input).length === 1) return '0' + input
} else {
if (String(input).length === 2) {
if (parseInt(input) > 50 && parseInt(input) < 100) {
return '19' + input
}
}
}
return input
},
/**
* Next Pay Date Change
*/
nextPayDateChange: function nextPayDateChange() {
string = this.formData.NextPaydateYear + '-' + this.formData.NextPaydateMonth + '-' + this.formData.NextPaydateDay
date = moment(string).format('DD/MM/YYYY')
if (this.formData.NextPaydateYear === '') return
this.NextPaydateError = (date === 'Invalid date') ? true : false
this.formData.NextPaydate = date
},
/**
* Following Pay Date Change
*/
followingPayDateChange: function followingPayDateChange() {
nextDate = this.formData.NextPaydateYear + '-' + this.formData.NextPaydateMonth + '-' + this.formData.NextPaydateDay
followingDate = this.formData.FollowingPaydateYear + '-' + this.formData.FollowingPaydateMonth + '-' + this.formData.FollowingPaydateDay
if (!moment(followingDate).isAfter(moment(nextDate))) {
this.FollowingPaydateError = true
return
}
date = moment(followingDate).format('DD/MM/YYYY')
if (this.formData.FollowingPaydateYear === '') return
this.FollowingPaydateError = (date === 'Invalid date') ? true : false
this.formData.FollowingPaydate = date
},
/**
* Find Last Working Day
* @param {bool} nextMonth
*/
lastBusinessDay: function lastBusinessDay(nextMonth) {
dateOffset = {
'Saturday': 1,
'Sunday': 2
}
currentDate = new Date()
date = new Date(currentDate.getFullYear(), currentDate.getMonth() + (nextMonth ? 2 : 1), 0)
lastDay = date.toLocaleString('en-GB', {
day: 'numeric'
})
lastWeekday = date.toLocaleString('en-GB', {
weekday: 'long',
})
return dateOffset[lastWeekday] ? lastDay - dateOffset[lastWeekday] : lastDay
},
/**
* Find Last Weekday
* @param {object} monthMoment
* @param {int} dayInt
*/
lastWeekdayOfMonth: function weekly(monthMoment, dayInt) {
var lastDay = monthMoment.endOf('month').startOf('day')
for (let i = 0; i <= 10; i++) {
if (lastDay.day() === dayInt) {
return lastDay
} else {
lastDay.subtract(1, 'days')
}
}
},
/**
* Weekly Workouts
*/
weekly: function weekly(year, month, date, day) {
date = new Date()
offset = 4
result = null
if ('undefined' === typeof day || null === day) {
day = 5
}
if ('undefined' === typeof year || null === year) {
year = date.getFullYear()
}
if ('undefined' === typeof month || null === month) {
month = date.getMonth()
}
do {
result = new Date(year, month, date.getDate() + offset)
offset++
} while (result.getDay() !== day)
return result
},
/**
* Pay Frequency Change
* @param {int} value
*/
payFrequencyChange: function payFrequencyChange(value) {
var elems = document.querySelectorAll('.dobbox.is-invalid')
if (typeof elems === 'object') {
elems.forEach.call(elems, function(el) {
el.classList.remove('is-invalid')
});
}
currentDate = new Date()
switch (parseInt(value)) {
case 0: // last working day
next = {
day: this.lastBusinessDay(false),
month: currentDate.getMonth() + 1,
year: currentDate.getFullYear()
}
following = {
day: this.lastBusinessDay(true),
month: ((currentDate.getMonth() + 2) === 13) ? 1 : currentDate.getMonth() + 2,
year: ((currentDate.getMonth() + 2) === 13) ? currentDate.getFullYear() + 1 : currentDate.getFullYear()
}
break
case 1: // weekly
next = this.weekly(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate(), 5)
follow = new Date(this.weekly(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate(), 5))
following = follow.setDate(follow.getDate() + 7)
next = {
day: moment(next).format('DD'),
month: moment(next).format('MM'),
year: moment(next).format('YYYY')
}
following = {
day: moment(following).format('DD'),
month: moment(following).format('MM'),
year: moment(following).format('YYYY')
}
break
case 2: // four weekly
next = this.weekly(currentDate.getFullYear(),currentDate.getMonth(), currentDate.getDate() + 4)
d = new Date(this.weekly(currentDate.getFullYear(),currentDate.getMonth(), currentDate.getDate() + 4))
d.setDate(d.getDate() + 28)
following = d
next = {
day: moment(next).format('DD'),
month: moment(next).format('MM'),
year: moment(next).format('YYYY')
}
following = {
day: moment(following).format('DD'),
month: moment(following).format('MM'),
year: moment(following).format('YYYY')
}
break
case 10: // specific date
next = { day: '', month: '', year: '' }
following = { day: '', month: '', year: '' }
break
case 3: // bi-weekly
next = { day: '', month: '', year: '' }
following = { day: '', month: '', year: '' }
break
case 9: // last friday
next = this.lastWeekdayOfMonth(moment(), 5)
following = this.lastWeekdayOfMonth(moment().add(1, 'months'), 5)
next = {
day: moment(next).format('DD'),
month: moment(next).format('MM'),
year: moment(next).format('YYYY')
}
following = {
day: moment(following).format('DD'),
month: moment(following).format('MM'),
year: moment(following).format('YYYY')
}
break
case 8: // last thursday
next = this.lastWeekdayOfMonth(moment(), 4)
following = this.lastWeekdayOfMonth(moment().add(1, 'months'), 4)
next = {
day: moment(next).format('DD'),
month: moment(next).format('MM'),
year: moment(next).format('YYYY')
}
following = {
day: moment(following).format('DD'),
month: moment(following).format('MM'),
year: moment(following).format('YYYY')
}
break
case 7: // last wednesday
next = this.lastWeekdayOfMonth(moment(), 3)
following = this.lastWeekdayOfMonth(moment().add(1, 'months'), 3)
next = {
day: moment(next).format('DD'),
month: moment(next).format('MM'),
year: moment(next).format('YYYY')
}
following = {
day: moment(following).format('DD'),
month: moment(following).format('MM'),
year: moment(following).format('YYYY')
}
break
case 6: // last tuesday
next = this.lastWeekdayOfMonth(moment(), 2)
following = this.lastWeekdayOfMonth(moment().add(1, 'months'), 2)
next = {
day: moment(next).format('DD'),
month: moment(next).format('MM'),
year: moment(next).format('YYYY')
}
following = {
day: moment(following).format('DD'),
month: moment(following).format('MM'),
year: moment(following).format('YYYY')
}
break
case 5: // last monday
next = this.lastWeekdayOfMonth(moment(), 1)
following = this.lastWeekdayOfMonth(moment().add(1, 'months'), 1)
next = {
day: moment(next).format('DD'),
month: moment(next).format('MM'),
year: moment(next).format('YYYY')
}
following = {
day: moment(following).format('DD'),
month: moment(following).format('MM'),
year: moment(following).format('YYYY')
}
break
}
// Populate new dates
this.formData.NextPaydateDay = this.leadingZeros(next.day)
this.formData.NextPaydateYear = next.year
this.formData.NextPaydateMonth = this.leadingZeros(next.month)
this.formData.FollowingPaydateDay = this.leadingZeros(following.day)
this.formData.FollowingPaydateYear = following.year
this.formData.FollowingPaydateMonth = this.leadingZeros(following.month)
setTimeout(function () { // Prevent validation errors
this.NextPaydateError = this.FollowingPaydateError = false
}.bind(this), 10)
}
},
watch: {
'formData.NextPaydateYear': function formDataNextPaydateYear() {
this.nextPayDateChange()
},
'formData.FollowingPaydateYear': function formDataFollowingPaydateYear() {
this.followingPayDateChange()
}
}
})
因此,有了上述内容,一切都会很好,因为它是月初,它应该增量下个月,然后递增一个月的字段,但在上周五选择时,它应该留在当月,除非它在月底前3天,那么它也应该增加。
我知道这需要接受很多,因此另外准备了一支代码笔:
https://codepen.io/sts-ryan-holton/pen/rXGzox
这里将不胜感激,这不是我写的东西,所以不能完全 100% 确定如何修复/添加这一关键功能。
【问题讨论】:
标签: javascript datetime vue.js vuejs2 momentjs