diff --git a/README.md b/README.md
index 1c13833..4662141 100644
--- a/README.md
+++ b/README.md
@@ -140,7 +140,7 @@ Section | Token | Output
> If not set, the `format` string is default to "HH:mm"
-### Customized Picker interval
+### Customized Picker Interval
```html
@@ -393,13 +393,47 @@ Sometimes you may want to limit hours picker to a specific range. The `hour-rang
```
-### Hide Disabled Hour Ranges
+### Set Minute and Second Range
+
+Similar to `hour-range`, you can determine values in the minutes and seconds dropdown by using `minute-range` and `second-range`.
+
+```html
+
+hour-range
, minute-range
, and second-range
.
+ ul
+ li
+ b hide-disabled-items
+ | : Hide all disabled items - hour, minute, and seconds.
+ li
+ b hide-disabled-hours
+ | : Hide disabled hour valus only.
+ li
+ b hide-disabled-minutes
+ | : Hide disabled minute values only.
+ li
+ b hide-disabled-seconds
+ | : Hide disabled second values only.
+ template(v-slot:codes)
+ highlight-code(lang="html" data-title="HTML")
+ | <!-- hide-disabled-items -->
+ | <vue-timepicker hide-disabled-items format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]"></vue-timepicker>
+ |
+ | <!-- hide-disabled-hours -->
+ | <vue-timepicker hide-disabled-hours format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]"></vue-timepicker>
+ |
+ | <!-- hide-disabled-minutes -->
+ | <vue-timepicker hide-disabled-minutes format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]"></vue-timepicker>
+ |
+ | <!-- hide-disabled-seconds -->
+ | <vue-timepicker hide-disabled-seconds format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]"></vue-timepicker>
+ template(v-slot:preview)
+ b hide-disabled-items
+ p
+ vue-timepicker(hide-disabled-items format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]")
+ b hide-disabled-hours
+ p
+ vue-timepicker(hide-disabled-hours format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]")
+ b hide-disabled-minutes
p
- vue-timepicker(:hour-range="[5, [8, 12], [14, 17], 19]" hide-disabled-hours)
- b Hour Range Sample 2 (12-hour format) with `hide-disabled-hours`
+ vue-timepicker(hide-disabled-minutes format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]")
+ b hide-disabled-seconds
p
- vue-timepicker(:hour-range="['7a', '9a', '11a', '1p', ['3p', '5p'], '7p']" format="hh:mm a" hide-disabled-hours)
+ vue-timepicker(hide-disabled-seconds format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]")
//- Hide Clear Button
sample-block#hideClearButton
@@ -344,12 +406,12 @@ section#mostlyUsedSamples
sample-block#onChangeSample
template(v-slot:title)
| The
- code @change
+ code change
| Event
template(v-slot:description)
- p A @change
event will be triggered every time the user alters timepicker's value.
- p Unlike the v-model
, which only returns data in your predefined format, @change
event will return a full package of all supported time tokens.
- p Started from v0.2.2
, a displayTime
string value is also included in the return data of @change
event.
+ p A change
event will be triggered every time the user alters timepicker's value.
+ p Unlike the v-model
, which only returns data in your predefined format, change
event will return a full package of all supported time tokens.
+ p Started from v0.2.2
, a displayTime
string value is also included in the return data of change
event.
p Play around with the two pickers below to see their data changes in live.
template(v-slot:codes)
highlight-code(lang="html" data-title="HTML")
@@ -387,9 +449,9 @@ section#mostlyUsedSamples
//- Open And Close Event
sample-block#openAndClose
template(v-slot:title)
- code @open
+ code open
| and
- code @close
+ code close
| event
p(slot="description")
| Help identifying current status of the dropdown picker
diff --git a/src/vue-timepicker.vue b/src/vue-timepicker.vue
index 234fd6a..d9cac3a 100644
--- a/src/vue-timepicker.vue
+++ b/src/vue-timepicker.vue
@@ -8,11 +8,15 @@ const CONFIG = {
const DEFAULT_OPTIONS = {
format: 'HH:mm',
- hideClearButton: false,
minuteInterval: 1,
secondInterval: 1,
hourRange: null,
- hideDisabledHours: false
+ minuteRange: null,
+ secondRange: null,
+ hideDisabledHours: false,
+ hideDisabledMinutes: false,
+ hideDisabledSeconds: false,
+ hideDisabledItems: false
}
export default {
@@ -20,11 +24,19 @@ export default {
props: {
value: { type: [ Object, String ] },
format: { type: String },
- hideClearButton: { type: Boolean, default: false },
minuteInterval: { type: [ Number, String ] },
secondInterval: { type: [ Number, String ] },
+
hourRange: { type: Array },
+ minuteRange: { type: Array },
+ secondRange: { type: Array },
+
hideDisabledHours: { type: Boolean, default: false },
+ hideDisabledMinutes: { type: Boolean, default: false },
+ hideDisabledSeconds: { type: Boolean, default: false },
+ hideDisabledItems: { type: Boolean, default: false },
+
+ hideClearButton: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
id: { type: String },
@@ -65,10 +77,6 @@ export default {
options.format = String(this.format)
}
- if (this.hideClearButton) {
- options.hideClearButton = true
- }
-
if (this.isNumber(this.minuteInterval)) {
options.minuteInterval = +this.minuteInterval
}
@@ -109,15 +117,46 @@ export default {
if (this.hourRange && Array.isArray(this.hourRange)) {
options.hourRange = JSON.parse(JSON.stringify(this.hourRange))
+ if (!this.hourRange.length && this.debugMode) {
+ this.debugLog('The "hour-range" array is empty (length === 0)')
+ }
+ }
+
+ if (this.minuteRange && Array.isArray(this.minuteRange)) {
+ options.minuteRange = JSON.parse(JSON.stringify(this.minuteRange))
+ if (!this.minuteRange.length && this.debugMode) {
+ this.debugLog('The "minute-range" array is empty (length === 0)')
+ }
+ }
+
+ if (this.secondRange && Array.isArray(this.secondRange)) {
+ options.secondRange = JSON.parse(JSON.stringify(this.secondRange))
+ if (!this.secondRange.length && this.debugMode) {
+ this.debugLog('The "second-range" array is empty (length === 0)')
+ }
}
- if (this.hideDisabledHours) {
+ if (this.hideDisabledItems) {
+ options.hideDisabledItems = true
+ }
+
+ if (this.hideDisabledHours || this.hideDisabledItems) {
options.hideDisabledHours = true
}
+ if (this.hideDisabledMinutes || this.hideDisabledItems) {
+ options.hideDisabledMinutes = true
+ }
+ if (this.hideDisabledSeconds || this.hideDisabledItems) {
+ options.hideDisabledSeconds = true
+ }
return options
},
+ useStringValue () {
+ return typeof this.value === 'string'
+ },
+
formatString () {
return this.opts.format || DEFAULT_OPTIONS.format
},
@@ -155,54 +194,50 @@ export default {
},
hourRangeIn24HrFormat () {
- if (this.opts.hourRange && this.opts.hourRange.length) {
- let range = []
- this.opts.hourRange.forEach((value) => {
- if (value instanceof Array) {
- if (value.length > 2 && this.debugMode) {
- this.debugLog(`Nested array within "hour-range" must contain no more than two items. Only the first two items of ${JSON.stringify(value)} will be taking into account.`)
- }
+ if (!this.opts.hourRange) { return false }
+ if (!this.opts.hourRange.length) { return [] }
+
+ const range = []
+ this.opts.hourRange.forEach(value => {
+ if (value instanceof Array) {
+ if (value.length > 2 && this.debugMode) {
+ this.debugLog(`Nested array within "hour-range" must contain no more than two items. Only the first two items of ${JSON.stringify(value)} will be taken into account.`)
+ }
- let start = value[0]
- let end = value[1] || value[0]
+ let start = value[0]
+ let end = value[1] || value[0]
- if (this.is12hRange(start)) {
- start = this.translate12hRange(start)
- }
- if (this.is12hRange(end)) {
- end = this.translate12hRange(end)
- }
+ if (this.is12hRange(start)) {
+ start = this.translate12hRange(start)
+ }
+ if (this.is12hRange(end)) {
+ end = this.translate12hRange(end)
+ }
- for (let i = +start; i <= +end; i++) {
- if (range.indexOf(i) === -1) {
- range.push(i)
- }
- }
- } else {
- if (this.is12hRange(value)) {
- value = this.translate12hRange(value)
- }
- if (range.indexOf(value) === -1) {
- range.push(value)
+ for (let i = +start; i <= +end; i++) {
+ if (i < 0 || i > 24) { continue }
+ if (!range.includes(i)) {
+ range.push(i)
}
}
- })
- range.sort((l, r) => { return l - r })
- return range
- }
- if (this.opts.hourRange && !this.opts.hourRange.length) {
- if (this.debugMode) {
- this.debugLog('The "hour-range" array is empty (length === 0)')
+ } else {
+ if (this.is12hRange(value)) {
+ value = this.translate12hRange(value)
+ }
+ if (value < 0 || value > 24) { return }
+ if (!range.includes(value)) {
+ range.push(value)
+ }
}
- return []
- }
- return false
+ })
+ range.sort((l, r) => { return l - r })
+ return range
},
restrictedHourRange () {
- if (!this.hourRangeIn24HrFormat) {
- return false
- }
+ // No restriction
+ if (!this.hourRangeIn24HrFormat) { return false }
+ // 12-Hour
if (this.baseOn12Hours) {
const range = this.hourRangeIn24HrFormat.map((value) => {
if (value === 12) {
@@ -210,10 +245,11 @@ export default {
} else if (value === 24) {
return '12a'
}
- return value > 12 ? value % 12 + 'p' : value + 'a'
+ return value > 12 ? `${value % 12}p` : `${value}a`
})
return range
}
+ // 24-Hour
return this.hourRangeIn24HrFormat
},
@@ -222,18 +258,88 @@ export default {
am: true,
pm: true
}
-
if (this.hourRangeIn24HrFormat && this.hourRangeIn24HrFormat.length) {
const range = [].concat([], this.hourRangeIn24HrFormat)
result.am = range.some(this.hasAm)
result.pm = range.some(this.hasPm)
}
-
return result
},
- useStringValue () {
- return typeof this.value === 'string'
+ minuteRangeList () {
+ if (!this.opts.minuteRange) { return false }
+ if (!this.opts.minuteRange.length) { return [] }
+ const range = []
+ let formatedValue
+ this.opts.minuteRange.forEach(value => {
+ if (value instanceof Array) {
+ if (value.length > 2 && this.debugMode) {
+ this.debugLog(`Nested array within "minute-range" must contain no more than two items. Only the first two items of ${JSON.stringify(value)} will be taken into account.`)
+ }
+ const start = value[0]
+ const end = value[1] || value[0]
+ for (let i = +start; i <= +end; i++) {
+ if (i < 0 || i > 59) { continue }
+ formatedValue = this.formatValue(this.minuteType, i)
+ if (!range.includes(formatedValue)) {
+ range.push(formatedValue)
+ }
+ }
+ } else {
+ if (value < 0 || value > 59) { return }
+ formatedValue = this.formatValue(this.minuteType, value)
+ if (!range.includes(formatedValue)) {
+ range.push(formatedValue)
+ }
+ }
+ })
+ range.sort((l, r) => { return l - r })
+ // Debug Mode
+ if (this.debugMode) {
+ const validItems = (this.minutes || []).filter(item => range.includes(item))
+ if (!validItems || !validItems.length) {
+ this.debugLog(`The minute list is empty due to the "minute-range" config\nminute-range: ${JSON.stringify(this.minuteRange)}\nminute-interval: ${this.opts.minuteInterval}`)
+ }
+ }
+ return range
+ },
+
+ secondRangeList () {
+ if (!this.opts.secondRange) { return false }
+ if (!this.opts.secondRange.length) { return [] }
+ const range = []
+ let formatedValue
+ this.opts.secondRange.forEach(value => {
+ if (value instanceof Array) {
+ if (value.length > 2 && this.debugMode) {
+ this.debugLog(`Nested array within "second-range" must contain no more than two items. Only the first two items of ${JSON.stringify(value)} will be taken into account.`)
+ }
+ const start = value[0]
+ const end = value[1] || value[0]
+ for (let i = +start; i <= +end; i++) {
+ if (i < 0 || i > 59) { continue }
+ formatedValue = this.formatValue(this.secondType, i)
+ if (!range.includes(formatedValue)) {
+ range.push(formatedValue)
+ }
+ }
+ } else {
+ if (value < 0 || value > 59) { return }
+ formatedValue = this.formatValue(this.secondType, value)
+ if (!range.includes(formatedValue)) {
+ range.push(formatedValue)
+ }
+ }
+ })
+ range.sort((l, r) => { return l - r })
+ // Debug Mode
+ if (this.debugMode) {
+ const validItems = (this.seconds || []).filter(item => range.includes(item))
+ if (!validItems || !validItems.length) {
+ this.debugLog(`The second list is empty due to the "second-range" config\nsecond-range: ${JSON.stringify(this.secondRange)}\nsecond-interval: ${this.opts.secondInterval}`)
+ }
+ }
+ return range
}
},
@@ -257,7 +363,7 @@ export default {
this.fillValues()
},
disabled (toDisabled) {
- // Force close dropdown when disabled
+ // Force close the dropdown when disabled
if (toDisabled && this.showDropdown) {
this.showDropdown = false
}
@@ -483,7 +589,7 @@ export default {
}
} else {
if (this.debugMode) {
- this.debugLog(`The input string in 'v-model' does NOT match the 'format' pattern\nformat: ${this.formatString}\nv-model: ${this.value}`)
+ this.debugLog(`The input string in "v-model" does NOT match the "format" pattern\nformat: ${this.formatString}\nv-model: ${this.value}`)
}
}
},
@@ -668,19 +774,26 @@ export default {
},
isDisabledHour (value) {
- if (this.restrictedHourRange) {
- if (this.baseOn12Hours) {
- if (!this.apm || !this.apm.length) {
- return false
- } else {
- const token = this.apm.toLowerCase() === 'am' ? 'a' : 'p'
- return this.restrictedHourRange.indexOf(`${+value}${token}`) === -1
- }
+ if (!this.restrictedHourRange) { return false }
+ if (this.baseOn12Hours) {
+ if (!this.apm || !this.apm.length) {
+ return false
} else {
- return this.restrictedHourRange.indexOf(+value) === -1
+ const token = this.apm.toLowerCase() === 'am' ? 'a' : 'p'
+ return !this.restrictedHourRange.includes(`${+value}${token}`)
}
}
- return false
+ return !this.restrictedHourRange.includes(+value)
+ },
+
+ isDisabledMinute (value) {
+ if (!this.minuteRangeList) { return false }
+ return !this.minuteRangeList.includes(value)
+ },
+
+ isDisabledSecond (value) {
+ if (!this.secondRangeList) { return false }
+ return !this.secondRangeList.includes(value)
},
forceApmSelection () {
@@ -719,8 +832,10 @@ export default {
if (this.isDisabledHour(value)) { return }
this.hour = value
} else if (type === 'minute') {
+ if (this.isDisabledMinute(value)) { return }
this.minute = value
} else if (type === 'second') {
+ if (this.isDisabledSecond(value)) { return }
this.second = value
} else if (type === 'apm') {
if (!this.has[value.toLowerCase()]) { return }
@@ -843,26 +958,32 @@ export default {