Skip to content
master
Go to file
Code

README.md

Vue2 Timepicker

GitHub version npm version GitHub release npm downloads


💡 Dead repo recharged 🔋


A dropdown time picker (hour|minute|second) for Vue 2.x, with flexible time format support.

Demo

You can see the Vue2 Timepicker in action in the Demo Page

Migration

Please check MIGRATION.md for basic guidelines if you are about to:

  • Migrate from the Vue 1.x version vue-time-picker
  • Migrate from Bower to Yarn or NPM (Vue2 Timepicker v0.1.x -> v0.2.0+)

Dependencies

Vue.js   npm peer dependency version

Installation

yarn add vue2-timepicker
npm install vue2-timepicker --save

NOTE: We stop Bower support from 0.2.0+, please check MIGRATION.md for migration guidelines.

Get Started

Step 1: Import VueTimepicker

Option A: Import component JS and CSS

// Main JS (in UMD format)
import VueTimepicker from 'vue2-timepicker'

// CSS
import 'vue2-timepicker/dist/VueTimepicker.css'

Option B: Choose any bundle version base on your needs

Javascript

// CommonJS
import VueTimepicker from 'vue2-timepicker/dist/VueTimepicker.common.js'
// UMD
import VueTimepicker from 'vue2-timepicker/dist/VueTimepicker.umd.js'
// UMD Minified
import VueTimepicker from 'vue2-timepicker/dist/VueTimepicker.umd.min.js'

CSS

@import 'vue2-timepicker/dist/VueTimepicker.css';

/* Or, with node_module alias path like: */
@import '~vue2-timepicker/dist/VueTimepicker.css';

/*
  NOTE: the path alias to `node_modules` differs between bundlers.
  Please change the `~` to any alias that works with your environment.
 */

Single File Component

// The *.vue file with CSS included
import VueTimepicker from 'vue2-timepicker/src/vue-timepicker.vue'
// NOTE: In some cases, it requires additional workarounds in the bundler's config

SSR Usage

// Import the *.vue file (CSS included)
import VueTimepicker from 'vue2-timepicker/sfc'
// Note the `/sfc` suffix here

If your server-side renderer cannot recognize the /sfc alias, please try --

// Manually point to the `/src` folder
import VueTimepicker from 'vue2-timepicker/src'
// Or, to the specific file name
import VueTimepicker from 'vue2-timepicker/src/vue-timepicker.vue'

Step 2: Include VueTimepicker in your component

var yourComponent = new Vue({
  components: { VueTimepicker },
  ...
})

Step 3: Put vue-timepicker in your component's template

Then, you can introduce the vue-timepicker tag anywhere you like in your component's template

<vue-timepicker></vue-timepicker>

Basic Usage

Base

<!-- Default to 24-Hour format HH:mm -->
<vue-timepicker></vue-timepicker>

Customized Time Format

<!-- Show seconds picker -->
<vue-timepicker format="HH:mm:ss"></vue-timepicker>

<!-- 12-hour format, with AM/PM picker -->
<vue-timepicker format="hh:mm A"></vue-timepicker>

<!-- 12-hour format, with seconds picker and am/pm picker -->
<vue-timepicker format="hh:mm:ss a"></vue-timepicker>

VueTimepicker recognizes the following tokens in the format string

Section Token Output
AM/PM A AM PM
  a am pm
Hour H 0 1 ... 22 23
  HH 00 01 ... 22 23
  h 1 2 ... 11 12
  hh 01 02 ... 11 12
  k 1 2 ... 23 24
  kk 01 02 ... 23 24
Minute m 0 1 ... 58 59
  mm 00 01 ... 58 59
Second s 0 1 ... 58 59
  ss 00 01 ... 58 59

If not set, the format string is default to "HH:mm"

Customized Picker Interval

<!-- Show minute picker's value in the form of 0, 5, 10, ... 55, 60 -->
<vue-timepicker :minute-interval="5"></vue-timepicker>

<!-- Show second picker's value in the form of 0, 10, 20, ... 50, 60 -->
<vue-timepicker :second-interval="10"></vue-timepicker>

<!-- Bind interval config with your own data variable -->
<vue-timepicker :minute-interval="yourMinuteInterval"></vue-timepicker>

