Home
Wiki
Home
Wiki
  1. 3. Reusables
  • Back to home
  • 1. Themes
  • Vs Code
    • Getting Started
  • Kitchenware
    • Layout
      • New Layout
      • Legacy Layout
    • Components
      • Announcement
      • Banner Carousel
      • Banner With Products Carousel
      • Blog Category List
      • Blog List
      • Brand List
      • Brands Carousel
      • Breadcrumb
      • Call To Action
      • Cart
      • Categories List
      • Change Password
      • Checkout
      • Cookie Manager
      • Filter list
      • Footer
      • Forgot Password
      • Form
      • Hero Carousel
      • Icon Block
      • Invitation
      • Last Visited Products
      • Layout
      • Login
      • Map
      • Nav Bar
      • Offer
      • Product Attachments
      • Product Attributes
      • Product Documentation
      • Product Expected
      • Product Modal
      • Products Block
      • Products Carousel
      • Product Single
      • Profile
      • Quote
      • Register
      • Related Products
      • Search
      • Stores
      • Subscribe Newsletter
      • Text with Image
      • Top Bar
      • Video
    • Reusables
      • Getting Started
    • Assets
      • Getting Started
    • SDK
      • Products
        • _findProductsByCategory
        • _findProductsByIds
        • _findProductsByTitle
        • _findProductsByFilter
        • _findProductsByCriteria
        • _findProductsAndCalculate
        • _findProductsThenCalculate
        • _getProductAttributeSet
        • _setLastVisited
      • Categories
        • _findCategoryTreeById
        • _findCategoriesByIds
        • _findCategoryByAlias
        • _findCategoryTreeByAlias
        • _getCategoryContent
      • Collections
        • _getCollectionContent
        • _findCollectionsByIds
        • _findCollectionsByIdsThenCalculate
      • Brands
        • _getBrandContent
        • _findBrandsByIds
      • Cart
        • _addToCartMulti
        • _addToCart
        • _setCart
        • _clearCart
        • _setCartListener
        • _removeFromCart
        • _calculateCart
      • Checkout
        • _startCheckout
        • _updateCheckout
        • _completeCheckout
      • Shopping Lists
        • _getShoppingLists
        • _updateShoppingList
        • _createShoppingList
        • _deleteShoppingList
        • _getShoppingListByAlias
      • Navigation
        • _getFooterMenu
        • _getHeaderMenu
      • Users
        • _getUserById
      • Utils
        • _calculateCurrency
        • _getCurrencySymbol
        • _getCulture
        • _subscribeToNewsletter
        • _findUnitsByIds
  • Noir
    • 0. Introduction
    • 1. Structure
      • Overview
      • LayoutA.liquid
      • ComponentsList.liquid
      • Metas.liquid
      • CssVariables.liquid
      • Json.liquid
      • GoogleTagManager.liquid
      • StagingButton.liquid
    • 2. Components
      • Overview
      • Announcement
      • BannerCarousel
      • BlogCategoryList
      • BlogList
      • BrandList
      • Breadcrumb
      • Cart
      • CategoriesList
      • ChangePassword
      • Checkout
      • CookieManager
      • FilterList
      • Footer
      • ForgotPassword
      • Form
      • IconBlock
      • Invitation
      • LastVisitedProducts
      • Login
      • Map
      • NavBar
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • Overview
      • Addresses
      • BillingRetail
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • Company
      • General
      • Login
      • LoginModal
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductListItem
      • ShoppingListsButton
      • ProductModal
      • ProfileInfo
      • PromptModal
      • Register
      • Shipping
      • ShoppingLists
      • ShoppingListsNavbar
      • Toast
      • Users
      • VariantContent
      • WishlistButton
      • Services
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • Overview
        • theme.js
      • Css / Scss
        • Overview
        • ThemeClasses
    • 5. SDK
      • Overview
      • LiquidGlobals
      • ServicesSDK
  1. 3. Reusables

ShoppingListsButton

Purpose#

The ShoppingListsButton reusable renders a toggle button that lets authenticated users add/remove the currently selected product variant to one or more shopping lists.
It opens a modal UI to select lists (and optionally create a new one), and then persists list changes via the shopping lists SDK endpoints.

Where it's rendered#

This reusable is rendered from product cards and product pages, for example:
Reusables/ProductGridItem/Default.liquid
Reusables/ProductListItem/Default.liquid
Typical render call:
{% render 'Reusables\\ShoppingListsButton\\Default', product: product %}

Inputs (Liquid render parameters)#

Named parameters:
product
The product object for which the current variant will be added/removed.
The variant selection is derived at runtime from $store.shoppingLists.dimension1Id / dimension2Id.

Template behavior (Liquid + Alpine)#

