Zmiana funkcji na klasy
This commit is contained in:
177
README.md
177
README.md
@@ -2,55 +2,108 @@
|
|||||||
Funkcje js składające się na customowe ramki rekomendacji
|
Funkcje js składające się na customowe ramki rekomendacji
|
||||||
|
|
||||||
## UWAGI PRZEDWDROŻENIOWE ##
|
## UWAGI PRZEDWDROŻENIOWE ##
|
||||||
- kod zawiera app_shop.fn.idmSetHeight używany do wyrównywania wysokości
|
- kod zawiera **app_shop.fn.idmGetOmnibusDetails** który jest przerobionym kodem idosella app_shop.fn.getOmnibusDetails używanym w zwykłych ramkach rekomendacji
|
||||||
- kod zawiera app_shop.fn.idmGetOmnibusDetails który jest przerobionym kodem idosella app_shop.fn.getOmnibusDetails używanym w zwykłych ramkach rekomendacji
|
|
||||||
|
|
||||||
### Pliki ###
|
### Pliki ###
|
||||||
- bundle.js - całość
|
- **style.css** - style wstawiane do css
|
||||||
- 1graphQL.js - graphQL + literały
|
- **klasa.js** - kod js
|
||||||
- 2funkcje.js - ogólne funkcje jak dodawanie do koszyka, czy lazy loading
|
|
||||||
- 3markup.js - funkcje związane z markupem np zdjęć, cen
|
|
||||||
- 4init.js - obiekt z ogólnymi ustawieniami Hotspota + init swipera
|
|
||||||
- 5ainsertHotspotHTML.js - wstawienie ramki po kodzie html
|
|
||||||
- 5binsertHotspotObject.js - wstawienie ramki po obiekcie js
|
|
||||||
- 6style.css -
|
|
||||||
|
|
||||||
### Użycie ###
|
### Użycie ###
|
||||||
1. Wstawienie całego kodu do komponentu/dodatku
|
1. Wstawienie całego kodu do komponentu (najlepiej chyba Hotspoty javascript RAYPATH - #IdoMods
|
||||||
2. Ustawienie defaultowych ustawień w obiekcie idmGeneralHotspotObjData
|
w zwykły Javascript)/dodatku(uwaga tutaj na literały)
|
||||||
|
2. Ustawienie defaultowych ustawień na początku klasy w **idmDefaultSwiperConfig** i w **idmDefaultHotspotOptions**
|
||||||
3. Wstawienie HTML lub Obiektu js z odpowienimi danymi i wywołanie funkcji od tworzenia ramek
|
3. Wstawienie HTML lub Obiektu js z odpowienimi danymi i wywołanie funkcji od tworzenia ramek
|
||||||
|
|
||||||
|
#### Dodatkowe informacje ####
|
||||||
|
Można użyć extends w innym miejscu (np tym razem w wydzielonym JS) żeby nadpisać jakąś metodę, bez zmian w kodzie ramki. Będzie to przydatne w przypadku gdzie trzeba będzie zaktualizować kod ramki.
|
||||||
|
|
||||||
|
**Przykład**
|
||||||
|
```
|
||||||
|
class IdmRaypathHotspot extends IdmHotspot {
|
||||||
|
markupLabel(prod) {
|
||||||
|
// Standardowe labelki
|
||||||
|
let labelMarkup = super.markupLabel(prod);
|
||||||
|
|
||||||
|
// Customowe labelki
|
||||||
|
const awards = prod?.awardedParameters;
|
||||||
|
if (awards?.length) {
|
||||||
|
const awardParam = awards.find(award => award.name === "Idm_custom_label");
|
||||||
|
const values = awardParam?.values?.map(v => v.name) || [];
|
||||||
|
|
||||||
|
const html = values
|
||||||
|
.map(label => {
|
||||||
|
const [text, bgColor, color] = label.split("||");
|
||||||
|
return `<span class="label --custom" style="background-color:${bgColor}; color:${color}">${text}</span>`;
|
||||||
|
})
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
labelMarkup += html;
|
||||||
|
}
|
||||||
|
|
||||||
|
return labelMarkup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Warto gdzieś później zapisać nową nazwę klasy np w opisie komponentu, albo w opisie szablonu.
|
||||||
|
|
||||||
|
### Literały do uzupełnienia w szablonie ###
|
||||||
|
- Coś poszło nie tak podczas dodawania do koszyka. Spróbuj ponownie lub odśwież stronę
|
||||||
|
- Błąd przy pobieraniu danych
|
||||||
|
- Maksymalna liczba sztuk tego towaru które możesz dodać do koszyka to:
|
||||||
|
- Minimalna liczba sztuk tego towaru które możesz dodać do koszyka to:
|
||||||
|
- Wystąpił błąd z inicjalizacją. Proszę odśwież stronę
|
||||||
|
- Nie znaleziono kontenera
|
||||||
|
- Nie znaleziono metody graphql
|
||||||
|
|
||||||
#### Przykład ####
|
#### Przykład ####
|
||||||
##### Jedna ramka - obiekt ######
|
##### Jedna ramka - obiekt ######
|
||||||
```
|
```
|
||||||
idmInsertHotspotObject({
|
new IdmHotspot({
|
||||||
{
|
id: "idmTestHotspot1",
|
||||||
id: "idmMainHotspot1",
|
title: "tescik",
|
||||||
title: "Nowoczesna ramka rekomendacji",
|
|
||||||
classes: "abcdefg",
|
|
||||||
placement: {
|
placement: {
|
||||||
selector: "#content",
|
selector: "#content",
|
||||||
insert: "afterbegin"
|
insert: "beforeend",
|
||||||
},
|
},
|
||||||
query: {
|
source: {
|
||||||
string: `searchInput: {productsId : [589, 180, 181590,160740, 155978, 153632, 123350, 82542, 37321, 17040, 25065, 25114, 85452]}`,
|
productsMenu: 1649
|
||||||
graphFn: IDM_PRODUCTS_GQL
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
lazy: false,
|
|
||||||
addToBasket: "range",
|
|
||||||
swiper: true,
|
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
})
|
|
||||||
```
|
|
||||||
##### Wszystkie ramki - tablica obiektów ######
|
|
||||||
```
|
|
||||||
idmInsertAllObjectHotspots(hotspotArr);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Wszystkie możliwe dane JS ####
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* @typedef {object} Hotspot
|
||||||
|
* @property {string} id - Identyfikator ramki (required).
|
||||||
|
* @property {string} title - Tytuł ramki.
|
||||||
|
* @property {string} classes - Dodatkowe klasy CSS.
|
||||||
|
* @property {object} placement - Określa, gdzie wstawić ramkę (required).
|
||||||
|
* @property {string} placement.selector - Selektor miejsca osadzenia.
|
||||||
|
* @property {string} placement.insert - Pozycja wstawienia względem selektora (np. "afterbegin", "beforeend").
|
||||||
|
* @property {object} source - Dane źródłowe dla hotspotu (required).
|
||||||
|
* @property {string} [source.hotspotType] - Typ hotspotu (np. "promotion").
|
||||||
|
* @property {number[]} [source.productsId] - Tablica ID produktów.
|
||||||
|
* @property {number} [source.productsMenu] - Identyfikator menu produktów.
|
||||||
|
* @property {object} query - Dane zapytania, nadpisują source (DEV).
|
||||||
|
* @property {string} query.string - Zapytanie w formacie GraphQL.
|
||||||
|
* @property {Function} query.graphFn - Funkcja do pobierania danych.
|
||||||
|
* @property {object} options - Ustawienia dla hotspotu (required).
|
||||||
|
* @property {boolean} options.lazy - Czy wczytywać w trybie lazy.
|
||||||
|
* @property {boolean|string} options.addToBasket - Obsługa koszyka:
|
||||||
|
* - true = włącz
|
||||||
|
* - false = wyłącz
|
||||||
|
* - "range" = dodaj z zakresem
|
||||||
|
* @property {boolean|object} options.swiper - Slider:
|
||||||
|
* - true = aktywny
|
||||||
|
* - false = nieaktywny
|
||||||
|
* - object = konfiguracja Swiper
|
||||||
|
* @property {Function} options.callbackFn - Funkcja callback która dzieje się po wywołaniu wszystkiego włącznie ze swiperem
|
||||||
|
*
|
||||||
|
* @type {Hotspot[]}
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
###### Jedna ramka - HTML ######
|
###### Jedna ramka - HTML ######
|
||||||
@@ -72,52 +125,24 @@ idmInsertAllObjectHotspots(hotspotArr);
|
|||||||
idmInsertHotspotElement(document.getElementByid("idmBlogHotspot1"));
|
idmInsertHotspotElement(document.getElementByid("idmBlogHotspot1"));
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
#### Wszystkie możliwe dane HTML####
|
||||||
###### Wszystkie ramki - HTML ######
|
|
||||||
```
|
```
|
||||||
idmInsertAllHTMLHotspots();
|
/**
|
||||||
|
* Struktura sekcji hotspotu w HTML.
|
||||||
|
*
|
||||||
|
* @typedef {HTMLElement} HotspotSection
|
||||||
|
* @property {string} id - Identyfikator elementu (np. "idmBlogHotspot1").
|
||||||
|
* @property {string} class - Klasy CSS używane do stylowania.
|
||||||
|
*
|
||||||
|
* @attribute {string} data-products-id - Lista ID produktów (rozdzielona przecinkami).
|
||||||
|
* @attribute {number} data-products-menu - Identyfikator menu produktów.
|
||||||
|
* @attribute {string} data-hotspots-type - Typ hotspotu (np. "promotion").
|
||||||
|
* @attribute {boolean} data-lazy - Czy sekcja ma być ładowana w trybie lazy.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### LISTA GLOBALNYCH FUNKCJI, ZMIENNYCH ###
|
|
||||||
##### INIT #####
|
|
||||||
- priceQuery
|
|
||||||
- productQuery
|
|
||||||
- IDM_PRODUCTS_GQL
|
|
||||||
- IDM_HOTSPOTS_GQL
|
|
||||||
- IDM_PRODUCT_GQL
|
|
||||||
- IDM_HOTSPOT_ADD_TO_BASKET
|
|
||||||
- idmHotspotTextObject
|
|
||||||
|
|
||||||
#### FUNKCJE ####
|
|
||||||
- app_shop.fn.idmGetOmnibusDetails
|
|
||||||
- idmHandleAddToBasket
|
|
||||||
- idmRangeMaxAlert
|
|
||||||
- idmRangeMinAlert
|
|
||||||
- idmQuantityButtonClick
|
|
||||||
- idmQuantityInputChange
|
|
||||||
- idmGetHotspotData
|
|
||||||
- idmGetQueryData
|
|
||||||
- idmObserveOnce
|
|
||||||
- app_shop.fn.idmSetHeight
|
|
||||||
|
|
||||||
|
|
||||||
#### MARKUP ####
|
|
||||||
- idmPrepareProductsMarkup
|
|
||||||
- idmPrepareSingleProductMarkup
|
|
||||||
- idmPrepareHotspotImgMarkup
|
|
||||||
- idmPrepareHotspotPriceMarkup
|
|
||||||
- idmPrepareHotspotAddToBasketMarkup
|
|
||||||
|
|
||||||
#### INIT ####
|
|
||||||
- idmPriceType
|
|
||||||
- idmGeneralHotspotObjData
|
|
||||||
- idmHotspotInit
|
|
||||||
|
|
||||||
#### INSERT ####
|
|
||||||
- idmInsertHotspotElement
|
|
||||||
- idmInsertAllHTMLHotspots
|
|
||||||
- idmInsertHotspotObject
|
|
||||||
- idmInsertAllObjectHotspots
|
|
||||||
|
|
||||||
Created by • **[IdoMods](https://idomods.pl/)** • 2025
|
Created by • **[IdoMods](https://idomods.pl/)** • 2025
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
///////////////////////////////////////////////
|
|
||||||
// GraphQL
|
|
||||||
// ogolne
|
|
||||||
const priceQuery = `price {
|
|
||||||
rebateCodeActive
|
|
||||||
price {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
omnibusPrice {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
omnibusPriceDetails {
|
|
||||||
unit {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
youSavePercent
|
|
||||||
omnibusPriceIsHigherThanSellingPrice
|
|
||||||
newPriceEffectiveUntil {
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
max {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unit {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unitConvertedPrice {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
youSavePercent
|
|
||||||
beforeRebate {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
beforeRebateDetails {
|
|
||||||
youSavePercent
|
|
||||||
unit {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
advancePrice {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
suggested {
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rebateNumber {
|
|
||||||
number
|
|
||||||
gross {
|
|
||||||
value
|
|
||||||
formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
|
|
||||||
const productQuery = `id
|
|
||||||
type
|
|
||||||
name
|
|
||||||
zones
|
|
||||||
icon
|
|
||||||
iconSecond
|
|
||||||
iconSmall
|
|
||||||
iconSmallSecond
|
|
||||||
link
|
|
||||||
zones
|
|
||||||
producer{
|
|
||||||
name
|
|
||||||
}
|
|
||||||
category{
|
|
||||||
name
|
|
||||||
}
|
|
||||||
sizes{
|
|
||||||
id
|
|
||||||
amount
|
|
||||||
name
|
|
||||||
${priceQuery}
|
|
||||||
}
|
|
||||||
group{
|
|
||||||
id
|
|
||||||
name
|
|
||||||
link
|
|
||||||
versions{
|
|
||||||
id
|
|
||||||
name
|
|
||||||
icon
|
|
||||||
iconSecond
|
|
||||||
iconSmall
|
|
||||||
iconSmallSecond
|
|
||||||
}
|
|
||||||
}
|
|
||||||
awardedParameters {
|
|
||||||
name
|
|
||||||
id
|
|
||||||
description
|
|
||||||
values {
|
|
||||||
name
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enclosuresImages {
|
|
||||||
position
|
|
||||||
url
|
|
||||||
}
|
|
||||||
points
|
|
||||||
unit{
|
|
||||||
id, name, singular, plural, fraction, sellBy, precision, unitConvertedFormat
|
|
||||||
}
|
|
||||||
${priceQuery}`;
|
|
||||||
// 1. products
|
|
||||||
const IDM_PRODUCTS_GQL = (args) => JSON.stringify({
|
|
||||||
query: `{
|
|
||||||
products(${args}){
|
|
||||||
took
|
|
||||||
products{
|
|
||||||
${productQuery}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. hotspots
|
|
||||||
const IDM_HOTSPOTS_GQL = (args) => JSON.stringify({
|
|
||||||
query: `{
|
|
||||||
hotspots(${args}){
|
|
||||||
took
|
|
||||||
products{
|
|
||||||
${productQuery}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
});
|
|
||||||
|
|
||||||
// 3. single product
|
|
||||||
const IDM_PRODUCT_GQL = (args) => JSON.stringify({
|
|
||||||
query: `{
|
|
||||||
product(${args}){
|
|
||||||
product{
|
|
||||||
${productQuery}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
});
|
|
||||||
// ADD TO BASKET
|
|
||||||
const IDM_HOTSPOT_ADD_TO_BASKET = (t, e, a) => JSON.stringify({
|
|
||||||
query: `mutation {\n addProductsToBasket(ProductInput: {id: ${t}, size: "${e}", quantity: ${a}}) {\n status\n results {\n status\n error {\n code\n message\n }\n productCode\n productId\n sizeId\n quantity\n quantityAvailable\n }\n clientDetailsInBasket {\n id\n login\n firstname\n lastname\n participationPartnerProgram\n usesVat\n email\n isWholesaler\n isWholesalerOrder\n clientIdUpc\n }\n }\n }`
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// TEXT
|
|
||||||
const idmHotspotTextObject = {
|
|
||||||
["Kod rabatowy"]: "Kod rabatowy",
|
|
||||||
["Okazja"]: "Okazja",
|
|
||||||
["Promocja"]: "Promocja",
|
|
||||||
["Bestseller"]: "Bestseller",
|
|
||||||
["Nowość"]: "Nowość",
|
|
||||||
["Ilość"]: "Ilość",
|
|
||||||
["Zwiększ ilość"]: "Zwiększ ilość",
|
|
||||||
["Zmniejsz ilość"]: "Zmniejsz ilość",
|
|
||||||
["Najniższa cena produktu w okresie 30 dni przed wprowadzeniem obniżki"]: "Najniższa cena produktu w okresie 30 dni przed wprowadzeniem obniżki",
|
|
||||||
["Cena regularna"]: "Cena regularna",
|
|
||||||
["Cena bez kodu"]: "Cena bez kodu",
|
|
||||||
["Cena nadchodząca od"]: "Cena nadchodząca od",
|
|
||||||
["Coś poszło nie tak podczas dodawania do koszyka. Spróbuj ponownie lub odśwież stronę"]: "Coś poszło nie tak podczas dodawania do koszyka. Spróbuj ponownie lub odśwież stronę",
|
|
||||||
["Nie znaleziono produktów"]: "Nie znaleziono produktów",
|
|
||||||
["Błąd przy pobieraniu danych"]: "Błąd przy pobieraniu danych",
|
|
||||||
["Kliknij, by przejść do formularza kontaktu"]: "Kliknij, by przejść do formularza kontaktu",
|
|
||||||
["Cena na telefon"]: "Cena na telefon",
|
|
||||||
["Dodany"]: "Dodany",
|
|
||||||
["Wystąpił błąd"]: "Wystąpił błąd",
|
|
||||||
["Do koszyka"]: "Do koszyka",
|
|
||||||
["Maksymalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]: "Maksymalna liczba sztuk tego towaru które możesz dodać do koszyka to:",
|
|
||||||
["Minimalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]: "Minimalna liczba sztuk tego towaru które możesz dodać do koszyka to:",
|
|
||||||
["Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"]: "Wystąpił błąd z inicjalizacją. Proszę odśwież stronę",
|
|
||||||
["Nie znaleziono kontenera"]: "Nie znaleziono kontenera",
|
|
||||||
["Nie znaleziono metody graphql"]: "Nie znaleziono metody graphql",
|
|
||||||
}
|
|
||||||
@@ -1,321 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////\\\\\\\\\\\\
|
|
||||||
// IDOSELL omnibus details
|
|
||||||
|
|
||||||
// omnibusDetailsTxt - nadpisać na własny obiekt
|
|
||||||
|
|
||||||
app_shop.fn.idmGetOmnibusDetails = (options) => {
|
|
||||||
const {
|
|
||||||
productData, sizeId, priceType = app_shop.vars.priceType,
|
|
||||||
} = options || {};
|
|
||||||
if (!productData) return false;
|
|
||||||
const sizeData = productData.sizes.find((size) => size.id === sizeId) || productData;
|
|
||||||
if (!sizeData?.price) return false;
|
|
||||||
const classes = {
|
|
||||||
add: [],
|
|
||||||
remove: ['--omnibus', '--omnibus-short', '--omnibus-code', '--omnibus-code-short', '--omnibus-new-price', '--omnibus-higher'],
|
|
||||||
};
|
|
||||||
const activeLabel = {};
|
|
||||||
|
|
||||||
const omnibusPrice = sizeData.price?.omnibusPriceDetails?.unit?.[priceType]?.formatted || sizeData.price.omnibusPrice[priceType]?.formatted;
|
|
||||||
if (!omnibusPrice) {
|
|
||||||
return {
|
|
||||||
classes,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// Omnibus
|
|
||||||
classes.add.push('--omnibus');
|
|
||||||
classes.remove = classes.remove.filter((item) => item !== '--omnibus');
|
|
||||||
|
|
||||||
const sellBy = productData?.unit?.sellBy;
|
|
||||||
|
|
||||||
const unitMaxPrice = sizeData?.price?.unit?.[priceType]?.formatted && sizeData.price.max?.[priceType]?.value ? format_price(parseFloat(sizeData.price.max?.[priceType]?.value) * parseFloat(sellBy), {
|
|
||||||
mask: app_shop.vars.currency_format,
|
|
||||||
currency: app_shop.vars?.currency?.symbol,
|
|
||||||
currency_space: app_shop.vars.currency_space,
|
|
||||||
currency_before_price: app_shop.vars.currency_before_value,
|
|
||||||
}) : false;
|
|
||||||
|
|
||||||
const maxPrice = unitMaxPrice || sizeData.price.max?.[priceType]?.formatted;
|
|
||||||
// Skrócona wersja omnibusa
|
|
||||||
if (!maxPrice || maxPrice === omnibusPrice) {
|
|
||||||
classes.add.push('--omnibus-short');
|
|
||||||
classes.remove = classes.remove.filter((item) => item !== '--omnibus-short');
|
|
||||||
}
|
|
||||||
// Aktywny kod rabatowy
|
|
||||||
if (app_shop.vars.omnibus?.rebateCodeActivate && sizeData.price?.rebateCodeActive) {
|
|
||||||
classes.add.push('--omnibus-code');
|
|
||||||
activeLabel.rebateCodeActive = `<span class="label --code --omnibus">${idmHotspotTextObject["Kod rabatowy"]}</span>`;
|
|
||||||
classes.remove = classes.remove.filter((item) => item !== '--omnibus-code');
|
|
||||||
}
|
|
||||||
// Skrócona wersja omnibusa, gdy aktywny kod rabatowy
|
|
||||||
const beforeRebatePrice = sizeData.price.beforeRebateDetails?.unit?.[priceType]?.formatted || sizeData.price.beforeRebate[priceType]?.formatted;
|
|
||||||
if (app_shop.vars.omnibus?.rebateCodeActivate && beforeRebatePrice === omnibusPrice && sizeData.price?.rebateCodeActive) {
|
|
||||||
classes.add.push('--omnibus-code-short');
|
|
||||||
classes.remove = classes.remove.filter((item) => item !== '--omnibus-code-short');
|
|
||||||
}
|
|
||||||
// Nadchodząca cena
|
|
||||||
const newDate = sizeData.price.omnibusPriceDetails?.newPriceEffectiveUntil?.formatted;
|
|
||||||
if (newDate && maxPrice) {
|
|
||||||
classes.add.push('--omnibus-new-price');
|
|
||||||
classes.remove = classes.remove.filter((item) => item !== '--omnibus-new-price');
|
|
||||||
}
|
|
||||||
// Cena omnibusa wyższa niż cena sprzedaży
|
|
||||||
const higher = sizeData.price.omnibusPriceDetails?.omnibusPriceIsHigherThanSellingPrice;
|
|
||||||
if (higher) {
|
|
||||||
classes.add.push('--omnibus-higher');
|
|
||||||
classes.remove = classes.remove.filter((item) => item !== '--omnibus-higher');
|
|
||||||
}
|
|
||||||
// label okazja
|
|
||||||
if ((!higher || newDate) && !activeLabel?.rebateCodeActive) {
|
|
||||||
activeLabel.bargain = `<span class="label --bargain --omnibus">${idmHotspotTextObject["Okazja"]}</span>`;
|
|
||||||
}
|
|
||||||
// label promocja
|
|
||||||
if (Object.keys(activeLabel)?.length === 0) {
|
|
||||||
activeLabel.bargain = `<span class="label --promo --omnibus">${idmHotspotTextObject["Promocja"]}</span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// labele zones
|
|
||||||
if(productData.zones.find(zone => zone ==="bestseller")) activeLabel.bestseller = `<span class="label --bestseller --omnibus">${idmHotspotTextObject["Bestseller"]}</span>`;
|
|
||||||
if(productData.zones.find(zone => zone ==="news")) activeLabel.news = `<span class="label --news --omnibus">${idmHotspotTextObject["Nowość"]}</span>`;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let omnibusPercentSign = '';
|
|
||||||
if (higher) {
|
|
||||||
omnibusPercentSign = '-';
|
|
||||||
} else if (sizeData.price.omnibusPriceDetails?.youSavePercent !== 0) {
|
|
||||||
omnibusPercentSign = '+';
|
|
||||||
}
|
|
||||||
const omnibusPercent = `${omnibusPercentSign}${sizeData.price.omnibusPriceDetails?.youSavePercent}%`;
|
|
||||||
const omnibus = {
|
|
||||||
price: omnibusPrice,
|
|
||||||
visible: true,
|
|
||||||
percent: omnibusPercent,
|
|
||||||
html: `<span class="omnibus_price__text">${idmHotspotTextObject['Najniższa cena produktu w okresie 30 dni przed wprowadzeniem obniżki']}: </span><del class="omnibus_price__value">${omnibusPrice}</del><span class="price_percent">${omnibusPercent}</span>`,
|
|
||||||
};
|
|
||||||
|
|
||||||
const max = (maxPrice) ? {
|
|
||||||
max: {
|
|
||||||
price: maxPrice,
|
|
||||||
visible: true,
|
|
||||||
percent: `-${sizeData.price.youSavePercent}%`,
|
|
||||||
html: `<span class="omnibus_label">${idmHotspotTextObject['Cena regularna']}: </span>
|
|
||||||
<del>${maxPrice}</del><span class="price_percent">-${sizeData.price.youSavePercent}%</span>`,
|
|
||||||
},
|
|
||||||
} : {};
|
|
||||||
|
|
||||||
const beforeRebate = (beforeRebatePrice) ? {
|
|
||||||
beforeRebate: {
|
|
||||||
price: beforeRebatePrice,
|
|
||||||
visible: !!classes.add.includes('--omnibus-code'),
|
|
||||||
percent: `-${sizeData.price.beforeRebateDetails?.youSavePercent}%`,
|
|
||||||
html: `<span class="omnibus_label">${idmHotspotTextObject['Cena bez kodu']}: </span>
|
|
||||||
<del>${beforeRebatePrice}</del>
|
|
||||||
<span class="price_percent">-${sizeData.price.beforeRebateDetails?.youSavePercent}%</span>`,
|
|
||||||
},
|
|
||||||
} : {};
|
|
||||||
|
|
||||||
const newPriceEffectiveUntil = (newDate) ? {
|
|
||||||
newPriceEffectiveUntil: {
|
|
||||||
date: newDate,
|
|
||||||
price: maxPrice,
|
|
||||||
visible: !!classes.add.includes('--omnibus-new-price'),
|
|
||||||
html: `<span class="omnibus_label">${idmHotspotTextObject['Cena nadchodząca od']} </span>
|
|
||||||
<span class="new_price__date">${newDate}: </span>
|
|
||||||
<span class="new_price__value">${maxPrice}</span>`,
|
|
||||||
},
|
|
||||||
} : {};
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
classes,
|
|
||||||
omnibus,
|
|
||||||
...max,
|
|
||||||
...beforeRebate,
|
|
||||||
...newPriceEffectiveUntil,
|
|
||||||
activeLabel,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// EVENTY
|
|
||||||
// dodawanie do koszyka
|
|
||||||
async function idmHandleAddToBasket(e){
|
|
||||||
const formEl = e.target.closest("form.add_to_basket");
|
|
||||||
if(!formEl) return;
|
|
||||||
try{
|
|
||||||
// pobieranie danych i elementów
|
|
||||||
formEl.classList.add("--loading")
|
|
||||||
const buttonEl = formEl.querySelector(".add_to_basket__button");
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const id = formEl.querySelector("input[name='product']")?.value;
|
|
||||||
const size = formEl.querySelector("input[type='hidden'][name='size']")?.value;
|
|
||||||
const number = formEl.querySelector("input[name='number']")?.value;
|
|
||||||
|
|
||||||
// dodanie do koszyka
|
|
||||||
const res = await fetch(`/graphql/v1/`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: IDM_HOTSPOT_ADD_TO_BASKET(id, size, number)
|
|
||||||
});
|
|
||||||
const data = await res.json();
|
|
||||||
|
|
||||||
// Błąd
|
|
||||||
if(data?.data?.addProductsToBasket?.status !== "success") throw new Error(data);
|
|
||||||
else{
|
|
||||||
// Obsługiwanie sukcesu
|
|
||||||
app_shop.graphql.trackingEvents(res);
|
|
||||||
buttonEl.classList.add("--success");
|
|
||||||
|
|
||||||
// Dodawanie do koszyka na stronie basketedit.php będzie wymagał innego indywidualnego kodu!!!!!
|
|
||||||
buttonEl.innerHTML = `<span>${buttonEl.dataset.success}</span>`;
|
|
||||||
setTimeout(()=>{
|
|
||||||
buttonEl.innerHTML = `<span>${buttonEl.dataset.text}</span>`;
|
|
||||||
app_shop.fn?.menu_basket_cache?.();
|
|
||||||
buttonEl.classList.remove("--success");
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}catch(err){
|
|
||||||
console.error(err);
|
|
||||||
Alertek.Error(idmHotspotTextObject["Coś poszło nie tak podczas dodawania do koszyka. Spróbuj ponownie lub odśwież stronę"]);
|
|
||||||
buttonEl.innerHTML = `<span>${buttonEl.dataset.error}</span>`;
|
|
||||||
buttonEl.classList.add("--error")
|
|
||||||
setTimeout(()=>{
|
|
||||||
buttonEl.classList.remove("--error")
|
|
||||||
buttonEl.innerHTML = `<span>${buttonEl.dataset.text}</span>`;
|
|
||||||
}, 3000);
|
|
||||||
}finally{
|
|
||||||
formEl.classList.remove("--loading")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///qty
|
|
||||||
const idmRangeMaxAlert = (max)=> Alertek.Error(`${idmHotspotTextObject["Maksymalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]} ${max}`)
|
|
||||||
const idmRangeMinAlert = (min)=> Alertek.Error(`${idmHotspotTextObject["Minimalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]} ${min}`)
|
|
||||||
|
|
||||||
function idmQuantityButtonClick(e){
|
|
||||||
if(e.target.classList.contains("idm-products-banner__qty-input")) return e.target.select();
|
|
||||||
const wrapper = e.target.closest(".idm-products-banner__qty");
|
|
||||||
|
|
||||||
const input = wrapper.querySelector(".idm-products-banner__qty-input");
|
|
||||||
const step = parseFloat(wrapper.dataset.sellBy || "1");
|
|
||||||
const precision = parseInt(wrapper.dataset.precision || "0");
|
|
||||||
const max = parseFloat(wrapper.dataset.max || "999999");
|
|
||||||
let current = parseFloat(input.value) || 0;
|
|
||||||
|
|
||||||
if (e.target.classList.contains("idm-products-banner__qty-increase")) {
|
|
||||||
current += step;
|
|
||||||
if (current > max){
|
|
||||||
current = max;
|
|
||||||
idmRangeMaxAlert(max)
|
|
||||||
}
|
|
||||||
} else if (e.target.classList.contains("idm-products-banner__qty-decrease")) {
|
|
||||||
current -= step;
|
|
||||||
if (current < step){
|
|
||||||
current = step;
|
|
||||||
idmRangeMinAlert(step)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input.value = current.toFixed(precision);
|
|
||||||
}
|
|
||||||
function idmQuantityInputChange(e){
|
|
||||||
if(e.target.value > +e.target.max){
|
|
||||||
idmRangeMaxAlert(e.target.max)
|
|
||||||
e.target.value = +e.target.max
|
|
||||||
}
|
|
||||||
if(e.target.value < +e.target.min){
|
|
||||||
idmRangeMinAlert(e.target.min)
|
|
||||||
e.target.value = +e.target.min;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// DANE
|
|
||||||
// dwie funkcje zamiast jednej
|
|
||||||
async function idmGetHotspotData(query, graphFn){
|
|
||||||
try{
|
|
||||||
const res = await fetch(`/graphql/v1/`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: graphFn ? graphFn(query) : IDM_PRODUCTS_GQL(query)
|
|
||||||
});
|
|
||||||
const data = await res.json();
|
|
||||||
const products = graphFn === IDM_HOTSPOTS_GQL ? data?.data?.hotspots?.products : data?.data?.products?.products;
|
|
||||||
if(!products || !products.length) throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]);
|
|
||||||
|
|
||||||
console.log(data);
|
|
||||||
return products;
|
|
||||||
}catch(err){
|
|
||||||
console.error(idmHotspotTextObject["Błąd przy pobieraniu danych"], err);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function idmGetQueryData({
|
|
||||||
productsID,
|
|
||||||
productsMenu,
|
|
||||||
hotspotsType
|
|
||||||
}){
|
|
||||||
let graphFn, query;
|
|
||||||
|
|
||||||
if(productsID){
|
|
||||||
graphFn = IDM_PRODUCTS_GQL;
|
|
||||||
query = `searchInput: {productsId: [${productsID}]}`;
|
|
||||||
}else if(productsMenu){
|
|
||||||
graphFn = IDM_PRODUCTS_GQL;
|
|
||||||
query = `searchInput: {navigation: ${productsMenu}}`;
|
|
||||||
}else if(hotspotsType){
|
|
||||||
graphFn = IDM_HOTSPOTS_GQL;
|
|
||||||
query = `searchInput: {hotspot: ${hotspotsType}, limit: 16}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {graphFn, query}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// LAZY LOADING
|
|
||||||
function idmObserveOnce(element, callback, options = { root: null, rootMargin: "0px", threshold: 0.1 }) {
|
|
||||||
if (!element) return;
|
|
||||||
|
|
||||||
const observer = new IntersectionObserver((entries, obs) => {
|
|
||||||
entries.forEach(entry => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
callback(entry); // run your callback
|
|
||||||
obs.disconnect(); // stop observing after first trigger
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
observer.observe(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
// IDM SET HEIGHT
|
|
||||||
app_shop.fn.idmSetHeight = options => {
|
|
||||||
const { selector, selectors, container } = options || {}
|
|
||||||
if ((!selector && !selectors) || !container) return
|
|
||||||
|
|
||||||
const containerElement = document.querySelector(container)
|
|
||||||
if (!containerElement) return
|
|
||||||
|
|
||||||
const adjustAllHeights = itemSelector => {
|
|
||||||
const targets = containerElement.querySelectorAll(itemSelector)
|
|
||||||
if (!targets.length) return
|
|
||||||
|
|
||||||
targets.forEach(el => (el.style.minHeight = ''))
|
|
||||||
|
|
||||||
const max = Math.max(...[...targets].map(el => el.offsetHeight || 0))
|
|
||||||
|
|
||||||
targets.forEach(el => (el.style.minHeight = `${max}px`))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selector) adjustAllHeights(selector)
|
|
||||||
if (selectors?.length) selectors.forEach(adjustAllHeights)
|
|
||||||
}
|
|
||||||
147
sklad/3markup.js
147
sklad/3markup.js
@@ -1,147 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Markup
|
|
||||||
|
|
||||||
// Funkcja przygotująca markup dla wszystkich produktów
|
|
||||||
function idmPrepareProductsMarkup(products, addToBasket){
|
|
||||||
let markup = "";
|
|
||||||
products.forEach((prod)=>{
|
|
||||||
markup += idmPrepareSingleProductMarkup(prod, addToBasket);
|
|
||||||
})
|
|
||||||
return markup;
|
|
||||||
}
|
|
||||||
|
|
||||||
// funkcja przygotowująca markup dla wybranego produktu
|
|
||||||
function idmPrepareSingleProductMarkup(prod, addToBasket){
|
|
||||||
const prodExchangedData = app_shop.fn?.idmGetOmnibusDetails({productData: prod});
|
|
||||||
|
|
||||||
// pobranie labelek
|
|
||||||
let labelHTMLMarkup = "";
|
|
||||||
if(typeof prodExchangedData.activeLabel === "object") Object.entries(prodExchangedData.activeLabel).forEach(([key,value])=>{
|
|
||||||
labelHTMLMarkup += value;
|
|
||||||
})
|
|
||||||
|
|
||||||
// markup pojedynczego produktu
|
|
||||||
let singleMarkup = "";
|
|
||||||
singleMarkup += `
|
|
||||||
<div class="product hotspot__product swiper-slide d-flex flex-column ${prod.price.price[idmPriceType].value === 0 ? "--phone" : ""}" data-id="${prod.id}">
|
|
||||||
<div class="product__yousave --hidden">
|
|
||||||
<span class="product__yousave --label"></span>
|
|
||||||
<span class="product__yousave --value"></span>
|
|
||||||
</div>
|
|
||||||
<a class="product__icon d-flex justify-content-center align-items-center" tabindex="-1" href="${prod.link}">
|
|
||||||
${idmPrepareHotspotImgMarkup(prod)}
|
|
||||||
<strong class="label_icons">
|
|
||||||
${labelHTMLMarkup}
|
|
||||||
</strong>
|
|
||||||
</a>
|
|
||||||
<div class="product__content_wrapper">
|
|
||||||
<a class="product__name" tabindex="0" href="${prod.link}" title="${prod.name}">${prod.name}</a>
|
|
||||||
<div class="product__prices mb-auto ${prodExchangedData?.classes?.add?.reduce((acc,val) => acc + " " + val,"")}">
|
|
||||||
${idmPrepareHotspotPriceMarkup(prod, prodExchangedData)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
${idmPrepareHotspotAddToBasketMarkup(prod, addToBasket)}
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
return singleMarkup;
|
|
||||||
}
|
|
||||||
|
|
||||||
// markup zdjęcia
|
|
||||||
function idmPrepareHotspotImgMarkup(prod){
|
|
||||||
let markup = "";
|
|
||||||
if(prod.iconSmallSecond !== undefined && prod.iconSecond !== undefined) markup +=`<picture>
|
|
||||||
<source media="(min-width: 421px)" type="image/webp" srcset="${prod.icon}"/>
|
|
||||||
<source media="(min-width: 421px)" type="image/jpeg" srcset="${prod.iconSecond}"/>
|
|
||||||
<source media="(max-width: 420px)" type="image/webp" srcset="${prod.iconSmall}"/>
|
|
||||||
<source media="(max-width: 420px)" type="image/jpeg" srcset="${prod.iconSmallSecond}"/>
|
|
||||||
<img src="${prod.iconSecond}" loading="lazy" alt="${prod.name}">
|
|
||||||
</picture>`;
|
|
||||||
else if(prod?.iconSmall !== undefined) markup += `<picture>
|
|
||||||
<source media="(min-width: 421px)" srcset="${prod.icon}"/>
|
|
||||||
<source media="(max-width: 420px)" srcset="${prod.iconSmall}"/>
|
|
||||||
<img src="${prod.iconSecond}" loading="lazy" alt="${prod.name}">
|
|
||||||
</picture>`;
|
|
||||||
else markup += `<img src="${prod.icon}" loading="lazy" alt="${prod.name}">`
|
|
||||||
return markup;
|
|
||||||
}
|
|
||||||
|
|
||||||
// markup cen
|
|
||||||
function idmPrepareHotspotPriceMarkup(prod, prodExchangedData){
|
|
||||||
const price = prod.price.price[idmPriceType];
|
|
||||||
const unit = prod.unit;
|
|
||||||
const pointsPrice = prod?.points;
|
|
||||||
const convertedPrice = prod.price?.unitConvertedPrice?.[idmPriceType]?.formatted;
|
|
||||||
|
|
||||||
return `
|
|
||||||
<strong class="price --normal --main ${price.value === 0 ? "--hidden" : ""}">
|
|
||||||
<span class="price__sub">${price.formatted}</span>
|
|
||||||
<span class="price_sellby">
|
|
||||||
<span class="price_sellby__sep">/</span>
|
|
||||||
<span class="price_sellby__sellby" data-sellby="${unit?.sellBy}">${unit?.sellBy}</span>
|
|
||||||
<span class="price_sellby__unit">${unit?.sellBy > 1 ? unit?.plural : unit?.singular}</span>
|
|
||||||
</span>
|
|
||||||
${convertedPrice ? `<span class="price --convert">${convertedPrice}</span>` : ""}
|
|
||||||
</strong>
|
|
||||||
${pointsPrice ? `<span class="price --points">${pointsPrice} pkt.</span>` : ""}
|
|
||||||
${price.value === 0 ? `<a class="price --phone" href="/contact.php" tabindex="-1" title="${idmHotspotTextObject["Kliknij, by przejść do formularza kontaktu"]}">${idmHotspotTextObject["Cena na telefon"]}</a>` : ""}
|
|
||||||
${prodExchangedData?.beforeRebate?.visible ? `<span class="price --before-rebate">${prodExchangedData?.beforeRebate?.html}</span>` : ""}
|
|
||||||
${prodExchangedData?.newPriceEffectiveUntil?.visible ? `<span class="price --new-price new_price">${prodExchangedData?.newPriceEffectiveUntil?.html}</span>` : ""}
|
|
||||||
${prodExchangedData?.omnibus?.visible ? `<span class="price --omnibus omnibus_price">${prodExchangedData?.omnibus?.html}</span>` : ""}
|
|
||||||
${prodExchangedData?.max?.visible ? `<span class="price --max">${prodExchangedData?.max?.html}</span>` : ""}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// markup dodawania do koszyka
|
|
||||||
function idmPrepareHotspotAddToBasketMarkup(prod, addToBasket){
|
|
||||||
let markup = "";
|
|
||||||
if(!addToBasket && typeof addToBasket !== "undefined" ||
|
|
||||||
(typeof addToBasket === "undefined" && typeof idmGeneralHotspotObjData === "object" && !idmGeneralHotspotObjData?.options?.addToBasket) ||
|
|
||||||
!addToBasket && typeof idmGeneralHotspotObjData === "undefined") return markup;
|
|
||||||
|
|
||||||
// link do produktu jak nie jest to zwykły produkt
|
|
||||||
if(prod.type !== "product") markup = `<a class="btn --solid --medium add_to_basket__link" href="${prod.href}">Zobacz produkt</a>`;
|
|
||||||
else if(addToBasket === "range"
|
|
||||||
|| typeof addToBasket === "undefined" && typeof idmGeneralHotspotObjData === "object" && idmGeneralHotspotObjData?.options?.addToBasket === "range") // +-
|
|
||||||
markup = `<form class="add_to_basket --range" action="/basketchange.php" type="post" onsubmit="idmHandleAddToBasket(event)">
|
|
||||||
<input name="mode" type="hidden" value="1">
|
|
||||||
<input name="product" type="hidden" value="${prod.id}">
|
|
||||||
<input name="size" type="hidden" value="${prod.sizes[0].id}">
|
|
||||||
<div class="idm-products-banner__qty"
|
|
||||||
data-sell-by="${prod.unit?.sellBy}"
|
|
||||||
data-precision="${prod.unit?.precision}"
|
|
||||||
data-max="${prod.sizes[0].amount === -1 ? 999999 : prod.sizes[0].amount}"
|
|
||||||
onclick="idmQuantityButtonClick(event)"
|
|
||||||
>
|
|
||||||
<button type="button" class="idm-products-banner__qty-decrease" aria-label="${idmHotspotTextObject["Zmniejsz ilość"]}">−</button>
|
|
||||||
|
|
||||||
<input type="number"
|
|
||||||
name="number"
|
|
||||||
class="idm-products-banner__qty-input"
|
|
||||||
value="${prod.unit?.sellBy}"
|
|
||||||
step="${prod.unit?.sellBy}"
|
|
||||||
min="${prod.unit?.sellBy}"
|
|
||||||
max="${prod.sizes[0].amount === -1 ? 999999 : prod.sizes[0].amount}"
|
|
||||||
aria-label="${idmHotspotTextObject["Ilość"]}"
|
|
||||||
oninput="idmQuantityInputChange(event)"
|
|
||||||
>
|
|
||||||
|
|
||||||
<button type="button" class="idm-products-banner__qty-increase" aria-label="${idmHotspotTextObject["Zwiększ ilość"]}">+</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn --solid --medium add_to_basket__button" tabindex="0" data-success="${idmHotspotTextObject["Dodany"]}" data-error="${idmHotspotTextObject["Wystąpił błąd"]}" data-text="${idmHotspotTextObject["Do koszyka"]}">
|
|
||||||
<span>${idmHotspotTextObject["Do koszyka"]}</span>
|
|
||||||
</button>
|
|
||||||
</form>`;
|
|
||||||
else // Zwykłe dodanie do koszyka
|
|
||||||
markup = `
|
|
||||||
<form class="add_to_basket" action="/basketchange.php" type="post" onsubmit="idmHandleAddToBasket(event)">
|
|
||||||
<input name="mode" type="hidden" value="1">
|
|
||||||
<input name="product" type="hidden" value="${prod.id}">
|
|
||||||
<input name="size" type="hidden" value="${prod.sizes[0].id}">
|
|
||||||
<input name="number" type="hidden" value="${prod.unit?.sellBy}">
|
|
||||||
<button type="submit" class="btn --solid --medium add_to_basket__button" tabindex="0" data-success="${idmHotspotTextObject["Dodany"]}" data-error="${idmHotspotTextObject["Wystąpił błąd"]}" data-text="${idmHotspotTextObject["Do koszyka"]}">
|
|
||||||
<span>${idmHotspotTextObject["Do koszyka"]}</span>
|
|
||||||
</button>
|
|
||||||
</form>`;
|
|
||||||
return markup;
|
|
||||||
}
|
|
||||||
167
sklad/4init.js
167
sklad/4init.js
@@ -1,167 +0,0 @@
|
|||||||
////////////////////////////////////////////////////
|
|
||||||
// INIT
|
|
||||||
|
|
||||||
// brutto/netto
|
|
||||||
const idmPriceType = app_shop?.vars?.priceType || "gross";
|
|
||||||
|
|
||||||
|
|
||||||
// Zmienna trzymająca dane o ustawieniach customowych ramek rekomendacji na całym sklepie
|
|
||||||
/**
|
|
||||||
* Obiekt konfiguracyjny ogólnych ustawień hotspotów rekomendacji.
|
|
||||||
*
|
|
||||||
* @typedef {object} idmGeneralHotspotObjData
|
|
||||||
* @property {object} options - Główne ustawienia hotspotów
|
|
||||||
* @property {boolean} options.lazy - Czy wczytywać zawartość w trybie lazy (required).
|
|
||||||
* @property {boolean|string} options.addToBasket - Zachowanie przy dodawaniu do koszyka:
|
|
||||||
* - true = przycisk dodaj do koszyka
|
|
||||||
* - false = brak przycisku
|
|
||||||
* - "range" = dodaj z wyborem zakresu (required).
|
|
||||||
* @property {boolean|object} options.swiper - Ustawienia slidera:
|
|
||||||
* - true/false = włącz/wyłącz
|
|
||||||
* - object = konfiguracja instancji Swiper (required jeśli obiekt).
|
|
||||||
*/
|
|
||||||
const idmGeneralHotspotObjData = {
|
|
||||||
options: {
|
|
||||||
lazy: true,
|
|
||||||
addToBasket: true, // true, false, "range"
|
|
||||||
swiper: { // true, false, obiekt z opcjami swipera
|
|
||||||
loop: false,
|
|
||||||
autoHeight: false,
|
|
||||||
spaceBetween: 16,
|
|
||||||
slidesPerView: 1.4,
|
|
||||||
centeredSlides: true,
|
|
||||||
centeredSlidesBounds: true,
|
|
||||||
breakpoints: {
|
|
||||||
550: {
|
|
||||||
slidesPerView: 3,
|
|
||||||
centeredSlides: true,
|
|
||||||
centeredSlidesBounds: true,
|
|
||||||
},
|
|
||||||
979: {
|
|
||||||
slidesPerView: 4,
|
|
||||||
centeredSlides: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Funkcja inicjalizująca wybranego hotspota(addtobasket range - swiper)
|
|
||||||
async function idmHotspotInit(id, options={}){
|
|
||||||
try{
|
|
||||||
const hotspotEl = document.getElementById(id);
|
|
||||||
if(!hotspotEl) throw new Error("Nie znaleziono elementu");
|
|
||||||
|
|
||||||
// add to basket + -
|
|
||||||
if(options?.addToBasket === "range" ||
|
|
||||||
typeof options?.addToBasket === "undefined" && typeof idmGeneralHotspotObjData === "object" && idmGeneralHotspotObjData?.options?.addToBasket === "range"){
|
|
||||||
|
|
||||||
// obsługa i sprawdzanie clicków
|
|
||||||
// hotspotEl.addEventListener("click", e=>{
|
|
||||||
// const wrapper = e.target.closest(".idm-products-banner__qty");
|
|
||||||
// if (!wrapper) return;
|
|
||||||
|
|
||||||
// if(e.target.classList.contains("idm-products-banner__qty-input")) return e.target.select();
|
|
||||||
|
|
||||||
// const input = wrapper.querySelector(".idm-products-banner__qty-input");
|
|
||||||
// const step = parseFloat(wrapper.dataset.sellBy || "1");
|
|
||||||
// const precision = parseInt(wrapper.dataset.precision || "0");
|
|
||||||
// const max = parseFloat(wrapper.dataset.max || "999999");
|
|
||||||
// let current = parseFloat(input.value) || 0;
|
|
||||||
|
|
||||||
// if (e.target.classList.contains("idm-products-banner__qty-increase")) {
|
|
||||||
// current += step;
|
|
||||||
// if (current > max){
|
|
||||||
// current = max;
|
|
||||||
// rangeMaxAlert(max)
|
|
||||||
// }
|
|
||||||
// } else if (e.target.classList.contains("idm-products-banner__qty-decrease")) {
|
|
||||||
// current -= step;
|
|
||||||
// if (current < step){
|
|
||||||
// current = step;
|
|
||||||
// rangeMinAlert(step)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// input.value = current.toFixed(precision);
|
|
||||||
// });
|
|
||||||
// sprawdzanie na input
|
|
||||||
// hotspotEl.querySelectorAll(".idm-products-banner__qty-input").forEach(inp=>{
|
|
||||||
// inp.addEventListener("input", e=>{
|
|
||||||
// if(e.target.value > +e.target.max){
|
|
||||||
// rangeMaxAlert(e.target.max)
|
|
||||||
// e.target.value = +e.target.max
|
|
||||||
// }
|
|
||||||
// if(e.target.value < +e.target.min){
|
|
||||||
// rangeMinAlert(e.target.min)
|
|
||||||
// e.target.value = +e.target.min;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// })
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// swiper || slick
|
|
||||||
if(options?.swiper ||
|
|
||||||
typeof options?.swiper === "undefined" && typeof idmGeneralHotspotObjData === "object" && idmGeneralHotspotObjData?.options?.swiper){
|
|
||||||
|
|
||||||
|
|
||||||
// Opcje swipera
|
|
||||||
let swiperOptions = typeof options.swiper === "object" ? options.swiper : "";
|
|
||||||
if(typeof options.swiper === "object") swiperOptions = options.swiper;
|
|
||||||
else if(typeof idmGeneralHotspotObjData === "object" && typeof idmGeneralHotspotObjData?.options?.swiper === "object"){
|
|
||||||
swiperOptions = idmGeneralHotspotObjData?.options?.swiper;
|
|
||||||
swiperOptions.navigation = {
|
|
||||||
nextEl: `#${id} .idm-button-next`,
|
|
||||||
prevEl: `#${id} .idm-button-prev`,
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
swiperOptions = {
|
|
||||||
loop: false,
|
|
||||||
autoHeight: false,
|
|
||||||
spaceBetween: 16,
|
|
||||||
slidesPerView: 1.4,
|
|
||||||
centeredSlides: true,
|
|
||||||
centeredSlidesBounds: true,
|
|
||||||
breakpoints: {
|
|
||||||
550: {
|
|
||||||
slidesPerView: 3,
|
|
||||||
centeredSlides: true,
|
|
||||||
centeredSlidesBounds: true,
|
|
||||||
},
|
|
||||||
979: {
|
|
||||||
slidesPerView: 4,
|
|
||||||
centeredSlides: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
navigation: {
|
|
||||||
nextEl: `#${id} .idm-button-next`,
|
|
||||||
prevEl: `#${id} .idm-button-prev`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wywołanie swipera
|
|
||||||
const selectedSwiper = new HotspotSlider({
|
|
||||||
selector: `#${id} .swiper`,
|
|
||||||
hotspotName: `${id}`,
|
|
||||||
options: swiperOptions,
|
|
||||||
});
|
|
||||||
await selectedSwiper.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(typeof options?.callbackFn === "function") options?.callbackFn();
|
|
||||||
|
|
||||||
// IDM setHeight
|
|
||||||
app_shop.fn.idmSetHeight({
|
|
||||||
selectors: [
|
|
||||||
`#${id} .product__prices`,
|
|
||||||
`#${id} .product__name`,
|
|
||||||
],
|
|
||||||
container: `#${id} .products__wrapper`,
|
|
||||||
});
|
|
||||||
console.log(`Initialized hotspot #${id}`);
|
|
||||||
}catch(err){
|
|
||||||
console.error(idmHotspotTextObject["Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"], err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
// Funkcja init ELEMENT HTML
|
|
||||||
async function idmInsertHotspotElement(selectedContainerEl){
|
|
||||||
|
|
||||||
selectedContainerEl.classList.add("--init");
|
|
||||||
const {graphFn, query} = idmGetQueryData({
|
|
||||||
productsID: selectedContainerEl?.dataset?.productsId,
|
|
||||||
productsMenu: selectedContainerEl?.dataset?.productsMenu,
|
|
||||||
hotspotsType: selectedContainerEl.dataset.hotspotsType
|
|
||||||
});
|
|
||||||
|
|
||||||
if(!graphFn || !query){
|
|
||||||
console.log(idmHotspotTextObject["Nie znaleziono metody graphql"], selectedContainerEl)
|
|
||||||
return selectedContainerEl.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Funkcja od uzupełniania danych
|
|
||||||
const idmFill = async ()=>{
|
|
||||||
try{
|
|
||||||
// pobranie danych o produktach
|
|
||||||
const products = await idmGetHotspotData(query, graphFn);
|
|
||||||
if(!products) throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]);
|
|
||||||
|
|
||||||
|
|
||||||
// wstawienie produktów zależnie czy w section jest .hotspot czy nie
|
|
||||||
const hotspotInsideEl = selectedContainerEl.querySelector(".hotspot");
|
|
||||||
if(hotspotInsideEl) hotspotInsideEl.innerHTML += `<div class="products__wrapper swiper">
|
|
||||||
<div class="products hotspot__products swiper-wrapper">
|
|
||||||
${idmPrepareProductsMarkup(products, true)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="swiper-button-prev --rounded --edge idm-button-prev"><i class="icon-angle-left"></i></div>
|
|
||||||
<div class="swiper-button-next --rounded --edge idm-button-next"><i class="icon-angle-right"></i></div>
|
|
||||||
<div class="swiper-pagination"></div>`;
|
|
||||||
else selectedContainerEl.innerHTML = `<div class="hotspot --initialized"><div class="products__wrapper swiper">
|
|
||||||
<div class="products hotspot__products swiper-wrapper">
|
|
||||||
${idmPrepareProductsMarkup(products, true)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="swiper-button-prev --rounded --edge idm-button-prev"><i class="icon-angle-left"></i></div>
|
|
||||||
<div class="swiper-button-next --rounded --edge idm-button-next"><i class="icon-angle-right"></i></div>
|
|
||||||
<div class="swiper-pagination"></div></div>`;
|
|
||||||
|
|
||||||
selectedContainerEl.classList.remove("idm-loading")
|
|
||||||
// init swipera
|
|
||||||
idmHotspotInit(selectedContainerEl.id)
|
|
||||||
}catch(err){
|
|
||||||
console.error(idmHotspotTextObject["Wystąpił błąd"], err);
|
|
||||||
selectedContainerEl.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(selectedContainerEl.dataset?.lazy ||
|
|
||||||
!selectedContainerEl.dataset?.lazy && typeof idmGeneralHotspotObjData === "object" && idmGeneralHotspotObjData?.options?.lazy) idmObserveOnce(selectedContainerEl, idmFill);
|
|
||||||
else idmFill();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Zebranie wszystkich ramek HTML i wstawienie ich.
|
|
||||||
async function idmInsertAllHTMLHotspots(){
|
|
||||||
try{
|
|
||||||
const reqArr = []
|
|
||||||
document.querySelectorAll(".idm__hotspot:not(.--init):not(.--lazy-hotspot)").forEach(hotspot=>{
|
|
||||||
reqArr.push(idmInsertHotspotElement(hotspot));
|
|
||||||
});
|
|
||||||
await Promise.all(reqArr);
|
|
||||||
}catch(err){
|
|
||||||
console.error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
idmInsertAllHTMLHotspots();
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
// wdrożenie dla elementu HTML
|
|
||||||
/**
|
|
||||||
* Struktura sekcji hotspotu w HTML.
|
|
||||||
*
|
|
||||||
* @typedef {HTMLElement} HotspotSection
|
|
||||||
* @property {string} id - Identyfikator elementu (np. "idmBlogHotspot1").
|
|
||||||
* @property {string} class - Klasy CSS używane do stylowania.
|
|
||||||
*
|
|
||||||
* @attribute {string} data-products-id - Lista ID produktów (rozdzielona przecinkami).
|
|
||||||
* @attribute {number} data-products-menu - Identyfikator menu produktów.
|
|
||||||
* @attribute {string} data-hotspots-type - Typ hotspotu (np. "promotion").
|
|
||||||
* @attribute {boolean} data-lazy - Czy sekcja ma być ładowana w trybie lazy.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
<section id="idmBlogHotspot1"
|
|
||||||
class="hotspot__wrapper idm__hotspot idm-loading"
|
|
||||||
data-products-id="589,180,181590"
|
|
||||||
data-products-menu="122"
|
|
||||||
data-hotspots-type="promotion"
|
|
||||||
data-lazy="true"
|
|
||||||
>
|
|
||||||
<div class="hotspot --initialized">
|
|
||||||
<h3 class="hotspot__name headline__wrapper">
|
|
||||||
<span class="headline">
|
|
||||||
<span class="headline__name" aria-label="aaa">aaa</span>
|
|
||||||
</span>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
*/
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
////////////////////////////////////////////////////
|
|
||||||
// Funkcja init OBIEKT JS
|
|
||||||
async function idmInsertHotspotObject(idmHotspotObj){
|
|
||||||
// Wstaw kontener
|
|
||||||
const selectedEl = document.querySelector(idmHotspotObj?.placement.selector);
|
|
||||||
if(!selectedEl) throw new Error(idmHotspotTextObject["Nie znaleziono kontenera"]);
|
|
||||||
|
|
||||||
selectedEl.insertAdjacentHTML(idmHotspotObj.placement.insert || "afterend", `<section id="${idmHotspotObj.id}" class="hotspot__wrapper idm__hotspot --init idm-loading ${idmHotspotObj?.classes}">
|
|
||||||
<div class="hotspot --initialized">
|
|
||||||
${idmHotspotObj?.title ? `
|
|
||||||
<h3 class="hotspot__name headline__wrapper">
|
|
||||||
<span class="headline"><span class="headline__name" aria-label="${idmHotspotObj.title}">${idmHotspotObj.title}</span></span>
|
|
||||||
</h3>
|
|
||||||
` : ""}
|
|
||||||
<div class="products__wrapper swiper">
|
|
||||||
<div class="products hotspot__products swiper-wrapper">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="swiper-button-prev --rounded --edge idm-button-prev"><i class="icon-angle-left"></i></div>
|
|
||||||
<div class="swiper-button-next --rounded --edge idm-button-next"><i class="icon-angle-right"></i></div>
|
|
||||||
<div class="swiper-pagination"></div>
|
|
||||||
</div>
|
|
||||||
</section>`);
|
|
||||||
|
|
||||||
|
|
||||||
// Utworzenie markupa HTML
|
|
||||||
const selectedContainerEl = document.getElementById(idmHotspotObj.id);
|
|
||||||
if(!selectedContainerEl) throw new Error(idmHotspotTextObject["Nie znaleziono kontenera"]);
|
|
||||||
|
|
||||||
const idmFill = async ()=>{
|
|
||||||
try{
|
|
||||||
let {graphFn, query} = idmGetQueryData({
|
|
||||||
productsID: idmHotspotObj?.source?.productsId,
|
|
||||||
productsMenu: idmHotspotObj?.source?.productsMenu,
|
|
||||||
hotspotsType: idmHotspotObj?.source?.hotspotsType
|
|
||||||
});
|
|
||||||
|
|
||||||
if(idmHotspotObj?.query?.graphFn && idmHotspotObj?.query?.string){
|
|
||||||
graphFn = idmHotspotObj.query.graphFn;
|
|
||||||
query = idmHotspotObj.query.string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pobranie danych o produktach
|
|
||||||
const products = await idmGetHotspotData(query, graphFn);
|
|
||||||
if(!products) throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]);
|
|
||||||
|
|
||||||
|
|
||||||
// Wstawienie markupa na strone
|
|
||||||
const hotspotMarkup = `${idmPrepareProductsMarkup(products, idmHotspotObj?.options?.addToBasket)}`;
|
|
||||||
selectedContainerEl.querySelector(".products.hotspot__products")?.insertAdjacentHTML("beforeend", hotspotMarkup);
|
|
||||||
selectedContainerEl.classList.remove("idm-loading");
|
|
||||||
|
|
||||||
// init swiper + add to basket
|
|
||||||
idmHotspotInit(idmHotspotObj.id, idmHotspotObj?.options)
|
|
||||||
}catch(err){
|
|
||||||
console.error(idmHotspotTextObject["Wystąpił błąd"], err);
|
|
||||||
selectedContainerEl.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(idmHotspotObj?.options?.lazy ||
|
|
||||||
typeof idmHotspotObj?.options?.lazy === "undefined" && typeof idmGeneralHotspotObjData === "object" && idmGeneralHotspotObjData?.options?.lazy) idmObserveOnce(selectedContainerEl, idmFill);
|
|
||||||
else idmFill();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// obiekt js z przykładowymi danymi
|
|
||||||
/**
|
|
||||||
* Tablica konfiguracji hotspotów rekomendacji.
|
|
||||||
*
|
|
||||||
* @typedef {object} Hotspot
|
|
||||||
* @property {string} id - Identyfikator ramki (required).
|
|
||||||
* @property {string} title - Tytuł ramki.
|
|
||||||
* @property {string} classes - Dodatkowe klasy CSS.
|
|
||||||
* @property {object} placement - Określa, gdzie wstawić ramkę (required).
|
|
||||||
* @property {string} placement.selector - Selektor miejsca osadzenia.
|
|
||||||
* @property {string} placement.insert - Pozycja wstawienia względem selektora (np. "afterbegin", "beforeend").
|
|
||||||
* @property {object} source - Dane źródłowe dla hotspotu (required).
|
|
||||||
* @property {string} [source.hotspotType] - Typ hotspotu (np. "promotion").
|
|
||||||
* @property {number[]} [source.productsId] - Tablica ID produktów.
|
|
||||||
* @property {number} [source.productsMenu] - Identyfikator menu produktów.
|
|
||||||
* @property {object} query - Dane zapytania, nadpisują source (DEV).
|
|
||||||
* @property {string} query.string - Zapytanie w formacie GraphQL.
|
|
||||||
* @property {Function} query.graphFn - Funkcja do pobierania danych.
|
|
||||||
* @property {object} options - Ustawienia dla hotspotu (required).
|
|
||||||
* @property {boolean} options.lazy - Czy wczytywać w trybie lazy.
|
|
||||||
* @property {boolean|string} options.addToBasket - Obsługa koszyka:
|
|
||||||
* - true = włącz
|
|
||||||
* - false = wyłącz
|
|
||||||
* - "range" = dodaj z zakresem
|
|
||||||
* @property {boolean|object} options.swiper - Slider:
|
|
||||||
* - true = aktywny
|
|
||||||
* - false = nieaktywny
|
|
||||||
* - object = konfiguracja Swiper
|
|
||||||
* @property {Function} options.callbackFn - Funkcja callback która dzieje się po wywołaniu wszystkiego włącznie ze swiperem
|
|
||||||
*
|
|
||||||
* @type {Hotspot[]}
|
|
||||||
*/
|
|
||||||
// const idmHotspotArr = [
|
|
||||||
// {
|
|
||||||
// id: "idmMainHotspot1",//!id ramki
|
|
||||||
// title: "Nowoczesna ramka rekomendacji",//
|
|
||||||
// classes: "abcdefg",
|
|
||||||
// placement: {
|
|
||||||
// selector: "#content",
|
|
||||||
// insert: "afterbegin"
|
|
||||||
// },
|
|
||||||
// source: {
|
|
||||||
// hotspotType: "protomtion",
|
|
||||||
// productsId: [11,12],
|
|
||||||
// productsMenu: 122,
|
|
||||||
// },
|
|
||||||
// query: {
|
|
||||||
// string: `searchInput: {productsId : [589, 180, 181590,160740, 155978, 153632, 123350, 82542, 37321, 17040, 25065, 25114, 85452]}`,
|
|
||||||
// graphFn: IDM_PRODUCTS_GQL
|
|
||||||
// },
|
|
||||||
// // addToBasket: true,
|
|
||||||
// options: {
|
|
||||||
// lazy: false,
|
|
||||||
// addToBasket: "range",
|
|
||||||
// swiper: true,
|
|
||||||
// callbackFn: ()=>{console.log("test")}
|
|
||||||
// // swiper: albo true false - albo obiekt z opcjami swipera
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: "idmMainHotspot2",
|
|
||||||
// title: "Super ramka rekomendacji",
|
|
||||||
// placement: {
|
|
||||||
// selector: "#content",
|
|
||||||
// insert: "beforeend"
|
|
||||||
// },
|
|
||||||
// source: {
|
|
||||||
// productsMenu: 488,
|
|
||||||
// },
|
|
||||||
// query: {
|
|
||||||
// string: `searchInput: {hotspot: promotion,limit: 16}`,
|
|
||||||
// graphFn: IDM_HOTSPOTS_GQL
|
|
||||||
// },
|
|
||||||
// // addToBasket: true,
|
|
||||||
// options: {
|
|
||||||
// lazy: true,
|
|
||||||
// addToBasket: "range",
|
|
||||||
// swiper: true,
|
|
||||||
// // swiper: albo true false - albo obiekt z opcjami swipera
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ];
|
|
||||||
|
|
||||||
|
|
||||||
// Wrzucenie na strone wszystkich ramek z obiektu js
|
|
||||||
async function idmInsertAllObjectHotspots(hotspotArr){
|
|
||||||
try{
|
|
||||||
const reqArr = []
|
|
||||||
hotspotArr.forEach(hotspotObj=>{
|
|
||||||
reqArr.push(idmInsertHotspotObject(hotspotObj));
|
|
||||||
});
|
|
||||||
await Promise.all(reqArr);
|
|
||||||
}catch(err){
|
|
||||||
console.error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// idmInsertAllObjectHotspots(idmHotspotArr);
|
|
||||||
Reference in New Issue
Block a user