Data Binding

Bind Value with v-model

From v1.0.0+, timepicker's v-model accepts value in both Object (default) and String format. The v0.x versions only support Object form.

Set Initial Value

For example, if you want to set "10:05:00" ("HH:mm:ss" format) as the initial value of vue-timepicker:

const yourComponent = new Vue({
  components: { VueTimepicker },
  data () {
    return {
      // Object form
      yourTimeValue: {
        HH: '10',
        mm: '05',
        ss: '00'
      },
      // String form
      yourStringTimeValue: '10:05:00',
      ...
    }
  },
  ...
})

Both forms lead to the same result.

<!-- Object form -->
<vue-timepicker v-model="yourTimeValue" format="HH:mm:ss"></vue-timepicker>

<!-- String form -->
<vue-timepicker v-model="yourStringTimeValue" format="HH:mm:ss"></vue-timepicker>

Set Empty Initial Value

When the initial value is completely unknown:

data () {
  return {
    // Will be rendered as Object form
    yourEmptyValue: {},
    emptyValueToo: undefined,
    emptyValueAsWell: null,

    // Will be taken into String form
    yourEmptyStringValue: ''
  }
}

Set Partially-Known Initial Value

For instance, if you want to set the initial hour value to 8 pm and leave the rest slots empty:

data () {
  return {
    // OBJECT FORM
    // Default 24-Hour
    timeValue: {
      HH: '20',
      mm: ''
    },
    // 12-Hour with seconds
    timeValueWithSec: {
      h: '8',
      mm: '',
      ss: '',
      A: 'PM'
    },

    // STRING FORM
    // Default 24-Hour + String value
    stringTimeValue: '20:mm',
    // 12-Hour with seconds + String value
    stringTimeValueWithSec: '8:mm:ss PM'
  }
}
<!-- OBJECT FORM -->
<!-- Default 24-Hour -->
<vue-timepicker v-model="timeValue"></vue-timepicker>
<!-- 12-Hour with seconds -->
<vue-timepicker v-model="timeValueWithSec" format="h:mm:ss A"></vue-timepicker>

<!-- STRING FORM -->
<!-- Default 24-Hour + String value -->
<vue-timepicker v-model="stringTimeValue"></vue-timepicker>
<!-- 12-Hour with seconds + String value -->
<vue-timepicker v-model="stringTimeValueWithSec" format="h:mm:ss A"></vue-timepicker>

Get Time Picker's Current Value

Get value from v-model

You can either read the binding v-model value anytime or add a handler to deal with the input event from vue-timepicker.

<vue-timepicker v-model="yourTimeValue" format="HH:mm:ss" @input="inputHandler"></vue-timepicker>
{
  data () {
    return {
      yourTimeValue: {
        HH: '10',
        mm: '05',
        ss: '00'
      },
      ...
    }
  },

  methods: {
    inputHandler (eventData) {
      console.log(eventData)
    }
  }
}

In this case, we set the initial value (yourTimeValue) to "10:05:00". Then, open the dropdown picker and pick a new time, like setting it to "14:30:15" for example.

// In `inputHandler`:
// console.log outputs -> {HH: "14", mm: "30", ss: "15"}

Read Data From change Event

<!-- A: No argument -->
<vue-timepicker v-model="yourTimeValue" @change="changeHandler"></vue-timepicker>

<!-- B: Custom arguments -->
<vue-timepicker v-model="yourTimeValue" @change="otherChangeHandler($event, 'foo', 42)"></vue-timepicker>
// A: No argument
changeHandler (eventData) {
  console.log(eventData)
  // -> {data: {HH:..., mm:... }, displayTime: "HH:mm"}
}

// B: Custom arguments
otherChangeHandler (eventData, yourArg1, yourArg2) {
  console.log(eventData)
  // -> {data: {HH:..., mm:... }, displayTime: "HH:mm"}
  console.log(yourArg1)
  // -> 'foo'
  console.log(yourArg2)
  // -> 42
}

Unlike v-model and input event, which only return the defined time tokens you provided in the binding variable, the change event delivers all supported formats.

In the example above, after the user set values to "14:30:15" in the picker, change event returns the following data:

