ha6_6ruブログ

主にフロントエンドの技術ネタを中心にしていく予定です。

コード値(区分値)選択用フィールドの作り方

概要

コード値(区分値)の選択用フィールドを、Vuetifyを使って実装する方法について解説します。 これだけだったらVuetifyの公式ドキュメントで十分な内容なのですが、今回は業務利用を想定したコード値選択用フィールドの実装について解説します。

業務用アプリケーションによくあるコード値の選択用フィールド

窓口業務で使うアプリケーションでは、オペレーターさんが直接コード値を入力するケースがあります。 これは、コード値がわかっていればドロップダウン式やスクロール式のリスト選択よりも入力が速くなるからだと思います*1

作り方

Vuetifyのv-autocomplete Autocomplete component — Vuetify を使って、入力を補完できるようにしてみます。 題材は銀行コードにします。銀行コードは馴染みがあると思いますが、こちら 金融機関コード・銀行コード検索 のコードです。

コード値選択フィールドの外観

これから作成するコード値選択フィールドの外観はこちらです。

コード値選択フィールド
コード値選択フィールド
選択フィールドには、選択肢としてコード値と名称の両方を表示します。

コード値選択フィールドの入力補助
コード値選択フィールドの入力補助

オートコンプリート機能は、コード値と名称の両方を扱えるようにします。

Vuetifyを使った実装指針

コード値と名称の両方を表示し、選択された値にコード値を扱えるようにするには*2、Vue.jsの実装としては表示(v-bind)と入力(v-on)を分ければよいですね。Vuetifyは最初からこれらを分離することができるように設計されており、専用のプロパティが用意されています。それでは実装方法を見ていきましょう。

その1 コード値をキャッシュする

選択肢が少ない場合は、クライアント上にキャッシュしてしまいましょう。

template

<v-autocomplete
  v-model="selectedBankCode"
  outlined
  dense
  :items="bankList"
  :item-text="formatBankCode"
  item-value="code"
  label="銀行コード"
/>

プロパティの解説です。

  • v-model: 選択したコード値を格納するプロパティを指定します。
  • outlined: フォームを線で囲まれたスタイルにします。
  • dense: フォームの高さを下げます。
  • items: 選択候補のリストを格納したプロパティ指定します。
  • item-text: コード値の表示をカスタマイズするためのメソッドを指定します。
  • item-value: 選択されたコード値のキーとして扱う値を、リストのプロパティから指定します。
  • label: フィールドの項目を示すラベルです。

script

script部は今回は@vue/composition-apiを使って記述します。

<script>
import { defineComponent, reactive, toRefs } from '@vue/composition-api';

export default defineComponent({
  setup() {
    const state = reactive({
      selectedBankCode: null,
      bankList: [
        { name: 'みずほ銀行', code: '0001' },
        { name: '三菱UFJ銀行', code: '0005' },
        { name: '三井住友銀行', code: '0009' },
        { name: 'りそな銀行', code: '0010' },
        { name: '埼玉りそな銀行', code: '0017' },
      ],
    });

    const formatBankCode = value => {
      return `${value.code}: ${value.name}`;
    };

    return {
      ...toRefs(state),
      formatBankCode,
    };
  },
});
</script>

bankListを固定のオブジェクトにしていますが、実際にはMVVMモデルでいうところのModelに格納し、値が空であればWebAPIを経由して取得するといった、キャッシュとして扱う形で実装します。
formatBankCodeでコード値と名称の両方を組み合わせた、リスト表示用の文字列を組み立てています。 コード値選択フィールドでコード値を選択すれば、selectedBankCodeにコード値(埼玉りそな銀行であれば0017)が格納されます。 ほぼほぼv-autocompleteの機能で実現できてしまうので簡単ですね。

その2 コード値を都度WebAPI経由で取得する

選択肢が多い場合は、クライアント上には大きなデータを保持しないようにするといいでしょう。 WebAPIで絞り込みを行い、該当するコード値のみを選択肢として表示する形を想定して実装し ます。

template

<v-autocomplete
  v-model="selectedBankCode"
  outlined
  dense
  no-filter
  :loading="isLoading"
  :search-input.sync="keyword"
  :items="bankList"
  :item-text="formatBankCode"
  item-value="code"
  label="銀行コード"
/>

その1のキャッシュ方式から追加したプロパティの解説です。

  • no-filter: ブラウザー上のフィルタリングを無効にします。有効にするとWebAPI経由での取得タイミングのずれによって、少し動作に違和感があったので無効にしています。
  • loading: リストの読み込み中であることを表現するプロパティを指定します。このプロパティを使うと、フィールド下部にプログレスバーが表示できます。
  • search-input: フィールドに入力した文字列を格納するプロパティを指定します。

script

<script>
import { defineComponent, reactive, toRefs, watch } from '@vue/composition-api';
import axios from 'axios';

const fetchBankCodes = async value => {
  const response = await axios.get('bank-codes');
  return response.data;
};

export default defineComponent({
  setup() {
    const state = reactive({
      isLoading: false,
      keyword: null,
      selectedBankCode: null,
      bankList: [],
    });

    watch(
      () => state.keyword,
      async () => {
        state.isLoading = true;
        state.bankList = await fetchBankCodes(state.keyword);
        state.isLoading = false;
      },
    );

    const formatBankCode = value => {
      return `${value.code}: ${value.name}`;
    };

    return {
      ...toRefs(state),
      formatBankCode,
    };
  },
});
</script>

search-inputで指定したプロパティkeywordをウォッチし、値が変更されたらWebAPIを呼び出して選択候補のコード値リストを取得し、プロパティに設定します。WebAPIの呼び出しはModelに実装することをおすすめしますが、ここでは単純化するめコンポーネント内に関数を配置しました。
WebAPIの呼び出し中にプログレスバーを表示するために、WebAPIの呼び出し前後でisLoadingプロパティを設定しています。

終わりに

実際にはここからさらにスタイルを変更したり、細かい動作の修正を行うことになると思いますが、Vuetifyを使うことでとても簡単に実装できました。
コード値と名称の両方でオートコンプリート機能を使うことができること、コード値と名称がセットで表示されるので入力誤りを防止する効果も期待できることがポイントです。コード値を選択するUIの候補として参考にしてもらえると嬉しいです。

書籍の紹介

宣伝となり恐縮ですが、こちらの書籍でVue.jsとVuetifyを扱っていますので、参考にしていただければ幸いです。


書籍の情報サイト

紹介

人気のJavaScriptフレームワークVue.jsにフォーカスし、フロントエンド開発の基礎から本格的なSPAの開発まで、ハンズオン形式で一歩ずつ、無理なく着実にステップアップしていきます。 さらに、2020年リリース予定のVue.js 3.0をいち早くキャッチアップ。Vue CLI 4に対応しつつ、Vue.js 2.xとの差分として新しい記述スタイル(Composition API)を併記するなど、バージョン移行を強力に支援します。

基本情報

*1:実際に窓口業務で使うアプリケーションの入力作業を見せてもらったことがあるのですが、オペレーターさんは私からすると異常な速さで入力していきます。

*2:コード値のデータ構造に依存するので、選択された値にIDを使用するケースもあるでしょう。