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
    • 6. FAQ
    • 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
      • Offer
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Quote
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • _Overview
      • Addresses
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • BillingRetail
      • BlogPostingStructuredData
      • BrandListStructuredData
      • CollectionStructuredData
      • Company
      • General
      • Login
      • LoginModal
      • MonthlyTransactions
      • Offers
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductGridItemClassic
      • ProductListItem
      • ProductModal
      • ProductStructuredData
      • ProfileInfo
      • PromptModal
      • Quotes
      • Register
      • Services
      • Shipping
      • ShoppingLists
      • ShoppingListsButton
      • ShoppingListsNavbar
      • StoresStructuredData
      • Toast
      • Transactions
      • Users
      • VariantContent
      • VariantContentClassic
      • WishlistButton
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • _Overview
        • theme.js
      • Css - Scss
        • _Overview
        • ThemeClasses
    • 5. SDK
      • _Overview
      • LiquidGlobals
      • ServicesSDK
  1. 3. Reusables

ProductGridItemClassic

Purpose#

ProductGridItemClassic is the Classic-theme counterpart of ProductGridItem: it renders the grid-view product card used in listing, category, and search result pages.
It mirrors ProductGridItem's behavior (media, pricing/labels, quick actions, add-to-cart) with Classic-specific markup, an image swiper, and cart-quantity syncing for items already in the cart.

Where it's rendered#

It's rendered from the same kind of listing/category/search contexts as ProductGridItem, using the Classic theme variant, e.g.:
{% render 'Reusables\ProductGridItemClassic\Default',
    product: product,
    modelId: id,
    listName: listName,
    position: forloop.index0
%}

Inputs (Liquid render parameters)#

Named parameters (same contract as ProductGridItem):
product
The product object shown in the card.
modelId
Used to build a unique key (modelId-product.id) for DOM scoping.
listName
Used for GA list tracking (select-item events).
position
Used for GA list tracking (select-item events).

Template behavior (Liquid + Alpine)#

High-level rendering follows ProductGridItem: brand badge, category/title, SKU/MPN blocks, dimension/variant selectors, and quick actions (comparison, wishlist, shopping lists) gated by the same GlobalData.Settings.* feature flags.
Differences from ProductGridItem:
Adds an image swiper (initImageSwiper) for cards with multiple product images.
Syncs displayed quantity with the item already present in the cart (cartItem, isInCart, handleCartIncrease/handleCartDecrease/handleCartQuantityInput).
Supports viewport-based, batched hydration of prices/constraints (hydrateOnViewport, scheduleConstraintsHydration, schedulePriceHydration).
Alpine wiring:
x-data='productgriditemclassicreusabledefault.initComponent({{ product | serialize | escape }}, "{{ Reusables.ProductGridItemClassic.Translations.AddToCartErrorMessage }}", "{{ Reusables.ProductGridItemClassic.Translations.UpdateProductQuantityErrorMessage }}")'
Defensive note: initComponent normalizes product.productVariants to [] when it's missing/not an array (catalog data may omit variants for the current visitor), so downstream getters never dereference undefined.

Data contract (JS runtime)#

Model shape (storefront example)#

Same product shape as ProductGridItem — see that page's Model shape sample for the sanitized JSON (id, title, alias, mediaItems[], dimension1/dimension2, productVariants[], price fields).

JavaScript#

Global object#

Global object: productgriditemclassicreusabledefault
Liquid wiring:
x-data="productgriditemclassicreusabledefault.initComponent(product, addToCartErrorMessage, updateProductQuantityErrorMessage, isProductSection, hydrateOnViewport, listName)"

initSwiper(refs)#

Creates a Swiper instance for dimension pickers (color/size carousels), same as ProductGridItem.

initImageSwiper(refs)#

Creates a Swiper instance for the card's product image gallery, enabling loop mode and next/prev navigation.

initComponent(product, addToCartErrorMessage, updateProductQuantityErrorMessage, isProductSection, hydrateOnViewport, listName)#

Initializes local Alpine state for dimension/variant selection, quantity handling, and cart syncing. Normalizes product.productVariants to an empty array when missing.

init#

Alpine lifecycle method. Sets up dimension selection defaults, registers listeners, and (when hydrateOnViewport is enabled) schedules price/constraint hydration once the card enters the viewport.

getTitleCatHeight#

Measures the title/category block and writes a CSS variable used for consistent card-height layout.

handleClickEvents#

Wires middle-click/Ctrl-click handling so the card opens in a new tab while still sending GA tracking.

sendSelectEvent#

Sends a GA selectItem event for the clicked product.

sendSelectEventAndRedirect#

Sends a GA selectItem event and then navigates to the product page.

setSelectedColor#

Sets the selected Color dimension id/label and recomputes the selected variant.

setSelectedOther#

Sets the selected non-color dimension id/label and recomputes the selected variant.

setDimension#

Generic setter for either dimension slot; recomputes the selected variant.

updateSelectedVariant#

Finds the variant matching the current dimension selections, updates selectedVariant, and refreshes quantity/active image state.

selectedVariant#

Getter that returns the currently selected variant, or null when the selection is incomplete.

hasMultipleVariants#

Getter indicating whether the product has more than one variant.

allDimensionsSelected#

Getter indicating whether the required dimension selections are complete.

isMultiVariant / isSingleVariant#