// `@change` event data
{
  data: {
    HH: "14",
    H: "14",
    hh: "14",
    a: "am",
    A: "AM",
    h: "14",
    kk: "14",
    k: "14",
    m: "30",
    mm: "30",
    s: "15",
    ss: "15"
  },
  // extra `displayTime` added since v0.2.2
  displayTime: "14:30:15"
}

Whereas the v-model / input only return the data with defined tokens

// Previously defined variable (`yourTimeValue` in this case) as {HH:..., mm:..., ss:...}
// Hence, the `v-model` returns:
{
  HH: "14",
  mm: "30",
  ss: "15"
}

Advance Usage

Hide Clear Button

<vue-timepicker hide-clear-button></vue-timepicker>

Enable to hide the "×" clear button on the right-hand side. Users can still pick new values from the dropdown, but they cannot erase any selected data.

Disable Picker

<vue-timepicker disabled></vue-timepicker>

Fully disable both dropdown picker and the "×" clear button in the UI, to prevent users from changing any values again.

Close on Complete

Automatically close the dropdown when the user finishes selecting all of the required fields.

<vue-timepicker close-on-complete></vue-timepicker>

Define Hour Range

Sometimes you may want to limit hours picker to a specific range. The hour-range parameter is here to help.

<!-- 24-Hour Format -->
<vue-timepicker :hour-range="[5, [8, 12], [14, 17], 19]"></vue-timepicker>
<!-- >> Equals to :hour-range="[5, 8, 9, 10, 11, 12, 14, 15, 16, 17, 19]" -->

<!-- 12-Hour Format -->
<vue-timepicker :hour-range="['7a', '9a', '11a', '1p', ['3p', '5p'], '7p']" format="hh:mm a">
<!-- >> Equals to :hour-range="['7a', '9a', '11a', '1p', '3p', '4p', '5p', '7p']" -->

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.

<!-- Minute range -->
<vue-timepicker :minute-range="[0, 6, [10, 30], 42, 50]"></vue-timepicker>
<!-- >> Active Items: 00, 06, 10, 11, 12, 13, ..., 27, 28, 29, 30, 42, 50 -->

<!-- Second range -->
<vue-timepicker format="H:m:s" :second-range="[0, 6, [10, 30], 42, 50]"></vue-timepicker>
<!-- >> Active Items: 0, 6, 10, 11, 12, 13, ..., 27, 28, 29, 30, 42, 50 -->

When implemented together with minute-interval and second-interval, the customized intervals take the priority.

<!-- Minute range + 5-minute interval -->
<vue-timepicker :minute-range="[0, 6, [10, 30], 42, 50]" :minute-interval="5"></vue-timepicker>
<!-- >> Active Items: 00, 10, 15, 20, 25, 30, 50 -->

<!-- Second range + 10-second interval-->
<vue-timepicker format="H:m:s" :second-range="[0, 6, [10, 30], 42, 50]" :second-interval="10"></vue-timepicker>
<!-- >> Active Items: 0, 10, 20, 30, 50 -->

Hide Disabled Items

There're four kinds of helper properties to let you hide the values excluded by hour-range, minute-range, and second-range.

  • hide-disabled-items: Hide all disabled items - hour, minute, and seconds.
  • hide-disabled-hours: Hide disabled hour values only.
  • hide-disabled-minutes: Hide disabled minute values only.
  • hide-disabled-seconds: Hide disabled second values only.
<!-- `hide-disabled-hours` sample -->
<vue-timepicker :hour-range="[5, [8, 12], [14, 17], 19]" hide-disabled-hours></vue-timepicker>

Here we take the hide-disabled-hours as an example. It's a pair with the hour-range parameter. In this case, the hour picker hides the invalid hours (0, 1, 2, 3, 4, 6, 7, 13, 18, 20, 21, 22, 23) and display the valid hours (5, 8, 9, ...) only.

Advanced Keyboard Support

Basic keyboard support includes:

  • Tab: Focus or blur the Timepicker
  • Esc: Close the dropdown

Advance Keyboard support (enabled with advanced-keyboard):

  • Arrow Keys: Navigate between valid (non-disabled) values and columns
  • Space or Enter: Select the focusing item
<vue-timepicker advanced-keyboard></vue-timepicker>

