shopify - Shopify 中的售罄选项样式

标签 shopify

我正在尝试将 css 添加到产品选项中,以便为用户提供哪些选项不可用(已售完)的视觉指示。当产品只有一组选项值时,此方法有效,但我的产品有两个(“日期”和“时间”)。我在大部分情况下都可以使用此功能,但是当我在日期之间切换时,可用的“时间”选项不会更新。如有任何帮助,我们将不胜感激。

在我的product-form.liquid 文件中,我有以下代码来添加一个类以售完选项。也许我需要一些js?

如果它有帮助,我正在使用 Prestige 主题,页面位于:https://neetfield.co.uk/pizza

                {%- if option.name == "Time" and product.selected_or_first_available_variant.option1 == product.variants[forloop.index0].option1 -%}
                  {%- if product.variants[forloop.index0].available -%}
                    {%- assign opt_sold = false -%}
                  {%- else -%}
                    {%- assign opt_sold = true -%}
                  {%- endif -%}
                {%- else -%}
                  {%- assign opt_sold = false -%}
                {%- endif -%}

然后,这用于向已售完选项添加一个类{% if opt_sold %}opt-sold-out{% endif %}

这是我到达的位置的屏幕截图(现在在实时网站上禁用,直到我在日期之间切换时它可以工作):

enter image description here

最佳答案

首页渲染(液体)

对于初始页面加载,您可以使用如下内容:

{%- liquid
  assign selected_option_1 = product.selected_or_first_available_variant.option1
  assign relevant_variants = product.variants | where: 'option1', selected_option_1
  assign available_timeslots = ''

  for variant in relevant_variants
    if variant.available
      assign available_timeslots = available_timeslots | append: ',' | append: variant.option2
    endif
  endfor

  assign available_timeslots = available_timeslots | remove_first: ',' | split: ','
-%}

此代码段会迭代所有产品变体,其中 option1 等于当前所选变体的 option1 值(例如“6 月 4 日星期六”)。对于每个变体,我们将检查其是否可用并将其推送到 available_timeslots 数组。

确保在迭代所有产品选项之前放置此代码段。

最后,使用此数组检查选项值是否可用:

{%- unless available_timeslots contains value -%}
  Disable option input
{%- endunless -%}

value 基本上是 option.values 的值。我相信您会在产品表单中的某个位置找到它:)

用户交互后(JavaScript)

由于 Liquid 是一种服务器端渲染模板语言,因此您只能通过客户端上的 JavaScript 更新变体更改时的选项输入元素来实现此目的。 Shopify Prestige 主题有一个有用的 CustomEvent对于这种情况:variant:changed

实现的示例如下所示:

/**
 * Gets the option index that is different between `variant` in `previousVariant`.
 *
 * @param {object} variant
 * @param {object} previousVariant
 * @returns {1 | 2 | 3}
 */
const getChangedOptionIndex = (variant, previousVariant) => {
  let changedOptionIndex;

  for (let i = 0; i < variant.options.length; i++) {
    if (variant.options[i] !== previousVariant.options[i]) {
      changedOptionIndex = i;
      break;
    }
  }

  return changedOptionIndex;
};

/**
 * Find a variant via its options.
 *
 * @param {object[]} variants
 * @param {{ option1: string, option2: string }} options
 * @returns {object | undefined}
 */
const findVariantByOptions = (variants, { option1, option2 }) => {
  return variants.find((variant) => variant.option1 === option1 && variant.option2 === option2);
};

const { product } = JSON.parse(document.querySelector('script[data-product-json]').innerHTML);

document.addEventListener('variant:changed', (event) => {
  // We might need a sanity check here. For example, if the current variant is
  // "Saturday 4th June / 18:30" and you switch to "Saturday 11th June" the time option
  // "18:30" might not exist which would result in `event.detail` being `undefined`.
  // if (!event.detail.variant) {
  //
  // }

  const { variant, previousVariant } = event.detail;
  const changedOptionIndex = getChangedOptionIndex(variant, previousVariant);

  const optionInputEls = document.querySelectorAll('input[name^="option-"]');

  // Note: This approach won't work anymore if a product has 3 options
  optionInputEls.forEach((optionInputEl) => {
    const optionIndex = Number(optionInputEl.name.split('-')[1]);

    // Only check option inputs that are not of the same group as the changed option
    if (optionIndex !== changedOptionIndex) {
      const foundVariant = findVariantByOptions(product.variants, {
        [`option${changedOptionIndex + 1}`]: variant.options[changedOptionIndex],
        [`option${optionIndex + 1}`]: optionInputEl.value,
      });

      if (!foundVariant || !foundVariant.available) {
        optionInputEl.nextElementSibling.classList.add('opt-sold-out');
      } else {
        optionInputEl.nextElementSibling.classList.remove('opt-sold-out');
      }
    }
  });
});

请记住,您并没有真正禁用输入。它只是在视觉上表明它已被禁用。如果这对您来说不是问题,请忽略此评论。

请注意,这不能处理以下情况:

  • 用户选择日期“A”
  • 用户选择时间“X”
  • 用户选择日期“B”(时间“X”不可用)

我猜选择哪个日期的决定总是首先出现的,所以这不应该是一个需要担心的重要场景。

关于shopify - Shopify 中的售罄选项样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72387972/

相关文章:

javascript - 在 Shopify 产品页面上显示单个产品图片

ruby-on-rails - 使用shopify_api gem的shopify订单履行问题

javascript - 如何使用 shopify Polaris DropZone 组件上传图片

Shopify API : Article Url

css - 将购物车图标与主 Logo 对齐 - Shopify

html - 在 Shopify 的页面上显示产品变体

javascript - 在图像上添加产品列表

android - 我可以使用 Shopify Mobile Buy SDK 为 shopify 商店构建 android 或 ios 应用程序吗?

CSS;如何为 on AND "off"hover 制作图像悬停过渡效果?

php - Shopify GraphQL Admin API 速率限制成本和 sleep 时间