> For the complete documentation index, see [llms.txt](https://en-ascent.webvista.studio/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://en-ascent.webvista.studio/ascent-mu-ban-shi-yong-shuo-ming/kai-fa-zhe/zi-ding-yi-jia-gou-an-niu-he-gou-wu-che-chou-ti.md).

# 自定义加购按钮

当你需要让自定义 Add to cart 按钮、自定义 Liquid 或自定义 JavaScript 在添加商品到购物车后，打开 Ascent 原生购物车抽屉时，可以参考本页。

## 推荐方式

最推荐的方式是复用 Ascent 内置的 `<product-form>`。它已经处理了加载状态、错误提示、购物车图标数量更新、购物车抽屉内容更新，以及打开购物车抽屉。

```liquid
<script src="{{ 'product-form.js' | asset_url }}" defer="defer"></script>

<product-form class="product-form" data-section="{{ section.id }}">
  <div
    id="Product-Form-Error-Message-{{ section.id }}"
    class="alert-message alert-error mb-2"
    role="alert"
    aria-live="assertive"
    hidden
  ></div>

  {% form 'product', product, class: 'form', novalidate: 'novalidate', data-type: 'add-to-cart-form' %}
    <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
    <input type="hidden" name="quantity" value="1">

    <button type="submit" name="add" class="button button--primary">
      加入购物车
    </button>
  {% endform %}
</product-form>
```

使用这个方式时，商店的购物车类型需要设置为抽屉，并且主题中需要存在购物车抽屉。

## 自定义 JavaScript 方式

如果你需要用完全自定义的 JavaScript 加购，可以在 Ajax 加购请求中带上需要刷新的 sections，然后更新返回的 section 内容，并打开购物车抽屉。

```html
<button type="button" data-custom-add-to-cart data-variant-id="1234567890">
  加入购物车
</button>

<script>
  document.querySelector("[data-custom-add-to-cart]")?.addEventListener("click", async (event) => {
    const button = event.currentTarget;
    const cartDrawer = document.getElementById("Cart-Drawer");
    const sectionsToRender = [
      {
        id: "Cart-Icon-Bubble",
        section: "cart-icon-bubble",
        selector: ".shopify-section"
      }
    ];

    if (cartDrawer && !cartDrawer.hasAttribute("data-status-silence")) {
      sectionsToRender.push({
        id: "Cart-Drawer",
        section: cartDrawer.dataset.section,
        selector: "#Cart-Drawer-Details"
      });
    }

    const formData = new FormData();
    formData.append("id", button.dataset.variantId);
    formData.append("quantity", "1");
    formData.append("sections", sectionsToRender.map((section) => section.section).join(","));
    formData.append("sections_url", window.location.pathname);

    const response = await fetch(window.routes.cart_add_url, {
      method: "POST",
      headers: {
        "X-Requested-With": "XMLHttpRequest"
      },
      body: formData
    });

    const cartData = await response.json();

    if (cartData.status) {
      console.error(cartData.description || cartData.message);
      return;
    }

    SectionDynamicUpdate.updateSections(sectionsToRender, cartData.sections);

    webvista.publish(PUB_SUB_EVENTS.cartUpdate, {
      source: "custom-add-to-cart",
      productVariantId: formData.get("id"),
      cartData
    });

    if (cartDrawer && !cartDrawer.hasAttribute("data-status-silence")) {
      cartDrawer.show(button);
    } else {
      window.location = window.routes.cart_url;
    }
  });
</script>
```

请把示例中的 `1234567890` 替换为需要加入购物车的变体 ID。

## 注意事项

* 加入购物车时使用的是变体 ID，不是产品 ID。
* 请求中需要包含 `sections_url`，这样 Shopify 才能返回当前页面对应的 section HTML。
* 在购物车页面不要强制打开抽屉；Ascent 会通过 `data-status-silence` 静默购物车抽屉。
* 如果只是普通产品加购按钮，优先使用内置 `<product-form>` 方式。
