<aside> 💡 このページでは、Liquid, JavaScriptの高度な内容を扱っています。

</aside>

概要

eギフトで商品をカートに追加したとき、カートページでは「配送日時指定」の要素を非表示にしたいご要望があるかと思います。

Shopifyにおいて「配送日時指定」機能を実現する方法は複数ありますが(アプリ, 独自実装, …)、どのパターンでも基本的に対応できる方法をご説明します。

方法

以下のJavaScriptファイルをテーマに追加し、カートページのLiquidファイル(cart.liquid等)読み込むようにしてください。

ファイル中の {配送日時指定要素のクラス名} には、配送日時指定コンポーネントの要素のクラス名を、Devtoolなどで調べて挿入してください。

<aside> 💡 以下は、2023年3月以降にインストールをしたストア様向けです。それ以前にインストールされ、UIがラジオボタン形式の場合は、ページ最下部にコードを記載しております。

</aside>

const sleep = msec =>
  new Promise(resolve => setTimeout(resolve, msec));

const searchShippingDayElement = async () => {
  for (let i = 0; i < 50; i++) {
    const shippingDayElement = document.querySelector('{配送日時指定要素のクラス名}');
    if (shippingDayElement) {
      return shippingDayElement;
    }
    await sleep(100);
  }
  return null;
};

searchShippingDayElement().then(shippingDayElement => {
  if (shippingDayElement) {
    fetch('/cart.js')
      .then(response => response.json())
      .then(cart => {
        const isGiftEnabledItemInCart = cart.items.some(item =>
          item.properties &&
          'ギフト購入' in item.properties &&
          item.properties['ギフト購入'] === '有効'
        );

        if (isGiftEnabledItemInCart) {
          shippingDayElement.style.display = 'none';
        }
      })
      .catch(error => {
        console.log(`cart.js 読み込み失敗 ${error.message}`);
      });
  }
});

上記のファイルを、例えば anygift-custom.js.liquid のようなファイル名にした場合、カートページのLiquidで以下のように記述して読み込むことができます。

{% comment %}AnyGift用のJavaScriptを読み込み{% endcomment %}
{{ 'anygift-custom.js' | asset_url | script_tag }}

動作確認をして、問題なければ完了です。

ラジオボタンUIの場合

eギフトのUIがラジオボタン型の場合は、以下のコードをご参照ください。

{% comment %}
    AnyGiftアプリ用: カートページでeギフト購入の商品がカートにあれば、配送設定の要素を削除するスクリプト
{% endcomment %}

const sleep = msec =>
  new Promise(resolve => setTimeout(resolve, msec))

{% comment %}配送日時指定要素を探索する。非同期的にレンダリングされる場合もあるので、見つかるまでリトライを重ねる{% endcomment %}
const searchShippingDayElement = async () => {
  for (let i = 0; i < 40; i++) {
      const shippingDayElement = document.querySelector('.{配送日時指定要素のクラス名}')
      if (shippingDayElement) {
          return shippingDayElement
      }
      await sleep(200)
  }
  return null
}

let shippingDayElement
searchShippingDayElement().then(element => {
  if (element) {
    shippingDayElement = element
  }
})

{% comment %}AnyGiftのギフトUIの選択肢要素を探索する{% endcomment %}
const searchGiftOptionElement = async () => {
   for (let i = 0; i < 40; i++) {
      const giftOptionElement = document.querySelectorAll('.anygift-option-button__circle')[1]
      if (giftOptionElement) {
          return giftOptionElement
      }
      await sleep(200)
  }
  return null
}

{% comment %}eギフトが選択されたら配送日時指定要素を隠す{% endcomment %}
searchGiftOptionElement().then((giftOptionElement) => {
  if (giftOptionElement) {
    const giftOptionObserver = new MutationObserver((mutations) => {
      mutations.forEach((value) => {
        const isGiftSelected = Array.from(value.target.classList).includes('anygift-option-button__circle-active')

        if (isGiftSelected) {
          shippingDayElement.style.display = 'none'
        } else {
          shippingDayElement.style.display = 'block'
        }
      });
    });

    const observerConfig = {
      childList: false,
      attributes: true,
      characterData: false,
      subtree: false,
    };

    giftOptionObserver.observe(giftOptionElement, observerConfig)
  }
})

{% comment %}商品ページからすでにギフト設定がされている場合にも、配送日時設定要素を隠す{% endcomment %}
fetch('/cart.js').then(
    async cart => {
        const res = await cart.json()
        const isGiftEnabledItemInCart = res.items.some(item =>
            item.properties &&
                'ギフト購入' in item.properties &&
                item.properties['ギフト購入'] === '有効',
        )
        if (isGiftEnabledItemInCart) {
          if (shippingDayElement) shippingDayElement.style.display = 'none'
        }                                        
    },
    error => {
        console.log(`cart.js 読み込み失敗 ${error.message}`);
    }
);