【Vue&Laravel】入力 or 選択できる「datalist」を使うサンプル

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、ここのところVueの記事を連続して投稿してきたので今回は少し気分を変えて、もっと根本的な内容をお届けしようと思います。

具体的には「HTML 5」です。

というのも、実はHTML 5が公開されたときに色々と新しい機能が追加になったのは知っていたのですが、なにせ「IEだけがサポートしてません・・・😫」というものが多かったのでスルーしているものが多かったんです。

でも、この間<datalist></datalist>という入力候補をリスト表示してくれる機能をつかってみたところ、とても便利で感動しました。(JavaScriptselect2とほぼ同等の機能です)

しかも、Can I use で確認したところdatalistはIE 11でも対応しているんです!(注意書きにはIEは一部のみ対応で、”すっごくバグがある”と書かれていますが、ちょっと確認した限りそこまでおかしな挙動はありませんでした)

ということで今回はこの<datalist></datalist>タグの基本的な使い方からLaravelVueでの動的な使い方までをサンプルとして紹介したいと思います。

ぜひ皆さんのお役に立てると嬉しいです😊✨

開発環境: Laravel 6x、Vue 2.6

まずは体験してみてください

では<datalist></datalist>がどんなものか体験してみてください。

以下は都道府県を入力 or 選択できるボックスになりますので、フォーカスを当ててみてください。都道府県がリスト表示されると思います。


さらにこの入力ボックスに「東」と入力してみてください。

どうでしょう。
東京都だけがフィルタリングされたと思います。

これ、便利ですよね😊✨

基本的な使い方

datalistの使い方は簡単で、通常の入力ボックスのlistプロパティにidを記述するだけです。

<input type="text" list="todofuken_list">
<datalist id="todofuken_list">
    <option value="東京都">
    <option value="大阪府">
    <option value="京都府">
    <option value="福岡県">
    <option value="北海道">
</datalist>

todofuken_listという名前は自由に変更してOKです。

Laravelで動的に使ってみる

では、このdatalistLaravelの中で動的(変数の内容によって可変)にしてみましょう。

シンプルな使い方

結局のところ、先ほどの例のように<option>を用意すればリストとして認識してくれるので、以下のようにループで作成することで実装することができます。

<input type="text" list="todofuken_list">
<datalist id="todofuken_list">
    @foreach(['東京都', '大阪府', '京都府', '福岡県', '北海道'] as $pref)
        <option value="{{ $pref }}">
    @endforeach
</datalist>

※ 分かりやすくするために都道府県を直に記述していますが、後で管理しやすいのでなどの変数に入れておくことをおすすめします。

コンポーネント化する

今回の例のような都道府県を選択する場面は1回だけでなく、何度も必要になってくることが多いです。

そのため、いつでも簡単にこのリストを取得できるように「コンポーネント化」しておくと便利でしょう。

まずコンポーネント本体として、

resources/views/components/todofuken_list.blade.php

というファイルを作成し、中身を以下のように変更します。

<!-- todofuken_list.blade.php -->

<datalist id="todofuken_list">
    @foreach(['東京都', '大阪府', '京都府', '福岡県', '北海道'] as $pref)
        <option value="{{ $pref }}">
    @endforeach
</datalist>

すると、以降は次のようにたった3行だけでリスト選択ができるようになります。

<input type="text" list="todofuken_list">
@component('components.todofuken_list')
@endcomponent

これを応用すると色々なリストを作っておくことができるので開発がより簡単になるでしょう。

Vueで動的に使ってみる

では続いてはVuedatalistを使う例です。

シンプルな使い方

<html>
<body>
    <div id="app">
        <input type="text" list="todofuken_list">
        <datalist id="todofuken_list">
            <option v-for="pref in prefs" :value="pref">
        </datalist>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
    <script>

        new Vue({
            el: '#app',
            data: {
                prefs: ['東京都', '大阪府', '京都府', '福岡県', '北海道']
            }
        });

    </script>
</body>
</html>

内容的には先ほどと同じく<datalist></datalist>内の<option>を動的に作成してやればいいだけなので、dataに都道府県リストを入れておいてv-forループでひとつずつoptionを作ってあげればOKです。

