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

ShoppingLists

Purpose#

The ShoppingLists reusable powers the Shopping Lists area inside the user profile. It supports:
displaying all shopping lists and their preview items
viewing a single list in detail
creating, renaming, and deleting lists
selecting items and adding them to cart (single or bulk)
updating quantities with debounced server updates
importing/exporting lists from/to Excel
clearing selected items from a list
It heavily integrates with the global PromptModal ($store.modal) for confirmations and input flows.

Where it's rendered#

This reusable is rendered from Components/Profile/Default.liquid:
{% render 'Reusables\\ShoppingLists\\Default', shoppingLists: shoppingLists %}

Inputs (Liquid render parameters)#

Liquid parameters#

shoppingLists (array)
The initial shopping lists data used to render the list view.
Passed into the JS via shoppinglistsreusabledefault.initComponent(...).

Model shape (storefront example)#

Sanitized real storefront example (provided by the user). Only the fields relevant to this reusable are kept.
[
  {
    "id": "Shopping List Id",
    "title": "Sample text",
    "alias": "sample",
    "items": [
      {
        "productId": "Product Id",
        "productVariantId": "Product Variant Id",
        "quantity": 1,
        "product": {
          "id": "Product Id",
          "title": "Sample text",
          "alias": "sample",
          "link": "product/sample",
          "mediaItems": [
            {
              "id": "Media Id",
              "link": "https://example.com/sample",
              "position": 0,
              "alt": "Sample text",
              "mediaType": "Image"
            },
            ...
          ],
          "productVariants": [
            {
              "id": "Product Variant Id",
              "quantityConstraints": {
                "additive": {
                  "minimum": 1,
                  "maximum": 999999,
                  "step": 1,
                  "isValid": true
                },
                "absolute": {
                  "minimum": 1,
                  "maximum": 999999,
                  "step": 1,
                  "isValid": true
                }
              },
              "dimension1ItemId": "Dimension Item Id",
              "dimension2ItemId": "Dimension Item Id",
              "sku": "Sample text",
              "canOrder": true,
              "sellOutOfStock": true,
              "startQuantity": 1
            },
            ...
          ],
          "dimension1": {
            "id": "Dimension Id",
            "name": "Sample text",
            "type": "Color",
            "items": [
              {
                "id": "Dimension Item Id",
                "value": "Sample text",
                "textColor": "#000000"
              },
              ...
            ]
          },
          "dimension2": {
            "id": "Dimension Id",
            "name": "Sample text",
            "type": "Size",
            "items": [
              {
                "id": "Dimension Item Id",
                "value": "Sample text"
              },
              ...
            ]
          }
        }
      },
      ...
    ]
  },
  ...
]

Required fields#

Per shopping list:
id
title
alias
items[]
Per item:
productId
productVariantId
quantity
product
id, title, alias
mediaItems[] (optional but used for previews)
productVariants[] (used for mapping dimensions/variant data)

Optional fields#

The implementation reads many product fields when available (categories, tags, labels, attributes, etc.) but the core UI only requires variant media + title/alias and variant dimension ids.

Template behavior (Liquid + Alpine)#

Feature flag#

Rendered only when:
GlobalData.Settings.EnableShoppingLists is truthy.

Alpine wiring#

The root wrapper mounts:
x-data='shoppinglistsreusabledefault.initComponent(shoppingLists, translationErrors)'
Where:
shoppingLists is the Liquid parameter
translationErrors is a JSON string built from Reusables.ShoppingLists.Translations.*

Two main views#

1.
Lists overview (selectedShoppingListIndex == null)
Shows list cards with title, preview images (up to 3), and actions.
Supports:
create new list (opens PromptModal)
view list
import/export
rename (inline)
delete (confirmation modal)
add items to cart
2.
List details (selectedShoppingListIndex != null)
Shows:
rename toolbar
import/export actions
item selection (select all / per item)
quantity controls (increase/decrease/input)
delete selected items (confirmation modal)
add selected to cart

PromptModal usage#

The template itself doesn’t mount the PromptModal; instead it opens it through $store.modal.open(...) and relies on:
promptmodalreusabledefault.isDataValid(modalData)
for validation of modal inputs.

JavaScript#

Global object#

Global object: shoppinglistsreusabledefault (in Reusables/ShoppingLists/Default.js).
Factory:
initComponent(shoppingLists, translationErrors)

State (returned object)#

Core state:
shoppingLists
selectedShoppingListIndex, selectedShoppingList
isLoadingLists, isShoppingListChanging, isUpdating
openPopup (per-list actions popover)
rename state:
isRenaming[]
originalTitles[]
draftTitles[]
delete state:
pendingDeleteIndex
debouncing/cancellation:
debounceMap
cancelTokenMap

Methods (nested inside initComponent)#

init()#

If URL path contains /shoppingLists/{alias}, auto-opens the matching shopping list.
If alias doesn’t exist, resets URL path.

getImage(item)#

Returns { link, alt } using variant media first, then product media.

sendSelectEvent(product, listName, position)#

