[EC-CUBE4.0.3]規格をラジオボタンにして一覧表示にする

  • 公開日:2019/10/24
この記事は最終更新日から4年以上が経過しています。

デフォルトでは規格はセレクトボックスになっていますが、今回どうしてもラジオボタンにして、一覧表示で在庫有無をわかりやすくしたいという要望があったので対応しました。

http://EC-CUBE4:規格レイアウト選択:プルダウン・ラジオボタン・規格ごとカートボタン
有償ですが、上記のようなステキなプラグインがあるようです。
ただ、今回は以下の条件さえ満たせば汎用性を必要としなかったので少し強引な方法ですが有償プラグインに頼らない方法で対応しました。

  • 規格は一つしか使わない
  • ラジオボタンでラベルのみ表示
  • 在庫0の場合は選択不可の「×」表示にする
  • 商品一覧ページには表示不要(カートボタンも表示なし)

AddCartTypeを拡張

まずは、商品をカートへ入れる処理をしているsrc/Eccube/Form/Type/AddCartType.phpを拡張します。
app/Customize/Form/Extension/AddCartTypeExtension.phpを作成し、以下の処理を追加します。

<?php
namespace Customize\Form\Extension;

use Eccube\Form\Type\AddCartType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;

class AddCartTypeExtension extends AbstractTypeExtension
{
    public function buildForm(FormBuilderInterface $builder, array $options)
	{
		if ($builder->has('classcategory_id1'))
		{
			$options = $builder->get('classcategory_id1')->getOptions();

			$options['compound'] = true;
			$options['expanded'] = true;
			unset($options['choices']['common.select']);

			$builder->add('classcategory_id1', ChoiceType::class, $options);
		}
    }

	public function getExtendedType()
	{
		return AddCartType::class;
	}
}

これで規格の表示がラジオボタンに変わりました。

ただし、このままだと規格を選択した時にformにProductClassのhidden値がセットされなくなってしまうので、規格選択時の処理を追加する必要があります。

規格選択時の処理を追加

以下のJavaScriptを商品詳細ページに追加します。(今回は商品一覧には規格表示しないので対応しません)

商品詳細ページ
app/template/default/Product/detail.twig

// 規格1選択時(radioボタン対応)
$('input[name=classcategory_id1]').change(function() {
	var $form = $(this).parents('form');
	var $product_id = $form.find('input[name=product_id]').val();
	var $sele1 = $(this);
	var $sele2 = $form.find('input[name=classcategory_id2]');

	// 規格1のみの場合
	if (!$sele2.length)
	{
		eccube.checkStock($form, product_id, $sele1.val(), null);
	}
	else // 規格2がある場合
	{
		eccube.setClassCategories($form, product_id, $sele1, $sele2);
	}
});

今回は規格を一つしか使わないのですが、参考サイトに載っていた記述をそのまま拝借しました。
商品一覧ページはこれだけではまだ動かないようです。今回は一覧ページには規格表示しないのでここまでの対応で留めます。一覧ページの対応は参考サイトをご覧ください。

ラジオボタンのHTMLタグをカスタマイズ

見た目を整えていきたいと思います。一覧表示にするためにtableタグにします。また、在庫がない場合にはラジオボタンは表示せず「×」として、選択不可なうえ、一目で品切れがわかるようにしたいと思います。

フロント用のフォーム内容を出力するためのテンプレートを修正します。
src/Eccube/Resource/template/default/Form/form_div_layout.twigをコピーしてapp/template/dafault/Form/form_div_layout.twigを作成します。

商品詳細ページでForm/form_div_layout.twigを利用することを宣言します。
app/template/default/Product/detail.twigに以下のように5行目を追加します。

{% extends 'default_frame.twig' %}

{% set body_class = 'product_page' %}

{% form_theme form 'Form/form_div_layout.twig' %}

{% block stylesheet %}
    <style>

準備が整ったので、app/template/dafault/Form/form_div_layout.twigのradio_widgetを以下のように変更します。

{%- block radio_widget -%}
    {% if type is defined and type == 'hidden' %}
        {{ block('form_widget_simple') }}
    {% else %}
		<tr>
			<th>
        		<label for="{{ id }}">
            		<span>{{ (label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)))|replace({'(品切れ中)':''}) }}</span>
        		</label>
			</th>
			<td>{{ '品切れ中' in label ? '×' : parent() }}</td>
		</tr>
    {% endif %}
{%- endblock radio_widget -%}

ここか少し強引にやっつけています。在庫がゼロの場合にラベルに付与される「(品切れ中)」は空白に置換して表示を消し、ラジオボタンを「×」にする条件指定にはラベルに「品切れ中」が含まれていたらという判定にしています。

もっとスマートな方法がある気がするのだけど・・・
とりあえず今回はcssを整えて完了です。

参考サイト:
【EC-CUBE4】規格をラジオボタンにして一覧表示する | クマひよ工房
フォームレイアウトの変更 | EC-CUBE 4.0 開発ドキュメント

おまけ:規格名を追加する

出来上がりイメージには規格名も表示しています。以下を商品詳細ページの表示したい場所に追加するだけです。

{{ form_label(form.classcategory_id1) }}