Przejdź do głównej zawartości

Webkomponent - Boxy produktowe Storefront

Boxy produktowe można wywołać w każdym miejscu na stronie, wstawiając element z odpowiednimi parametrami:

<mmz-products product-ids="3722">...</mmz-products>

W edytorze wizualnym (Froala) konieczne jest dodawanie prefiksu data- przed każdym atrybutem webkomponentu. W przeciwnym wypadku Shoper wyczyści atrybuty:

<mmz-products data-product-ids="3722">...</mmz-products>

Aby webkomponent został prawidłowo wygenerowany, wymaga jednego z poniższych parametrów:

  • product-ids
  • show (promotion, new, potd, bestsellers) → DOSTĘPNE WKRÓTCE
  • search
  • category-id
  • collection-id

Webkomponent obsługuje poniższe metody:

Za pomocą metody getCurrentProductsData można w szybki sposób uzyskać dostęp do aktualnej tablicy obiektów typu produkt, na podstawie której webkomponent domyślnie się renderuje (jeśli nie zostanie zmodyfikowana przez mmzProducts.filterData).

Do czego ta metoda może zostać wykorzystana:

Gdy w sklepie istnieje już nasłuchiwanie na zdarzenie mmzProducts.filterData, które zmienia strukturę danych z obiektów na tekst (aby utworzyć własny kafelek produktu), dane produktów zostają zgubione i zdarzenie mmzProducts.onRendered nie otrzyma tablicy obiektów typu produkt w parametrze. Wtedy metoda getCurrentProductsData pozwala dostać się do tych danych, które zostały nadpisane przez zdarzenie.

Informacje zwracane przez metodę:

Webkomponent emituje następujące zdarzenia:

Wszystkie zdarzenia emitowane są jednocześnie w dwóch formach:

  • jako zdarzenie zgodne z Shoper Event Bus,
  • jako własne DOM event.

Decyzja o tym, w jaki sposób developer chce nasłuchiwać na zdarzenie, zależy głównie od tego, czy posiadamy dostęp do useStorefront oraz czy potrzebujemy dostać się do historii zdarzeń.

Różnica pomiędzy DOM event a Event Bus polega na tym, gdzie każde ze zdarzeń przechowuje informacje:

  • w Event Bus pod event.body,
  • w DOM events pod event.detail.

mmzProducts.onConnected to zdarzenie z Event Bus, które występuje za każdym razem, gdy element boxów produktowych zostanie połączony z DOM.

Do czego to zdarzenie może zostać wykorzystane:

  • przeniesienie webkomponentu w inne miejsce w DOM (np. na mobile).

Informacje zawarte w zdarzeniu:

Z uwzględnieniem historii zdarzeń, które miały już miejsce:

let myCustomProductBoxesConnectedFn = (node) => {
console.log('Nowy element boxów produktowych pojawił się w DOM', node);
}
useStorefront((storefront) => {
const messageStorageApi = storefront.getApiSync('messageStorageSystemApi');
const pastEvents = messageStorageApi.getChannelMessages('mmzProducts.onConnected');
if (pastEvents.length > 0) {
pastEvents.forEach(({ body: eventBody }) => {
myCustomProductBoxesConnectedFn(eventBody.node);
});
}
storefront.eventBus.on('mmzProducts.onConnected', ({ body: eventBody }) => {
myCustomProductBoxesConnectedFn(eventBody.node);
});
});

Bez useStorefront (bez sprawdzenia zdarzeń, które miały już miejsce).

let myCustomProductBoxesConnectedFn = (node) => {
console.log('Nowy element boxów produktowych pojawił się w DOM', node);
}
document.addEventListener('mmzProducts.onAttributeChanged', (event) => {
myCustomProductBoxesConnectedFn(event.detail.node);
});

mmzProducts.onAttributeChanged to zdarzenie z Event Bus, które występuje za każdym razem, gdy wartość jednego ze specjalnych atrybutów elementu ulegnie zmianie.

Do czego to zdarzenie może zostać wykorzystane:

  • chcemy dynamicznie wyświetlać, dla jakiego zapytania search prezentowane są produkty w elemencie (gdy inny skrypt modyfikuje atrybut search).

Informacje zawarte w zdarzeniu:

useStorefront((storefront) => {
storefront.eventBus.on('mmzProducts.onAttributeChanged', ({ body: eventBody }) => {
console.log(eventBody); // wyświetli parametry zdarzenia
});
});
document.addEventListener('mmzProducts.onAttributeChanged', (event) => {
console.log(event.detail); // wyświetli parametry zdarzenia
});