Please be aware that after putting the advanced-keyboard on, hundreds of additional keyboard event listeners are going to be attached to the component. The amount of listeners depends on how many hours, minutes, and seconds value you enabled in the current Timepicker.

Blur Delay

<!-- Unit: million second -->
<vue-timepicker :blur-delay="500"></vue-timepicker>

Sets the blur delay time for the dropdown. Defaults to 300 if not set.

Manual Input Support

<vue-timepicker manual-input></vue-timepicker>

Let users add or change values through the <input> box besides the dropdown picker.

Manual Input Timeout

<!-- Unit: million second -->
<vue-timepicker :manual-input-timeout="1500"></vue-timepicker>

Works with manual-input mode. It sets the timeout for continuous input. Defaults to 1000 if not set.

How It Works?

For example, when a user focuses on the hour slot (HH) of a "HH:mm" formatted Timepicker (with the default value 1000):

  • Case 1: User first inputs 1, and then inputs 2 500ms later -> Timepicker takes 12 as the final value and set it to the "HH" slot.
  • Case 2: User inputs 1, and then presses the key 2 1200ms later -> Timepicker takes 2 as the final value and set it to 02 for the "HH" slot.

Hide Dropdown

NOTE: To use this feature, you MUST ENABLE the manual-input mode (v.1.1.0+) in the first place.

It makes the dropdown picker hidden by default.

<vue-timepicker manual-input hide-dropdown></vue-timepicker>

Users can still choose to open the dropdown by clicking the triangle ("▾") button on the right. (v.1.1.3+)

Lazy Event Mode

<vue-timepicker lazy></vue-timepicker>

When lazy event mode is toggled on, only an actual user behavior can trigger the input and change events. Which are:

  • The user opened the dropdown and picked a new value
  • The user clicked the ("×") clear button

In other words, on lazy mode, Timepicker won't emit input and change events on mounted, nor after the value got modified programmatically.

Auto-Scroll

<vue-timepicker auto-scroll></vue-timepicker>

Auto-scroll to selected values on dropdown open. It works with both:

  • Programmatically defined value. E.g., the initial value from v-model
  • Values manually picked by the user.

Enable Debug Mode

<vue-timepicker debug-mode></vue-timepicker>

It's aimed to help developers to investigate the input -> output process. When debug mode is toggled on, you can see extra DEBUG: ... logs coming through the console window as you interact with the vue-timepicker.

Let's create a "bug" here as an example --

<!-- Manual Bug Sample: Define timepicker with format "h:mm:ss A" -->
<vue-timepicker v-model="yourStringValue" format="h:mm:ss A" debug-mode></vue-timepicker>
{
  data () {
    return {
      // Manual Bug Sample:
      // Should be '3:mm:05 A' but oops.. the finger slipped
      yourStringValue: 'e:mm:05 A'
    }
  }
}

Then, in the console window, you should see a debug log saying:

DEBUG: The input string in "v-model" does NOT match the "format" pattern
format: h:mm:ss A
v-model: e:mm:05 A

Main Props API Overview

Prop Type Required Default Value
v-model Object, String no undefined
format String no "HH:mm"
minute-interval Number no undefined
second-interval Number no undefined
hide-clear-button Boolean no false
disabled Boolean no false
close-on-complete Boolean no false
hour-range Array no undefined
minute-range Array no undefined
second-range Array no undefined
hide-disabled-hours Boolean no false
hide-disabled-minutes Boolean no false
hide-disabled-seconds Boolean no false
hide-disabled-items Boolean no false
advanced-keyboard Boolean no false
blur-delay Number no 300
manual-input Boolean no false
manual-input-timeout Number no 1000
hide-dropdown Boolean no false
lazy Boolean no false
auto-scroll Boolean no false
debug-mode Boolean no false

Input Props API

Prop Type Required Default Value
id String no undefined
name String no undefined
placeholder String no undefined
tabindex Number no 0
autocomplete String no 'off'
input-class String, Array, Object no undefined
input-width String no '10em'

Timepicker supports id, name, placeholder, and tabindex like common form elements. These values are assigned to the <input type="text" class="display-time"> within the component.

Input id, name and tabindex

<!-- id -->
<vue-timepicker id="myFirstPicker"></vue-timepicker>

