WooCommerce:無料プラグイン+jQueryでバリエーションを一覧表示し複数選択可能にする
目次
バリエーション商品を複数選択可能にしたい
WooCommerce でバリエーション商品の時に
プルダウンでの表示となりますが
これを一覧にして複数選択可能にしたいと思いました。
色々と調べて有料プラグインの導入も検討しましたが
がっつり改良出来る機能豊富なプラグインが多くて
ただこれだけをやりたいだけなのにそんなに複雑な機能は要らないなぁと思い…。
試行錯誤しつつなんとかそれっぽい動作を実現する事が出来たので
記録しておこうと思います。
うちの環境
・WooCommerce v8.1.1
・テーマ:StoreFront v1.0.1
(StoreFrontが古いのでバージョンアップしたい所..)
プラグイン:Side Cart Woocommerce
こちらのプラグインを使用しています。
Side Cart Woocommerce (Ajax) – WordPress プラグイン | WordPress.org 日本語
ajaxでカートに入れる系のプラグインをいくつか試してみたのですが
こちらが動作も安定しておりデザインや操作性も良いです!✨
JS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
jQuery(document).ready(function ($) { // data-product_variations属性からJSONデータを取得 var productVariations = JSON.parse($('.variations_form.cart').attr('data-product_variations')); // テーブル要素を生成 var table = $('<table class="variation-table">').appendTo('body'); // thead var thead = $('<thead>').appendTo(table); var theadRow = $('<tr>').appendTo(thead); theadRow.append($('<th class="variation-table-check">')); theadRow.append($('<th class="variation-table-product">').text('商品')); theadRow.append($('<th class="variation-table-price">').html('価格')); // tfoot var tfoot = $('<tfoot>').appendTo(table); var tfootRow = $('<tr>'); tfootRow.append($('<th colspan="2">').text('合計金額')); tfootRow.append($('<th class="variation-table-price">').text('¥0')); tfoot.append(tfootRow); // tbody var tbody = $('<tbody>').appendTo(table); // JSONデータをテーブルに挿入 productVariations.forEach(function (product) { var row = $('<tr>').appendTo(tbody); // 属性名 var key = Object.keys(product.attributes)[0]; // チェックボックス var selectCheckbox = $('<input>').attr('type', 'checkbox').attr('value', product.attributes[key]); row.append($('<td class="variation-table-check">').append(selectCheckbox)); // 商品名 row.append($('<td class="variation-table-product">').append(product.attributes[key])); // 金額 row.append($('<td class="variation-table-price">').text('¥' + product.display_price.toLocaleString())); }); // テーブルを.variations_formの上に挿入 $('.variations_form').before(table); // チェックボックス $(".variation-table-check input").on("change", function() { var totalAmount = 0; // チェックボックスがチェックされている行の価格を合計 $('td.variation-table-check input[type="checkbox"]:checked').each(function () { var price = parseFloat($(this).closest('tr').find('.variation-table-price').text().replace('¥', '').replace(',', '')); totalAmount += price; }); // 合計金額を表示 $('.variation-table tfoot .variation-table-price').text('¥' + totalAmount.toLocaleString()); // カートに追加ボタン if ( totalAmount > 0 ) { $('.variation-table-btn').removeClass('disabled'); } else { $('.variation-table-btn').addClass('disabled'); } }); // カートに追加ボタン var purchaseButton = $('<button class="variation-table-btn disabled">').text('カートに追加').on('click', function () { if ( $(this).hasClass('disabled') ) { alert('商品を選択して下さい'); } // チェックボックスがチェックされている行だけ処理を実行 var checkboxes = $('.variation-table-check input[type="checkbox"]:checked'); checkboxes.each(function (index) { var selectedValue = $(this).val(); var delay = index * 1000; setTimeout(function () { $('.variations select').val(selectedValue).change(); // ボタンをクリックする $(".single_add_to_cart_button").click(); }, delay); }); }); $('.variation-table').after(purchaseButton); }); |
jQueryでバリエーションの情報を整形してチェックボックスで表示し
「選択した商品をカートに入れる処理を繰り返す」という形になっています。
Ajaxで追加する処理を実装した方が良さそうなのですがやり方がよく分からないため
間隔を開けて(setTimeout)カートボタンのクリックを実行しています。
たまにカートに入らない時があるような…
ここの処理は要検討。
ChatGPT
最近コードはもっぱらChatGPTに書いて貰います…。
コードが長くなると破綻してきたり説明も面倒になってくるので
分解して部分部分で質問すると良い感じです。
大枠の作りとか処理の流れを決めて
細かい処理の部分はChatGPTで書いてもらう
ってのが楽で良いですね〜…
CSS
cssは表示を多少整えているだけなので
テーマに合わせて適宜…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* デフォルト項目の非表示 */ .variations, .single_variation_wrap, .variations_form.cart, .entry-summary .price { display: none; } /*表示調整 */ .variation-table-check { width: 30px; } .variation-table-price { width: 120px; text-align: right; } .variation-table-btn { width: 100%; margin-bottom: 1rem; } |
補足:バリエーションのデータ
form.variations_form[product_variations] に
バリエーションのデータが入っていたので、
こちらを取得しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<form class="variations_form cart" action="https://shop.homemadegarbage.com/?post_type=product&p=8828" method="post" enctype="multipart/form-data" data-product_id="8828" data-product_variations="[{"attributes":{"attribute_%e3%83%90%e3%83%aa%e3%82%a8%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3":"\u30c6\u30b9\u30c8\u5546\u54c1A"},"availability_html":"","backorders_allowed":false,"dimensions":{"length":"","width":"","height":""},"dimensions_html":"\u8a72\u5f53\u306a\u3057","display_price":3300,"display_regular_price":3300,"image":{"title":"","caption":"","url":"","alt":"","src":"","srcset":false,"sizes":false},"image_id":0,"is_downloadable":false,"is_in_stock":true,"is_purchasable":true,"is_sold_individually":"no","is_virtual":false,"max_qty":"","min_qty":1,"price_html":"<span class=\"price\"><span class=\"woocommerce-Price-amount amount\"><bdi><span class=\"woocommerce-Price-currencySymbol\">&yen;<\/span>3,300<\/bdi><\/span> <small class=\"woocommerce-price-suffix\">\uff08\u7a0e\u8fbc\uff09<\/small><\/span>","sku":"","variation_description":"<p>\u5546\u54c1\u306e\u8aac\u660e\u5546\u54c1\u306e\u8aac\u660e\u5546\u54c1\u306e\u8aac\u660e<\/p>\n","variation_id":8832,"variation_is_active":true,"variation_is_visible":true,"weight":"","weight_html":"\u8a72\u5f53\u306a\u3057"},{"attributes":{"attribute_%e3%83%90%e3%83%aa%e3%82%a8%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3":"\u30c6\u30b9\u30c8\u5546\u54c1B"},"availability_html":"","backorders_allowed":false,"dimensions":{"length":"","width":"","height":""},"dimensions_html":"\u8a72\u5f53\u306a\u3057","display_price":4950,"display_regular_price":4950,"image":{"title":"","caption":"","url":"","alt":"","src":"","srcset":false,"sizes":false},"image_id":0,"is_downloadable":false,"is_in_stock":true,"is_purchasable":true,"is_sold_individually":"no","is_virtual":false,"max_qty":"","min_qty":1,"price_html":"<span class=\"price\"><span class=\"woocommerce-Price-amount amount\"><bdi><span class=\"woocommerce-Price-currencySymbol\">&yen;<\/span>4,950<\/bdi><\/span> <small class=\"woocommerce-price-suffix\">\uff08\u7a0e\u8fbc\uff09<\/small><\/span>","sku":"","variation_description":"","variation_id":8833,"variation_is_active":true,"variation_is_visible":true,"weight":"","weight_html":"\u8a72\u5f53\u306a\u3057"},{"attributes":{"attribute_%e3%83%90%e3%83%aa%e3%82%a8%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3":"\u30c6\u30b9\u30c8\u5546\u54c1C"},"availability_html":"","backorders_allowed":false,"dimensions":{"length":"","width":"","height":""},"dimensions_html":"\u8a72\u5f53\u306a\u3057","display_price":5500,"display_regular_price":5500,"image":{"title":"","caption":"","url":"","alt":"","src":"","srcset":false,"sizes":false},"image_id":0,"is_downloadable":false,"is_in_stock":true,"is_purchasable":true,"is_sold_individually":"no","is_virtual":false,"max_qty":"","min_qty":1,"price_html":"<span class=\"price\"><span class=\"woocommerce-Price-amount amount\"><bdi><span class=\"woocommerce-Price-currencySymbol\">&yen;<\/span>5,500<\/bdi><\/span> <small class=\"woocommerce-price-suffix\">\uff08\u7a0e\u8fbc\uff09<\/small><\/span>","sku":"","variation_description":"","variation_id":8834,"variation_is_active":true,"variation_is_visible":true,"weight":"","weight_html":"\u8a72\u5f53\u306a\u3057"}]" current-image=""> <table class="variations" cellspacing="0" role="presentation" style="display: none;"> <tbody> <tr> <th class="label"><label for="%e3%83%90%e3%83%aa%e3%82%a8%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3">バリエーション</label></th> <td class="value"> <select id="%e3%83%90%e3%83%aa%e3%82%a8%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3" class="" name="attribute_%e3%83%90%e3%83%aa%e3%82%a8%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3" data-attribute_name="attribute_%e3%83%90%e3%83%aa%e3%82%a8%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3" data-show_option_none="yes"><option value="">選択してください</option><option value="テスト商品A" class="attached enabled">テスト商品A</option><option value="テスト商品B" class="attached enabled">テスト商品B</option><option value="テスト商品C" class="attached enabled">テスト商品C</option></select><a class="reset_variations" href="#" style="visibility: visible;">クリア</a> </td> </tr> </tbody> </table> <div class="single_variation_wrap" style=""> <div class="woocommerce-variation single_variation" style=""> <div class="woocommerce-variation-description"><p>商品の説明商品の説明商品の説明</p> </div> <div class="woocommerce-variation-price"><span class="price"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">¥</span>3,300</bdi></span> <small class="woocommerce-price-suffix">(税込)</small></span></div> <div class="woocommerce-variation-availability"></div> </div><div class="woocommerce-variation-add-to-cart variations_button woocommerce-variation-add-to-cart-enabled"> <div class="quantity"> <label class="screen-reader-text" for="quantity_651f75763f6f5">variation-table デモページ個</label> <input type="number" id="quantity_651f75763f6f5" class="input-text qty text" name="quantity" value="1" aria-label="商品数量" size="4" min="1" max="" step="1" placeholder="" inputmode="numeric" autocomplete="off"> </div> <button type="submit" class="single_add_to_cart_button button alt added">お買い物カゴに追加</button><a href="https://shop.homemadegarbage.com/cart/" class="added_to_cart wc-forward" title="お買い物カゴを表示">お買い物カゴを表示</a> <input type="hidden" name="add-to-cart" value="8828"> <input type="hidden" name="product_id" value="8828"> <input type="hidden" name="variation_id" class="variation_id" value="8832"> </div> </div> </form> |
ChatGPTに整形してもらった所
このようなjsonデータが入っているようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
[ { "attributes": { "attribute_バリエーション": "テスト商品A" }, "availability_html": "", "backorders_allowed": false, "dimensions": { "length": "", "width": "", "height": "" }, "dimensions_html": "該当なし", "display_price": 3300, "display_regular_price": 3300, "image": { "title": "", "caption": "", "url": "", "alt": "", "src": "", "srcset": false, "sizes": false }, "image_id": 0, "is_downloadable": false, "is_in_stock": true, "is_purchasable": true, "is_sold_individually": "no", "is_virtual": false, "max_qty": "", "min_qty": 1, "price_html": "<span class=\"price\"><span class=\"woocommerce-Price-amount amount\"><bdi><span class=\"woocommerce-Price-currencySymbol\">¥</span>3,300</bdi></span> <small class=\"woocommerce-price-suffix\">(税込)</small></span>", "sku": "", "variation_description": "", "variation_id": 8832, "variation_is_active": true, "variation_is_visible": true, "weight": "", "weight_html": "該当なし" }, { "attributes": { "attribute_バリエーション": "テスト商品B" }, "availability_html": "", "backorders_allowed": false, "dimensions": { "length": "", "width": "", "height": "" }, "dimensions_html": "該当なし", "display_price": 4950, "display_regular_price": 4950, "image": { "title": "", "caption": "", "url": "", "alt": "", "src": "", "srcset": false, "sizes": false }, "image_id": 0, "is_downloadable": false, "is_in_stock": true, "is_purchasable": true, "is_sold_individually": "no", "is_virtual": false, "max_qty": "", "min_qty": 1, "price_html": "<span class=\"price\"><span class=\"woocommerce-Price-amount amount\"><bdi><span class=\"woocommerce-Price-currencySymbol\">¥</span>4,950</bdi></span> <small class=\"woocommerce-price-suffix\">(税込)</small></span>", "sku": "", "variation_description": "", "variation_id": 8833, "variation_is_active": true, "variation_is_visible": true, "weight": "", "weight_html": "該当なし" }, { "attributes": { "attribute_バリエーション": "テスト商品C" }, "availability_html": "", "backorders_allowed": false, "dimensions": { "length": "", "width": "", "height": "" }, "dimensions_html": "該当なし", "display_price": 5500, "display_regular_price": 5500, "image": { "title": "", "caption": "", "url": "", "alt": "", "src": "", "srcset": false, "sizes": false }, "image_id": 0, "is_downloadable": false, "is_in_stock": true, "is_purchasable": true, "is_sold_individually": "no", "is_virtual": false, "max_qty": "", "min_qty": 1, "price_html": "<span class=\"price\"><span class=\"woocommerce-Price-amount amount\"><bdi><span class=\"woocommerce-Price-currencySymbol\">¥</span>5,500</bdi></span> <small class=\"woocommerce-price-suffix\">(税込)</small></span>", "sku": "", "variation_description": "", "variation_id": 8834, "variation_is_active": true, "variation_is_visible": true, "weight": "", "weight_html": "該当なし" } ] |
テーマによってはまた違ってくるのかも知れませんが
他のテーマを使った事は無いのでわかりません。
動作デモ
試行錯誤しましたが
なんとか目的の動作を達成出来て嬉しい〜…
色々と荒いので調整する必要がありますが
なにかの参考になれば幸いです。