Sends GA event selectItem using prepareListProducts(...).

setUrlPath(alias)#

Updates the current URL path to either:
/.../shoppingLists (no alias)
/.../shoppingLists/{alias}

getDimension(item, dimensionName)#

Resolves display name/value for a dimension (e.g. dimension1, dimension2) by:
finding the variant
reading variant.dimension1ItemId / variant.dimension2ItemId
mapping to product.dimensionX.items[]

getVariant(item, variantId)#

Returns the matching product variant by id.

selectAllItems() / deselectAllItems()#

Toggles item.selected for all items in selectedShoppingList.

selectItem(item) / deselectItem(item)#

Toggles selection on a single item.

createNewShoppingList(modalTranslations)#

Opens PromptModal for a required newShoppingList input.
Uses promptmodalreusabledefault.isDataValid(modalData).
Blocks duplicate list names client-side.
Calls servicesreusabledefault.createShoppingList({ title }).
Refreshes via Alpine.store('shoppingLists').fetch() and replaces local shoppingLists.

viewShoppingList(index) / viewShoppingLists()#

Switches between overview and list details.
Clones items to avoid mutating the original reference.

openRenameShoppingList(index)#

Enters rename mode for a list.
Snapshots original title and draft title.

saveRenaming(modalTranslations, index)#

Validates empty name and duplicates.
Calls servicesreusabledefault.updateShoppingList(list).
On success, updates both local shoppingLists and the global Alpine.store('shoppingLists').list.

cancelRenaming(clearToasts)#

Clears toast messages (optional).
Reverts drafts to originals and exits rename mode.

confirmShoppingListDeletion(alias, modalTranslations)#

Opens a confirmation modal.
On confirm, calls deleteShoppingList(...).

deleteShoppingList(alias, deleteErrorMessage)#

Calls servicesreusabledefault.deleteShoppingList(alias).
On success, refreshes via Alpine.store('shoppingLists').fetch().

addItemToCart(...)#

Calls servicesreusabledefault.addToCart(...).
Handles response.data.lineFailures[] by mapping error types to translated messages.

addSelectedItemsToCart(items, errorMessages, selectAllItems)#

Calls servicesreusabledefault.addMultipleToCart(variations).
Handles lineFailures similarly to single add.

getLineFailureMessages(lineFailure, errorMessages, selectedProductTitle)#

Maps server error types to UI messages.
Ensures messages are unique.

deleteItemFromShoppingList(itemIndex, deleteItemErrorMessage)#

Removes a single item by index and updates the shopping list via updateShoppingList service call.

handleClearShoppingList(modalTranslations, items)#

Opens confirmation modal to clear selected items.

deleteSelectedItemsFromShoppingList(items, deleteErrorMessage)#

Removes selected items, sends servicesreusabledefault.updateShoppingList(...), and syncs local + global state.

debounceUpdate(item, delay)#

Debounces server update per item id.
Cancels any pending axios request (via stored cancel token).

updateShoppingList(item, useDebounce)#

Updates the current shopping list on the server via servicesreusabledefault.updateShoppingList(this.selectedShoppingList).
On success, syncs shoppingLists[listIndex].items to Alpine.store('shoppingLists').list.

increaseQuantity(item, variant) / decreaseQuantity(item, variant) / updateItemQuantity(newQuantity, item, variant)#

Updates quantities and calls updateShoppingList(..., true) (debounced).

handleImportShoppingList(alias, modalTranslations, template)#

Opens PromptModal with a required file input.
On confirm, reads file from #importFile and calls importShoppingList(alias, file).

importShoppingList(alias, file)#

Calls servicesreusabledefault.importShoppingList(alias, file).
Refreshes shopping lists via the global store.

exportShoppingList(alias)#

Calls servicesreusabledefault.exportShoppingList(alias).

Global Alpine stores#

This reusable uses:
$store.shoppingLists
list
fetch()
$store.modal
open(...)
close()
$store.toast
removeAll()
add(...)

Services / API calls#

This reusable calls (via servicesreusabledefault):
createShoppingList({ title })
updateShoppingList(list)
deleteShoppingList(alias)
addToCart(productId, variantId, quantity, finalPrice, originalPrice, showToast)
addMultipleToCart(variations)
importShoppingList(alias, file)
exportShoppingList(alias)

Dependencies#

Liquid: Reusables/ShoppingLists/Default.liquid
JS: Reusables/ShoppingLists/Default.js
Translations: Reusables/ShoppingLists/Default.json
Render sites:
Components/Profile/Default.liquid
Reusable dependency:
Reusables/PromptModal/Default.* (via $store.modal + promptmodalreusabledefault.isDataValid)

Notes#

The local shoppingLists array is kept in sync with Alpine.store('shoppingLists').list after create/update/delete/import.
The code excludes the pseudo-list entry ("save to different list") by slicing to slice(0, -1) after fetching.
Quantity updates are debounced and can cancel previous requests; this avoids spamming the server when users type quickly.
Modified at 2026-04-14 13:18:56
Previous
Shipping
Next
ShoppingListsNavbar
Built with