LoginSignup
2
5

More than 5 years have passed since last update.

Vue.js ElementUIのTimePickerに任意の値を入力する

Last updated at Posted at 2018-03-17

※ピッカーで選択したときに値が入らないという不具合があり、ソースを修正しました(2018.3.18 10:10)

ElementUIのTimePicker(el-time-select)は、基本的にstepで設定した時間刻みでしかバインドしたモデルに値が入りません。
オプションのeditableがtrue(デフォルトでtrue)であっても、stepの値に合うよう自動補正されます。
例えばデフォルトではstepは30分のため、9:02と手動入力すると画面表示錠は9:02ですが、データバインドされる値は9:00です。
el-time-select は Fixed time picker と書かれていますしね。

色々調べたところ、TimePickerコンポーネント自体のuserInputというプロパティで手動入力値を保持しており、Pickerで選択した場合には、valueOnOpenに値が入っているようですので、値のあるほうを取得して手動で代入すればOKでした。

さらに、TimePickerを要素数が動的に変わるようなリスト形式の中で使用したかったので、x番目のオブジェクトにバインドするため、x番目を取得する方法として、タグに属性値を付与して、そこにx番という値を持たせるようにしました。

<template>
<div>
  <el-col id='scheduleArea'>
    <div v-for='(schedule, index) in scheduleList'>
      <el-row>
        ({{index + 1}}日目)
        <!-- DatePicker, TimePicker にリストの番号をidxNumberという属性で付与しておく -->
        <el-date-picker v-bind:idxNumber='index' v-model='schedule.startDate' type='date' />
        <el-time-select v-bind:idxNumber='index' v-model='schedule.startTime' @blur='inputToStartTime' /> -
        <el-time-select v-bind:idxNumber='index' v-model='schedule.endTime' @blur='inputToEndTime' />
      </el-row>
    </div>
  </el-col>
  <el-col>{{scheduleList}}</el-col>
</div>
</template>

<script>
export default {
  data() {
    return {
      scheduleList: [{
          startDate: '2018-03-18',
          startTime: '09:00',
          endTime: '17:00'
        },
        {
          startDate: '2018-03-19',
          startTime: '09:00',
          endTime: '17:00'
        }
      ],
    }
  },
  computed: {},
  methods: {
    // 引数 componentには、elementUIによってコンポーネント自体(TimePicker)が渡される。
    // _data.userInputには、ユーザ入力値が入っている。
    // _date.valueOnOpenには、ピッカーで選択した値が入っている。
    // 手入力・ピッカーでの選択により、userInputとvalueOnOpenどちらかに値が入り、もう一方はNullのよう。
    // TimePickerはstepに設定された値単位に補正してmodelにバインドするため、手動で値を代入する。
    inputToStartTime(component) {
      this.scheduleList[component.$attrs.idxNumber].startTime =
        (component._data.userInput) ? component._data.userInput : component._data.valueOnOpen;

    },
    inputToEndTime(component) {
      this.scheduleList[component.$attrs.idxNumber].endTime =
        (component._data.userInput) ? component._data.userInput : component._data.valueOnOpen;
    }
  }
}
</script>

実行してみると、ちゃんと入力値がデータバインドされています。
timepicker.png

ただし、この方法では時刻以外の形式でも入力できてしまうため、何らか入力値チェックや補正をする必要があります。
→ 実装しました。こちらのページへ https://qiita.com/at-sea/items/96fec874ab0566512256

なお、userInputやvalueOnOpenに値が入っていることはChromeの開発者ツールで地道に調べました。下記スクリーンショットだと右のペインですが、[Scope]-[Local]で引数のcomponentの値を調べられますので、その中を一つ一つ開いて[_data]にあることを確認しました。地味な作業でした・・・。値で調べる方法をご存知の方、教えてください。。。
picker2.png

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5