<!-- name -->
<vue-timepicker name="nameInForm"></vue-timepicker>

<!-- tabindex -->
<vue-timepicker :tabindex="5"></vue-timepicker>

Input placeholder

When placeholder is undefined, timepicker takes the determined format string instead.

<!-- placeholder is set -->
<vue-timepicker placeholder="Start Time"></vue-timepicker>
<!-- -> "Start Time" -->

<!-- placeholder not set -->
<vue-timepicker format="hh:mm A"></vue-timepicker>
<!-- -> "hh:mm A" -->

<!-- both placeholder and format are not set -->
<vue-timepicker></vue-timepicker>
<!-- -> "HH:mm" -->

Input autocomplete Attribute

NOTE: To use this property, you MUST ENABLE the manual-input mode (v.1.1.0+) in the first place.

<!-- In Vue Template -->
<vue-timepicker name="starttime" autocomplete="on" manual-input></vue-timepicker>
<!-- HTML result -->
<span class="vue__time-picker time-picker">
  <input class="display-time" name="starttime" type="text" autocomplete="on">
  <!-- ... -->
</span>

When enabled, it accepts any string value supported by the HTML input autocomplete attribute. The value is assigned to the embedding text <input>, which means it follows form autofill rules and configs set in the browser level. For example, most of the browsers require the input to have a name and/or id attribute. Some browsers, like Firefox, demand the input to be a descendant of a <form> element.

Please refer to the HTML documentation and the developer guideline of each browser for more information (i.e., MDN docs here).

The input-class

The input-class is assigned to the text input within the component as well.

<!-- Set your own `input-class` in the Vue template -->
<vue-timepicker input-class="my-awesome-picker"></vue-timepicker>
<!-- HTML result -->
<span class="vue__time-picker time-picker">
  <input class="display-time my-awesome-picker" type="text" readonly="readonly">
  <!-- ... -->
</span>

Start from v1.0.4, besides String format, input-class accepts value in Array and Object type as well.

<!-- String type -->
<vue-timepicker input-class="your-awesome-timepicker i-am-vue2-timepicker"></vue-timepicker>

<!-- Array type -->
<vue-timepicker :input-class="['your-awesome-timepicker', 'i-am-vue2-timepicker']"></vue-timepicker>

<!-- Object type -->
<vue-timepicker :input-class="{
  'your-awesome-timepicker': true,
  'foo': false,
  'i-am-vue2-timepicker': true,
  'bar': false
}"></vue-timepicker>
<!-- All of the three samples above return the same result in rendered HTML -->
<span class="vue__time-picker time-picker">
  <input class="display-time your-awesome-timepicker i-am-vue2-timepicker" type="text" readonly="readonly">
  <!-- ... -->
</span>

The input-width

The input-width helps you to adjust both the <input> and the dropdown picker's width without overriding the CSS style on your own. It accepts any valid CSS width values like 8em, 200px, etc.

<!-- In `px` -->
<vue-timepicker input-width="100px"></vue-timepicker>

<!-- In `em` -->
<vue-timepicker input-width="12em" format="HH:mm:ss"></vue-timepicker>

Events API

Event Arguments Description
input (value) Emit after value changes
change (eventData) Emit after value changes
open   Emit when the dropdown opens
close   Emit when the dropdown closes
focus   Emit when the user start focusing on the <input>
blur   Emit when the user blurs the <input>
error (eventData) Emit when the input value becomes invalid

The open and close Event of the Dropdown Picker

Help to identify the current status of the dropdown picker

data () {
  return {
    dropdownStatus: 'closed'
  }
}
<p>Dropdown Status: I'm {{dropdownStatus}}!</p>

<vue-timepicker @open="dropdownStatus = 'opened'" @close="dropdownStatus = 'closed'"></vue-timepicker>

The focus and blur Event

It works with the Manual Input mode, aimed to identify the focus/blur state of the <input> box. Specially useful in cases where the dropdown is force hidden by hide-dropdown.

data () {
  return {
    focusState: 'blurred'
  }
}
<p>Focus State: {{focusState}}</p>

<vue-timepicker manual-input hide-dropdown @focus="focusState = 'focused'" @blur="focusState = 'blurred'"></vue-timepicker>

