LoginSignup
0
0

More than 1 year has passed since last update.

Vuetify v-text-filedで数値のmax, minを設定する方法

Posted at

はじめに

Vuetifyのv-text-filedで最大値、最小値の2つを下記のようなルールで入力させたいときの方法です。
いろいろな実現方法あると思いますが、一つの方法として参考になればと思います。

注意:最大値、最小値の上限下限が決まっている場合に有効な方法です。(だと思います)

入力制限ルール:

  • 最大値入力欄には、最小値未満の値を入れられない
  • 最小値入力欄には、最大値未満の値を入れられない

イメージ

  • 初期状態

image.png

  • 最小値のみ入力

image.png

  • 最大値のみ入力

image.png

  • ルール違反時

image.png

コード

<template>
  <v-row align="center">
    <v-col cols="5">
      <v-text-field
        class="inputValue"
        v-model.number="inputMin"
        :rules="[rules.min(inputMax, inputMin)]"
        label="数値を入力"
        type="number"
        @focusout="focusout('min')"
      />
    </v-col>
    <v-col cols="2" class="text-center"><span></span></v-col>
    <v-col cols="5">
      <v-text-field
        class="inputValue"
        v-model.number="inputMax"
        :rules="[rules.max(inputMin, inputMax)]"
        label="数値を入力"
        type="number"
        @focusout="focusout('max')"
      />
    </v-col>
  </v-row>
</template>

<script>
  export default {

    components: {
    },

    props: [
    ],

    data () {
      return {
        inputMin: null,
        inputMax: null,

        INPUT_MIN_VALUE: 0,
        INPUT_MAX_VALUE: 10000,
        rules: {
          min: (max, v) => {
            const _max = max === null? this.INPUT_MAX_VALUE: max // maxが未設定(null)の場合は適当に大きな数字を設定可能な最大値に設定
            return v <= _max || `最大値 よりも小さい値を設定してください`;
          },

          max: (min, v) => {
            if (v === null) return true // 最大値未入力の場合そのままtrueを返す
            const _min = min === null? this.INPUT_MIN_VALUE: min // minが未設定(null)の場合は0を設定可能な最小値に設定
            return v >= _min || `最小値 よりも大きい値を設定してください`;
          }
        }
      }
    },

    computed: {
    },

    watch: {
    },

    methods: {
      focusout (type) {
        // v-text-filedはフォーカスを当てて、何も入力しないでフォーカスを外すと空文字("")がv-modelの中に入るので、その対応
        // (もっとスマートなロジックにしたい)
        const targetVal = type === 'min'? this.inputMin: this.inputMax
        if ((typeof targetVal) === 'string') {
          switch(type) {
            case 'min':
              this.inputMin = null
              break
            case 'max':
              this.inputMax = null
              break
            default
              break
          }
        }
      }
    }
  }
</script>

<style scoped>
.inputValue >>> input[type="number"] {
  -moz-appearance: textfield;
}
.inputValue >>> input::-webkit-outer-spin-button,
.inputValue >>> input::-webkit-inner-spin-button {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
}
</style>

おわりに

ある程度のテストはしていますが、簡単に作ったものなので、入力パターンによっては不具合があるかもしれません。

参考

0
0
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
0
0