Gift chooser JavaScript API
On this page
window.AndOrQuickview.open(options) opens the gift chooser dialog and
returns its <andor-quickview> element. The cart gift slot is the only
caller in AndOr today. You can call it from your own code to reuse the
same two-step product and variant picker.
Caution The script loads only when needed. The gift slot loads it the first time it needs the chooser, so
window.AndOrQuickviewmay not exist yet. Check for it before you call it.
open(options)
const dialog = window.AndOrQuickview.open(options);The dialog is a native <dialog> opened with showModal(). It draws in
the browser’s top layer, above the page and the theme’s cart drawer. It
traps focus, makes the page behind it inert and returns focus to the
button that opened it.
Options
| Option | Type | What it does |
|---|---|---|
into |
element | where the dialog is appended. Keep it inside the cart drawer when you open it from the drawer |
title |
string | the dialog’s heading |
slots |
number | how many picks. Default 1 |
products |
array | the products to offer (shape below) |
price(product, variant) |
function | returns [was, now] text, or null |
strings |
object | the dialog’s words (keys below) |
onSubmit(picks) |
function | gets the picks. Resolve to close, reject to show the error |
onClose() |
function | runs after the dialog closes, added or not |
buttonClass |
string | extra classes for the Add button |
products
Each product is { id, title, image, options, variants, swatches }:
optionsis[{ name, values }].- Each variant is
{ id, title, price, available, options, image }. - A variant that is not
availablemay addreason. The chooser says the reason instead of “Sold out”. swatchesis optional. It maps an option’s position (1 based, as a string) to a list of[name, swatch]pairs. A swatch is a CSS color or an image URL. Example:{ "1": [["Red", "#c0392b"], ["Blue", "#1f4e9c"]] }. An option is drawn as swatches only when every value has one. Without a listed swatch, an option named like a color tries the value’s name as a CSS color, else it is drawn as pills.
price
price(product, variant) returns two strings, [was, now], for example
["$24.95", "Free"], or null. variant is null on a product card in
step 1. Return null when you are not sure of the price or of “Free”:
the chooser then shows no price at all.
strings
Keys: close, back, add, addMany, slot, products,
optionsTitle, options, chosen, soldOut, clear, error. In
addMany, slot, chosen and clear, @ and # are filled in. For
example "Add @ gifts" becomes “Add 2 gifts”, and "Gift @ of #"
becomes “Gift 1 of 2”.
The chooser has no built-in words. Pass every key you need.
onSubmit
onSubmit(picks) gets [{ product, variant }], one entry per filled
slot. Return a promise. Resolve it to close the dialog. Reject it to show
the error string and keep the dialog open.
Example
Show the code
function openGiftPicker(button) {
if (!window.AndOrQuickview) return; // not loaded on this page yet
window.AndOrQuickview.open({
into: button.closest("cart-drawer") || document.body,
title: "Choose your free gift",
slots: 1,
products: [
{
id: 111,
title: "Ski wax",
image: "https://cdn.shopify.com/.../wax.jpg",
options: [{ name: "Scent", values: ["Pine", "Citrus"] }],
swatches: {}, // no swatches: Scent is drawn as pills
variants: [
{ id: 1, title: "Pine", price: 2495, available: true,
options: ["Pine"], image: null },
{ id: 2, title: "Citrus", price: 2495, available: false,
options: ["Citrus"], image: null },
],
},
],
price: () => null, // not sure it is free: show no price
strings: {
close: "Close", back: "Back", add: "Add gift",
addMany: "Add @ gifts", slot: "Gift @ of #",
products: "Choose a product", optionsTitle: "Choose your options",
options: "Choose options", chosen: "@ of # gifts chosen",
soldOut: "Sold out", clear: "Remove @",
error: "We could not add your gift. Please try again.",
},
onSubmit: (picks) =>
fetch("/cart/add.js", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
items: picks.map(({ variant }) => ({ id: variant.id, quantity: 1 })),
}),
}).then((response) => {
if (!response.ok) throw new Error("add failed");
}),
onClose: () => button.focus(),
});
}Behavior to know
- Escape closes the chooser and leaves Dawn’s cart drawer open. A
cancelevent is stopped too. - Everything is drawn with
textContent. No product data becomes HTML. - The Add button also gets the class list of your theme’s checkout
button (
[name="checkout"]) when the page has one, so it looks like your primary button on Dawn and Horizon. - The chooser adds its own stylesheet the first time the script runs. A first open with the stylesheet still loading keeps the dialog invisible until it loads, for 800 ms at most.
See it in action