app/template/default/Product/detail.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.     <style>
  12.         .slick-slider {
  13.             margin-bottom: 30px;
  14.         }
  15.         .slick-dots {
  16.             position: absolute;
  17.             bottom: -45px;
  18.             display: block;
  19.             width: 100%;
  20.             padding: 0;
  21.             list-style: none;
  22.             text-align: center;
  23.         }
  24.         .slick-dots li {
  25.             position: relative;
  26.             display: inline-block;
  27.             width: 20px;
  28.             height: 20px;
  29.             margin: 0 5px;
  30.             padding: 0;
  31.             cursor: pointer;
  32.         }
  33.         .slick-dots li button {
  34.             font-size: 0;
  35.             line-height: 0;
  36.             display: block;
  37.             width: 20px;
  38.             height: 20px;
  39.             padding: 5px;
  40.             cursor: pointer;
  41.             color: transparent;
  42.             border: 0;
  43.             outline: none;
  44.             background: transparent;
  45.         }
  46.         .slick-dots li button:hover,
  47.         .slick-dots li button:focus {
  48.             outline: none;
  49.         }
  50.         .slick-dots li button:hover:before,
  51.         .slick-dots li button:focus:before {
  52.             opacity: 1;
  53.         }
  54.         .slick-dots li button:before {
  55.             content: " ";
  56.             line-height: 20px;
  57.             position: absolute;
  58.             top: 0;
  59.             left: 0;
  60.             width: 12px;
  61.             height: 12px;
  62.             text-align: center;
  63.             opacity: .25;
  64.             background-color: black;
  65.             border-radius: 50%;
  66.         }
  67.         .slick-dots li.slick-active button:before {
  68.             opacity: .75;
  69.             background-color: black;
  70.         }
  71.         .slick-dots li button.thumbnail img {
  72.             width: 0;
  73.             height: 0;
  74.         }
  75.     </style>
  76.     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
  77.     <link rel="stylesheet" href="/html/template/default/assets/css/swiper-customize.min.css">
  78.     <style>
  79.         #modalWrapAlert {
  80.             display: none;
  81.             background: 0 0;
  82.             width: 100%;
  83.             height: 100%;
  84.             position: fixed;
  85.             top: 0;
  86.             left: 0;
  87.             z-index: 100;
  88.             overflow: hidden
  89.         }
  90.         .modalBoxAlert {
  91.             position: fixed;
  92.             width: 85%;
  93.             max-width: 420px;
  94.             height: 0;
  95.             top: 0;
  96.             bottom: 0;
  97.             left: 0;
  98.             right: 0;
  99.             margin: auto;
  100.             overflow: hidden;
  101.             opacity: 1;
  102.             display: none;
  103.             border-radius: 3px;
  104.             z-index: 1000
  105.         }
  106.         .modalInnerAlert {
  107.             padding: 10px;
  108.             text-align: center;
  109.             box-sizing: border-box;
  110.             background: rgba(0, 0, 0, .7);
  111.             color: #fff
  112.         }
  113.     </style>
  114. {% endblock %}
  115. {% block javascript %}
  116.     {# この商品の最上位カテゴリidを取得 #}
  117.     {% set rootCategoryId = null %}
  118.     {% for ProductCategory in Product.ProductCategories %}
  119.         {% set Category = ProductCategory.Category %}
  120.         {% set rootCategory = Category %}
  121.         {% for i in 1..10 if rootCategory.Parent %}
  122.             {% set rootCategory = rootCategory.Parent %}
  123.         {% endfor %}
  124.         {% set rootCategoryId = rootCategory.id %}
  125.     {% endfor %}
  126.     <script>
  127.         eccube.classCategories = {{ class_categories_as_json(Product)|raw }};
  128.         // 規格2に選択肢を割り当てる。
  129.         function fnSetClassCategories(form, classcat_id2_selected) {
  130.             var $form = $(form);
  131.             var product_id = $form.find('input[name=product_id]').val();
  132.             var $sele1 = $form.find('select[name=classcategory_id1]');
  133.             var $sele2 = $form.find('select[name=classcategory_id2]');
  134.             eccube.setClassCategories($form, product_id, $sele1, $sele2, classcat_id2_selected);
  135.         }
  136. {# ▼▼▼GOLFPRINT:▼▼▼ #}
  137.     {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  138.         window.addEventListener('load', () => {
  139.             const selectElement = document.getElementById('classcategory_id1');
  140.             if (selectElement) {
  141.                 selectElement.selectedIndex = 1;    // 2番目のoptionを選択
  142.                 // 規格1の選択後に規格2の選択肢を設定
  143.                 fnSetClassCategories($('#form1'), null);
  144.                 // イベント発火処理(ネイティブ+jQuery)
  145.                 const triggerChangeEvents = () => {
  146.                     // 規格1の変更イベントを発火
  147.                     $(selectElement).trigger('change');
  148.                 };
  149.                 // 規格1の変更イベントを発火(300msの遅延を追加)
  150.                 setTimeout(triggerChangeEvents, 300);
  151.             }
  152.             {% if form.classcategory_id2 is defined %}
  153.             fnSetClassCategories(
  154.                 $('#form1'), {{ form.classcategory_id2.vars.value|json_encode|raw }}
  155.             );
  156.             {% elseif form.classcategory_id1 is defined %}
  157.             eccube.checkStock($('#form1'), {{ Product.id }}, {{ form.classcategory_id1.vars.value|json_encode|raw }}, null);
  158.             {% else %}
  159.             // 規格が存在しない場合の処理
  160.             eccube.checkStock($('#form1'), {{ Product.id }}, null, null);
  161.             {% endif %}
  162.         });
  163.     {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  164.     {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  165.     {% elseif rootCategoryId == 10 %}{# ラッピング #}
  166.         {% if form.classcategory_id2 is defined %}
  167.         fnSetClassCategories(
  168.             $('#form1'), {{ form.classcategory_id2.vars.value|json_encode|raw }}
  169.         );
  170.         {% elseif form.classcategory_id1 is defined %}
  171.         eccube.checkStock($('#form1'), {{ Product.id }}, {{ form.classcategory_id1.vars.value|json_encode|raw }}, null);
  172.         {% endif %}
  173.     {% endif %}
  174. {# ▲▲▲GOLFPRINT:▲▲▲ #}
  175.     </script>
  176.     <script>
  177.         $(function() {
  178.             // bfcache無効化
  179.             $(window).bind('pageshow', function(event) {
  180.                 if (event.originalEvent.persisted) {
  181.                     location.reload(true);
  182.                 }
  183.             });
  184.             // Core Web Vital の Cumulative Layout Shift(CLS)対策のため
  185.             // img タグに width, height が付与されている.
  186.             // 630px 未満の画面サイズでは縦横比が壊れるための対策
  187.             // see https://github.com/EC-CUBE/ec-cube/pull/5023
  188.             $('.ec-grid2__cell').hide();
  189.             var removeSize = function () {
  190.                 $('.slide-item').height('');
  191.                 $('.slide-item img')
  192.                     .removeAttr('width')
  193.                     .removeAttr('height')
  194.                     .removeAttr('style');
  195.             };
  196.             var slickInitial = function(slick) {
  197.                 $('.ec-grid2__cell').fadeIn(1500);
  198.                 var baseHeight = $(slick.target).height();
  199.                 var baseWidth = $(slick.target).width();
  200.                 var rate = baseWidth / baseHeight;
  201.                 $('.slide-item').height(baseHeight * rate); // 余白を削除する
  202.                 // transform を使用することでCLSの影響を受けないようにする
  203.                 $('.slide-item img')
  204.                     .css(
  205.                         {
  206.                             'transform-origin': 'top left',
  207.                             'transform': 'scaleY(' + rate + ')',
  208.                             'transition': 'transform .1s'
  209.                         }
  210.                     );
  211.                 // 正しいサイズに近くなったら属性を解除する
  212.                 setTimeout(removeSize, 500);
  213.             };
  214.             $('.item_visual').on('init', slickInitial);
  215.             // リサイズ時は CLS の影響を受けないため属性を解除する
  216.             $(window).resize(removeSize);
  217.             $('.item_visual').slick({
  218.                 dots: false,
  219.                 arrows: false,
  220.                 responsive: [{
  221.                     breakpoint: 768,
  222.                     settings: {
  223.                         dots: true
  224.                     }
  225.                 }]
  226.             });
  227.             $('.slideThumb').on('click', function() {
  228.                 var index = $(this).attr('data-index');
  229.                 $('.item_visual').slick('slickGoTo', index, false);
  230.             })
  231.         });
  232.     </script>
  233.     <script>
  234.         $(function() {
  235.             $('.add-cart').on('click', function(event) {
  236.                 {% if form.classcategory_id1 is defined %}
  237.                 // 規格1フォームの必須チェック
  238.                 if ($('#classcategory_id1').val() == '__unselected' || $('#classcategory_id1').val() == '') {
  239.                     $('#classcategory_id1')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  240.                     return true;
  241.                 } else {
  242.                     $('#classcategory_id1')[0].setCustomValidity('');
  243.                 }
  244.                 {% endif %}
  245.                 {% if form.classcategory_id2 is defined %}
  246.                 // 規格2フォームの必須チェック
  247.                 if ($('#classcategory_id2').val() == '__unselected' || $('#classcategory_id2').val() == '') {
  248.                     $('#classcategory_id2')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  249.                     return true;
  250.                 } else {
  251.                     $('#classcategory_id2')[0].setCustomValidity('');
  252.                 }
  253.                 {% endif %}
  254.                 // 個数フォームのチェック
  255.                 if ($('#quantity').val() < 1) {
  256.                     $('#quantity')[0].setCustomValidity('{{ '1以上で入力してください。'|trans }}');
  257.                     return true;
  258.                 } else {
  259.                     $('#quantity')[0].setCustomValidity('');
  260.                 }
  261.                 event.preventDefault();
  262.                 $form = $('#form1');
  263.                 $.ajax({
  264.                     url: $form.attr('action'),
  265.                     type: $form.attr('method'),
  266.                     data: $form.serialize(),
  267.                     dataType: 'json',
  268.                     beforeSend: function(xhr, settings) {
  269.                         // Buttonを無効にする
  270.                         $('.add-cart').prop('disabled', true);
  271.                     }
  272.                 }).done(function(data) {
  273.                     // レスポンス内のメッセージをalertで表示
  274.                     $.each(data.messages, function() {
  275.                         $('#ec-modal-header').text(this);
  276.                     });
  277.                     $('.ec-modal').show()
  278.                     // カートブロックを更新する
  279.                     $.ajax({
  280.                         url: "{{ url('block_cart') }}",
  281.                         type: 'GET',
  282.                         dataType: 'html'
  283.                     }).done(function(html) {
  284.                         $('.ec-headerRole__cart').html(html);
  285.                     });
  286.                 }).fail(function(data) {
  287.                     alert('{{ 'カートへの追加に失敗しました。'|trans }}');
  288.                 }).always(function(data) {
  289.                     // Buttonを有効にする
  290.                     $('.add-cart').prop('disabled', false);
  291.                 });
  292.             });
  293.         });
  294.         $('.ec-modal-wrap').on('click', function(e) {
  295.             // モーダル内の処理は外側にバブリングさせない
  296.             e.stopPropagation();
  297.         });
  298.         $('.ec-modal-overlay, .ec-modal, .ec-modal-close, .inlineBtn--cancel').on('click', function() {
  299.             $('.ec-modal').hide()
  300.         });
  301.     </script>
  302.     <script type="application/ld+json">
  303.     {
  304.         "@context": "https://schema.org/",
  305.         "@type": "Product",
  306.         "name": "{{ Product.name }}",
  307.         "image": [
  308.             {% for img in Product.ProductImage %}
  309.                 "{{ app.request.schemeAndHttpHost }}{{ asset(img, 'save_image') }}"{% if not loop.last %},{% endif %}
  310.             {% else %}
  311.                 "{{ app.request.schemeAndHttpHost }}{{ asset(''|no_image_product, 'save_image') }}"
  312.             {% endfor %}
  313.         ],
  314.         "description": "{{ Product.description_list | default(Product.description_detail) | replace({'\n': '', '\r': ''}) | slice(0,300) }}",
  315.         {% if Product.code_min %}
  316.         "sku": "{{ Product.code_min }}",
  317.         {% endif %}
  318.         "offers": {
  319.             "@type": "Offer",
  320.             "url": "{{ url('product_detail', {'id': Product.id}) }}",
  321.             "priceCurrency": "{{ eccube_config.currency }}",
  322.             "price": {{ Product.getPrice02IncTaxMin ? Product.getPrice02IncTaxMin : 0}},
  323.             "availability": "{{ Product.stock_find ? "InStock" : "OutOfStock" }}"
  324.         }
  325.     }
  326.     </script>
  327.     <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
  328.     <script>
  329.         // swiperを生成
  330.         var swiperMain = new Swiper('.swiper-container', {
  331.             effect: 'fade', // フェードエフェクトを適用
  332.             speed: 600,
  333.             loop: true,
  334.             pagination: {
  335.             el: '.swiper-pagination',
  336.             clickable: true,
  337.             },
  338.             navigation: { // コメントアウトまたは削除
  339.             nextEl: '.swiper-button-next',
  340.             prevEl: '.swiper-button-prev',
  341.             },
  342.         });
  343.         // slideToメソッドを実行する関数を定義
  344.         function slideThumb(index) {
  345.             swiperMain.slideTo(index);
  346.         }
  347.     </script>
  348.     <script>
  349.     {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  350.         $(function() {
  351.             $('.ball_type').change(function() {
  352.                 let selCnt = 0;
  353.                 const ballType = document.forms.formSelPC.ball_type;
  354.                 for( let i=0; i < ballType.length; i++ ) {
  355.                     if( ballType[i].checked ) {
  356.                         selCnt++;
  357.                     }
  358.                 }
  359.                 if( selCnt == ballType.length ) {
  360.                     for( let i=0; i < ballType.length; i++ ) {
  361.                         ballType[i].checked = false;
  362.                     }
  363.                     //alert('絞り込みたい項目がある場合のみチェックしてください。');
  364.                     selAlert();
  365.                 }
  366.             });
  367.             $('.ball_nums').change(function() {
  368.                 let selCnt = 0;
  369.                 const ballNums = document.forms.formSelPC.ball_nums;
  370.                 for( let i=0; i < ballNums.length; i++ ) {
  371.                     if( ballNums[i].checked ) {
  372.                         selCnt++;
  373.                     }
  374.                 }
  375.                 if( selCnt == ballNums.length ) {
  376.                     for( let i=0; i < ballNums.length; i++ ) {
  377.                         ballNums[i].checked = false;
  378.                     }
  379.                     //alert('絞り込みたい項目がある場合のみチェックしてください。');
  380.                     selAlert();
  381.                 }
  382.             });
  383.             $('.ball_price').change(function() {
  384.                 let selCnt = 0;
  385.                 const ballPrice = document.forms.formSelPC.ball_price;
  386.                 for( let i=0; i < ballPrice.length; i++ ) {
  387.                     if( ballPrice[i].checked ) {
  388.                         selCnt++;
  389.                     }
  390.                 }
  391.                 if( selCnt == ballPrice.length ) {
  392.                     for( let i=0; i < ballPrice.length; i++ ) {
  393.                         ballPrice[i].checked = false;
  394.                     }
  395.                     //alert('絞り込みたい項目がある場合のみチェックしてください。');
  396.                     selAlert();
  397.                 }
  398.             });
  399.             $('.ball_type_sp').change(function() {
  400.                 let selCnt = 0;
  401.                 const ballType = document.forms.formSelSP.ball_type;
  402.                 for( let i=0; i < ballType.length; i++ ) {
  403.                     if( ballType[i].checked ) {
  404.                         selCnt++;
  405.                     }
  406.                 }
  407.                 if( selCnt == ballType.length ) {
  408.                     for( let i=0; i < ballType.length; i++ ) {
  409.                         ballType[i].checked = false;
  410.                     }
  411.                     //alert('絞り込みたい項目がある場合のみチェックしてください。');
  412.                     selAlert();
  413.                 }
  414.             });
  415.             $('.ball_nums_sp').change(function() {
  416.                 let selCnt = 0;
  417.                 const ballNums = document.forms.formSelSP.ball_nums;
  418.                 for( let i=0; i < ballNums.length; i++ ) {
  419.                     if( ballNums[i].checked ) {
  420.                         selCnt++;
  421.                     }
  422.                 }
  423.                 if( selCnt == ballNums.length ) {
  424.                     for( let i=0; i < ballNums.length; i++ ) {
  425.                         ballNums[i].checked = false;
  426.                     }
  427.                     //alert('絞り込みたい項目がある場合のみチェックしてください。');
  428.                     selAlert();
  429.                 }
  430.             });
  431.             $('.ball_price_sp').change(function() {
  432.                 let selCnt = 0;
  433.                 const ballPrice = document.forms.formSelSP.ball_price;
  434.                 for( let i=0; i < ballPrice.length; i++ ) {
  435.                     if( ballPrice[i].checked ) {
  436.                         selCnt++;
  437.                     }
  438.                 }
  439.                 if( selCnt == ballPrice.length ) {
  440.                     for( let i=0; i < ballPrice.length; i++ ) {
  441.                         ballPrice[i].checked = false;
  442.                     }
  443.                     //alert('絞り込みたい項目がある場合のみチェックしてください。');
  444.                     selAlert();
  445.                 }
  446.             });
  447.         });
  448.         function setValPC() {
  449.             let sels_type = '';
  450.             const ballType = document.forms.formSelPC.ball_type;
  451.             for( let i=0; i < ballType.length; i++ ) {
  452.                 if( ballType[i].checked ) {
  453.                     if( sels_type ) {
  454.                         sels_type = sels_type + ',';
  455.                     }
  456.                     sels_type = sels_type + ballType[i].value;
  457.                 }
  458.             }
  459.             document.forms.formSelPC2.elements['ball-type'].value = sels_type;
  460.             let sels_nums = '';
  461.             const ballNums = document.forms.formSelPC.ball_nums;
  462.             for( let i=0; i < ballNums.length; i++ ) {
  463.                 if( ballNums[i].checked ) {
  464.                     if( sels_nums ) {
  465.                         sels_nums = sels_nums + ',';
  466.                     }
  467.                     sels_nums = sels_nums + ballNums[i].value;
  468.                 }
  469.             }
  470.             document.forms.formSelPC2.elements['ball-nums'].value = sels_nums;
  471.             let sels_price = '';
  472.             const ballPrice = document.forms.formSelPC.ball_price;
  473.             for( let i=0; i < ballPrice.length; i++ ) {
  474.                 if( ballPrice[i].checked ) {
  475.                     if( sels_price ) {
  476.                         sels_price = sels_price + ',';
  477.                     }
  478.                     sels_price = sels_price + ballPrice[i].value;
  479.                 }
  480.             }
  481.             document.forms.formSelPC2.elements['ball-price'].value = sels_price;
  482.             document.forms.formSelPC2.submit();
  483.         }
  484.         function setValSP() {
  485.             let sels_type = '';
  486.             const ballType = document.forms.formSelSP.ball_type;
  487.             for( let i=0; i < ballType.length; i++ ) {
  488.                 if( ballType[i].checked ) {
  489.                     if( sels_type ) {
  490.                         sels_type = sels_type + ',';
  491.                     }
  492.                     sels_type = sels_type + ballType[i].value;
  493.                 }
  494.             }
  495.             document.forms.formSelSP2.elements['ball-type'].value = sels_type;
  496.             let sels_nums = '';
  497.             const ballNums = document.forms.formSelSP.ball_nums;
  498.             for( let i=0; i < ballNums.length; i++ ) {
  499.                 if( ballNums[i].checked ) {
  500.                     if( sels_nums ) {
  501.                         sels_nums = sels_nums + ',';
  502.                     }
  503.                     sels_nums = sels_nums + ballNums[i].value;
  504.                 }
  505.             }
  506.             document.forms.formSelSP2.elements['ball-nums'].value = sels_nums;
  507.             let sels_price = '';
  508.             const ballPrice = document.forms.formSelSP.ball_price;
  509.             for( let i=0; i < ballPrice.length; i++ ) {
  510.                 if( ballPrice[i].checked ) {
  511.                     if( sels_price ) {
  512.                         sels_price = sels_price + ',';
  513.                     }
  514.                     sels_price = sels_price + ballPrice[i].value;
  515.                 }
  516.             }
  517.             document.forms.formSelSP2.elements['ball-price'].value = sels_price;
  518.             document.forms.formSelSP2.submit();
  519.         }
  520.     {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  521.     {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  522.         $(function() {
  523.             $('.design_cate').change(function() {
  524.                 let selCnt = 0;
  525.                 const designCate = document.forms.formSelPC.design_cate;
  526.                 for( let i=0; i < designCate.length; i++ ) {
  527.                     if( designCate[i].checked ) {
  528.                         selCnt++;
  529.                     }
  530.                 }
  531.                 if( selCnt == designCate.length ) {
  532.                     for( let i=0; i < designCate.length; i++ ) {
  533.                         designCate[i].checked = false;
  534.                     }
  535.                     //alert('絞り込みたい項目がある場合のみチェックしてください。');
  536.                     selAlert();
  537.                 }
  538.             });
  539.             $('.design_cate_sp').change(function() {
  540.                 let selCnt = 0;
  541.                 const designCate = document.forms.formSelSP.design_cate;
  542.                 for( let i=0; i < designCate.length; i++ ) {
  543.                     if( designCate[i].checked ) {
  544.                         selCnt++;
  545.                     }
  546.                 }
  547.                 if( selCnt == designCate.length ) {
  548.                     for( let i=0; i < designCate.length; i++ ) {
  549.                         designCate[i].checked = false;
  550.                     }
  551.                     //alert('絞り込みたい項目がある場合のみチェックしてください。');
  552.                     selAlert();
  553.                 }
  554.             });
  555.         });
  556.         function setValPC() {
  557.             let sels_design = '';
  558.             const designCate = document.forms.formSelPC.design_cate;
  559.             for( let i=0; i < designCate.length; i++ ) {
  560.                 if( designCate[i].checked ) {
  561.                     if( sels_design ) {
  562.                         sels_design = sels_design + ',';
  563.                     }
  564.                     sels_design = sels_design + designCate[i].value;
  565.                 }
  566.             }
  567.             document.forms.formSelPC2.elements['design-cate'].value = sels_design;
  568.             document.forms.formSelPC2.submit();
  569.         }
  570.         function setValSP() {
  571.             let sels_design = '';
  572.             const designCate = document.forms.formSelSP.design_cate;
  573.             for( let i=0; i < designCate.length; i++ ) {
  574.                 if( designCate[i].checked ) {
  575.                     if( sels_design ) {
  576.                         sels_design = sels_design + ',';
  577.                     }
  578.                     sels_design = sels_design + designCate[i].value;
  579.                 }
  580.             }
  581.             document.forms.formSelSP2.elements['design-cate'].value = sels_design;
  582.             document.forms.formSelSP2.submit();
  583.         }
  584.     {% elseif rootCategoryId == 10 %}{# ラッピング #}
  585.     {% endif %}
  586.     </script>
  587.     <script>
  588.         function selAlert() {
  589.             var modalThis = $('body').find('#alert01');
  590.             //bodyの最下にwrapを作る 
  591.             $('body').append('<div id="modalWrapAlert" />');
  592.             var wrap = $('#modalWrapAlert');
  593.             wrap.fadeIn('200');
  594.             modalThis.fadeIn('200');
  595.             //モーダルの高さを取ってくる 
  596.             function mdlHeight() {
  597.                 var wh = $(window).innerHeight();
  598.                 var attH = modalThis.find('.modalInnerAlert').innerHeight();
  599.                 modalThis.css({
  600.                     height: attH
  601.                 });
  602.             }
  603.             mdlHeight();
  604.             $(window).on('resize', function () {
  605.                 mdlHeight();
  606.             });
  607.             function clickAction() {
  608.                 modalThis.fadeOut('200');
  609.                 wrap.fadeOut('200', function () {
  610.                     wrap.remove();
  611.                 });
  612.             }
  613.             //wrapクリックされたら 
  614.             wrap.on('click', function () {
  615.                 clickAction();
  616.                 return false;
  617.             });
  618.             //2秒後に消える 
  619.             setTimeout(clickAction, 2000);
  620.             return false;
  621.         }
  622.     </script>
  623. {% endblock %}
  624. {% block main %}
  625.     {# この商品の最上位カテゴリidを取得 #}
  626.     {% set rootCategoryId = null %}
  627.     {% for ProductCategory in Product.ProductCategories %}
  628.         {% set Category = ProductCategory.Category %}
  629.         {% set rootCategory = Category %}
  630.         {% for i in 1..10 if rootCategory.Parent %}
  631.             {% set rootCategory = rootCategory.Parent %}
  632.         {% endfor %}
  633.         {% set rootCategoryId = rootCategory.id %}
  634.     {% endfor %}
  635.     <div class="container">
  636.         <!-- パンくずリスト -->
  637.         <nav aria-label="breadcrumb" class="my-3">
  638.             <ol class="breadcrumb">
  639.                 <li class="breadcrumb-item"><a href="{{ url('homepage') }}">ホーム</a></li>
  640.                 {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  641.                     <li class="breadcrumb-item"><a href="{{ url('product_list', {'category_id': 7}) }}">ボールを選ぶ</a></li>
  642.                     <li class="breadcrumb-item active" aria-current="page">{{ Product.name }}</li>
  643.                 {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  644.                 {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  645.                     <li class="breadcrumb-item"><a href="{{ url('product_list', {'category_id': 9}) }}">デザインを選ぶ</a></li>
  646.                     <li class="breadcrumb-item active" aria-current="page">{{ Product.name }}</li>
  647.                 {% elseif rootCategoryId == 10 %}{# ラッピング #}
  648.                 {% endif %}
  649.             </ol>
  650.         </nav>
  651.         <div class="layout-2colmun">
  652.             {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  653.                 {{ include('Product/aside_ball.twig') }}
  654.             {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  655.             {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  656.                 {{ include('Product/aside_design.twig') }}
  657.             {% elseif rootCategoryId == 10 %}{# ラッピング #}
  658.             {% endif %}
  659.             <main class="main">
  660.                 <div class="row mb-5">
  661.                     <div class="col-md-6">
  662.                         <div id="product-detail">
  663.                             <!-- main -->
  664.                             <div class="swiper-container">
  665.                                 <div class="swiper-wrapper">
  666.                                     {% for ProductImage in Product.ProductImage %}
  667.                                         <div class="swiper-slide" style="background-image: url('{{ asset(ProductImage, 'save_image') }}'); background-size: contain; background-repeat: no-repeat;"></div>
  668.                                     {% else %}
  669.                                         <div class="swiper-slide" style="background-image: url('{{ asset(''|no_image_product, 'save_image') }}'); background-size: contain; background-repeat: no-repeat;"></div>
  670.                                     {% endfor %}
  671.                                 </div>
  672.                                 <div class="swiper-button-prev"></div>
  673.                                 <div class="swiper-button-next"></div>
  674.                             </div>
  675.                             <!-- thumbnail -->
  676.                             <ul class="thumb-list">
  677.                                 {% for ProductImage in Product.ProductImage %}
  678.                                     <li class="thumb-item">
  679.                                         <a class="thumb-link" href="javascript:void(0);" onclick="slideThumb({{ loop.index0 }})" style="background-image: url('{{ asset(ProductImage, 'save_image') }}')"></a>
  680.                                     </li>
  681.                                 {% endfor %}
  682.                             </ul>
  683.                         </div>
  684.                     </div>
  685.                     <div class="col-md-6">
  686.                         <h1 class="fw-bold _fs-5 mb-3">{{ Product.name }}</h1>
  687.                         <div class="item-thumb mb-3">
  688.                             {% for Tag in Product.Tags %}
  689.                                 {% if Tag.name == '一番人気' %}
  690.                                     <span class="icon -popular -large">一番人気</span>
  691.                                 {% elseif Tag.name == '即日配送' %}
  692.                                     <span class="icon -rapid -large">即日配送</span>
  693.                                 {% elseif Tag.name == '代引手数料無料' %}
  694.                                     <span class="icon -free -large">代引手数料無料</span>
  695.                                 {% elseif Tag.name == '送料無料' %}
  696.                                     <span class="icon -free -large">送料無料</span>
  697.                                 {% elseif Tag.name == '3%還元' %}
  698.                                     <span class="icon -point -large">3%還元</span>
  699.                                 {% elseif Tag.name == '人気' %}
  700.                                     <span class="icon -popular -large">人気</span>
  701.                                 {% endif %}
  702.                             {% endfor %}
  703.                             {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  704.                             {% if Product.hasProductClass -%}
  705.                                 {% if Product.getPrice02IncTaxMin == Product.getPrice02IncTaxMax %}
  706.                                     <div class="price -large"><span class="price02-default">&yen;{{ Product.getPrice02IncTaxMin|number_format }}</span> <span>(税込)</span></div>
  707.                                 {% else %}
  708.                                     <div class="price -large"><span class="price02-default">&yen;{{ Product.getPrice02IncTaxMin|number_format }} ~ &yen;{{ Product.getPrice02IncTaxMax|number_format }}</span> <span>(税込)</span></div>
  709.                                 {% endif %}
  710.                             {% else %}
  711.                                 <div class="price -large"><span class="price02-default">&yen;{{ Product.getPrice02IncTaxMin|number_format }}</span> <span>(税込)</span></div>
  712.                             {% endif %}
  713.                             {% endif %}
  714.                         </div>
  715.                         <form action="{{ url('product_add_cart', {id:Product.id}) }}" method="post" id="form1" name="form1">
  716.                             {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  717.                             <div class="border-top border-bottom py-3 mb-4">
  718.                                 <div class="d-flex align-items-center pb-3">
  719.                                     <div class="w-25 text-end">{{ '商品コード'|trans }}:</div>
  720.                                     <div class="ps-3">{{ Product.code_min }}{% if Product.code_min != Product.code_max %} ~ {{ Product.code_max }}{% endif %}</div>
  721.                                 </div>
  722.                                 {% if Product.stock_find %}
  723.                                     {% if form.classcategory_id1 is defined %}
  724.                                         <div class="d-flex align-items-center pb-1 d-none">
  725.                                             {{ form_row(form.classcategory_id1) }}
  726.                                             {{ form_errors(form.classcategory_id1) }}
  727.                                         </div>
  728.                                         {% if form.classcategory_id2 is defined %}
  729.                                             <div class="detail-color pb-1">
  730.                                                 {{ form_row(form.classcategory_id2) }}
  731.                                                 {{ form_errors(form.classcategory_id2) }}
  732.                                             </div>
  733.                                         {% endif %}
  734.                                     {% endif %}
  735.                                     <div class="d-flex align-items-center py-1">
  736.                                         <div class="w-25 text-end">{{ '数量'|trans }}</div>
  737.                                         <div class="ps-3">
  738.                                             {{ form_widget(form.quantity) }}
  739.                                             {{ form_errors(form.quantity) }}
  740.                                         </div>
  741.                                     </div>
  742.                                 {% endif %}
  743.                             </div>
  744.                             {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  745.                             {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  746.                             <div class="d-flex align-items-center pb-3">
  747.                                 <div class="text-start">{{ '商品コード'|trans }}:</div>
  748.                                 <div class="ps-3">{{ Product.code_min }}{% if Product.code_min != Product.code_max %} ~ {{ Product.code_max }}{% endif %}</div>
  749.                             </div>
  750.                             {% if Product.stock_find %}
  751.                                 {% if form.classcategory_id1 is defined %}
  752.                                     {{ form_row(form.classcategory_id1, {'attr': {'type': 'hidden'}}) }}
  753.                                     {{ form_errors(form.classcategory_id1) }}
  754.                                     {% if form.classcategory_id2 is defined %}
  755.                                         {{ form_row(form.classcategory_id2, {'attr': {'type': 'hidden'}}) }}
  756.                                         {{ form_errors(form.classcategory_id2) }}
  757.                                     {% endif %}
  758.                                 {% endif %}
  759.                                 {{ form_widget(form.quantity, {'type': 'hidden'}) }}
  760.                                 {{ form_errors(form.quantity) }}
  761.                             {% endif %}
  762.                             {% elseif rootCategoryId == 10 %}{# ラッピング #}
  763.                             {% endif %}
  764.                             <div class="d-flex justify-content-between">
  765.                                 {% if Product.stock_find %}
  766.                                     <a href="javascript:void(0);" class="me-1 btn btn-danger btn-lg rounded-0 w-100 add-cart"><i class="icon-shopping_cart"></i>{{ 'カートに入れる'|trans }}</a>
  767.                                 {% else %}
  768.                                     <button type="button" class="me-1 btn btn-danger btn-lg rounded-0 w-100" disabled="disabled">{{ 'ただいま品切れ中です。'|trans }}</button>
  769.                                 {% endif %}
  770.                                 {% if BaseInfo.option_favorite_product %}
  771.                                     {% if is_favorite == false %}
  772.                                         <a href="javascript:void(0);" onclick="document.forms.formFavorite.submit();" class="ms-1 btn btn-dark btn-lg rounded-0 w-100">{{ 'お気に入りに追加'|trans }}</a>
  773.                                     {% else %}
  774.                                         <button type="button" id="favorite" class="ms-1 btn btn-dark btn-lg rounded-0 w-100" disabled="disabled">{{ 'お気に入り登録済'|trans }}</button>
  775.                                     {% endif %}
  776.                                 {% endif %}
  777.                             </div>
  778.                             {{ form_rest(form) }}
  779.                         </form>
  780.                         {# お気に入りに追加用フォーム #}
  781.                         <form action="{{ url('product_add_favorite', {id:Product.id}) }}" method="post" id="formFavorite" name="formFavorite"></form>
  782. {##}
  783.                         <div class="ec-modal">
  784.                             <div class="ec-modal-overlay">
  785.                                 <div class="ec-modal-wrap">
  786.                                     <span class="ec-modal-close"><span class="ec-icon"><img src="{{ asset('assets/icon/cross-dark.svg') }}" alt=""/></span></span>
  787.                                     <div id="ec-modal-header" class="text-center">{{ 'カートに追加しました。'|trans }}</div>
  788.                                     <div class="ec-modal-box">
  789.                                         <div class="ec-role">
  790.                                             <span class="btn btn-dark btn-lg me-2 mb-3 inlineBtn--cancel">{{ 'お買い物を続ける'|trans }}</span>
  791.                                             <a href="{{ url('cart') }}" class="btn btn-danger btn-lg mb-3"><i class="icon-shopping_cart"></i>{{ 'カートへ進む'|trans }}</a>
  792.                                         </div>
  793.                                     </div>
  794.                                 </div>
  795.                             </div>
  796.                         </div>
  797. {##}
  798.                         <div class="_bg-gray p-3 mt-4">
  799.                             {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  800.                                 <ul class="list-unstyled mb-0">
  801.                                     <li>※価格は【印刷代込み(税込)】です。</li>
  802.                                     <li>※パッケージは予告なく変更になる場合がございます。</li>
  803.                                     <li>※3球単位で 1 デザイン印刷可能です。</li>
  804.                                 </ul>
  805.                             {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  806.                             {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  807.                                 <ul class="list-unstyled mb-0">
  808.                                     <li>※3球単位で 1 デザイン印刷可能です。</li>
  809.                                 </ul>
  810.                             {% elseif rootCategoryId == 10 %}{# ラッピング #}
  811.                             {% endif %}
  812.                         </div>
  813.                     </div>
  814.                 </div>
  815.                 <div class="me-2 d-block d-lg-none">
  816.                     <a href="" class="btn btn-outline-dark btn-lg w-100" data-bs-toggle="modal" data-bs-target="#filterModal">別の商品を見る</a>
  817.                 </div>
  818.                 
  819.                 <hr class="my-5">
  820. {% if Product.freearea %}
  821.                 <div class="ec-productRole__description">{{ Product.freearea|raw|nl2br }}</div>
  822. {% endif %}
  823. {# 商品管理 - 商品登録 商品説明 欄に入力!
  824.                 <div class="text-center">
  825.                     <img src="/html/template/default/assets/img/products/item01.png" width="600" height="600" alt="ゼクシオ リバウンド ドライブ II" class="img-fluid">
  826.                 </div>
  827.                 <p>
  828.                     「ゼクシオ リバウンド ドライブ II」は、ダンロップが提供する高性能ゴルフボールです。
  829.                     このボールは、ウレタンカバーとアイオノマーカバーの長所を融合し、柔らかな打感と優れたスピン性能、直進性、そして高い飛距離性能を実現しています。3層構造の「リバウンドフレーム」は、剛性の高いエリアと低いエリアを交互に配置し、各ショットで最適なパフォーマンスを発揮しま
  830.                     す。また、ティーショットからパッティングまで、すべてのショットで高いパフォーマンスを提供する「ALL OK!」性能がさらに進化しています。
  831.                     カラーバリエーションは、ホワイト、プレミアムホワイト、ライムイエロー、プレミアムピンク、X Mark Edition ホワイトの5種類があり、プレーヤー
  832.                     の好みに合わせて選択できます。
  833.                 </p>
  834. #}
  835.                 {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  836.                     {{ include('Block/product_detail.twig') }}{# 印刷サイズ・サービス #}
  837.                 {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  838.                 {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  839.                     {{ include('Block/product_detail.twig') }}{# 印刷サイズ・サービス #}
  840.                 {% elseif rootCategoryId == 10 %}{# ラッピング #}
  841.                 {% endif %}
  842.                 <form name="formSelSP2" id="formSelSP2" method="get" action="{{ url('product_list') }}">
  843.                     <input type="hidden" name="mode">
  844.                     {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  845.                     <input type="hidden" name="category_id" value="7">
  846.                     {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  847.                     {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  848.                     <input type="hidden" name="category_id" value="9">
  849.                     {% elseif rootCategoryId == 10 %}{# ラッピング #}
  850.                     {% endif %}
  851.                     <input type="hidden" name="name">
  852.                     <input type="hidden" name="pageno" value="1">
  853.                     <input type="hidden" name="disp_number" value="21">
  854.                     <input type="hidden" name="orderby" value="2">
  855.                     {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  856.                     <input type="hidden" id="ball-type" name="ball-type">
  857.                     <input type="hidden" id="ball-nums" name="ball-nums">
  858.                     <input type="hidden" id="ball-price" name="ball-price">
  859.                     {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  860.                     {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  861.                     <input type="hidden" id="design-cate" name="design-cate">
  862.                     {% elseif rootCategoryId == 10 %}{# ラッピング #}
  863.                     {% endif %}
  864.                 </form>
  865.                 <div class="modalBoxAlert" id="alert01">
  866.                     <div class="modalInnerAlert">
  867.                         絞り込みたい項目がある場合のみチェックしてください。
  868.                     </div>
  869.                 </div>
  870.             </main>
  871.         </div>
  872.     </div>
  873.     <!-- modal -->
  874.     <div class="modal fade" id="filterModal" tabindex="-1" aria-labelledby="filterModalLabel" aria-hidden="true">
  875.         <div class="modal-dialog">
  876.             <div class="modal-content">
  877.                 <div class="modal-header">
  878.                     <h5 class="modal-title" id="filterModalLabel">絞り込み</h5>
  879.                     <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  880.                 </div>
  881.                 <form name="formSelSP" id="formSelSP">
  882.                 <div class="modal-body">
  883.                     <!-- 絞り込みフォームの内容をここに追加 -->
  884.                     {% if rootCategoryId == 7 %}{# ボールを選ぶ #}
  885.                     <div class="aside-filter _modal">
  886.                         <div class="title">
  887.                             ボールの種類から選ぶ
  888.                         </div>
  889.                         <ul class="list-unstyled mb-0 list">
  890.                             <li>
  891.                                 <label>
  892.                                     <input type="checkbox" name="ball_type" class="ball_type_sp" value="14">
  893.                                     持ち込みボール
  894.                                 </label>
  895.                             </li>
  896.                             <li>
  897.                                 <label>
  898.                                     <input type="checkbox" name="ball_type" class="ball_type_sp" value="11">
  899.                                     スリクソン
  900.                                 </label>
  901.                             </li>
  902.                             <li>
  903.                                 <label>
  904.                                     <input type="checkbox" name="ball_type" class="ball_type_sp" value="12">
  905.                                     ゼクシオ
  906.                                 </label>
  907.                             </li>
  908.                             <li>
  909.                                 <label>
  910.                                     <input type="checkbox" name="ball_type" class="ball_type_sp" value="13">
  911.                                     ツアースペシャル
  912.                                 </label>
  913.                             </li>
  914.                         </ul>
  915.                         <div class="title">
  916.                             ボールの球数から選ぶ
  917.                         </div>
  918.                         <ul class="list-unstyled mb-0 list">
  919.                             <li>
  920.                                 <label>
  921.                                     <input type="checkbox" name="ball_nums" class="ball_nums_sp" value="8,13">
  922.                                     3球
  923.                                 </label>
  924.                             </li>
  925.                             <li>
  926.                                 <label>
  927.                                     <input type="checkbox" name="ball_nums" class="ball_nums_sp" value="11,14">
  928.                                     6球
  929.                                 </label>
  930.                             </li>
  931.                             <li>
  932.                                 <label>
  933.                                     <input type="checkbox" name="ball_nums" class="ball_nums_sp" value="12,15">
  934.                                     12球
  935.                                 </label>
  936.                             </li>
  937.                         </ul>
  938.                         <div class="title">
  939.                             価格で選ぶ
  940.                         </div>
  941.                         <ul class="list-unstyled mb-0 list">
  942.                             <li>
  943.                                 <label>
  944.                                     <input type="checkbox" name="ball_price" class="ball_price_sp" value="1">
  945.                                     ~2,999円
  946.                                 </label>
  947.                             </li>
  948.                             <li>
  949.                                 <label>
  950.                                     <input type="checkbox" name="ball_price" class="ball_price_sp" value="2">
  951.                                     3,000円~4,999円
  952.                                 </label>
  953.                             </li>
  954.                             <li>
  955.                                 <label>
  956.                                     <input type="checkbox" name="ball_price" class="ball_price_sp" value="3">
  957.                                     5,000円~9,999円
  958.                                 </label>
  959.                             </li>
  960.                             <li>
  961.                                 <label>
  962.                                     <input type="checkbox" name="ball_price" class="ball_price_sp" value="4">
  963.                                     10,000円以上
  964.                                 </label>
  965.                             </li>
  966.                         </ul>
  967.                     </div>
  968.                     {% elseif rootCategoryId == 8 %}{# マーカーを選ぶ #}
  969.                     {% elseif rootCategoryId == 9 %}{# デザインを選ぶ #}
  970.                     <div class="aside-filter _modal">
  971.                         <div class="title">
  972.                         カテゴリから選ぶ
  973.                         </div>
  974.                         <ul class="list-unstyled mb-0 list">
  975.                             <li>
  976.                                 <label>
  977.                                     <input type="checkbox" name="design_cate" class="design_cate_sp" value="15">
  978.                                     誕生日祝い
  979.                                 </label>
  980.                             </li>
  981.                             <li>
  982.                                 <label>
  983.                                     <input type="checkbox" name="design_cate" class="design_cate_sp" value="16">
  984.                                     定年退職祝い
  985.                                 </label>
  986.                             </li>
  987.                             <li>
  988.                                 <label>
  989.                                     <input type="checkbox" name="design_cate" class="design_cate_sp" value="17">
  990.                                     還暦祝い
  991.                                 </label>
  992.                             </li>
  993.                             <li>
  994.                                 <label>
  995.                                     <input type="checkbox" name="design_cate" class="design_cate_sp" value="18">
  996.                                     コンペ景品
  997.                                 </label>
  998.                             </li>
  999.                             <li>
  1000.                                 <label>
  1001.                                     <input type="checkbox" name="design_cate" class="design_cate_sp" value="19">
  1002.                                     父の日祝い
  1003.                                 </label>
  1004.                             </li>
  1005.                             <li>
  1006.                                 <label>
  1007.                                     <input type="checkbox" name="design_cate" class="design_cate_sp" value="20">
  1008.                                     母の日祝い
  1009.                                 </label>
  1010.                             </li>
  1011.                             <li>
  1012.                                 <label>
  1013.                                     <input type="checkbox" name="design_cate" class="design_cate_sp" value="21">
  1014.                                     GOLFPRINT オリジナル
  1015.                                 </label>
  1016.                             </li>
  1017.                         </ul>
  1018.                     </div>
  1019.                     {% elseif rootCategoryId == 10 %}{# ラッピング #}
  1020.                     {% endif %}
  1021.                 </div>
  1022.                 <div class="modal-footer">
  1023.                     <button type="button" class="btn btn-outline-dark" data-bs-dismiss="modal">閉じる</button>
  1024.                     <button type="button" class="btn btn-outline-dark" onclick="location.href='{{ url('product_detail', {'id': Product.id}) }}'">クリア</button>
  1025.                     <button type="button" onclick="setValSP()" class="btn btn-primary">絞り込む</button>
  1026.                 </div>
  1027.                 </form>
  1028.             </div>
  1029.         </div>
  1030.     </div>
  1031. {% endblock %}