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: 12px;
  14.         }
  15.         .item_visual{
  16.             opacity: 0;
  17.             transition: opacity .3s linear;
  18.         }
  19.         .item_visual.slick-initialized.slick-slider{
  20.             opacity: 1;
  21.         }
  22.         .item_visual .slide-item:focus,
  23.         .item_visual .slide-item:focus-visible{
  24.             outline: none;
  25.         }
  26.         #colorbox #cboxContent {
  27.           background-color: transparent;
  28.           padding: 8px 70px;
  29.         }
  30.         #cboxOverlay{
  31.             background: hsla(0,0%,88.6%,.9);
  32.         }
  33.         #cboxContent,
  34.         #cboxLoadedContent{
  35.             background: transparent;
  36.             border: none;
  37.         }
  38.         .cboxPhoto{
  39.             border-radius: 4px;
  40.         }
  41.         #cboxPrevious,
  42.         #cboxNext{
  43.             position: absolute;
  44.             top: 50%;
  45.             background: #fff;
  46.             padding: 10px;
  47.             border-radius: 50px;
  48.             width: 40px;
  49.             height: 40px;
  50.             z-index: 100;
  51.         } 
  52.         #cboxPrevious{
  53.             left: 0px;
  54.         }
  55.         #cboxPrevious::before{
  56.             content: "";
  57.             display: inline-block;
  58.             padding: 3px;
  59.             margin: 0 10px;
  60.             border-left: 2px solid #000;
  61.             border-bottom: 2px solid #000;
  62.             transform: rotate(45deg);
  63.             position: absolute;
  64.             top: 15px;
  65.             left: 8px;
  66.         }
  67.         #cboxNext{
  68.             right: 0px;
  69.         }
  70.         #cboxNext::before{
  71.             content: "";
  72.             display: inline-block;
  73.             padding: 3px;
  74.             margin: 0 10px;
  75.             border-top: 2px solid #000;
  76.             border-right: 2px solid #000;
  77.             transform: rotate(45deg);
  78.             position: absolute;
  79.             top: 15px;
  80.             right: 8px;
  81.         }
  82.         #cboxSlideshow{
  83.             display: none;
  84.         }
  85.         
  86.         #cboxClose{
  87.             background: #fff;
  88.             padding: 10px;
  89.             border-radius: 50px;
  90.             top: -10px;
  91.             right: 0px;
  92.             width: 40px;
  93.             height: 40px;
  94.             cursor: pointer;
  95.             display: block;
  96.         }
  97.         #cboxClose::before,
  98.         #cboxClose::after{
  99.             content: "";
  100.             display: block;
  101.             background-color: #000;
  102.             position: absolute;
  103.             top: 0;
  104.             left: 0;
  105.             right: 0;
  106.             bottom: 0;
  107.             margin: auto;
  108.             width: 1.25vw;
  109.             height: 1px;
  110.         }
  111.         #cboxClose::before{
  112.             transform: rotate(45deg);
  113.         }
  114.         #cboxClose::after{
  115.             transform: rotate(-45deg);
  116.         }
  117.         #cboxCloseSP{
  118.             display: none;
  119.         }
  120.         @media only screen and (max-width: 767px) {
  121.             .item_visual a:hover{
  122.                 opacity: 1;
  123.                 outline: none;
  124.             }
  125.             #colorbox #cboxContent{
  126.                 padding: 0;
  127.             }
  128.             #cboxClose{
  129.                 display: none;
  130.             }
  131.             #cboxClose::before,
  132.             #cboxClose::after{
  133.                 width: 5vw;
  134.             }
  135.             #cboxPrevious,
  136.             #cboxNext{
  137.                 display: none!important;
  138.             }
  139.             #cboxCloseSP{
  140.                 display: block;
  141.                 position: absolute;
  142.                 background: #fff;
  143.                 padding: 10px;
  144.                 border-radius: 50px;
  145.                 border: none;
  146.                 width: 40px;
  147.                 height: 40px;
  148.                 cursor: pointer;
  149.                 top: 10px;
  150.                 right: 10px;
  151.                 z-index: 9999;
  152.             }
  153.             #cboxCloseSP::before,
  154.             #cboxCloseSP::after{
  155.                 content: "";
  156.                 display: block;
  157.                 background-color: #000;
  158.                 position: absolute;
  159.                 top: 0;
  160.                 left: 0;
  161.                 right: 0;
  162.                 bottom: 0;
  163.                 margin: auto;
  164.                 width: 5vw;
  165.                 height: 1px;
  166.             }
  167.             #cboxCloseSP::before{
  168.                 transform: rotate(45deg);
  169.             }
  170.             #cboxCloseSP::after{
  171.                 transform: rotate(-45deg);
  172.             }
  173.         }
  174.     </style>
  175. {% endblock %}
  176. {% block javascript %}
  177.     <script>
  178.         eccube.classCategories = {{ class_categories_as_json(Product)|raw }};
  179.         // 規格2に選択肢を割り当てる。
  180.         function fnSetClassCategories(form, classcat_id2_selected) {
  181.             var $form = $(form);
  182.             var product_id = $form.find('input[name=product_id]').val();
  183.             var $sele1 = $form.find('select[name=classcategory_id1]');
  184.             var $sele2 = $form.find('select[name=classcategory_id2]');
  185.             eccube.setClassCategories($form, product_id, $sele1, $sele2, classcat_id2_selected);
  186.         }
  187.         {% if form.classcategory_id2 is defined %}
  188.         fnSetClassCategories(
  189.             $('#form1'), {{ form.classcategory_id2.vars.value|json_encode|raw }}
  190.         );
  191.         {% elseif form.classcategory_id1 is defined %}
  192.         eccube.checkStock($('#form1'), {{ Product.id }}, {{ form.classcategory_id1.vars.value|json_encode|raw }}, null);
  193.         {% endif %}
  194.     </script>
  195.     <script>
  196.         $(function() {
  197.             $('.add-cart').on('click', function(event) {
  198.                 {% if form.classcategory_id1 is defined %}
  199.                 // 規格1フォームの必須チェック
  200.                 if ($('#classcategory_id1').val() == '__unselected' || $('#classcategory_id1').val() == '') {
  201.                     $('#classcategory_id1')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  202.                     return true;
  203.                 } else {
  204.                     $('#classcategory_id1')[0].setCustomValidity('');
  205.                 }
  206.                 {% endif %}
  207.                 {% if form.classcategory_id2 is defined %}
  208.                 // 規格2フォームの必須チェック
  209.                 if ($('#classcategory_id2').val() == '__unselected' || $('#classcategory_id2').val() == '') {
  210.                     $('#classcategory_id2')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  211.                     return true;
  212.                 } else {
  213.                     $('#classcategory_id2')[0].setCustomValidity('');
  214.                 }
  215.                 {% endif %}
  216.                 // 個数フォームのチェック
  217.                 if ($('#quantity').val() < 1) {
  218.                     $('#quantity')[0].setCustomValidity('{{ '1以上で入力してください。'|trans }}');
  219.                     return true;
  220.                 } else {
  221.                     $('#quantity')[0].setCustomValidity('');
  222.                 }
  223.                 event.preventDefault();
  224.                 $form = $('#form1');
  225.                 $.ajax({
  226.                     url: $form.attr('action'),
  227.                     type: $form.attr('method'),
  228.                     data: $form.serialize(),
  229.                     dataType: 'json',
  230.                     beforeSend: function(xhr, settings) {
  231.                         // Buttonを無効にする
  232.                         $('.add-cart').prop('disabled', true);
  233.                     }
  234.                 }).done(function(data) {
  235.                     // レスポンス内のメッセージをalertで表示
  236.                     $.each(data.messages, function() {
  237.                         $('#ec-modal-header').text(this);
  238.                     });
  239.                     $('.ec-modal').show()
  240.                     // カートブロックを更新する
  241.                     $.ajax({
  242.                         url: "{{ url('block_cart') }}",
  243.                         type: 'GET',
  244.                         dataType: 'html'
  245.                     }).done(function(html) {
  246.                         $('.ec-headerRole__cart').html(html);
  247.                     });
  248.                 }).fail(function(data) {
  249.                     alert('{{ 'カートへの追加に失敗しました。'|trans }}');
  250.                 }).always(function(data) {
  251.                     // Buttonを有効にする
  252.                     $('.add-cart').prop('disabled', false);
  253.                 });
  254.             });
  255.         });
  256.         $('.ec-modal-overlay, .ec-modal .ec-inlineBtn--cancel').on('click', function() {
  257.             $('.ec-modal').hide()
  258.         });
  259.     </script>
  260.     <script>
  261.         $(function() {
  262.             // bfcache無効化
  263.             $(window).bind('pageshow', function(event) {
  264.                 if (event.originalEvent.persisted) {
  265.                     location.reload(true);
  266.                 }
  267.             });
  268.             
  269.             $('.item_visual').slick({
  270.                 dots: false,
  271.                 arrows: false,
  272.                 infinite: false,
  273.             });
  274.             $('.slideThumb:first-child').addClass("is-current");
  275.             
  276.             $('.slideThumb').on('click', function() {
  277.                 var index = $(this).attr('data-index');
  278.                 var visual = $('.slideThumb');
  279.                 $(visual).removeClass("is-current");
  280.                 $(this).addClass("is-current");
  281.                 $('.item_visual').slick('slickGoTo', index, false);
  282.             });
  283.         });
  284.     </script>
  285.     
  286.     <script src="{{ asset('assets/js/jquery.colorbox-min.js') }}"></script>
  287.     <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.touchswipe/1.6.19/jquery.touchSwipe.min.js"></script>
  288.     <script>
  289.         $(document).bind('cbox_open', function(){
  290.             var test = document.getElementById('colorbox');
  291.             test.insertAdjacentHTML('beforebegin','<button type="button" id="cboxCloseSP"></button>');
  292.             if(!navigator.userAgent.match(/(iPhone|iPad|iPod|Android)/)) {
  293.                 $('#cboxCloseSP').on('click', function(){
  294.                     $.colorbox.close();
  295.                     $("#cboxCloseSP").remove();
  296.                 });
  297.                 
  298.                 $('#colorbox').swipe({
  299.                     swipeLeft:function(){
  300.                       $.colorbox.next()
  301.                     },
  302.                     swipeRight:function(){
  303.                       $.colorbox.prev()
  304.                     },
  305.                     threshold:0
  306.                 });
  307.             }
  308.             return false;
  309.         });
  310.         $(document).ready(function(){
  311.             if(!navigator.userAgent.match(/(iPhone|iPad|iPod|Android)/)) {
  312.                 $("#cboxCurrent").remove();
  313.                 $(".gallery-slide").colorbox({
  314.                     rel:'slideshow',
  315.                     maxWidth:"90%",
  316.                     maxHeight:"90%",
  317.                     opacity: 0.7,
  318.                     overlayClose: true,
  319.                     returnFocus:false,
  320.                     onOpen:function() {
  321.                       var ycoord = $(this).scrollTop();
  322.                       $('#colorbox').data('ycoord',ycoord);
  323.                       ycoord = ycoord * -1;
  324.                       $('body').css('position','fixed').css('left','0px').css('right','0px').css('top',ycoord + 'px');
  325.                     },
  326.                     onClosed:function(){
  327.                       $('#cboxOverlay').removeClass('customization');
  328.                       $('body').css('position','').css('left','auto').css('right','auto').css('top','auto');
  329.                       $(window).scrollTop($('#colorbox').data('ycoord'));
  330.                     },
  331.                     onComplete: function() {
  332.                         $.colorbox.position(0);
  333.                     }
  334.                 });
  335.                 $('.gallery-slide').on('click', function(){
  336.                   $('#cboxOverlay').addClass('customization');
  337.                 });
  338.             }
  339.             return false;
  340.         });
  341.         $('.gallery-slide').on('click', function(){
  342.             if(window.matchMedia("(max-width: 768px)").matches){
  343.                 return false;
  344.             }
  345.         });
  346.     </script>
  347. {% endblock %}
  348. {% block main %}
  349.     <link rel="stylesheet" href="{{ asset('assets/js/colorbox/colorbox.css') }}">
  350.     <div class="ec-productRole">
  351.     
  352.         {# タグ #}
  353.         <ul class="ec-productRole__tags">
  354.             {% for Tag in Product.Tags %}
  355.                 <li class="ec-productRole__tag tag_{{ Tag.id }}">{{ Tag }}</li>
  356.             {% endfor %}
  357.         </ul>
  358.         {# 商品名 #}
  359.         <div class="ec-productRole__title">
  360.             <h2 class="ec-headingTitle">{{ Product.name }}</h2>
  361.         </div>
  362.     
  363.     
  364.         <div class="ec-grid2">
  365.             <div class="ec-grid2__cell">
  366.                 <div class="ec-sliderItemRole">
  367.                     <div class="item_visual">
  368.                         {% for ProductImage in Product.ProductImage %}
  369.                             <a href="{{ asset(ProductImage, 'save_image') }}" class="gallery-slide">
  370.                                 <div class="slide-item">
  371.                                     <img src="{{ asset(ProductImage, 'save_image') }}">
  372.                                     <div class="icon_zoom"><img src="{{ asset('assets/icon/icon_zoom.svg') }}"></div>
  373.                                 </div>
  374.                             </a>
  375.                         {% else %}
  376.                             <div class="slide-item"><img src="{{ asset(''|no_image_product, 'save_image') }}"/></div>
  377.                         {% endfor %}
  378.                     </div>
  379.                     <div class="item_nav">
  380.                         {% for ProductImage in Product.ProductImage %}
  381.                             <div class="slideThumb" data-index="{{ loop.index0 }}"><img src="{{ asset(ProductImage, 'save_image') }}"></div>
  382.                         {% endfor %}
  383.                     </div>
  384.                 </div>
  385.             </div>
  386.             <div class="ec-grid2__cell">
  387.                 <div class="ec-productRole__profile">
  388.                     
  389.                     {# 通常価格 #}
  390.                     {% if Product.hasProductClass -%}
  391.                         <div class="ec-productRole__priceRegular">
  392.                             {% if Product.getPrice01Min is not null and Product.getPrice01IncTaxMin == Product.getPrice01IncTaxMax %}
  393.                                 <span class="ec-productRole__priceRegularPrice">{{ '通常価格'|trans }}:<span class="price01-default">{{ Product.getPrice01IncTaxMin|number_format }}</span></span>
  394.                                 <span class="ec-productRole__priceRegularTax">{{ '円(税込)'|trans }}</span>
  395.                             {% elseif Product.getPrice01Min is not null and Product.getPrice01Max is not null %}
  396.                                 <span class="ec-productRole__priceRegularPrice">{{ '通常価格'|trans }}:<span class="price01-default">{{ Product.getPrice01IncTaxMin|number_format }}~ {{ Product.getPrice01IncTaxMax|number_format }}</span></span>
  397.                                 <span class="ec-productRole__priceRegularTax">{{ '円(税込)'|trans }}</span>
  398.                             {% endif %}
  399.                         </div>
  400.                     {% else %}
  401.                         {% if Product.getPrice01Max is not null %}
  402.                             <span class="ec-productRole__priceRegularPrice">{{ '通常価格'|trans }}:{{ Product.getPrice01IncTaxMin|number_format }}</span>
  403.                             <span class="ec-productRole__priceRegularTax">{{ '円(税込)'|trans }}</span>
  404.                         {% endif %}
  405.                     {% endif %}
  406.                     {# 販売価格 #}
  407.                     <div class="ec-productRole__price">
  408.                         {% if Product.hasProductClass -%}
  409.                             {% if Product.getPrice02IncTaxMin == Product.getPrice02IncTaxMax %}
  410.                                 <div class="ec-price">
  411.                                     <span class="ec-price__price price02-default">{{ Product.getPrice02IncTaxMin|number_format }}</span>
  412.                                     <span class="ec-price__tax">{{ '円(税込)'|trans }}</span>
  413.                                 </div>
  414.                             {% else %}
  415.                                 <div class="ec-price">
  416.                                     <span class="ec-price__price price02-default">{{ Product.getPrice02IncTaxMin|number_format }} ~ {{ Product.getPrice02IncTaxMax|number_format }}</span>
  417.                                     <span class="ec-price__tax">{{ '円(税込)'|trans }}</span>
  418.                                 </div>
  419.                             {% endif %}
  420.                         {% else %}
  421.                             <div class="ec-price">
  422.                                 <span class="ec-price__price">{{ Product.getPrice02IncTaxMin|number_format }}</span>
  423.                                 <span class="ec-price__tax">{{ '円(税込)'|trans }}</span>
  424.                             </div>
  425.                         {% endif %}
  426.                     </div>
  427.                     {# ポイント #}
  428.                     <div class="ec-productRole__point ec-productRole__code point-display-container" style="display:none">
  429.                         <span class="product-point-default">{{ 'joolendisplaypoints4.front.point.label'|trans }}</span>
  430.                         <span class="point-display"></span>
  431.                     </div>
  432.                     <div class="border__box">
  433.                         {# 商品コード #}
  434.                         {% if Product.code_min is not empty %}
  435.                             <div class="ec-productRole__code">
  436.                                 {{ '商品コード'|trans }}: <span class="product-code-default">{{ Product.code_min }}{% if Product.code_min != Product.code_max %} ~ {{ Product.code_max }}{% endif %}</span>
  437.                             </div>
  438.                         {% endif %}
  439.                         <form action="{{ url('product_add_cart', {id:Product.id}) }}" method="post" id="form1" name="form1" class="conversion_box">
  440.                             {% if Product.stock_find %}
  441.                                 <div class="ec-productRole__actions">
  442.                                     {% if form.classcategory_id1 is defined %}
  443.                                         <div class="ec-select">
  444.                                             {{ form_widget(form.classcategory_id1) }}
  445.                                             {{ form_errors(form.classcategory_id1) }}
  446.                                         </div>
  447.                                         {% if form.classcategory_id2 is defined %}
  448.                                             <div class="ec-select">
  449.                                                 {{ form_widget(form.classcategory_id2) }}
  450.                                                 {{ form_errors(form.classcategory_id2) }}
  451.                                             </div>
  452.                                         {% endif %}
  453.                                     {% endif %}
  454.                                 </div>
  455.                                 <div class="ec-productRole__btn conversion_btn">
  456.                                     <div class="ec-numberInput select_amount"><span class="amount">{{ '数量'|trans }}</span>
  457.                                         {{ form_widget(form.quantity) }}
  458.                                         {{ form_errors(form.quantity) }}
  459.                                     </div>
  460.                                     <button type="submit" class="ec-blockBtn--action add-cart">
  461.                                         {{ 'カートに入れる'|trans }}
  462. {#                                         <span class="ec-icon"><img src="{{ asset('assets/icon/icon_cart_wh.svg') }}" alt="カートアイコン"/></span> #}
  463.                                     </button>
  464.                                 </div>
  465.                             {% else %}
  466.                                 <div class="ec-productRole__btn conversion_btn">
  467.                                     <button type="button" class="ec-blockBtn--action" disabled="disabled">
  468.                                         {{ 'ただいま品切れ中です。'|trans }}
  469.                                     </button>
  470.                                 </div>
  471.                             {% endif %}
  472.     
  473.                             {{ form_rest(form) }}
  474.                         </form>
  475.                     </div>
  476.                     <div class="ec-modal">
  477.                         <div class="ec-modal-overlay">
  478.                             <div class="ec-modal-wrap">
  479.                                 <span class="ec-modal-close"><span class="ec-icon"><img src="{{ asset('assets/icon/cross-dark.svg') }}" alt=""/></span></span>
  480.                                 <div id="ec-modal-header" class="text-center">{{ 'カートに追加しました。'|trans }}</div>
  481.                                 <div class="ec-modal-box">
  482.                                     <div class="ec-role">
  483.                                         <span class="ec-inlineBtn--cancel">{{ 'お買い物を続ける'|trans }}</span>
  484.                                         <a href="{{ url('cart') }}" class="ec-inlineBtn--action">{{ 'カートへ進む'|trans }}</a>
  485.                                     </div>
  486.                                 </div>
  487.                             </div>
  488.                         </div>
  489.                     </div>
  490.                     {% if BaseInfo.option_favorite_product %}
  491.                         <form action="{{ url('product_add_favorite', {id:Product.id}) }}" method="post">
  492.                             <div class="ec-productRole__btn">
  493.                                 {% if is_favorite == false %}
  494.                                     <button type="submit" id="favorite" class="ec-blockBtn--cancel btn_outline">
  495.                                         <span class="ec-icon"><img src="{{ asset('assets/icon/icon_heart_line.svg') }}" alt=""/></span>{{ 'お気に入りに追加'|trans }}
  496.                                     </button>
  497.                                 {% else %}
  498.                                     <button type="submit" id="favorite" class="ec-blockBtn--cancel"
  499.                                             disabled="disabled">{{ 'お気に入りに追加済です。'|trans }}
  500.                                     </button>
  501.                                 {% endif %}
  502.                             </div>
  503.                         </form>
  504.                     {% endif %}
  505.                 </div>
  506.             </div>
  507.         </div>
  508.         
  509.         <div class="ec-productRole__description">
  510.             {{ Product.description_detail|raw|nl2br }}
  511.         </div>
  512.         {% if Product.freearea %}
  513.              <div class="ec-productRole__description">
  514.                  {{ include(template_from_string(Product.freearea), sandboxed = true) }}
  515.             </div>
  516.         {% endif %}
  517.         {# 関連カテゴリ #}
  518.         {% if Product.ProductCategories is not empty %}
  519.             <div class="ec-productRole__category ec-productRole__description">
  520.                 <h3><label>{{ '関連カテゴリ'|trans }}</label></h3>
  521.                 {% for ProductCategory in Product.ProductCategories %}
  522.                     <ul>
  523.                         <li>
  524.                             {% for Category in ProductCategory.Category.path %}
  525.                                 <a href="{{ url('product_list') }}?category_id={{ Category.id }}">{{ Category.name }}</a> {%- if loop.last == false %}
  526.                                 <span>></span>{% endif -%}
  527.                             {% endfor %}
  528.                         </li>
  529.                     </ul>
  530.                 {% endfor %}
  531.             </div>
  532.         {% endif %}
  533.     </div>
  534.     
  535.     {% include 'Block/guide.twig' %}
  536.     
  537. {% endblock %}