The error event

Starts from v.1.1.0+, Timepicker will emit an error event when the current input value becomes invalid. E.g., when it contains an hour value that is not in the hour-range list or a minute value that doesn't fit in the minute-interval.

<!-- Got the `hour-range` and `minute-interval` set -->
<!-- And add a hanlder to pick up the "error" event -->
<vue-timepicker format="H:mm:ss" v-model="erroredInputSample" :hour-range="[8, 9, 10, 11]" :minute-interval="5" @error="errorHanlder"></vue-timepicker>
data () {
  return {
    erroredInputSample: { H: '5', mm: '03', ss: '00' }
    // NOTE:
    // H: '5' -> invalid. Value is not in the `hour-range` list
    // mm: '03' -> invalid. Value does not fit in the `minute-interval`
    // ss: '00' -> valid.
  }
},

methods: {
  errorHanlder (eventData) {
    console.log(eventData)
    // console.log outputs -> ["hour", "minute"]
  }
}

The error event returns an Array of invalid fields' names. When it returns an empty array [], it means the current input is valid, and all previous errors are gone

NOTE: Empty value will not be marked as invalid.

Helper CSS Class Names

Started from v.1.1.0+, Vue Timepicker will add additional CSS classes to the <input> element base on the state of the current input value.

  • invalid: One or more fields containing an invalid or disabled value.
    • Additional CSS Style: The <input> border turns red.
    • If you want to mute this red border style, add "skip-error-style" to input-class
  • is-empty: The input value (v-model) is empty. No additional style.
  • all-selected: All fields (hour/minute/second/apm) required by the format string are not empty. No additional style.
<!-- To mute the red border style of "invalid" state -->
<timepicker input-class="skip-error-style"></timepicker>
<timepicker :input-class="['skip-error-style', 'your-other-class-names']"></timepicker>

Miscellaneous Props API

Prop Type Required Default Value
hour-label String no undefined
minute-label String no undefined
second-label String no undefined
apm-label String no undefined
am-text String no undefined
pm-text String no undefined

Customized Picker Labels

You can define customized labels on top of the hour, minute, second, and APM pickers with the following properties: hour-label, minute-label, second-label, and apm-label.

Furthermore, you can replace those am/pm (or AM/PM) string by setting the am-text and pm-text parameters.

Please note that these two parameters only change the labels expose to the users (the UI level). The v-model value and displayTime value returned by the change event (the data level) still use the standard am/pm (AM/PM) format.

<!-- 24-hour format with customized hour and minute label -->
<vue-timepicker hour-label="heure" minute-label="minute"></vue-timepicker>

<!-- 12-hour format with customized am/pm text -->
<vue-timepicker hour-label="" minute-label="" second-label="" apm-label="" am-text="上午" pm-text="下午" format="h:mm:ss a"></vue-timepicker>

Slots

We introduce three slots in v.1.1.4 to help you customize the clear button, the dropdown button, and the input icon with your own icon/image.

Slot Name Position Description
icon left On the lefthand side of the <input>
clearButton right In the same spot of the default clear button
dropdownButton right In the same spot of the default dropdown button

Please note that Vue v2.6.0+ introduces a significant update of the Named Slots syntax. Check the official documentation for more information.

<!-- For Vue 2.6.0+ -->

<!-- Input icon (image) -->
<vue-timepicker>
  <template v-slot:icon>
    <img src="$YOUR_ICON_SRC" />
  </template>
</vue-timepicker>

<!-- Customized clear button (image) -->
<vue-timepicker>
  <template v-slot:clearButton>
    <img src="$YOUR_CUSTOM_IMAGE_SRC" />
  </template>
</vue-timepicker>

<!-- Customized dropdown button (character entity) -->
<vue-timepicker manual-input hide-dropdown>
  <template v-slot:dropdownButton>&#x02263;</template>
</vue-timepicker>

Contribution

Please feel free to fork and help developing. Check CONTRIBUTING.md for more details.

Change Log

Detail changes of each release: CHANGELOG.md

License

MIT

About

A dropdown time picker (hour|minute|second) for Vue 2.x, with flexible time format support

Resources

License

Packages

No packages published
You can’t perform that action at this time.