FROM CACHE - jp_header
このコミュニティはピアツーピアサポートに移行しました。Shopify サポートは今後、このコミュニティへのサービスを提供いたしません。これからもぜひ、他のマーチャントやパートナーとつながり、サポートし合い、経験を共有してください。 当社の行動規範に違反する行動や削除を希望するコンテンツがありましたら、引き続きご報告ください

【Dawnテーマ】リアルタイムでカートの商品を確認したい

【Dawnテーマ】リアルタイムでカートの商品を確認したい

むろ
Shopify Partner
11 0 0

現在年齢確認をつけるため、Dawnで以下のようなコードを作成しています。

 

カートに追加した際に出てくるポップアップの「購入画面へ」ボタンを押し、対象商品がカートに入っていれば年齢確認を出すというものです。

 

対象商品がカート内に入っている状態→何かを追加→購入ボタンを押す

だと、しっかりと年齢確認が出るのですが、

対象商品がカート内にない状態→対象商品を追加→購入ボタン

だと、そのまま決済画面へ進んでしまいます。

 

おそらくページ読み込み時の時点でカートを確認してしまい、反映されないという状態だと思うのですが、何か解決策などお願いします。

 

{% comment %}
  Renders cart notification

  Accepts:
  - color_scheme: {String} sets the color scheme of the notification (optional)
  - desktop_menu_type: {String} passes the desktop menu type which allows us to use the right css class (optional)

  Usage:
  {% render 'cart-notification' %}
{% endcomment %}

<cart-notification>
  <div class="cart-notification-wrapper{% if desktop_menu_type != 'drawer' %} page-width{% endif %}">
    <div
      id="cart-notification"
      class="cart-notification focus-inset{% if color_scheme %} color-{{ color_scheme }} gradient{% endif %}"
      aria-modal="true"
      aria-label="{{ 'general.cart.item_added' | t }}"
      role="dialog"
      tabindex="-1"
    >
      <div class="cart-notification__header">
        <h2 class="cart-notification__heading caption-large text-body">
          {%- render 'icon-checkmark' -%}
          {{ 'general.cart.item_added' | t }}
        </h2>
        <button
          type="button"
          class="cart-notification__close modal__close-button link link--text focus-inset"
          aria-label="{{ 'accessibility.close' | t }}"
        >
          <svg class="icon icon-close" aria-hidden="true" focusable="false">
            <use href="#icon-close">
          </svg>
        </button>
      </div>
      <div id="cart-notification-product" class="cart-notification-product"></div>
      <div class="cart-notification__links">
        <a
          href="{{ routes.cart_url }}"
          id="cart-notification-button"
          class="button button--secondary button--full-width"
        >
          {{- 'general.cart.view_empty_cart' | t -}}
        </a>
        {% comment %}カート内に年齢確認商品があるかチェックする変数を初期化{% endcomment %}
{% assign has_age_restricted_item = false %}

{% comment %}カート内の各商品をチェック{% endcomment %}
{% for item in cart.items %}
  {% for collection in item.product.collections %}
    {% if collection.title == "年齢確認商品" %}
      {% assign has_age_restricted_item = true %}
      {% break %}
    {% endif %}
  {% endfor %}
  {% if has_age_restricted_item %}
    {% break %}
  {% endif %}
{% endfor %}
        <form action="{{ routes.cart_url }}" method="post" id="cart-notification-form">
          <button       onclick="checkCartAndShowPopup()" class="button button--primary button--full-width" name="checkout">
            {{ 'sections.cart.checkout' | t }}
          </button>
        </form>
        <button type="button" class="link button-label">{{ 'general.continue_shopping' | t }}</button>
      </div>
    </div>
  </div>
</cart-notification>
<!-- ポップアップの HTML -->
    <div id="checkoutPopup" class="popup">
      <div class="popup-content">
        <span class="close" onclick="closePopup()">&times;</span>
        <h2>年齢確認</h2>
        <h5 style="font-size:15px;line-height:0.1px;margin:0;">カートに酒類が含まれているため、年齢確認が必要です</h5>
        <p>生年月日を入力してください。</p>
        <input id="popup-birthinput" type="date" style="padding: 10px 10px" class="dobInput field__input" value="2000-01-01">
        <p>年齢を入力してください。</p>
        <input class="field__input" id="popupfield" type="number" min="0" value="0">
        <p class="popupmini">20歳未満の飲酒は法律で禁止されています。20歳未満の方への酒類の販売はできません。</p>
        <button type="button" id="validateButton" onclick="validateAndCheckout()">決済へ進む</button>
      </div>
    </div>
  </div>
