beyond-rails 0.0.139
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/src/font/icomoon.eot +0 -0
- data/src/font/icomoon.svg +125 -0
- data/src/font/icomoon.ttf +0 -0
- data/src/font/icomoon.woff +0 -0
- data/src/img/black-cat.svg +15 -0
- data/src/img/cart.svg +16 -0
- data/src/img/china-flag.svg +16 -0
- data/src/img/ecpay.svg +12 -0
- data/src/img/family-mart.svg +13 -0
- data/src/img/fb-messenger.svg +12 -0
- data/src/img/fb.svg +10 -0
- data/src/img/hct.svg +16 -0
- data/src/img/hi-life.svg +23 -0
- data/src/img/line.svg +14 -0
- data/src/img/ok-mart.svg +9 -0
- data/src/img/pelican.svg +33 -0
- data/src/img/seven-eleven.svg +13 -0
- data/src/img/smilepay.svg +13 -0
- data/src/img/taiwan-flag.svg +17 -0
- data/src/js/components/Alert.js +23 -0
- data/src/js/components/Autocomplete.js +110 -0
- data/src/js/components/AutocompleteMenu.js +88 -0
- data/src/js/components/Btn.js +41 -0
- data/src/js/components/Checkbox.js +24 -0
- data/src/js/components/DateInput.js +74 -0
- data/src/js/components/DateMenu.js +370 -0
- data/src/js/components/DateTimeRanger.js +436 -0
- data/src/js/components/Datepicker.js +250 -0
- data/src/js/components/DatepickerBtnArrow.js +18 -0
- data/src/js/components/Dropdown.js +137 -0
- data/src/js/components/Menu.js +43 -0
- data/src/js/components/Modal.js +76 -0
- data/src/js/components/Navbar.js +47 -0
- data/src/js/components/Radio.js +24 -0
- data/src/js/components/SearchDropdown.js +339 -0
- data/src/js/components/Sidebar.js +56 -0
- data/src/js/components/Tabbox.js +229 -0
- data/src/js/components/TimeInput.js +71 -0
- data/src/js/components/TimeMenu.js +117 -0
- data/src/js/components/Toast.js +47 -0
- data/src/js/components/ToastItem.js +62 -0
- data/src/js/components/Tooltip.js +94 -0
- data/src/js/consts/createdComponents.js +1 -0
- data/src/js/consts/index.js +5 -0
- data/src/js/helpers/bind.js +53 -0
- data/src/js/helpers/dateEq.js +5 -0
- data/src/js/helpers/dateGt.js +5 -0
- data/src/js/helpers/dateLt.js +5 -0
- data/src/js/helpers/docReady.js +10 -0
- data/src/js/helpers/getFloatedTargetPos.js +250 -0
- data/src/js/helpers/getKey.js +14 -0
- data/src/js/helpers/isTouchDevice.js +3 -0
- data/src/js/helpers/msToS.js +3 -0
- data/src/js/helpers/promisify.js +9 -0
- data/src/js/helpers/range.js +7 -0
- data/src/js/helpers/supportDom.js +46 -0
- data/src/js/helpers/toPixel.js +3 -0
- data/src/js/helpers/unbindAll.js +6 -0
- data/src/js/index.js +47 -0
- data/src/js/jquery/bindAlertFn.js +13 -0
- data/src/js/jquery/bindAutocompleteFn.js +13 -0
- data/src/js/jquery/bindBtnFn.js +17 -0
- data/src/js/jquery/bindCheckboxFn.js +13 -0
- data/src/js/jquery/bindDateTimeRangerFn.js +14 -0
- data/src/js/jquery/bindDatepickerFn.js +14 -0
- data/src/js/jquery/bindDropdownFn.js +14 -0
- data/src/js/jquery/bindMenuFn.js +13 -0
- data/src/js/jquery/bindModalFn.js +14 -0
- data/src/js/jquery/bindNavbarFn.js +13 -0
- data/src/js/jquery/bindRadioFn.js +13 -0
- data/src/js/jquery/bindSearchDropdownFn.js +14 -0
- data/src/js/jquery/bindSidebarFn.js +13 -0
- data/src/js/jquery/bindTabboxFn.js +13 -0
- data/src/js/jquery/bindToastFn.js +6 -0
- data/src/js/jquery/bindTooltipFn.js +13 -0
- data/src/js/jquery/index.js +52 -0
- data/src/js/polyfills/classList.js +263 -0
- data/src/js/polyfills/elementDataset.js +3 -0
- data/src/js/polyfills/nodeContains.js +17 -0
- data/src/js/polyfills/nodeHasAttribute.js +5 -0
- data/src/js/polyfills/nodeRemove.js +19 -0
- data/src/sass/_beyond-sprockets.scss +1 -0
- data/src/sass/_beyond.scss +50 -0
- data/src/sass/_main.scss +141 -0
- data/src/sass/abstracts/_mixins.scss +129 -0
- data/src/sass/abstracts/_placeholders.scss +43 -0
- data/src/sass/abstracts/_variables.scss +355 -0
- data/src/sass/base/_background.scss +10 -0
- data/src/sass/base/_typography.scss +183 -0
- data/src/sass/components/_alert.scss +50 -0
- data/src/sass/components/_autocomplete.scss +29 -0
- data/src/sass/components/_avatar.scss +28 -0
- data/src/sass/components/_badge.scss +29 -0
- data/src/sass/components/_breadcrumb.scss +17 -0
- data/src/sass/components/_btn-group.scss +19 -0
- data/src/sass/components/_btn.scss +172 -0
- data/src/sass/components/_card.scss +183 -0
- data/src/sass/components/_checkbox.scss +99 -0
- data/src/sass/components/_date-input.scss +28 -0
- data/src/sass/components/_date-menu.scss +85 -0
- data/src/sass/components/_date-time-ranger.scss +21 -0
- data/src/sass/components/_datepicker.scss +3 -0
- data/src/sass/components/_dropdown.scss +144 -0
- data/src/sass/components/_form.scss +383 -0
- data/src/sass/components/_icon.scss +371 -0
- data/src/sass/components/_input.scss +48 -0
- data/src/sass/components/_list.scss +23 -0
- data/src/sass/components/_modal.scss +72 -0
- data/src/sass/components/_nav.scss +75 -0
- data/src/sass/components/_navbar.scss +211 -0
- data/src/sass/components/_pagination.scss +64 -0
- data/src/sass/components/_radio.scss +71 -0
- data/src/sass/components/_search-dropdown.scss +28 -0
- data/src/sass/components/_select.scss +54 -0
- data/src/sass/components/_sidebar.scss +35 -0
- data/src/sass/components/_spinner.scss +79 -0
- data/src/sass/components/_tabbox.scss +83 -0
- data/src/sass/components/_table.scss +65 -0
- data/src/sass/components/_tag.scss +43 -0
- data/src/sass/components/_time-input.scss +28 -0
- data/src/sass/components/_time-menu.scss +24 -0
- data/src/sass/components/_toast.scss +51 -0
- data/src/sass/components/_tooltip.scss +10 -0
- data/src/sass/img/arrow-dropdown.svg +4 -0
- data/src/sass/img/arrow-select-ex.svg +18 -0
- data/src/sass/img/arrow-select.svg +18 -0
- data/src/sass/layout/_border-util.scss +36 -0
- data/src/sass/layout/_col.scss +90 -0
- data/src/sass/layout/_container.scss +44 -0
- data/src/sass/layout/_flex-util.scss +18 -0
- data/src/sass/layout/_offset-util.scss +20 -0
- data/src/sass/layout/_sizing-util.scss +14 -0
- data/src/sass/layout/_spacing-util.scss +9 -0
- data/src/sass/layout/_visibility-util.scss +25 -0
- data/src/sass/vendor/_normalize.scss +578 -0
- data/src/sass/vendor/_turbolink.scss +5 -0
- metadata +235 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
import getFloatedTargetPos from '../helpers/getFloatedTargetPos'
|
2
|
+
import toPixel from '../helpers/toPixel'
|
3
|
+
import supportDom from '../helpers/supportDom'
|
4
|
+
|
5
|
+
@supportDom
|
6
|
+
export default class AutocompleteMenu {
|
7
|
+
|
8
|
+
constructor(options = {}) {
|
9
|
+
this.options = options
|
10
|
+
this.isVisible = false
|
11
|
+
this.lastSrc = null
|
12
|
+
this.init()
|
13
|
+
}
|
14
|
+
|
15
|
+
init() {
|
16
|
+
this.addMenu()
|
17
|
+
this.addEvents()
|
18
|
+
}
|
19
|
+
|
20
|
+
pos(src) {
|
21
|
+
const offsetLeft = this.options.offsetLeft || 0
|
22
|
+
const offsetTop = this.options.offsetTop || 0
|
23
|
+
const { pos } = getFloatedTargetPos({
|
24
|
+
src,
|
25
|
+
target: this.dom,
|
26
|
+
place: 'bottom',
|
27
|
+
align: 'left',
|
28
|
+
offset: 3,
|
29
|
+
offsetLeft,
|
30
|
+
offsetTop
|
31
|
+
})
|
32
|
+
this.dom.style.left = toPixel(pos.left)
|
33
|
+
this.dom.style.top = toPixel(pos.top)
|
34
|
+
this.lastSrc = src
|
35
|
+
}
|
36
|
+
|
37
|
+
show(src) {
|
38
|
+
this.dom.style.opacity = 0
|
39
|
+
this.dom.style.display = 'block'
|
40
|
+
this.pos(src)
|
41
|
+
this.dom.style.opacity = 1
|
42
|
+
this.isVisible = true
|
43
|
+
}
|
44
|
+
|
45
|
+
hide() {
|
46
|
+
this.dom.style.display = 'none'
|
47
|
+
this.isVisible = false
|
48
|
+
}
|
49
|
+
|
50
|
+
addMenu() {
|
51
|
+
const dom = document.createElement('div')
|
52
|
+
dom.className = 'autocomplete-menu'
|
53
|
+
dom.style.display = 'none'
|
54
|
+
document.body.appendChild(dom)
|
55
|
+
this.dom = dom
|
56
|
+
}
|
57
|
+
|
58
|
+
renderMenuItem(rows, renderFunc) {
|
59
|
+
const nodes = rows.map(row => renderFunc(row))
|
60
|
+
const html = nodes.map(node => {
|
61
|
+
if ((typeof node === 'object') && ('outerHTML' in node)) {
|
62
|
+
return node.outerHTML
|
63
|
+
}
|
64
|
+
return node
|
65
|
+
}).join('')
|
66
|
+
this.dom.innerHTML = html
|
67
|
+
}
|
68
|
+
|
69
|
+
addEvents() {
|
70
|
+
this.addEvent(this.dom, 'click', event => {
|
71
|
+
let node = event.target
|
72
|
+
while (node.parentNode !== this.dom) {
|
73
|
+
node = node.parentNode
|
74
|
+
}
|
75
|
+
const index = Array.from(this.dom.children).indexOf(node)
|
76
|
+
this.fire('click', index)
|
77
|
+
})
|
78
|
+
this.addEvent(window, 'resize', () => {
|
79
|
+
if (this.isVisible && this.lastSrc) {
|
80
|
+
this.pos(this.lastSrc)
|
81
|
+
}
|
82
|
+
})
|
83
|
+
}
|
84
|
+
|
85
|
+
destroy() {
|
86
|
+
this.dom.remove()
|
87
|
+
}
|
88
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import supportDom from '../helpers/supportDom'
|
2
|
+
import toPixel from '../helpers/toPixel'
|
3
|
+
|
4
|
+
@supportDom
|
5
|
+
export default class Btn {
|
6
|
+
|
7
|
+
constructor(dom) {
|
8
|
+
this.dom = dom
|
9
|
+
this.loading = false
|
10
|
+
this.init()
|
11
|
+
}
|
12
|
+
|
13
|
+
showLoader() {
|
14
|
+
const { dom } = this
|
15
|
+
this._innerHtml = dom.innerHTML
|
16
|
+
dom.style.height = toPixel(dom.offsetHeight)
|
17
|
+
dom.style.width = toPixel(dom.offsetWidth)
|
18
|
+
dom.innerHTML = `
|
19
|
+
<div class="btn-loader">
|
20
|
+
<div class="ring-loader">
|
21
|
+
<div></div>
|
22
|
+
<div></div>
|
23
|
+
<div></div>
|
24
|
+
<div></div>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
`
|
28
|
+
}
|
29
|
+
|
30
|
+
hideLoader() {
|
31
|
+
const { dom } = this
|
32
|
+
dom.style.removeProperty('width')
|
33
|
+
dom.style.removeProperty('height')
|
34
|
+
dom.innerHTML = this._innerHtml
|
35
|
+
}
|
36
|
+
|
37
|
+
setLoading(loading) {
|
38
|
+
this.loading = loading
|
39
|
+
loading ? this.showLoader() : this.hideLoader()
|
40
|
+
}
|
41
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import supportDom from '../helpers/supportDom'
|
2
|
+
|
3
|
+
@supportDom
|
4
|
+
export default class Checkbox {
|
5
|
+
|
6
|
+
constructor(dom) {
|
7
|
+
this.dom = dom
|
8
|
+
this.init()
|
9
|
+
}
|
10
|
+
|
11
|
+
init() {
|
12
|
+
const { dom } = this
|
13
|
+
this.addEvent(dom, 'focus', this.handleFocus)
|
14
|
+
this.addEvent(dom, 'blur', this.handleBlur)
|
15
|
+
}
|
16
|
+
|
17
|
+
handleFocus() {
|
18
|
+
this.parentNode.classList.add('focus')
|
19
|
+
}
|
20
|
+
|
21
|
+
handleBlur() {
|
22
|
+
this.parentNode.classList.remove('focus')
|
23
|
+
}
|
24
|
+
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import { format } from 'date-fns-tz'
|
2
|
+
import { DEFAULT_TIMEZONE } from '../consts'
|
3
|
+
import supportDom from '../helpers/supportDom'
|
4
|
+
import isTouchDevice from '../helpers/isTouchDevice'
|
5
|
+
|
6
|
+
@supportDom
|
7
|
+
export default class DateInput {
|
8
|
+
|
9
|
+
constructor(dom, date, options = {}) {
|
10
|
+
this.active = false
|
11
|
+
this.danger = false
|
12
|
+
this.dom = dom
|
13
|
+
this.date = date
|
14
|
+
this.options = options
|
15
|
+
this.tz = options.tz || DEFAULT_TIMEZONE
|
16
|
+
this.datePattern = options.datePattern || 'yyyy/MM/dd'
|
17
|
+
this.init()
|
18
|
+
}
|
19
|
+
|
20
|
+
focus() {
|
21
|
+
this.dom.focus()
|
22
|
+
}
|
23
|
+
|
24
|
+
init() {
|
25
|
+
this.initInput()
|
26
|
+
this.addEvents()
|
27
|
+
}
|
28
|
+
|
29
|
+
initInput() {
|
30
|
+
const { dom } = this
|
31
|
+
if (this.date) {
|
32
|
+
dom.value = this.format(this.date)
|
33
|
+
}
|
34
|
+
if (! dom.hasAttribute('placeholder')) {
|
35
|
+
dom.setAttribute('placeholder', this.datePattern.toUpperCase())
|
36
|
+
}
|
37
|
+
if (isTouchDevice()) {
|
38
|
+
dom.setAttribute('readonly', 'readonly')
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
format(date) {
|
43
|
+
return format(date, this.datePattern, { timezone: this.tz })
|
44
|
+
}
|
45
|
+
|
46
|
+
setDate(date) {
|
47
|
+
this.date = date
|
48
|
+
this.dom.value = date ? this.format(date) : ''
|
49
|
+
}
|
50
|
+
|
51
|
+
setActive(active) {
|
52
|
+
this.active = active
|
53
|
+
const func = active ? 'add' : 'remove'
|
54
|
+
this.dom.classList[func]('active')
|
55
|
+
}
|
56
|
+
|
57
|
+
setDanger(danger) {
|
58
|
+
this.danger = danger
|
59
|
+
const func = danger ? 'add' : 'remove'
|
60
|
+
this.dom.classList[func]('danger')
|
61
|
+
}
|
62
|
+
|
63
|
+
clearStatus() {
|
64
|
+
this.setActive(false)
|
65
|
+
this.setDanger(false)
|
66
|
+
}
|
67
|
+
|
68
|
+
addEvents() {
|
69
|
+
const { dom } = this
|
70
|
+
this.addEvent(dom, 'focus', event => this.fire('focus', event))
|
71
|
+
this.addEvent(dom, 'keyup', event => this.fire('keyup', event))
|
72
|
+
this.addEvent(dom, 'blur', event => this.fire('blur', event))
|
73
|
+
}
|
74
|
+
}
|
@@ -0,0 +1,370 @@
|
|
1
|
+
import { format } from 'date-fns-tz'
|
2
|
+
import addDays from 'date-fns/addDays'
|
3
|
+
import set from 'date-fns/set'
|
4
|
+
import addMonths from 'date-fns/addMonths'
|
5
|
+
import compareAsc from 'date-fns/compareAsc'
|
6
|
+
import endOfMonth from 'date-fns/endOfMonth'
|
7
|
+
import getDay from 'date-fns/getDay'
|
8
|
+
import getDaysInMonth from 'date-fns/getDaysInMonth'
|
9
|
+
import getMonth from 'date-fns/getMonth'
|
10
|
+
import getYear from 'date-fns/getYear'
|
11
|
+
import startOfDay from 'date-fns/startOfDay'
|
12
|
+
import startOfMonth from 'date-fns/startOfMonth'
|
13
|
+
import subMonths from 'date-fns/subMonths'
|
14
|
+
import getFloatedTargetPos from '../helpers/getFloatedTargetPos'
|
15
|
+
import range from '../helpers/range'
|
16
|
+
import toPixel from '../helpers/toPixel'
|
17
|
+
import isTouchDevice from '../helpers/isTouchDevice'
|
18
|
+
import dateLt from '../helpers/dateLt'
|
19
|
+
import dateEq from '../helpers/dateEq'
|
20
|
+
import { DEFAULT_TIMEZONE, DEFAULT_LOCALE } from '../consts'
|
21
|
+
import supportDom from '../helpers/supportDom'
|
22
|
+
import throttle from 'lodash.throttle'
|
23
|
+
|
24
|
+
const DEFAULT_WEEK_HEADER_ITEMS = [
|
25
|
+
{ id: 'monday', text: '一' },
|
26
|
+
{ id: 'tuesday', text: '二' },
|
27
|
+
{ id: 'wednesday', text: '三' },
|
28
|
+
{ id: 'thursday', text: '四' },
|
29
|
+
{ id: 'friday', text: '五' },
|
30
|
+
{ id: 'saturday', text: '六' },
|
31
|
+
{ id: 'sunday', text: '日' }
|
32
|
+
]
|
33
|
+
|
34
|
+
const CELL_TYPE_EMPTY = Symbol('CELL_TYPE_EMPTY')
|
35
|
+
const CELL_TYPE_DAY = Symbol('CELL_TYPE_DAY')
|
36
|
+
|
37
|
+
@supportDom
|
38
|
+
export default class DateMenu {
|
39
|
+
|
40
|
+
constructor({ date, startDate, endDate, options = {} }) {
|
41
|
+
this.date = date
|
42
|
+
this.date2 = addMonths(date, 1)
|
43
|
+
this.startDate = startDate
|
44
|
+
this.endDate = endDate
|
45
|
+
this.hoveredCellData = null
|
46
|
+
this.options = options
|
47
|
+
this.tz = options.tz || DEFAULT_TIMEZONE
|
48
|
+
this.locale = options.locale || DEFAULT_LOCALE
|
49
|
+
this.captionPattern = options.captionPattern || 'yyyy MMMM'
|
50
|
+
this.weekHeaderItems = options.weekHeaderItems || DEFAULT_WEEK_HEADER_ITEMS
|
51
|
+
this.isVisible = false
|
52
|
+
this.init()
|
53
|
+
}
|
54
|
+
|
55
|
+
init() {
|
56
|
+
this.addMenu()
|
57
|
+
this.addEvents()
|
58
|
+
}
|
59
|
+
|
60
|
+
useSingleMenu() {
|
61
|
+
return isTouchDevice() || this.options.useSingleMenu
|
62
|
+
}
|
63
|
+
|
64
|
+
setHoveredCell(data) {
|
65
|
+
const dataChanged = JSON.stringify(data) !== JSON.stringify(this.hoveredCellData)
|
66
|
+
if (dataChanged && (! this.endDate)) {
|
67
|
+
this.hoveredCellData = data
|
68
|
+
this.drawTables()
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
getTableRows(date) {
|
73
|
+
|
74
|
+
const { startDate, endDate } = this
|
75
|
+
|
76
|
+
const daysInMonth = getDaysInMonth(date)
|
77
|
+
const firstDateOfMonth = startOfMonth(date)
|
78
|
+
const toEmptyCell = () => ({ type: CELL_TYPE_EMPTY })
|
79
|
+
|
80
|
+
const firstWeekday = getDay(startOfMonth(date))
|
81
|
+
const beforeWeekday = ((firstWeekday - 1) === -1) ? 6 : (firstWeekday - 1)
|
82
|
+
const emptyHeadRows = range(1, beforeWeekday).map(toEmptyCell)
|
83
|
+
|
84
|
+
const initialStartDate = startOfDay(startDate)
|
85
|
+
const initialEndDate = startOfDay(endDate)
|
86
|
+
|
87
|
+
// 00:00:00
|
88
|
+
// eslint-disable-next-line prefer-const
|
89
|
+
let startOfStartDate = initialStartDate
|
90
|
+
|
91
|
+
// eslint-disable-next-line prefer-const
|
92
|
+
let startOfEndDate = initialEndDate
|
93
|
+
|
94
|
+
if (startDate && (! endDate) && this.hoveredCellData) {
|
95
|
+
const { year: y, month: m, date: d } = this.hoveredCellData
|
96
|
+
startOfEndDate = set(startOfStartDate, { year: y, month: m, date: d })
|
97
|
+
if (dateLt(startOfEndDate, startOfStartDate)) {
|
98
|
+
[startOfStartDate, startOfEndDate] = [startOfEndDate, startOfStartDate]
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
const formatDate = date => {
|
103
|
+
return format(date, 'yyyy-MM-dd', { timezone: this.tz, locale: this.locale })
|
104
|
+
}
|
105
|
+
const today = formatDate(new Date())
|
106
|
+
|
107
|
+
const rows = range(1, daysInMonth).map(day => {
|
108
|
+
|
109
|
+
const d = addDays(firstDateOfMonth, day - 1)
|
110
|
+
const resCompareStart = compareAsc(startOfStartDate, d)
|
111
|
+
const resCompareEnd = compareAsc(startOfEndDate, d)
|
112
|
+
|
113
|
+
return {
|
114
|
+
type: CELL_TYPE_DAY,
|
115
|
+
isStartDate: dateEq(initialStartDate, d),
|
116
|
+
isEndDate: dateEq(initialEndDate, d),
|
117
|
+
isSelected: (resCompareStart <= 0) && (resCompareEnd >= 0),
|
118
|
+
isToday: (today === formatDate(d)),
|
119
|
+
day
|
120
|
+
}
|
121
|
+
})
|
122
|
+
|
123
|
+
const lastWeekday = getDay(endOfMonth(date))
|
124
|
+
const emptyDays = ((7 - lastWeekday) % 7)
|
125
|
+
const emptyTailRows = range(1, emptyDays).map(toEmptyCell)
|
126
|
+
|
127
|
+
return emptyHeadRows.concat(rows).concat(emptyTailRows)
|
128
|
+
}
|
129
|
+
|
130
|
+
setCaption() {
|
131
|
+
const { date, date2 } = this
|
132
|
+
const options = { timezone: this.tz, locale: this.locale }
|
133
|
+
if (this.useSingleMenu()) {
|
134
|
+
this.caption.textContent = format(date, this.captionPattern, options)
|
135
|
+
}
|
136
|
+
else {
|
137
|
+
this.caption1.textContent = format(date, this.captionPattern, options)
|
138
|
+
this.caption2.textContent = format(date2, this.captionPattern, options)
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
drawTables() {
|
143
|
+
if (this.useSingleMenu()) {
|
144
|
+
const rows = this.getTableRows(this.date)
|
145
|
+
this.table.innerHTML = this.getTableHtml(rows)
|
146
|
+
}
|
147
|
+
else {
|
148
|
+
this.table1.innerHTML = this.getTableHtml(this.getTableRows(this.date))
|
149
|
+
this.table2.innerHTML = this.getTableHtml(this.getTableRows(this.date2))
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
setDate({ date, startDate, endDate }) {
|
154
|
+
if (date) {
|
155
|
+
this.date = date
|
156
|
+
this.date2 = addMonths(date, 1)
|
157
|
+
this.setCaption()
|
158
|
+
}
|
159
|
+
if (typeof startDate !== 'undefined') {
|
160
|
+
this.startDate = startDate
|
161
|
+
}
|
162
|
+
if (typeof endDate !== 'undefined') {
|
163
|
+
this.endDate = endDate
|
164
|
+
}
|
165
|
+
this.drawTables()
|
166
|
+
}
|
167
|
+
|
168
|
+
getWeekHeaderItems() {
|
169
|
+
return this.weekHeaderItems.map(item => `<li>${item.text}</li>`)
|
170
|
+
.join('')
|
171
|
+
}
|
172
|
+
|
173
|
+
getTableHtml(rows) {
|
174
|
+
return rows.map((row, i) => {
|
175
|
+
const rowHtml = this.getTdHtml(row)
|
176
|
+
const r = i % 7
|
177
|
+
if (r === 0) {
|
178
|
+
return `<tr>${rowHtml}`
|
179
|
+
}
|
180
|
+
if (r === 6) {
|
181
|
+
return `${rowHtml}</tr>`
|
182
|
+
}
|
183
|
+
return rowHtml
|
184
|
+
}).join('')
|
185
|
+
}
|
186
|
+
|
187
|
+
getTdHtml(row) {
|
188
|
+
if (row.type === CELL_TYPE_EMPTY) {
|
189
|
+
return '<td></td>'
|
190
|
+
}
|
191
|
+
if (row.isStartDate || row.isEndDate) {
|
192
|
+
return `<td class="cell selected-ex" data-date-table-cell>${row.day}</td>`
|
193
|
+
}
|
194
|
+
if (row.isSelected) {
|
195
|
+
return `<td class="cell selected" data-date-table-cell>${row.day}</td>`
|
196
|
+
}
|
197
|
+
if (this.options.highlightToday && row.isToday) {
|
198
|
+
return `<td class="cell today" data-date-table-cell>${row.day}</td>`
|
199
|
+
}
|
200
|
+
return `<td class="cell" data-date-table-cell>${row.day}</td>`
|
201
|
+
}
|
202
|
+
|
203
|
+
addMenu() {
|
204
|
+
const dom = document.createElement('div')
|
205
|
+
dom.className = 'date-menu'
|
206
|
+
|
207
|
+
if (this.useSingleMenu()) {
|
208
|
+
dom.innerHTML = `
|
209
|
+
<div class="date-menu-content">
|
210
|
+
<div class="date-menu-caption" data-menu-caption></div>
|
211
|
+
<ul class="date-menu-week-header">
|
212
|
+
${this.getWeekHeaderItems()}
|
213
|
+
</ul>
|
214
|
+
<table class="date-menu-date-table" data-date-table></table>
|
215
|
+
<button class="date-menu-btn-prev" data-btn-prev>
|
216
|
+
<i class="icon icon-chevron-left"></i>
|
217
|
+
</button>
|
218
|
+
<button class="date-menu-btn-next" data-btn-next>
|
219
|
+
<i class="icon icon-chevron-right"></i>
|
220
|
+
</button>
|
221
|
+
</div>
|
222
|
+
`
|
223
|
+
this.caption = dom.querySelector('[data-menu-caption]')
|
224
|
+
this.table = dom.querySelector('[data-date-table]')
|
225
|
+
this.btnPrev = dom.querySelector('[data-btn-prev]')
|
226
|
+
this.btnNext = dom.querySelector('[data-btn-next]')
|
227
|
+
}
|
228
|
+
else {
|
229
|
+
dom.innerHTML = `
|
230
|
+
<div class="date-menu-content">
|
231
|
+
<div class="date-menu-caption" data-menu-caption1></div>
|
232
|
+
<ul class="date-menu-week-header">
|
233
|
+
${this.getWeekHeaderItems()}
|
234
|
+
</ul>
|
235
|
+
<table class="date-menu-date-table" data-date-table1></table>
|
236
|
+
<button class="date-menu-btn-prev" data-btn-prev>
|
237
|
+
<i class="icon icon-chevron-left"></i>
|
238
|
+
</button>
|
239
|
+
</div>
|
240
|
+
<div class="date-menu-content second-content">
|
241
|
+
<div class="date-menu-caption" data-menu-caption2></div>
|
242
|
+
<ul class="date-menu-week-header">
|
243
|
+
${this.getWeekHeaderItems()}
|
244
|
+
</ul>
|
245
|
+
<table class="date-menu-date-table" data-date-table2></table>
|
246
|
+
<button class="date-menu-btn-next" data-btn-next>
|
247
|
+
<i class="icon icon-chevron-right"></i>
|
248
|
+
</button>
|
249
|
+
</div>
|
250
|
+
`
|
251
|
+
this.caption1 = dom.querySelector('[data-menu-caption1]')
|
252
|
+
this.caption2 = dom.querySelector('[data-menu-caption2]')
|
253
|
+
this.table1 = dom.querySelector('[data-date-table1]')
|
254
|
+
this.table2 = dom.querySelector('[data-date-table2]')
|
255
|
+
this.btnPrev = dom.querySelector('[data-btn-prev]')
|
256
|
+
this.btnNext = dom.querySelector('[data-btn-next]')
|
257
|
+
}
|
258
|
+
document.body.appendChild(dom)
|
259
|
+
this.dom = dom
|
260
|
+
}
|
261
|
+
|
262
|
+
findTable(target) {
|
263
|
+
let node = target
|
264
|
+
while (node.parentNode) {
|
265
|
+
node = node.parentNode
|
266
|
+
if (node.tagName === 'TABLE') {
|
267
|
+
return node
|
268
|
+
}
|
269
|
+
}
|
270
|
+
return null
|
271
|
+
}
|
272
|
+
|
273
|
+
addEvents() {
|
274
|
+
this.addEvent(this.btnPrev, 'click', event => {
|
275
|
+
this.setDate({ date: subMonths(this.date, 1) })
|
276
|
+
})
|
277
|
+
|
278
|
+
this.addEvent(this.btnNext, 'click', () => {
|
279
|
+
this.setDate({ date: addMonths(this.date, 1) })
|
280
|
+
})
|
281
|
+
|
282
|
+
if (this.useSingleMenu()) {
|
283
|
+
this.addEvent(this.table, 'click', event => {
|
284
|
+
if ('dateTableCell' in event.target.dataset) {
|
285
|
+
const res = {
|
286
|
+
year: getYear(this.date),
|
287
|
+
month: getMonth(this.date),
|
288
|
+
date: parseInt(event.target.textContent.trim(), 10)
|
289
|
+
}
|
290
|
+
this.fire('td-click', event, res)
|
291
|
+
}
|
292
|
+
})
|
293
|
+
}
|
294
|
+
else {
|
295
|
+
this.addEvent(this.table1, 'click', event => {
|
296
|
+
if ('dateTableCell' in event.target.dataset) {
|
297
|
+
const res = {
|
298
|
+
year: getYear(this.date),
|
299
|
+
month: getMonth(this.date),
|
300
|
+
date: parseInt(event.target.textContent.trim(), 10)
|
301
|
+
}
|
302
|
+
this.fire('td-click', event, res)
|
303
|
+
}
|
304
|
+
})
|
305
|
+
this.addEvent(this.table2, 'click', event => {
|
306
|
+
if ('dateTableCell' in event.target.dataset) {
|
307
|
+
const res = {
|
308
|
+
year: getYear(this.date2),
|
309
|
+
month: getMonth(this.date2),
|
310
|
+
date: parseInt(event.target.textContent.trim(), 10)
|
311
|
+
}
|
312
|
+
this.fire('td-click', event, res)
|
313
|
+
}
|
314
|
+
})
|
315
|
+
|
316
|
+
if (this.options.useMouseOver) {
|
317
|
+
this.addEvent(this.dom, 'mouseover', throttle(event => {
|
318
|
+
if ('dateTableCell' in event.target.dataset) {
|
319
|
+
const table = this.findTable(event.target)
|
320
|
+
const date = ('dateTable1' in table.dataset) ? this.date : this.date2
|
321
|
+
const res = {
|
322
|
+
year: getYear(date),
|
323
|
+
month: getMonth(date),
|
324
|
+
date: parseInt(event.target.textContent.trim(), 10)
|
325
|
+
}
|
326
|
+
return this.fire('td-mouseover', event, res)
|
327
|
+
}
|
328
|
+
this.fire('td-mouseover', event, null)
|
329
|
+
}, 300))
|
330
|
+
}
|
331
|
+
|
332
|
+
}
|
333
|
+
}
|
334
|
+
|
335
|
+
pos(src) {
|
336
|
+
const { dom } = this
|
337
|
+
const { pos } = getFloatedTargetPos({
|
338
|
+
src,
|
339
|
+
target: dom,
|
340
|
+
place: 'bottom',
|
341
|
+
align: 'left',
|
342
|
+
offset: 4
|
343
|
+
})
|
344
|
+
dom.style.left = toPixel(pos.left)
|
345
|
+
dom.style.top = toPixel(pos.top)
|
346
|
+
}
|
347
|
+
|
348
|
+
show(src) {
|
349
|
+
const { dom } = this
|
350
|
+
dom.style.opacity = 0
|
351
|
+
dom.style.display = 'block'
|
352
|
+
this.pos(src)
|
353
|
+
dom.style.opacity = 1
|
354
|
+
this.isVisible = true
|
355
|
+
}
|
356
|
+
|
357
|
+
hide() {
|
358
|
+
this.dom.style.display = 'none'
|
359
|
+
this.isVisible = false
|
360
|
+
}
|
361
|
+
|
362
|
+
destroy() {
|
363
|
+
this.caption = null
|
364
|
+
this.btnPrev = null
|
365
|
+
this.btnNext = null
|
366
|
+
this.table = null
|
367
|
+
this.dom.remove()
|
368
|
+
this.menu = null
|
369
|
+
}
|
370
|
+
}
|