mmzProducts.filterData to zdarzenie, które występuje za każdym razem, gdy dane o produktach zostaną zwrócone przez API Shopera do aplikacji Boxy produktowe - zanim aplikacja wygeneruje ich strukturę w DOM.

Do czego to zdarzenie może zostać wykorzystane:

  • chcemy odfiltrować produkty (np. te z określonym statusem dostępności),
  • chcemy dołożyć własny element HTML do listy produktów (np. baner jako pierwszy element),
  • chcemy wygenerować całkiem inne kafelki produktowe niż domyślne (np. samą grafikę).

Informacje zawarte w zdarzeniu:

document.addEventListener('mmzProducts.filterData', (event) => {
let new_products = [];
event.detail.products.forEach((product) => {
// Własna nazwa produktu dla "Materac piankowy Bari 90x200"
if (product.name == 'Materac piankowy Bari 90x200') {
product.name = 'Super materac 90x200';
}
new_products.push(product);
});
event.detail.products = new_products;
});

Zabezpieczenie na wypadek elementów tekstowych znajdujących się w event.detail.products. Takie zabezpieczenie jest wskazane, gdy wiemy, że w sklepie znajduje się wiele skryptów nasłuchujących na zdarzenie filterData.

document.addEventListener('mmzProducts.filterData', (event) => {
let new_products = [];
event.detail.products.forEach((product) => {
if (typeof product == 'string') {
new_products.push(product);
return true;
}
// Własna nazwa produktu dla "Materac piankowy Bari 90x200"
if (product.name == 'Materac piankowy Bari 90x200') {
product.name = 'Super materac 90x200';
}
new_products.push(product);
});
event.detail.products = new_products;
});

Sytuacja, w której chcemy wygenerować własny kafelek od zera, a nie edytować go dopiero po wyrenderowaniu - np. dlatego, że diametralnie różni się od domyślnego.

document.addEventListener('mmzProducts.filterData', (event) => {
if (!(event.detail.node.closest('[data-module-instance="17289"]'))) return true;
let new_products = [];
event.detail.products.forEach((product) => {
let imageFilename = product.main_image_filename
? '/environment/cache/images/500_500_productGfx_' + product.main_image_filename
: '/environment/cache/images/500_500_productGfx___overlay.jpg';
let custom_tile = '<product-tile product-id="' + product.id + '" name="' + product.name.replace('"', '&quot;') + '" class="product-tile ">' +
'<product-link id="' + product.id + '" name="' + product.name.replace('"', '&quot;') + '">' +
'<a href="' + product.url + '" title="' + product.name.replace('"', '&quot;') + '" aria-label="Przejdź do produktu ' + product.name.replace('"', '&quot;') + '">' +
'<picture class="image">' +
'<img src="' + imageFilename + '" alt="' + product.name.replace('"', '&quot;') + '" width="500" height="500" loading="lazy" style="aspect-ratio: 1; object-fit: cover; object-position: top center;">' +
'</picture>' +
'</a>' +
'</product-link>' +
'<product-link id="' + product.id + '" name="' + product.name.replace('"', '&quot;') + '" style="position: absolute; bottom: 0; left: 0; width: 100%; padding: 0 10px; box-sizing: border-box; text-shadow: 0 0 5px white;">' +
'<a href="' + product.url + '" title="' + product.name.replace('"', '&quot;') + '" class="link_no-underline">' +
'<h3 class="product-tile__name' + (window.mmzProductBoxes_config.shouldShortenLongProductName ? ' product-tile__name_fixed-height' : '') + '">' + product.name + '</h3>' +
'</a>' +
'</product-link>' +
'</product-tile>';
new_products.push(custom_tile);
});
event.detail.products = new_products;
});

mmzProducts.onRendered to zdarzenie, które występuje za każdym razem, gdy aplikacja wygeneruje strukturę boxów w DOM i skrypt (przynajmniej tymczasowo - dopóki nie zmieni się żaden ze specjalnych atrybutów) zakończy modyfikację danego elementu.

Do czego to zdarzenie może zostać wykorzystane:

  • modyfikacje kafelka produktu (np. przesunięcie nazwy producenta pod cenę),
  • dodanie własnych wstążek na kafelki produktów.

Informacje zawarte w zdarzeniu:

useStorefront((storefront) => {
storefront.eventBus.on('mmzProducts.onRendered', ({ body: eventBody }) => {
console.log(eventBody); // wyświetli parametry zdarzenia
});
});
document.addEventListener('mmzProducts.onRendered', (event) => {
console.log(event.detail); // wyświetli parametry zdarzenia
});