
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、先日とあるオンライン・ショッピングサイトにスマホで訪問したのですが、注文をするときに「こうだったらいいのにな」と思うことがありました。
それは・・・
セレクトボックスに画像がほしい
というものでした。
・・・というのも、その注文では5〜6個の商品を個別に選ぶことができたんですが、選ぶときに商品名だけなので「うーん、どの商品かイメージできない」となったからなんですね。
(しかも、スマホだったので別ページに移動すると選択した商品がクリアされてしまうわけです)
そこで!
今回はVue
を使って「ポップアップする画像つきセレクトボックス」をつくってみたいと思います。
ぜひ皆さんのお役に立てると嬉しいです
(最後に今回実際に開発したソースコード一式をダウンロードできますよ)
「ステイホームなので、
YouTubeばかり見ています」
開発環境: Laravel 7.x、Vue 2.6、jQuery 3.4.1、Bootstrap 4.4.1
この記事を見たらできること
以下のような画像つきのセレクトボックスをつくることができます。
なお、「選択を解除」をクリックすると選択がクリアされるようにします。
ではやっていきましょう
HTML部分をつくる
まず基本となるHTMLを用意します。
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="app" class="p-3">
<!-- セレクトボックス(実際はボタン) ・・・ ① -->
<button type="button" class="btn border-secondary" data-toggle="modal" data-target="#image-select-modal">
<div v-if="!selectedItem">選択してください ▼</div>
<div v-else>
<img :src="selectedItem.thumbnailUrl" style="height:30px;">
<span class="mr-1" v-text="selectedItem.title"></span>
</div>
</button>
<!-- ポップアップ部分(モーダル) ・・・ ② -->
<div class="modal fade" id="image-select-modal">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">選択してください</h5>
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
</div>
<div id="modal-body" ref="modal-body" class="modal-body p-0" style="width:100%;overflow:auto;">
<table class="table table-striped">
<tr v-for="item in items"
:id="'item-'+ item.id"
style="cursor:pointer;"
@click="selectItem(item)">
<td class="p-3 align-top">
<img :src="item.thumbnailUrl">
</td>
<td class="pt-3 pr-3 align-top" style="width:100%;">
<h5 v-text="item.title"></h5>
<p style="white-space:pre-wrap;" class="text-secondary" v-html="item.description"></p>
</td>
</tr>
</table>
</div>
<div class="modal-footer">
<a href="#" class="modal-default-button" @click.prevent="clearItem">選択を解除</a>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.bundle.min.js"></script>
<script>
new Vue({
el: '#app',
// ここにVueのコード(次の項目で説明します)
});
</script>
</body>
</html>
① セレクトボックス(実際はボタン)
実際は<button>...</button>
タグなので、セレクトボックスではありませんが、ここをクリックするとポップアップで画像つきの商品が選択できるようにします。
また、商品が「選択されている or 選択されていない」で表示を切り替えるようにし、選択されたらサムネイル画像と商品名を表示するようにします。
( こんなカンジです)
② ポップアップ(モーダル)部分
ここはBootstrap
のモーダル機能を使って実装します。
ただし、このモーダルの中に表示される「商品リスト」はVue
でレンダリングしていることに注目してください。
なお、:id="'item-'+ item.id"
の部分は例えば「item-1」のようなIDになりますが、これは後ほどスクロール位置を移動させるために使います。
JavaScript部分をつくる
では、JavaScript
の部分をつくっていきましょう。
先ほどつくったVueコード
を次のように変更してください。
new Vue({
el: '#app',
data: {
items: [],
selectedItem: null
},
methods: {
selectItem(item) { // リストから選択 ・・・ ①
this.selectedItem = item;
$('#image-select-modal').modal('hide');
},
clearItem() { // 選択を解除 ・・・ ②
this.selectedItem = null;
$('#image-select-modal').modal('hide');
}
},
mounted() {
// テスト商品データをつくる ・・・ ③
let items = [];
for(let i = 1 ; i <= 25 ; i++) {
items.push({
id: i,
title: 'サンプル商品名 - '+ i,
description: "サンプル商品説明\nサンプル商品説明\nサンプル商品説明 - "+ i,
thumbnailUrl: 'https://via.placeholder.com/100/FF5555/FFFFFF?text=item+'+ i
});
}
this.items = items;
// モーダルの高さを調整 ・・・ ④
const modalBody = this.$refs['modal-body'];
modalBody.style.maxHeight = parseInt(window.innerHeight*0.7) +'px';
// モーダルが表示されたら選択位置へ移動 ・・・ ⑤
$('#image-select-modal').on('shown.bs.modal', () => {
const top = (this.selectedItem)
? $('#item-'+ this.selectedItem.id).position().top
: 0;
$('#modal-body').scrollTop(top);
});
}
});
では、ひとつずつ解説していきます。
① リストから選択
ポップアップ表示された商品データが選択されたときに実行されるコードです。
ここで選択されたデータをselectedItem
に格納し、結果としてVue
が自動的にセレクトボックスの表示を切り替えることになります。(また、自動的にポップアップは閉じます。)
② 選択を解除
「選択を解除」リンクがクリックされたときに実行されるコードです。
ここでは、selectedItem
をnull
に戻し、ポップアップを閉じることになります。すると、Vue
がセレクトボックスの表示を元に戻すことになります。
③ テスト商品データをつくる
ポップアップする商品リストのテストデータです。
今回はfor()
ループで作っていますが、実際にはAjax
などでデータを取ってくることになると思います。
なお、サムネイル画像はplaceholder.comを利用しています。
④ モーダルの高さを調整
モーダル(ポップアップ)の高さをウィンドウサイズの70%に変更しています。お好みで変更してください。
⑤ モーダルが表示されたら選択位置へ移動
すでに商品が選択されている場合、モーダルを再表示したときにスクロール位置をその商品に合わせるようにしています。(ここでHTML側でつくったIDを使っています)
なお、商品が選択されていない場合はトップ位置になります。
テストしてみる
では実際にテストしてみましょう!
まず表示されたボタンをクリックします。
すると、次のようなポップアップが表示されました。
適当に商品を選択してみます。
選択された商品がボタンの中に表示されました。
選択されました
ではもう一度ポップアップさせて、「選択を解除」をクリックしてみましょう。
すると、初期状態に戻りました。
成功です
教材ソースコードをダウンロードする
今回実際に開発した教材ソースコードを以下からダウンロードできます。
Vueでポップアップする画像つきセレクトボックスをつくる※CDN
を使っているので展開したらすぐ実行できますよ
おわりに
ということで今回はVue
を使った画像つきセレクトボックスをつくってみました。
セレクトボックスに画像がついていると、イメージがしやすいですし、画面移動しなくて良くなるので特にスマホではユーザビリティが向上するんじゃないでしょうか。
また、今回のコードではjQuery
とVue
が共存していますが、こういう使い方もできるんだというのを体験していただけると嬉しいです。
JavaScript
のフレームワークも1つだけに絞った方がいいのはもちろんですが、それも状況によって臨機応変に使えば開発スピードを上げることができると思います。
ぜひそのあたりも注目しながらチャレンジしてみてくださいね。
ではでは〜
「そういえば、Bootstrap 5では
jQueryは不要になるらしいですね」