You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
301 lines
9.4 KiB
301 lines
9.4 KiB
<tiny-datepicker>
|
|
<div class="tiny-datepicker">
|
|
<div class="tiny-datepicker__calendar">
|
|
<div class="tiny-datepicker__date">
|
|
{ state.date.format('dddd, DD. MMMM YYYY') }
|
|
</div>
|
|
|
|
<div class="tiny-datepicker__days">
|
|
<div class="tiny-datepicker__week">
|
|
<div class="tiny-datepicker__day tiny-datepicker__day--header" each={ name in state.weekdaysNames }>
|
|
{ name }
|
|
</div>
|
|
</div>
|
|
<div class="tiny-datepicker__week" each={ week in state.weeks }>
|
|
<div class="{ addClassDay(day, ['tiny-datepicker__day']) }" each={ day in week } onclick={ (event) => { handleSelectDay(event, day) }}>
|
|
{ day.date() }
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="tiny-datepicker__select m-top-3 m-bottom-3">
|
|
<button class="button m-bottom-0 tiny-datepicker__button" onclick={ () => { handlePreviousMonth(event) }}>
|
|
<span class="icon-arrow">❮</span>
|
|
</button>
|
|
<div class="tiny-datepicker__label m-top-3 m-bottom-3">
|
|
<select class="field-choice" onchange={ (event) => { handleSelectMonth(event) }}>
|
|
<option each={ (name, index) in state.monthNames } value={ index } selected={ state.date.month() === index }>{ name }</option>
|
|
</select>
|
|
</div>
|
|
<button class="button m-bottom-0 tiny-datepicker__button" onclick={ () => { handleNextMonth(event) }}>
|
|
<span class="icon-arrow">❯</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="tiny-datepicker__select m-top-3 m-bottom-3">
|
|
<button class="button m-bottom-0 tiny-datepicker__button" onclick={ () => { handlePreviousYear(event) }}>
|
|
<span class="icon-arrow">❮</span>
|
|
</button>
|
|
<div class="tiny-datepicker__label">
|
|
<input class="field-text" value="{ state.date.format('YYYY') }" onkeyup={ (event) => { handleSelectYear(event) }} />
|
|
</div>
|
|
<button class="button m-bottom-0 tiny-datepicker__button" onclick={ () => { handleNextYear(event) }}>
|
|
<span class="icon-arrow">❯</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
// add function for iso
|
|
import isoWeek from 'dayjs/plugin/isoWeek'
|
|
dayjs.extend(isoWeek)
|
|
|
|
// getting local data for names
|
|
import localeData from 'dayjs/plugin/localeData'
|
|
dayjs.extend(localeData)
|
|
|
|
export default {
|
|
/**
|
|
*
|
|
*
|
|
*/
|
|
onBeforeMount() {
|
|
|
|
this.state = {
|
|
date: dayjs(),
|
|
weeks: [],
|
|
|
|
firstDayOfMonth: false,
|
|
firstDayOfWeek: false,
|
|
lastDayOfMonth: false,
|
|
|
|
// getting names for language
|
|
monthNames: dayjs.months(),
|
|
weekdaysNames: dayjs.weekdaysShort(),
|
|
|
|
weekFormat: 'isoWeek',
|
|
|
|
isoFormat: true,
|
|
namespace: ''
|
|
}
|
|
|
|
// check for date prop
|
|
if (this.props.date) {
|
|
this.state.date = dayjs(this.props.date)
|
|
}
|
|
|
|
// check for namespace
|
|
if (this.props.namespace) {
|
|
this.state.namespace = this.props.namespace + '.'
|
|
}
|
|
|
|
// change
|
|
if (this.props.isoFormat === 0) {
|
|
this.state.isoFormat = false
|
|
this.state.weekFormat = 'week'
|
|
} else {
|
|
this.state.weekdaysNames.push(this.state.weekdaysNames.shift())
|
|
}
|
|
|
|
this.props.dispatcher.on('update', (data) => {
|
|
this.state.date = dayjs(data.date)
|
|
})
|
|
|
|
this.props.dispatcher.on('update-props', (data) => {
|
|
this.state.date = dayjs(this.props.date)
|
|
this.update()
|
|
})
|
|
|
|
this.createWeeksAndDays()
|
|
},
|
|
|
|
/**
|
|
* create weeks and days
|
|
*
|
|
*
|
|
*/
|
|
createWeeksAndDays() {
|
|
|
|
this.state.weeks = []
|
|
|
|
// getting first day of Month
|
|
this.state.firstDayOfMonth = this.state.date.startOf('month')
|
|
this.state.firstDayOfWeek = this.state.firstDayOfMonth.startOf(this.state.weekFormat)
|
|
this.state.lastDayOfMonth = this.state.date.endOf('month')
|
|
|
|
const lastDayOfWeek = this.state.lastDayOfMonth.endOf(this.state.weekFormat).startOf('day')
|
|
|
|
let day = this.state.firstDayOfWeek.clone()
|
|
|
|
do {
|
|
day = this.fillWeek(day)
|
|
} while (day.isBefore(lastDayOfWeek))
|
|
},
|
|
|
|
/**
|
|
* fill week with days
|
|
*
|
|
* @param {object} day
|
|
*
|
|
*/
|
|
fillWeek(day) {
|
|
|
|
const days = []
|
|
|
|
days.push(day)
|
|
|
|
do {
|
|
day = day.add(1, 'day')
|
|
days.push(day)
|
|
} while (days.length <= 6)
|
|
|
|
this.state.weeks.push(days)
|
|
|
|
// raise day for start of week
|
|
return day.add(1, 'day')
|
|
},
|
|
|
|
/**
|
|
* select single day
|
|
*
|
|
* @param {object} event
|
|
* @param {object} day
|
|
*
|
|
*/
|
|
handleSelectDay(event, day) {
|
|
if (day.isSame(this.state.date)) {
|
|
return false
|
|
}
|
|
|
|
this.trigger('select-day')
|
|
|
|
this.state.date = day
|
|
this.update()
|
|
},
|
|
|
|
/**
|
|
* select month
|
|
*
|
|
* @param {object} event
|
|
*
|
|
*/
|
|
handleSelectMonth(event) {
|
|
this.state.date = this.state.date.month(event.target.value)
|
|
this.createWeeksAndDays()
|
|
this.trigger('select-month')
|
|
|
|
this.update()
|
|
},
|
|
|
|
/**
|
|
* select year
|
|
*
|
|
* @param {object} event
|
|
*
|
|
*/
|
|
handleSelectYear(event) {
|
|
this.state.date = this.state.date.year(event.target.value)
|
|
this.createWeeksAndDays()
|
|
this.trigger('select-year')
|
|
|
|
this.update()
|
|
},
|
|
|
|
/**
|
|
* previous month
|
|
*
|
|
* @param {object} event
|
|
* @param {object} day
|
|
*
|
|
*/
|
|
handlePreviousMonth(event) {
|
|
this.state.date = this.state.date.subtract(1, 'month')
|
|
this.createWeeksAndDays()
|
|
this.trigger('previous-month')
|
|
|
|
this.update()
|
|
},
|
|
|
|
/**
|
|
* next month
|
|
*
|
|
* @param {object} event
|
|
* @param {object} day
|
|
*
|
|
*/
|
|
handleNextMonth(event) {
|
|
this.state.date = this.state.date.add(1, 'month')
|
|
this.createWeeksAndDays()
|
|
this.trigger('next-month')
|
|
|
|
this.update()
|
|
},
|
|
|
|
/**
|
|
* previous year
|
|
*
|
|
* @param {object} event
|
|
*
|
|
*/
|
|
handlePreviousYear(event) {
|
|
this.state.date = this.state.date.subtract(1, 'year')
|
|
this.createWeeksAndDays()
|
|
this.trigger('previous-year')
|
|
|
|
this.update()
|
|
},
|
|
|
|
/**
|
|
* next year
|
|
*
|
|
* @param {object} event
|
|
*
|
|
*/
|
|
handleNextYear(event) {
|
|
this.state.date = this.state.date.add(1, 'year')
|
|
this.createWeeksAndDays()
|
|
this.trigger('next-year')
|
|
|
|
this.update()
|
|
},
|
|
|
|
/**
|
|
* trigger event & change for specific
|
|
*
|
|
*/
|
|
trigger(eventName) {
|
|
const data = {
|
|
'date': this.state.date.clone()
|
|
}
|
|
|
|
this.props.dispatcher.trigger(this.state.namespace + eventName, data)
|
|
this.props.dispatcher.trigger(this.state.namespace + 'change', data)
|
|
},
|
|
|
|
/**
|
|
* getting classes for single day
|
|
*
|
|
* @param {object} event
|
|
* @param {array} classes
|
|
* @return {string}
|
|
*/
|
|
addClassDay(day, classes) {
|
|
|
|
if (day.isSame(this.state.date, 'day')) {
|
|
classes.push('tiny-datepicker__day--current')
|
|
}
|
|
|
|
if (day.isBefore(this.state.firstDayOfMonth) || day.isAfter(this.state.lastDayOfMonth)) {
|
|
classes.push('tiny-datepicker__day--not-current')
|
|
}
|
|
|
|
return classes.join(' ')
|
|
}
|
|
}
|
|
</script>
|
|
</tiny-datepicker>
|