Rendering is gated by the feature flag:
GlobalData.Settings.EnableShoppingLists
The button is disabled while the store is loading:
:disabled="$store.shoppingLists.loading"
Active state is derived from the store:
:class='{"active": $store.shoppingLists.isInShoppingLists(product)}'
On init, it wires DOM listeners for variant selection changes:
x-init="shoppinglistsbuttonreusabledefault.init($el)"
On click:
If the user is not authenticated, it opens the login modal:
$store.loginModal.open(false, true)
Otherwise, it opens a modal flow:
shoppinglistsbuttonreusabledefault.handleShoppingListsModal($el, modalTranslations, product)
Notes:
modalTranslations is constructed in Liquid as a JSON object string built from Reusables.ShoppingListsButton.Translations.* keys.

Data contract (JS runtime)#

Model shape (storefront example)#

The reusable needs enough product data to resolve a selected variant id:
{
  "id": "Product Id",
  "title": "Sample title",
  "productVariants": [
    {
      "id": "Variant Id",
      "dimension1ItemId": "Dim Item Id",
      "dimension2ItemId": "Dim Item Id",
      "quantityConstraints": {
        "additive": { "minimum": 1 }
      }
    },
    ...
  ],
  "dimension1": { "items": [ { "id": "Dim Item Id" }, ... ] },
  "dimension2": { "items": [ { "id": "Dim Item Id" }, ... ] }
}

Runtime state#

$store.shoppingLists.list
Array of lists loaded from the API, plus a synthetic new list option.
$store.shoppingLists.dimension1Id / $store.shoppingLists.dimension2Id
Updated by shoppinglistsbuttonreusabledefault.init($el) and isVariantSelected(...) by listening to variant pickers in the closest .product-card / .product-single.

JavaScript#

Global object#

Global object: shoppinglistsbuttonreusabledefault

init(element)#

What it does
Waits for $store.shoppingLists to be ready.
Finds the closest .product-card or .product-single container.
Attaches click / change listeners to dimension pickers (.product-card__variants__single) in order to keep $store.shoppingLists.dimension1Id and dimension2Id in sync.
Key behaviors / edge cases
If no product container is found, it logs a warning and returns.

waitForShoppingListsReady({ fetchIfEmpty = true, timeout = 8000 } = {})#

What it does
Polls until $store.shoppingLists exists and has finished loading.
Optionally calls store.fetch() once if the list is empty.

handleShoppingListsModal(element, modalTranslations, product)#

What it does
Ensures a valid variant selection via isVariantSelected(element).
Computes the currently selected variant id via $store.shoppingLists.fetchSelectedVariantId(product).
Opens $store.modal with:
checkbox options for existing lists
a conditional text input to create a new list
a confirm button that calls setShoppingLists(...)
Key behaviors / edge cases
If variants are not selected, it shows a toast with modalTranslations.selectVariantsFirst.

setShoppingLists(modalData, productId, variantId, quantity)#

What it does
Parses selected list ids from the modal output.
For each list:
adds the variant item if selected and not present
removes the variant item if unselected and present
Persists changes by calling servicesreusabledefault.updateShoppingList(list).
Refreshes state via $store.shoppingLists.fetch().

isVariantSelected(element)#

What it does
Finds the closest .product-card / .product-single.
Detects variant selection from either:
button.active elements
or <select> selected option data-variantid
Writes ids into $store.shoppingLists.dimension1Id / dimension2Id.
Returns true only when the required dimensions are selected.

Global Alpine stores#

$store.shoppingLists#

What it represents
A client-side representation of shopping lists (loaded from the API) plus helper methods:
fetchSelectedVariantId(product)
isInShoppingLists(product)
fetch()
How this reusable uses it
Determines active state for the button.
Resolves selected variant ids.
Provides list options for the modal.

store.modal/store.toast / $store.loginModal#

$store.modal is used to render the selection UI.
$store.toast is used for errors and validation feedback.
$store.loginModal is used when the user is not authenticated.

Services / API calls#

The reusable calls:
servicesreusabledefault.getShoppingLists() (indirectly via $store.shoppingLists.init() and .fetch())
servicesreusabledefault.createShoppingList({ title })
servicesreusabledefault.updateShoppingList(list)

Dependencies#

Liquid: Reusables/ShoppingListsButton/Default.liquid
JS: Reusables/ShoppingListsButton/Default.js
Translations: Reusables/ShoppingListsButton/Default.json
Feature flag: GlobalData.Settings.EnableShoppingLists
Alpine stores:
$store.shoppingLists (defined in Assets/js/theme.js)
$store.modal
$store.toast
$store.loginModal
SDK wrapper: servicesreusabledefault.* shopping list methods

Notes#

Variant selection is mandatory for multi-variant products; otherwise the modal will refuse to proceed.
The button inspects DOM selectors (.product-card__variants__single) to infer selection state. If those selectors change, the shopping lists integration must be updated.
Modified at 2026-04-14 13:18:56
Previous
ProductListItem
Next
ProductModal
Built with