アパレル系のショッピングサイトで見かける、色やサイズを別々に選択するタイプのカートボタンを作成しました。
カラーとサイズを選択したらカートボタンをクリックできる仕様です。
最終的にformでデータを送信することを想定して、パラメーターも設定できるようにしたのでメモ。
作成のポイントは次の通りです。
- 1ページに複数のカートボタンの設置が可能。
- カートボタンをクリック後、プルダウンメニューの項目をリセット。
- 欠品がある場合にも対応。(欠品の場合、メニューに「売り切れ」を表示)
- 最終的に、formで送信するパラメーターが複数の場合も対応。
完成したカートボタンを確認する
こちらが完成した動作です。最初、サイズは選択できませんが、カラーを選んだら選択できるようになります。
動作デモ
実際の動作はこちらでご確認ください!(別ウィンドウが開きます)
ソースコードを確認
カラーを選択したら、サイズのオプションが連動して切り替わります。動作は全てjavascriptで実装しました。
作成手順のポイントをメモしておきます。
ページの構造をHTMLで作る
<div class="form_wrap">
<form name="form_select_1" class="form_layout form_select">
<div class="select_wrap">
<span class="select_label">カラー:</span>
<span class="select_box">
<select name="sku_color" class="sku_color">
<option value="">--カラーを選択してください--</option>
<option value="0">レッド</option>
<option value="1">グリーン</option>
<option value="2">イエロー</option>
<option value="3">パープル</option>
</select>
</span>
</div>
<div class="select_wrap">
<span class="select_label">サイズ:</span>
<span class="select_box">
<select name="sku_size" class="sku_size">
<option value="">--サイズを選択してください--</option>
</select>
</span>
</div>
<p class="shopping-btn">
<!--デザイン-->
<a onclick="form_sku_select(document.form_select_1);return false;" href="">
お買い物かごに入れる<i class="fas fa-shopping-cart"></i>
</a>
</p>
</form>
</div><!-- /form_wrap -->
form名は固有の名前にします。ここでは「form_select_1」です。
このformは、お買い物かごをクリックした時に実行される関数「form_sku_select」に引数として渡します。
複数のカートボタンを設置する事を想定して、共通のクラス名「form_layout」を設定します。
サイズのオプションに関しては、選択されたカラーによって動的に切り替わるのでHTMLには記述しません。
そして「お買い物かご」をクリックしたら、カラー・サイズのオプション選択の判定及び、プルダウンメニューのリセットを実行します。
読み込み時、カラー・サイズのオプションを初期化する
ここからはjavascriptで実装していきます。
ページ読み込み時、全てのカラー・サイズのオプションを初期化します。
複数のカートボタンがあることを想定して、「form_select」のクラス名があるformに対して同じ処理を実行します。
// 読み込み時の「色・サイズ」を選択なしに設定
let setSizeDefault = (function() {
var form_select = document.querySelectorAll(".form_select");
for(var i = 0; i < form_select.length; ++i){
setDefaultOption(form_select[i]);
};
})();
// オプション初期化
function setDefaultOption(targetForm) {
// 初期化
targetForm.sku_color.options[0].selected = true;
targetForm.sku_size.textContent = null;
// option生成
let op = document.createElement("option");
op.value = "";
op.text = "--サイズを選択してください--";
op.hidden = true;
targetForm.sku_size.style.backgroundColor = "#999";
targetForm.sku_size.appendChild(op);
}
関数setDefaultOptionでは、カラーの選択を初期値「–カラーを選択してください–」に変更します。
そして、サイズのオプションの中身を一旦全て削除し、改めて初期値だけのオプションを生成します。
その際、サイズメニューが選択できないようにします。
また、選択できないことを分かりやすくするため、背景の色をグレーにします。
この関数は、カラーの選択を初期値「–カラーを選択してください–」にした場合、都度実行されます。
カラー変更時にサイズのオプションが連動して切り替わるようにする
カラーを変更したらサイズのオプションが切り替わるようにしますが、生成されるサイズのタグは次のようになります。
カラー「赤」を選択した時に生成されるサイズのオプション
<select name="sku_size" class="sku_size">
<option value="">--サイズを選択してください--</option>
<option value="レッド(22.5cm),CLS11">22.5cm</option>
<option value="レッド(23.0cm),CLS12">23.0cm</option>
<option value="レッド(23.5cm),CLS13">23.5cm</option>
<option value="レッド(24.0cm),CLS14">24.0cm</option>
<option value="レッド(24.5cm),CLS15">24.5cm</option>
</select>
optionタグのvalue値に、送信したいパラメーターを「,」で区切って記載します。
ここでは、色とサイズ(例:レッド(22.5cm))、そして商品コード(例:CLS11)をパラメーターとして渡すと仮定します。
サイズ、商品コードを配列に格納する
サイズの属性に設定する値は、次のように配列に格納しておきます。
let SizeRed = [
{label:"--サイズを選択してください--",skuCode:""},
{label:"22.5cm",skuCode:"レッド(22.5cm),CLS11"},
{label:"23.0cm",skuCode:"レッド(23.0cm),CLS12"},
{label:"23.5cm",skuCode:"レッド(23.5cm),CLS13"},
{label:"24.0cm",skuCode:"レッド(24.0cm),CLS14"},
{label:"24.5cm",skuCode:"レッド(24.5cm),CLS15"}
];
各カラーごとにサイズと商品コードを変数に格納します。今回はレッド、グリーン、イエロー、パープルの4色分の変数を設定しています。
ついでに欠品した商品も配列に格納しておきます。格納するのは商品コードのみで、欠品商品がなければ配列は空の状態にしておきます。今回は3つの商品が欠品になっているとします。
// 欠品-商品番号
let soldOut = ["CLS21","CLS19","CLS30"];
カラー変更時のイベントをセットする
カラーのプルダウンメニューが変更されたらイベントが発火するようにセットします。
複数のカートボタンがあることを想定して、「sku_color」のクラス名があるプルダウンメニューすべてにイベントをセットします。
// 「カラー」変更時のイベントセット
let sku_color = document.querySelectorAll(".sku_color");
for(let i = 0; i < sku_color.length; ++i) {
sku_color[i].addEventListener('change', changeSize);
};
先ほどセットしたイベントで実行される関数はこんな感じです。
// カラーの選択肢が変更された際の処理
function changeSize() {
let changeForm = this.form;
let changedColorValue = this.value;
if (changedColorValue == "0") {
setSize(SizeRed,changeForm);
} else if (changedColorValue == "1") {
setSize(SizeGreen,changeForm);
} else if (changedColorValue == "2") {
setSize(SizeYellow,changeForm);
} else if (changedColorValue == "3") {
setSize(Sizepurple,changeForm);
} else {
setDefaultOption(changeForm)
}
}
カラーのプルダウンメニューを変更した時、設定されているvalueの値を取得します。
設定されている値は次の通りです。
初期値→値無し、レッド→0、グリーン→1、イエロー→2、パープル→3
value値によって、関数「setSize」に引数で渡す「商品のサイズ、商品コード」を変更します。
// カラーの選択肢が変更された際の処理
function changeSize() {
let changeForm = this.form;
let changedColorValue = this.value;
if (changedColorValue == "0") {
setSize(SizeRed,changeForm);
} else if (changedColorValue == "1") {
setSize(SizeGreen,changeForm);
} else if (changedColorValue == "2") {
setSize(SizeYellow,changeForm);
} else if (changedColorValue == "3") {
setSize(Sizepurple,changeForm);
} else {
setDefaultOption(changeForm)
}
}
setSize関数でサイズオプションの切り替えをします。
実行の際、選択された「カラーのサイズ、商品コード」と「カラーを変更したform自身」が引き渡されています。
// オプションセット
function setSize(sizeColor,targetForm) {
// 初期化
targetForm.sku_size.textContent = null;
targetForm.sku_size.style.backgroundColor = "#fff";
sizeColor.forEach(function(value) {
let op = document.createElement("option");
op.value = value.skuCode;
op.text = value.label;
//欠品対応
for (let i=0; i<soldOut.length;i++){
if(op.value.match(soldOut[i])) {
op.disabled = true;
op.text += " " + "売り切れ"
}
}
targetForm.sku_size.appendChild(op);
});
}
最初にサイズオプションを初期化した後、配列で渡された「カラーのサイズ、商品コード」を元にオプションを生成します。
その際、売り切れの商品があったら選択できないようにして「売り切れ」の文言を追加します。
参考サイト
「お買い物かごに入れる」ボタンをクリックした時の処理
最後に、購入ボタンをクリックした時の処理を記述します。
// カートボタンをクリックした時の処理
function form_sku_select(form_sku_select){
if(!form_sku_select.sku_size.value){
alert("色・サイズを選択してください。");
return;
}
let cartParam= form_sku_select.sku_size.value.split(",");
alert('選択した商品は' + cartParam[0] + "、SKUコードは" + cartParam[1] + "です");
//セレクトボックスを初期値に戻す
let form_select = document.querySelectorAll(".form_select");
for(let i = 0; i < form_select.length; ++i){
form_select[i].sku_color.options[0].selected = true;
form_select[i].sku_size.options[0].selected = true;
}
}
まず、サイズのvalue値があるかでカラーとサイズが選択されているかをチェックします。
選択していなかったら、アラートを表示して処理を中止します。
カラーとサイズが選択されていたら、サイズのvalue値を取得します。値は次のような文字列となっています。
レッド(22.5cm),CLS11
この文字列を「,」(カンマ)で分割して、配列にします。
今回は分割したパラメーターをアラートで表示しましたが、必要に応じて別のformに値をセットします。
パラメーターの値に関しての処理が終わったら、プルダウンメニューの選択を初期化します。
「form_select」のクラス名があるformに対して初期化する処理を実行します。
メニューを初期化する理由ですが、ページが遷移した後、ブラウザの「戻る」などで元のページに戻ると、ブラウザによっては、選択したメニューの値が残っています。
選択したメニューの値が残っていると、動的に生成したサイズのオプションが表示されなくなるので、対応処置として初期化します。。
まとめ
今回のカートのプルダウンメニューで難しかったのは、色々な動作で常にサイズオプションのリセット(初期化)が必要なところです。
あと、イベント実行のタイミングでエラーが表示されることも多かったです。。
一応動くサンプルが作れたので、メモしておきます!
コメント