なお、Vuedatalistを使った場合に何が良いかと言うと、「後からリストを変更してもOK!」という点です。今回のようにprefsという変数にリストを入れておけば、後からその内容を変更しても自動的にリスト内容が変更になります。

つまり、以下のようにmounted内でリストを格納してもいいですし、クリックイベントでリスト内容を変更しても問題ありません😊

<div id="app">
    <input type="text" list="todofuken_list">
    <datalist id="todofuken_list">
        <option v-for="pref in prefs" :value="pref">
    </datalist>
    <br>
    <button type="button" @click="changeList">リストを変更</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
<script>

    new Vue({
        el: '#app',
        data: {
            prefs: []
        },
        methods: {
            changeList() {

                // リスト内容を変更する
                this.prefs = ['兵庫県', '奈良県', '滋賀県', '和歌山県', '三重県'];

            }
        },
        mounted() {

            this.prefs = ['東京都', '大阪府', '京都府', '福岡県', '北海道'];

        }
    });

コンポーネント化する

続いて、Vueでもコンポーネントにして後で使いやすくしてみましょう。

// 都道府県リストのコンポーネント
Vue.component('todofuken_list', {
    data() {
        return {
            prefs: ['東京都', '大阪府', '京都府', '福岡県', '北海道']
        };
    },
    template: '<datalist id="todofuken_list">'+
        '<option v-for="pref in prefs" :value="pref"></option>'+
        '</datalist>'
});

new Vue({
    el: '#app'
});

dataが関数の返り値になっていることに注意してください。コンポーネント内ではこのように記述することになっています。

そして、コンポーネントはこのようにして使うことができます。

<div id="app">
    <input type="text" list="todofuken_list">
    <todofuken_list></todofuken_list>
</div>

独自タグを使えるのでより直感的かもしれません。

もっと汎用的なコンポーネント

今回のコンポーネントは都道府県限定でしたが、もしデータの中身が変わっても使える汎用的なコンポーネントも作ってみましょう。

<html>
<body>

    <div id="app">

        <!-- 名前 -->
        <input type="text" list="name">
        <input-list id="name" :options="names"></input-list>

        <!-- 郵便番号 -->
        <input type="text" list="postal-code">
        <input-list id="postal-code" :options="postalCodes"></input-list>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
    <script>

        // コンポーネント本体
        Vue.component('input-list', {
            props: ['options'],
            template: '<datalist>'+
                '<option v-for="option in options" :value="option"></option>'+
                '</datalist>'
        });

        new Vue({
            el: '#app',
            data: {
                names: ['山田太郎', '佐藤次郎', '田中三郎', '山本四郎', '鈴木五朗'],
                postalCodes: ['111-1111', '222-2222', '333-3333'],
            }
        });

    </script>
</body>
</html>

内容としては、input-listというコンポーネントがoptionsというプロパティを取得できるようにし、その内容をループで表示しているだけです。

ただ、ここで重要なのが作成した独自コンポーネントに直接 id を指定ことができるという点です。

<input type="text" list="name">
<input-list id="name" :options="names"></input-list>

先ほどは都道府県で固定でしたのでtodofuken_listというidを直接コンポーネント本体に記述しましたが、今回は<input-list></input-list>タグに指定するようにしています。

つまり、VueコンポーネントはHTMLタグと同じようにつかえるので、より汎用的に使えるというわけですね。

開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回はいつもと違って根本的なHTML 5の内容をお届けしました。

<datalist></datalist>はこれまであまり使ってきませんでしたが、IE 11では対応しているようなので、今後はドシドシ使っていこうと考えています。

また、これまではselect2を使っていたのですが、バージョンで違いがあったりBootstrapのモーダル内では動かなかったりといろいろと手間がかかってしまっていたのも事実なので今後はよりシンプルなコードにするために<datalist></datalist>に置き換えることも考えていかないといけないかな、とも感じました。

ということで、今更ながらですが他のHTML 5もちょっとずつ試していきたいと思います。

ぜひ皆さんも挑戦してみてくださいね。

ではでは〜!

このエントリーをはてなブックマークに追加       follow us in feedly