Getters that classify the product as multi- or single-variant for UI branching.

shouldShowAddToCartButton#

Getter controlling whether the add-to-cart button is shown (desktop: always; mobile: single-variant only).

showMobileModalButton#

Getter controlling whether the "choose variant" mobile modal trigger is shown.

displayStartPrice / displayFinalPrice / displayOriginalPrice#

Getters controlling which price block (range/start, final, original/discounted) is shown for the current selection.

isOtherOptionOrderable(otherId)#

For 2-dimension products, checks whether a given "other" dimension value is orderable with the currently selected color.

isSingleOptionOrderable(dimId, isDim1)#

Checks whether a single-dimension option is orderable by looking at matching variants' quantity constraints.

canAddToCart#

Returns whether the current selection is orderable and not blocked by quantity constraints.

handleAddToCart#

Adds the selected variant to the cart via servicesreusabledefault.addToCart(...), then updates quantity constraints and the cart-synced quantity from the response.

variantOrDefault(path, displayNullLine)#

Reads a value from the selected variant first, falling back to the product; returns - when displayNullLine is true and the value is missing.

getDynamicLabelClass(el)#

Computes a CSS class for availability labels based on variantOrDefault('stockAvailability.label').

getDynamicColorStyle#

Computes an inline style (background color/gradient) for color swatches based on textColor values, supporting the two-hex "split" color pattern.

getActiveImage(mediaItemId)#

Locates the image matching a media item id and slides the image swiper to it.

swiperInitSingleProductImages#

Initializes the Swiper/LightGallery integration used when the card renders inside a product-single section.

updateHeaderHeight / updateStickyElementTop / updateStickyState / updateActiveButtonOnScroll#

Sticky-positioning helpers used only when the card is rendered inside a product-single section (isProductSection === true).

scrollToTop(selector)#

Scrolls smoothly to a section and updates the active sticky button.

increaseQuantity / decreaseQuantity#

Adjust the local quantity using the selected variant's additive quantity constraints (step/min/max).

debounceUpdateProduct#

Debounces calls to updateQuantity(...) per product id, cancelling in-flight quantity-check requests via Axios cancel tokens.

updateQuantity(newQuantity, product, productVariantId, checkQuantity, useDebounce)#

Validates/normalizes the quantity server-side (via servicesreusabledefault.updateProductQuantity) when checkQuantity is true, otherwise updates the local quantity directly.

runPriceHydration / schedulePriceHydration#

Hydrate personalized/ERP prices client-side (batched per page) when the card enters the viewport, since the server renders cards from a cached price-free view model.

runConstraintsHydration / scheduleConstraintsHydration#

Hydrate personalized quantity constraints client-side (batched per page) when the card enters the viewport; falls back to permissive defaults (min: 1, step: 1, max: 999999) on failure.

cartItem#

Getter that finds the matching item already present in $store.cart, used to display the current cart quantity on the card.

isInCart#

Getter that returns whether the currently selected variant is already present in the cart.

applyCartItemQuantity#

Syncs the local quantity field from the matching cart item, so the card reflects quantities already added.

handleCartIncrease / handleCartDecrease / handleCartQuantityInput#

Update the quantity of an item already in the cart (increment, decrement, or direct input) and persist the change via servicesreusabledefault.updateProductCart(...).

debouncedUpdateCartItemQuantity#

Debounces cart-quantity updates from the increase/decrease/input handlers before calling the cart update service.

removeCartItem#

Removes the matching item from the cart via servicesreusabledefault.removeFromCart(...) when quantity is reduced to zero (or explicitly removed).

Global Alpine stores#

$store.cart (reading/updating the item already in the cart)
$store.productModal (used indirectly by nested reusables/quick-add flows that may open the variant modal from this card)
$store.toast (error feedback for add-to-cart/quantity updates)

Services / API calls#

Uses servicesreusabledefault for cart and quantity-related operations, same as ProductGridItem, plus cart-quantity syncing calls used only in the Classic variant:
servicesreusabledefault.hydrateProductPrices(products)
servicesreusabledefault.hydrateProductConstraints(product)
Falls back to servicesreusabledefault._applyDefaultConstraints(product) when hydration fails, keeping the card orderable with permissive defaults.
servicesreusabledefault.addToCart(...)
servicesreusabledefault.updateProductQuantity(...)
servicesreusabledefault.updateProductCart(...) — used by handleCartIncrease/handleCartDecrease/handleCartQuantityInput to persist quantity changes for an item already in the cart.
servicesreusabledefault.removeFromCart(...) — used by removeCartItem to remove the item when quantity reaches zero.

Dependencies#

Liquid: Reusables/ProductGridItemClassic/Default.liquid
JS: Reusables/ProductGridItemClassic/Default.js
Translations: Reusables/ProductGridItemClassic/Default.json
Nested reusables: Reusables/ProductComparisonButton/Default, Reusables/WishlistButton/Default, Reusables/ShoppingListsButton/Default
Vendor JS: Swiper, LightGallery

Notes#

Functionally equivalent to ProductGridItem; consult that page for the full dimension/variant selection model shape.
Cart-quantity syncing (cartItem, isInCart, applyCartItemQuantity, cart increase/decrease/input handlers, removeCartItem) is Classic-specific and not present in ProductGridItem.
Modified at 2026-07-24 07:19:31
Previous
ProductGridItem
Next
ProductListItem
Built with