<div id="cart-errors"></div>
</div>
</div>
</div>
</div>

<script>
var hasAgeRestrictedItem = {{ has_age_restricted_item | json }};
var date = new Date();
var yyyy = date.getFullYear();
var mm = ("0"+(date.getMonth()+1)).slice(-2);
var dd = ("0"+date.getDate()).slice(-2);
document.getElementById("popup-birthinput").max=yyyy+'-'+mm+'-'+dd;
//ここまで日付取得
document.addEventListener('DOMContentLoaded', function () {
  const checkoutButton = document.querySelector('button[name="checkout"]');
  const cartForm = document.querySelector('form[action="/cart"]');

  if (checkoutButton && cartForm) {
    checkoutButton.addEventListener('click', function (event) {
      event.preventDefault();
      checkCartAndShowPopup();
    });

    cartForm.addEventListener('submit', function (event) {
      if (hasAgeRestrictedItem) {
        event.preventDefault();
        checkCartAndShowPopup();
      }
    });
  }

  function isIE() {
    const ua = window.navigator.userAgent;
    const msie = ua.indexOf('MSIE ');
    const trident = ua.indexOf('Trident/');
    return msie > 0 || trident > 0;
  }

  if (isIE()) {
    const cartSubmitInput = document.createElement('input');
    cartSubmitInput.setAttribute('name', 'checkout');
    cartSubmitInput.setAttribute('type', 'hidden');
    document.querySelector('#cart').appendChild(cartSubmitInput);
  }
});

function checkCartAndShowPopup() {
  if (hasAgeRestrictedItem) {
    showPopup();
  } else {
    proceedToCheckout();
  }
}

function showPopup() {
  document.getElementById('checkoutPopup').style.display = 'block';
}

function closePopup() {
  document.getElementById('checkoutPopup').style.display = 'none';
}

function calculateAge(birthDate) {
  const today = new Date();
  const birthDateObj = new Date(birthDate);
  let age = today.getFullYear() - birthDateObj.getFullYear();
  const monthDiff = today.getMonth() - birthDateObj.getMonth();
  
  if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDateObj.getDate())) {
    age--;
  }
  
  return age;
}

function validateAndCheckout() {
  const dobInput = document.getElementById('popup-birthinput');
  const ageInput = document.getElementById('popupfield');
  
  const calculatedAge = calculateAge(dobInput.value);
  const inputAge = parseInt(ageInput.value);

  if (calculatedAge !== inputAge) {
    alert('生年月日または年齢が間違っています。');
    return;
  }

  if (calculatedAge >= 20) {
    proceedToCheckout();
  } else {
    alert('20歳未満の飲酒は法律で禁止されています。20歳未満の方への酒類の販売はできません。');
  }
}

function proceedToCheckout() {
  const form = document.querySelector('form[action="/cart"]');
  if (form) {
    const input = document.createElement('input');
    input.type = 'hidden';
    input.name = 'checkout';
    input.value = '1';
    form.appendChild(input);
    form.submit();
  } else {
    console.error('Checkout form not found');
  }
}

// ポップアップ外クリックで閉じる
window.onclick = function(event) {
  var popup = document.getElementById('checkoutPopup');
  if (event.target == popup) {
    closePopup();
  }
}
</script>

 

3件の返信3

Jizo_Inagaki
Shopify Partner
1100 409 716

https://shopify.dev/docs/api/ajax/reference/cart

上記のCart APIで対応可能かと思います。

Jizo_Inagaki | フリーランスのwebデザイナー
- テーマのカスタム承れます。
- 記載した回答で解決できましたらベストソリューションの承認をお願いします。
- DMや指名による対応はご依頼として有料でのみ承ります。
むろ
Shopify Partner
11 0 0

具体的なコードを教えていただきたいです

Jizo_Inagaki
Shopify Partner
1100 409 716

無料での対応範囲を超えるため対応できかねますのでご了承ください。

ご自身で対応できない場合はエキスパートやパートナーに依頼するか、アプリで対応可能か検討することをお勧めします。

Jizo_Inagaki | フリーランスのwebデザイナー
- テーマのカスタム承れます。
- 記載した回答で解決できましたらベストソリューションの承認をお願いします。
- DMや指名による対応はご依頼として有料でのみ承ります。