勉強のため、メルカリのクローンアプリ作成中です。
商品出品ページに関する備忘録です。
何がしたいか?
- メルカリ本家の商品出品ページと同様、カテゴリーを選択すると、サイズのプルダウンが表示される。
- サイズテーブルは作成せず、activehashで実装。
- 選択したカテゴリーに応じて、サイズの選択肢を変更。
- 選択したカテゴリーにサイズの分類がない場合は、サイズボックスは表示せず、自動的に 該当なし を選択。
最終ゴール
考え方
カテゴリーテーブルとサイズテーブル間に、紐付けるためのテーブルを新たに作成することも考えましたが、今回は、データ量が多くないので、簡易的にJSで実装する方法を考えてみました。
※ 本来は前者がセオリーだと思うので、あまり良い方法ではないかもしれません。
- サイズの全データを取得し、collection_selectで表示
- カテゴリー選択によりイベントを発火させ、カテゴリーidを取得し、カテゴリーidに応じて、不要な選択肢を
display:none;
で隠す。
実装の手順
activehashを導入し、sizeモデルを作成。
※ activehashの導入まで:Qiita【Rails】初めてのactive_hash
size.rb
class Size < ActiveHash::Base
self.data = [
{id: 1, name: 'XXS以下'},
{id: 2, name: 'XS(SS)'},
{id: 3, name: 'S'},
{id: 4, name: 'M'},
{id: 5, name: 'L'},
{id: 6, name: 'XL(LL)'},
{id: 7, name: '2XL(3L)'},
{id: 8, name: '3XL(4L)'},
{id: 9, name: '4XL(5L)以上'},
{id: 10, name: 'FREE SIZE'},
{id: 11, name: '20cm以下'},
{id: 12, name: '20.5cm'},
{id: 13, name: '21cm'},
{id: 14, name: '21.5cm'},
{id: 15, name: '22cm'},
{id: 16, name: '22.5cm'},
{id: 17, name: '23cm'},
{id: 18, name: '23.5cm'},
{id: 19, name: '24cm'},
{id: 20, name: '24.5cm'},
{id: 21, name: '25cm'},
{id: 22, name: '25.5cm'},
{id: 23, name: '26cm'},
{id: 24, name: '26.5cm'},
{id: 25, name: '27cm'},
{id: 26, name: '27.5cm以上'},
{id: 27, name: '60cm'},
{id: 28, name: '70cm'},
{id: 29, name: '80cm'},
{id: 30, name: '90cm'},
{id: 31, name: '95cm'},
{id: 32, name: '100cm'},
{id: 33, name: '110cm'},
{id: 34, name: '120cm'},
{id: 35, name: '130cm'},
{id: 36, name: '140cm'},
{id: 37, name: '150cm'},
{id: 38, name: '160cm'},
{id: 39, name: '10.5cm以下'},
{id: 40, name: '11cm・11.5cm'},
{id: 41, name: '12cm・12.5cm'},
{id: 42, name: '13cm・13.5cm'},
{id: 43, name: '14cm・14.5cm'},
{id: 44, name: '15cm・15.5cm'},
{id: 45, name: '16cm・16.5cm'},
{id: 46, name: '17cm以上'},
:
{id: 65, name: '該当なし'}
]
end
ビューに、selectボックスを作成(※DBからデータ取得するため、selectではなく、collection_selectを使用)。
cssでdisplay:none;
の状態にしておき、カテゴリー選択により、表示させる。
form.html.haml
= form_for @item, local: true do |f|
:
#size_box
%label.item_input__body__label
サイズ
%span.required 必須
.pulldown#size_selectbox
= f.collection_select :size_id, Size.all, :id, :name, {include_blank: "選択してください"}, {class: "size_box"}
= icon('fa', 'chevron-down')
:
jQuery実装。
カテゴリー選択で、イベント発火させる。
item.js
$(document).on('change', '#grandchildren_box', function() {
//選択肢たカテゴリーid情報を取得
let grandchildId = $('#grandchildren_category').val();
//カテゴリーが初期値でない場合
if (grandchildId != "") {
$('.size_box').val('');
$('.size_box option').css('display', 'block');
$('#size_box').css('display', 'block');
//カテゴリー選択によって、サイズボックスの選択肢を変更
if (grandchildId <= 66||grandchildId >= 78 && grandchildId <= 80||grandchildId >= 174 && grandchildId <= 176||grandchildId >= 178 && grandchildId <= 181||grandchildId >= 186 && grandchildId <= 194||grandchildId >= 200 && grandchildId <= 247||grandchildId >= 270 && grandchildId <= 274||grandchildId >= 330 && grandchildId <= 332||grandchildId >= 340 && grandchildId <= 342) {
$('.size_box option[value]').each(function(i) {
if (i>=11) {
$('.size_box option[value = ' +(i)+ ']').css('display', 'none');
}
});
} else if (grandchildId >= 67 && grandchildId <= 77||grandchildId >= 248 && grandchildId <= 256) {
$('.size_box option[value]').each(function(i) {
if (i>=1&&i<11 || i>=27) {
$('.size_box option[value = ' +(i)+ ']').css('display', 'none');
}
});
:
:
//サイズの分類がないカテゴリーが選択された時
} else {
$('#size_box').css('display', 'none');
$('.size_box').val(65);
}
//カテゴリーが初期値の場合
} else {
$('.size_box').val('');
$('#size_box').css('display', 'none');
}
});