app/template/default/Product/list.twig line 1

Open in your IDE?
  1. {#
  2. This file is part of EC-CUBE
  3. Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  4. http://www.ec-cube.co.jp/
  5. For the full copyright and license information, please view the LICENSE
  6. file that was distributed with this source code.
  7. #}
  8. {% extends 'default_frame.twig' %}
  9. {% set body_class = 'product_page' %}
  10. {% block stylesheet %}
  11.     <link rel="stylesheet" href="/html/plugins/ion-rangeslider/css/ion.rangeSlider.min.css">
  12.     <style>
  13.         /* ============================================
  14.            サイドバー付き 2カラムレイアウト
  15.         ============================================ */
  16.         .ec-productListLayout {
  17.             display: flex;
  18.             gap: 32px;
  19.             align-items: flex-start;
  20.         }
  21.         /* ============================================
  22.            サイドバー(フィルターパネル)
  23.         ============================================ */
  24.         .ec-filterSidebar {
  25.             position: static;
  26.             margin: 20px;
  27.             width: 240px;
  28.             flex-shrink: 0;
  29.         }
  30.         @media (min-width: 767px) {
  31.             .ec-searchnavRole {
  32.                 margin-left: calc((100% - 1130px - 280px) / 2);
  33.             }
  34.             .ec-shelfRole {
  35.                 margin-left: calc((100% - 1130px - 280px) / 2);
  36.             }
  37.             .ec-pagerRole {
  38.                 margin-left: calc((100% - 1130px - 280px) / 2);
  39.             }
  40.         }
  41.         .ec-filterSidebar__section {
  42.             background: #fff;
  43.             border: 1px solid #e8e8e8;
  44.             border-radius: 6px;
  45.             padding: 18px 16px;
  46.             margin-bottom: 16px;
  47.         }
  48.         .ec-filterSidebar__heading {
  49.             font-size: 13px;
  50.             font-weight: bold;
  51.             color: #222;
  52.             margin: 0 0 12px;
  53.             padding-bottom: 10px;
  54.             border-bottom: 2px solid #222;
  55.             letter-spacing: 0.05em;
  56.         }
  57.         /* カテゴリリスト */
  58.         .ec-filterSidebar__categoryList,
  59.         .ec-filterSidebar__categoryList ul {
  60.             list-style: none;
  61.             padding: 0;
  62.             margin: 0;
  63.         }
  64.         .ec-filterSidebar__categoryList li a {
  65.             display: block;
  66.             padding: 6px 8px;
  67.             font-size: 13px;
  68.             color: #444;
  69.             text-decoration: none;
  70.             border-radius: 4px;
  71.             transition: background 0.15s, color 0.15s;
  72.         }
  73.         .ec-filterSidebar__categoryList li a:hover {
  74.             background: #f5f5f5;
  75.             color: #222;
  76.         }
  77.         .ec-filterSidebar__categoryList li.is-active > a {
  78.             font-weight: bold;
  79.             color: #c00;
  80.             background: #fff5f5;
  81.         }
  82.         /* サブカテゴリ */
  83.         .ec-filterSidebar__categoryList ul {
  84.             padding-left: 12px;
  85.             margin-top: 2px;
  86.         }
  87.         .ec-filterSidebar__categoryList ul li a {
  88.             font-size: 12px;
  89.             color: #666;
  90.             padding: 4px 8px;
  91.         }
  92.         /* メーカーリスト */
  93.         .ec-filterSidebar__makerList {
  94.             list-style: none;
  95.             padding: 0;
  96.             margin: 0;
  97.         }
  98.         .ec-filterSidebar__makerList li {
  99.             border-bottom: 1px solid #f0f0f0;
  100.         }
  101.         .ec-filterSidebar__makerList li:last-child {
  102.             border-bottom: none;
  103.         }
  104.         .ec-filterSidebar__makerList li a {
  105.             display: flex;
  106.             align-items: center;
  107.             gap: 6px;
  108.             padding: 7px 6px;
  109.             font-size: 13px;
  110.             color: #444;
  111.             text-decoration: none;
  112.             transition: color 0.15s;
  113.         }
  114.         .ec-filterSidebar__makerList li a:hover {
  115.             color: #c00;
  116.         }
  117.         .ec-filterSidebar__makerList li.is-active a {
  118.             font-weight: bold;
  119.             color: #c00;
  120.         }
  121.         .ec-filterSidebar__makerList li.is-active a::before {
  122.             content: "✓";
  123.             font-size: 11px;
  124.             color: #c00;
  125.         }
  126.         /* 価格帯フィルター */
  127.         .ec-filterSidebar__priceDisplay {
  128.             text-align: center;
  129.             font-size: 13px;
  130.             color: #333;
  131.             margin-bottom: 12px;
  132.             font-weight: bold;
  133.         }
  134.         .ec-filterSidebar__priceDisplay span {
  135.             color: #c00;
  136.         }
  137.         .ec-filterSidebar__priceSliderWrap {
  138.             padding: 0 4px;
  139.             margin-bottom: 16px;
  140.         }
  141.         .ec-filterSidebar__priceApply {
  142.             display: block;
  143.             width: 100%;
  144.             padding: 8px;
  145.             background: #222;
  146.             color: #fff;
  147.             border: none;
  148.             border-radius: 4px;
  149.             font-size: 13px;
  150.             cursor: pointer;
  151.             text-align: center;
  152.             transition: background 0.2s;
  153.         }
  154.         .ec-filterSidebar__priceApply:hover {
  155.             background: #444;
  156.         }
  157.         .ec-filterSidebar__pricePreset {
  158.             list-style: none;
  159.             padding: 0;
  160.             margin: 10px 0 0;
  161.         }
  162.         .ec-filterSidebar__pricePreset li a {
  163.             display: block;
  164.             padding: 5px 6px;
  165.             font-size: 12px;
  166.             color: #666;
  167.             text-decoration: none;
  168.             border-radius: 4px;
  169.             transition: background 0.15s;
  170.         }
  171.         .ec-filterSidebar__pricePreset li a:hover {
  172.             background: #f5f5f5;
  173.             color: #333;
  174.         }
  175.         /* 絞り込みリセット */
  176.         .ec-filterSidebar__reset a {
  177.             display: block;
  178.             text-align: center;
  179.             padding: 8px;
  180.             font-size: 12px;
  181.             color: #888;
  182.             text-decoration: underline;
  183.             border: 1px solid #ddd;
  184.             border-radius: 4px;
  185.             transition: color 0.15s, border-color 0.15s;
  186.         }
  187.         .ec-filterSidebar__reset a:hover {
  188.             color: #c00;
  189.             border-color: #c00;
  190.         }
  191.         /* 現在の絞り込み条件バッジ */
  192.         .ec-filterActive {
  193.             display: flex;
  194.             flex-wrap: wrap;
  195.             gap: 6px;
  196.             margin-bottom: 12px;
  197.             padding: 10px 12px;
  198.             background: #f9f9f9;
  199.             border: 1px solid #e8e8e8;
  200.             border-radius: 6px;
  201.         }
  202.         .ec-filterActive__label {
  203.             font-size: 11px;
  204.             color: #888;
  205.             align-self: center;
  206.             margin-right: 4px;
  207.         }
  208.         .ec-filterActive__tag {
  209.             display: inline-flex;
  210.             align-items: center;
  211.             gap: 4px;
  212.             padding: 3px 8px;
  213.             background: #222;
  214.             color: #fff;
  215.             border-radius: 20px;
  216.             font-size: 11px;
  217.         }
  218.         .ec-filterActive__tag a {
  219.             color: #aaa;
  220.             text-decoration: none;
  221.             font-size: 12px;
  222.             line-height: 1;
  223.         }
  224.         .ec-filterActive__tag a:hover {
  225.             color: #fff;
  226.         }
  227.         /* メインコンテンツ側 */
  228.         .ec-productListMain {
  229.             flex: 1;
  230.             min-width: 0;
  231.             width: 100%;  
  232.         }
  233.         /* ion-rangeslider カスタマイズ */
  234.         .irs--flat .irs-bar {
  235.             background-color: #222;
  236.         }
  237.         .irs--flat .irs-handle > i:first-child {
  238.             background-color: #222;
  239.         }
  240.         .irs--flat .irs-from,
  241.         .irs--flat .irs-to,
  242.         .irs--flat .irs-single {
  243.             background-color: #222;
  244.             font-size: 11px;
  245.         }
  246.         /* モバイル対応 */
  247.         @media (max-width: 767px) {
  248.             /* 横スクロール禁止 */
  249.             body, html {
  250.                 overflow-x: hidden;
  251.                 max-width: 100vw;
  252.             }
  253.             .ec-productListLayout {
  254.                 flex-direction: column;
  255.                 gap: 0;
  256.             }
  257.             .ec-filterSidebar {
  258.                 width: 100%;
  259.                 margin: 0;
  260.             }
  261.             /* スマホで商品一覧を確実に表示 */
  262.             .ec-productListMain {
  263.                 width: 100%;
  264.                 flex: none;
  265.                 margin: 0;
  266.             }
  267.             .ec-filterSidebar__section {
  268.                 margin-bottom: 10px;
  269.             }
  270.             /* モバイルではアコーディオン形式 */
  271.             .ec-filterSidebar__body {
  272.                 display: none;
  273.             }
  274.             .ec-filterSidebar__body.is-open {
  275.                 display: block;
  276.             }
  277.             .ec-filterSidebar__heading {
  278.                 cursor: pointer;
  279.                 display: flex;
  280.                 justify-content: space-between;
  281.                 align-items: center;
  282.                 margin-bottom: 0;
  283.                 padding-bottom: 0;
  284.                 border-bottom: none;
  285.             }
  286.             .ec-filterSidebar__heading.is-open {
  287.                 margin-bottom: 12px;
  288.                 padding-bottom: 10px;
  289.                 border-bottom: 2px solid #222;
  290.             }
  291.             .ec-filterSidebar__heading::after {
  292.                 content: "▼";
  293.                 font-size: 10px;
  294.                 color: #888;
  295.                 transition: transform 0.2s;
  296.             }
  297.             .ec-filterSidebar__heading.is-open::after {
  298.                 transform: rotate(180deg);
  299.             }
  300.         }
  301.     </style>
  302. {% endblock %}
  303. {% block javascript %}
  304.     <script>
  305.         eccube.productsClassCategories = {
  306.             {% for Product in pagination %}
  307.             "{{ Product.id|escape('js') }}": {{ class_categories_as_json(Product)|raw }}{% if loop.last == false %}, {% endif %}
  308.             {% endfor %}
  309.         };
  310.         $(function() {
  311.             // 表示件数を変更
  312.             $('.disp-number').change(function() {
  313.                 var dispNumber = $(this).val();
  314.                 $('#disp_number').val(dispNumber);
  315.                 $('#pageno').val(1);
  316.                 $("#form1").submit();
  317.             });
  318.             // 並び順を変更
  319.             $('.order-by').change(function() {
  320.                 var orderBy = $(this).val();
  321.                 $('#orderby').val(orderBy);
  322.                 $('#pageno').val(1);
  323.                 $("#form1").submit();
  324.             });
  325.             // ==============================
  326.             // 価格帯スライダー(ion-rangeslider)
  327.             // ==============================
  328.             var priceMin = parseInt('{{ app.request.query.get("price_min") ?: 0 }}') || 0;
  329.             var priceMax = parseInt('{{ app.request.query.get("price_max") ?: 5000000 }}') || 5000000;
  330.             $("#price-range-slider").ionRangeSlider({
  331.                 type: "double",
  332.                 min: 0,
  333.                 max: 5000000,
  334.                 from: priceMin,
  335.                 to: priceMax,
  336.                 step: 10000,
  337.                 prettify_enabled: true,
  338.                 prettify_separator: ",",
  339.                 postfix: "円",
  340.                 onFinish: function(data) {
  341.                     $('#price_min_val').val(data.from);
  342.                     $('#price_max_val').val(data.to);
  343.                     // 表示更新
  344.                     $('#price-display-min').text(Number(data.from).toLocaleString());
  345.                     $('#price-display-max').text(Number(data.to).toLocaleString());
  346.                 }
  347.             });
  348.             // 価格フォーム送信
  349.             $('#price-filter-apply').on('click', function() {
  350.                 var min = $('#price_min_val').val();
  351.                 var max = $('#price_max_val').val();
  352.                 var url = new URL(window.location.href);
  353.                 url.searchParams.set('price_min', min);
  354.                 url.searchParams.set('price_max', max);
  355.                 url.searchParams.delete('pageno');
  356.                 window.location.href = url.toString();
  357.             });
  358.             // モバイル:アコーディオン(初期状態を閉じる)
  359.             function initMobileAccordion() {
  360.                 if ($(window).width() <= 767) {
  361.                     $('.ec-filterSidebar__heading').removeClass('is-open');
  362.                     $('.ec-filterSidebar__body').removeClass('is-open');
  363.                 }
  364.             }
  365.             initMobileAccordion();
  366.             $(window).on('resize', initMobileAccordion);
  367.             $('.ec-filterSidebar__heading').on('click', function() {
  368.                 if ($(window).width() <= 767) {
  369.                     $(this).toggleClass('is-open');
  370.                     $(this).next('.ec-filterSidebar__body').toggleClass('is-open');
  371.                 }
  372.             });
  373.         });
  374.         $('.ec-modal-wrap').on('click', function(e) {
  375.             e.stopPropagation();
  376.         });
  377.         $('.ec-modal-overlay, .ec-modal, .ec-modal-close, .ec-inlineBtn--cancel').on('click', function() {
  378.             $('.ec-modal').hide()
  379.         });
  380.         // 価格プリセットのクイック適用
  381.         function applyPrice(min, max) {
  382.             var url = new URL(window.location.href);
  383.             url.searchParams.set('price_min', min);
  384.             url.searchParams.set('price_max', max);
  385.             url.searchParams.delete('pageno');
  386.             window.location.href = url.toString();
  387.         }
  388.     </script>
  389.     <script src="/html/plugins/ion-rangeslider/js/ion.rangeSlider.min.js"></script>
  390. {% endblock %}
  391. {% block main %}
  392.         {% set hasFilter = app.request.query.get('category_id') or app.request.query.get('maker_id') or app.request.query.get('price_min') or app.request.query.get('price_max') %}
  393.         {# ==============================
  394.            2カラムレイアウト本体
  395.         ============================== #}
  396.         <div class="ec-productListLayout">
  397.             {# ===== サイドバー(左カラム)===== #}
  398.             <aside class="ec-filterSidebar">
  399.                 {# ----- 価格帯 ----- #}
  400.                 <div class="ec-filterSidebar__section">
  401.                     <h3 class="ec-filterSidebar__heading">価格帯</h3>
  402.                     <div class="ec-filterSidebar__body is-open">
  403.                         <div class="ec-filterSidebar__priceDisplay">
  404.                             <span id="price-display-min">{{ app.request.query.get('price_min') ? app.request.query.get('price_min')|number_format : '0' }}</span>円
  405.                             〜
  406.                             <span id="price-display-max">{{ app.request.query.get('price_max') ? app.request.query.get('price_max')|number_format : '5,000,000' }}</span>円
  407.                         </div>
  408.                         <div class="ec-filterSidebar__priceSliderWrap">
  409.                             <input type="text" id="price-range-slider" style="display:none;">
  410.                             <input type="hidden" id="price_min_val" value="{{ app.request.query.get('price_min') ?: 0 }}">
  411.                             <input type="hidden" id="price_max_val" value="{{ app.request.query.get('price_max') ?: 5000000 }}">
  412.                         </div>
  413.                         <button id="price-filter-apply" class="ec-filterSidebar__priceApply">この価格帯で絞り込む</button>
  414.                         <ul class="ec-filterSidebar__pricePreset">
  415.                             <li><a href="javascript:void(0);" onclick="applyPrice(0, 300000)">〜30万円</a></li>
  416.                             <li><a href="javascript:void(0);" onclick="applyPrice(300000, 600000)">30万円〜60万円</a></li>
  417.                             <li><a href="javascript:void(0);" onclick="applyPrice(600000, 1000000)">60万円〜100万円</a></li>
  418.                             <li><a href="javascript:void(0);" onclick="applyPrice(1000000, 5000000)">100万円〜</a></li>
  419.                         </ul>
  420.                     </div>
  421.                 </div>
  422.                 {# ----- メーカー(ブランド)----- #}
  423.                 <div class="ec-filterSidebar__section">
  424.                     <h3 class="ec-filterSidebar__heading">ブランド</h3>
  425.                     <div class="ec-filterSidebar__body is-open">
  426.                         <ul class="ec-filterSidebar__makerList">
  427.                             {% if Makers is defined %}
  428.                                 {% for MakerItem in Makers %}
  429.                                     <li class="{{ Maker is not null and Maker.id == MakerItem.id ? 'is-active' : '' }}">
  430.                                         <a href="{{ url('product_list') }}?maker_id={{ MakerItem.id }}{% if app.request.query.get('category_id') %}&category_id={{ app.request.query.get('category_id') }}{% endif %}">
  431.                                             {{ MakerItem.name }}
  432.                                         </a>
  433.                                     </li>
  434.                                 {% endfor %}
  435.                             {% else %}
  436.                                 {# Makersがコントローラから渡されない場合は静的リストで対応 #}
  437.                                 {% set makerList = [
  438.                                     {id: 1,  name: 'LIXIL'},
  439.                                     {id: 2,  name: 'YKK AP'},
  440.                                     {id: 3,  name: '三協アルミ'},
  441.                                     {id: 4,  name: '四国化成'},
  442.                                     {id: 5,  name: 'タカショー'},
  443.                                     {id: 6,  name: 'ユニソン'},
  444.                                     {id: 7,  name: 'エスビック'},
  445.                                     {id: 8,  name: 'パナソニック'},
  446.                                     {id: 9,  name: 'イナバ'},
  447.                                     {id: 10, name: 'ヨドコウ'},
  448.                                     {id: 13, name: 'タクボ'}
  449.                                 ] %}
  450.                                 {% for maker in makerList %}
  451.                                     <li class="{{ Maker is not null and Maker.id == maker.id ? 'is-active' : '' }}">
  452.                                         <a href="{{ url('product_list') }}?maker_id={{ maker.id }}{% if app.request.query.get('category_id') %}&category_id={{ app.request.query.get('category_id') }}{% endif %}">
  453.                                             {{ maker.name }}
  454.                                         </a>
  455.                                     </li>
  456.                                 {% endfor %}
  457.                             {% endif %}
  458.                         </ul>
  459.                     </div>
  460.                 </div>
  461.                 {# ----- カテゴリ ----- #}
  462.                 <div class="ec-filterSidebar__section">
  463.                     <h3 class="ec-filterSidebar__heading">カテゴリ</h3>
  464.                     <div class="ec-filterSidebar__body is-open">
  465.                         {% set categoryList = [
  466.                             {id: 7,  name: 'カーポート・車庫',         children: []},
  467.                             {id: 16, name: 'ガレージ・倉庫',           children: []},
  468.                             {id: 8,  name: 'サイクルポート・駐輪場',   children: []},
  469.                             {id: 9,  name: 'ゲート',                   children: [
  470.                                 {id: 30, name: '跳ね上げ式ゲート'},
  471.                                 {id: 29, name: '伸縮ゲート'},
  472.                                 {id: 31, name: 'ガレージシャッター'}
  473.                             ]},
  474.                             {id: 12, name: 'テラス',                   children: [
  475.                                 {id: 33, name: 'テラス囲い'},
  476.                                 {id: 32, name: 'テラス屋根'}
  477.                             ]},
  478.                             {id: 19, name: 'ベランダ・バルコニー',     children: [
  479.                                 {id: 35, name: 'ベランダ・バルコニー屋根'},
  480.                                 {id: 34, name: 'ベランダ・バルコニー'}
  481.                             ]},
  482.                             {id: 18, name: 'オーニング・日よけ',       children: []},
  483.                             {id: 11, name: 'ウッドデッキ',             children: [
  484.                                 {id: 37, name: 'タイルデッキ'},
  485.                                 {id: 36, name: 'ウッドデッキ'}
  486.                             ]},
  487.                             {id: 14, name: 'フェンス・柵',             children: []},
  488.                             {id: 25, name: '門扉',                     children: []},
  489.                             {id: 13, name: 'ポスト・門柱宅配ボックス', children: []},
  490.                             {id: 15, name: '物置・収納・屋外倉庫',     children: []},
  491.                             {id: 20, name: 'ガーデンファニチャー',     children: []},
  492.                             {id: 22, name: '人工芝',                   children: []},
  493.                             {id: 17, name: '内窓・二重窓',             children: []},
  494.                             {id: 26, name: 'その他',                   children: [
  495.                                 {id: 38, name: 'パーゴラ'},
  496.                                 {id: 39, name: '立水栓・ガーデンシンク'},
  497.                                 {id: 40, name: '手すり'},
  498.                                 {id: 10, name: 'ストックヤード'},
  499.                                 {id: 27, name: 'ゴミステーション'},
  500.                                 {id: 42, name: '面格子・窓格子'},
  501.                                 {id: 41, name: '窓シャッター'},
  502.                                 {id: 43, name: '玄関ドア'},
  503.                                 {id: 28, name: '石材'},
  504.                                 {id: 44, name: '照明'},
  505.                                 {id: 21, name: 'DIY材料'}
  506.                             ]}
  507.                         ] %}
  508.                         <ul class="ec-filterSidebar__categoryList">
  509.                             <li class="{{ app.request.query.get('category_id') is empty and Maker is null ? 'is-active' : '' }}">
  510.                                 <a href="{{ url('product_list') }}">すべて</a>
  511.                             </li>
  512.                             {% for cat in categoryList %}
  513.                                 <li class="{{ app.request.query.get('category_id') == cat.id ? 'is-active' : '' }}">
  514.                                     <a href="{{ url('product_list') }}?category_id={{ cat.id }}{% if app.request.query.get('maker_id') %}&maker_id={{ app.request.query.get('maker_id') }}{% endif %}">
  515.                                         {{ cat.name }}
  516.                                     </a>
  517.                                     {% if cat.children|length > 0 %}
  518.                                         <ul>
  519.                                             {% for child in cat.children %}
  520.                                                 <li class="{{ app.request.query.get('category_id') == child.id ? 'is-active' : '' }}">
  521.                                                     <a href="{{ url('product_list') }}?category_id={{ child.id }}{% if app.request.query.get('maker_id') %}&maker_id={{ app.request.query.get('maker_id') }}{% endif %}">
  522.                                                         {{ child.name }}
  523.                                                     </a>
  524.                                                 </li>
  525.                                             {% endfor %}
  526.                                         </ul>
  527.                                     {% endif %}
  528.                                 </li>
  529.                             {% endfor %}
  530.                         </ul>
  531.                     </div>
  532.                 </div>
  533.                 {# ----- リセット ----- #}
  534.                 {% if hasFilter %}
  535.                     <div class="ec-filterSidebar__reset">
  536.                         <a href="{{ url('product_list') }}">絞り込みをすべてリセット</a>
  537.                     </div>
  538.                 {% endif %}
  539.             </aside>
  540.             {# / サイドバー #}
  541.             {# ===== 商品一覧(右カラム)===== #}
  542.             <div class="ec-productListMain">
  543.     {% if search_form.category_id.vars.errors|length > 0 %}
  544.         <div class="ec-searchnavRole">
  545.             <p class="errormsg text-danger">{{ 'ご指定のカテゴリは存在しません'|trans }}</p>
  546.         </div>
  547.     {% else %}
  548.         {# 検索フォーム(hidden) #}
  549.         <div class="ec-searchnavRole">
  550.             <form name="form1" id="form1" method="get" action="?">
  551.                 {% for item in search_form %}
  552.                     <input type="hidden" id="{{ item.vars.id }}"
  553.                            name="{{ item.vars.full_name }}"
  554.                            {% if item.vars.value is not empty %}value="{{ item.vars.value }}" {% endif %}/>
  555.                 {% endfor %}
  556.             </form>
  557.             {# パンくずリスト #}
  558.             <div class="ec-searchnavRole__topicpath">
  559.                 <ol class="ec-topicpath">
  560.                     <li class="ec-topicpath__item"><a href="{{ url('product_list') }}">{{ '全て'|trans }}</a></li>
  561.                     {% if Category is not null %}
  562.                         {% for Path in Category.path %}
  563.                             <li class="ec-topicpath__divider">|</li>
  564.                             <li class="ec-topicpath__item{% if loop.last %}--active{% endif %}">
  565.                                 <a href="{{ url('product_list') }}?category_id={{ Path.id }}">{{ Path.name }}</a>
  566.                             </li>
  567.                         {% endfor %}
  568.                     {% endif %}
  569.                     {% if Maker is not null %}
  570.                         <li class="ec-topicpath__divider">|</li>
  571.                         <li class="ec-topicpath__item--active">
  572.                             <a href="{{ url('product_list') }}?maker_id={{ Maker.id }}">{{ Maker.name }}</a>
  573.                         </li>
  574.                     {% endif %}
  575.                     {% if search_form.vars.value and search_form.vars.value.name %}
  576.                         <li class="ec-topicpath__divider">|</li>
  577.                         <li class="ec-topicpath__item">{{ '「%name%」の検索結果'|trans({ '%name%': search_form.vars.value.name }) }}</li>
  578.                     {% endif %}
  579.                 </ol>
  580.             </div>
  581.         {# ==============================
  582.            現在の絞り込み条件バッジ
  583.         ============================== #}
  584.         {% if hasFilter %}
  585.             <div class="ec-filterActive">
  586.                 <span class="ec-filterActive__label">絞り込み中:</span>
  587.                 {% if Category is not null %}
  588.                     {% set removeCategoryParam = 'category_id=' ~ app.request.query.get('category_id') %}
  589.                     <span class="ec-filterActive__tag">
  590.                         {{ Category.name }}
  591.                         <a href="{{ app.request.uri|replace({(removeCategoryParam): ''}) }}" title="解除">✕</a>
  592.                     </span>
  593.                 {% endif %}
  594.                 {% if Maker is not null %}
  595.                     <span class="ec-filterActive__tag">
  596.                         {{ Maker.name }}
  597.                         <a href="{{ url('product_list') }}{% if app.request.query.get('category_id') %}?category_id={{ app.request.query.get('category_id') }}{% endif %}" title="解除">✕</a>
  598.                     </span>
  599.                 {% endif %}
  600.                 {% if app.request.query.get('price_min') or app.request.query.get('price_max') %}
  601.                     <span class="ec-filterActive__tag">
  602.                         {% if app.request.query.get('price_min') %}{{ app.request.query.get('price_min')|number_format }}円{% else %}0円{% endif %}
  603.                         〜
  604.                         {% if app.request.query.get('price_max') %}{{ app.request.query.get('price_max')|number_format }}円{% else %}上限なし{% endif %}
  605.                         <a href="javascript:void(0);" onclick="
  606.                             var url = new URL(window.location.href);
  607.                             url.searchParams.delete('price_min');
  608.                             url.searchParams.delete('price_max');
  609.                             window.location.href = url.toString();
  610.                         " title="解除">✕</a>
  611.                     </span>
  612.                 {% endif %}
  613.             </div>
  614.         {% endif %}
  615.             {# 件数・並び順 #}
  616.             <div class="ec-searchnavRole__infos">
  617.                 <div class="ec-searchnavRole__counter">
  618.                     {% if pagination.totalItemCount > 0 %}
  619.                         {{ '<span class="ec-font-bold">%count%件</span><span>の商品が見つかりました</span>'|trans({ '%count%': pagination.totalItemCount })|raw }}
  620.                     {% else %}
  621.                         <span>{{ 'お探しの商品は見つかりませんでした'|trans }}</span>
  622.                     {% endif %}
  623.                 </div>
  624.                 {% if pagination.totalItemCount > 0 %}
  625.                     <div class="ec-searchnavRole__actions">
  626.                         <div class="ec-select">
  627.                             {{ form_widget(search_form.disp_number, {'id': '', 'attr': {'class': 'disp-number'}}) }}
  628.                             {{ form_widget(search_form.orderby, {'id': '', 'attr': {'class': 'order-by'}}) }}
  629.                         </div>
  630.                     </div>
  631.                 {% endif %}
  632.             </div>
  633.         </div>
  634.                 {% if pagination.totalItemCount > 0 %}
  635.                     <div class="ec-shelfRole">
  636.                         <ul class="ec-shelfGrid">
  637.                             {% for Product in pagination %}
  638.                                 <li class="ec-shelfGrid__item" style="position:relative;">
  639.                                     {% if BaseInfo.option_favorite_product %}
  640.                                         <div style="position:absolute;top:8px;right:20px;z-index:10;">
  641.                                             <form action="{{ url('product_add_favorite', {id:Product.id}) }}" method="post">
  642.                                                 <button type="submit" id="favorite" class="favorite">&#9825;</button>
  643.                                             </form>
  644.                                         </div>
  645.                                     {% endif %}
  646.                                     <a href="{{ url('product_detail', {'id': Product.id}) }}">
  647.                                         <p class="ec-shelfGrid__item-image">
  648.                                             <img src="{{ asset(Product.main_list_image|no_image_product, 'save_image') }}" alt="{{ Product.name }}" {% if loop.index > 5 %} loading="lazy"{% endif %}>
  649.                                         </p>
  650.                                         <h5><strong>{{ getProduct_field(Product.id,"related_keyword") }}</strong></h5>
  651.                                         <p class="price02-default">
  652.                                             {% if Product.hasProductClass %}
  653.                                                 {% if Product.getPrice02Min == Product.getPrice02Max %}
  654.                                                     {{ Product.getPrice02IncTaxMin|number_format }}円
  655.                                                 {% else %}
  656.                                                     {{ Product.getPrice02IncTaxMin|number_format }}円  ~ {{ Product.getPrice02IncTaxMax|number_format }}円
  657.                                                 {% endif %}
  658.                                             {% else %}
  659.                                                 {{ Product.getPrice02IncTaxMin|number_format }}円 ~
  660.                                             {% endif %}
  661.                                         </p>
  662.                                     </a>
  663.                                     {% if Product.stock_find %}
  664.                                         {% set form = forms[Product.id] %}
  665.                                         <form name="form{{ Product.id }}" id="productForm{{ Product.id }}" action="{{ url('product_detail', {id:Product.id}) }}" method="get">
  666.                                             <div class="ec-productRole__actions">
  667.                                                 {% if form.classcategory_id1 is defined %}
  668.                                                     <div class="ec-select">
  669.                                                         {{ form_widget(form.classcategory_id1) }}
  670.                                                         {{ form_errors(form.classcategory_id1) }}
  671.                                                     </div>
  672.                                                     {% if form.classcategory_id2 is defined %}
  673.                                                         <div class="ec-select">
  674.                                                             {{ form_widget(form.classcategory_id2) }}
  675.                                                             {{ form_errors(form.classcategory_id2) }}
  676.                                                         </div>
  677.                                                     {% endif %}
  678.                                                 {% endif %}
  679.                                                 <div class="ec-numberInput" style="display:none;"><span>{{ '数量'|trans }}</span>
  680.                                                     {{ form_errors(form.quantity) }}
  681.                                                 </div>
  682.                                             </div>
  683.                                             <div class="ec-productRole__btn">
  684.                                                 <button class="ec-blockBtn--action">
  685.                                                     {{ 'お見積もり詳細はこちら'|trans }}
  686.                                                 </button>
  687.                                             </div>
  688.                                         </form>
  689.                                     {% else %}
  690.                                         <div class="ec-productRole__btn">
  691.                                             <button type="button" class="ec-blockBtn--action" disabled="disabled">
  692.                                                 {{ 'ただいま品切れ中です。'|trans }}
  693.                                             </button>
  694.                                         </div>
  695.                                     {% endif %}
  696.                                 </li>
  697.                             {% endfor %}
  698.                         </ul>
  699.                     </div>
  700.                     <div class="ec-pagerRole">
  701.                         {% include "pager.twig" with {'pages': pagination.paginationData} %}
  702.                     </div>
  703.                 {% endif %}
  704.             </div>
  705.             {# / 商品一覧 #}
  706.         </div>
  707.         {# / ec-productListLayout #}
  708.     {% endif %}
  709. {% endblock %}