diff --git a/README.md b/README.md
index 4185e4f..1946dda 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,7 @@ Warto gdzieś później zapisać nową nazwę klasy np w opisie komponentu, albo
- Nie znaleziono kontenera
- Nie znaleziono metody graphql
- Najniższa cena
+- Drugie Zdjęcie
### Przykłady UŻYCIA ###
##### Jedna ramka - obiekt ######
@@ -84,33 +85,44 @@ new IdmHotspot({
* @property {string} title - Tytuł ramki.
* @property {string} classes - Dodatkowe klasy CSS.
* @property {object[]} [products] - tablica produktów z układem danych takich jak w graphql. Opcjonalne, pod specjalne funkcjonalności.
+
+
* @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 {object} source - Dane źródłowe dla hotspotu.
* @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} [options.devMode] - Czy wczytywać ramki tylko dla stron z dev=true.
+ * @property {boolean} [options.omnibusTooltip] - Czy wyświetlać omnibusa w formie tooltip
+ * @property {Function} [options.callbackFn] - Funkcja callback która dzieje się po wywołaniu wszystkiego włącznie ze swiperem
+
* @property {boolean} [options.addToFavorites] - Czy włączać dodawanie do ulubionych(DZIAŁA TYLKO PO ZMIANACH SZABLONOWYCH)
* @property {boolean} [options.addToCompare] - Czy włączać dodawanie do porównywania
* @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 {boolean} [options.swiperScrollbar] - Czy włączać scrollbar w swiperze - DO DZIAŁANIA WYMAGA WŁĄCZONEGO SWIPERA
- * @property {Function} [options.callbackFn] - Funkcja callback która dzieje się po wywołaniu wszystkiego włącznie ze swiperem
- * @property {boolean} [options.omnibusTooltip] - Czy wyświetlać omnibusa w formie tooltip
* @property {boolean} [options.showOpinions] - Czy wyświetlać opinie o produkcie w formie gwiazdek nad nazwą
+ * @property {boolean} [options.showSecondImage] - Czy wyświetlać drugie zdjęcie na hover
*
* @type {Hotspot[]}
*/
diff --git a/klasa.js b/klasa.js
index 6aa36e3..b8b2c4e 100644
--- a/klasa.js
+++ b/klasa.js
@@ -31,6 +31,7 @@ const idmHotspotTextObject = {
[]: ,
[]: ,
[]: ,
+ []: ,
};
// STRING
// const idmHotspotTextObject = {
@@ -240,7 +241,18 @@ const IDM_PRODUCT_GQL = (args) => JSON.stringify({
});
// 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 }`
+ query: `mutation {
+ addProductsToBasket(ProductInput: {id: ${t}, size: "${e}", quantity: ${a}}) {
+ status
+ results {
+ status
+ error {
+ code
+ message
+ }
+ }
+ }
+ }`
});
/////////////////////////////////////////
// JS
@@ -420,6 +432,7 @@ class IdmHotspot{
// POKAZANIE
showOpinions: false,
+ showSecondImage: false,
// DODAWANIE
addToBasket: true, // true, false, "range"
@@ -468,6 +481,8 @@ class IdmHotspot{
this.handleQuantityInputChange = this.handleQuantityInputChange.bind(this);
this.handleAddToCompare = this.handleAddToCompare.bind(this);
this.handleAddToFav = this.handleAddToFav.bind(this);
+ this.handleShowSecondImage = this.handleShowSecondImage.bind(this);
+ this.handleHideSecondImage = this.handleHideSecondImage.bind(this);
this.init();
}
@@ -619,14 +634,17 @@ class IdmHotspot{
-
+
`;
else if(prod?.iconSmall) markup += `
-
+
`;
- else markup += `
`
+ else markup += `
`;
+
+ if(this.options?.showSecondImage && prod.enclosuresImages?.[1]?.url) markup += `
`;
+
return markup;
}
@@ -941,6 +959,22 @@ class IdmHotspot{
input.value = current.toFixed(precision);
}
+ /**
+ * Obsługuje Pokazywanie zdjęcia na hover
+ */
+ handleShowSecondImage(e){
+ const prodIconEl = e.target.closest(".product__icon");
+ if(!prodIconEl) return;
+
+ prodIconEl.classList.add("--toggle-icon");
+ }
+
+ handleHideSecondImage(e){
+ const prodIconEl = e.target.closest(".product__icon");
+ if(!prodIconEl) return;
+
+ prodIconEl.classList.remove("--toggle-icon");
+ }
/**
* Walidacja zmian ilości w polu input.
*/
@@ -1129,28 +1163,27 @@ class IdmHotspot{
// DODAWANIE DO KOSZYKA
if(this.options?.addToBasket){
const addToBasketEl = prodEl.querySelector("form.add_to_basket");
- if(!addToBasketEl) return;
- addToBasketEl.addEventListener("submit", this.handleAddToBasket);
+ addToBasketEl?.addEventListener("submit", this.handleAddToBasket);
// + -
if(this?.options?.addToBasket === "range"){
- addToBasketEl.querySelector(".idm-products-banner__qty")?.addEventListener("click",this.handleQuantityButtonClick);
- addToBasketEl.querySelector(".idm-products-banner__qty-input")?.addEventListener("input",this.handleQuantityInputChange);
+ addToBasketEl?.querySelector(".idm-products-banner__qty")?.addEventListener("click",this.handleQuantityButtonClick);
+ addToBasketEl?.querySelector(".idm-products-banner__qty-input")?.addEventListener("input",this.handleQuantityInputChange);
}
}
- // Tooltip
- // if(this.options?.omnibusTooltip){
- // const tooltipEl = prodEl.querySelector(".idm_tooltip");
-
- // tooltipEl.addEventListener("click", ()=>{
- // this.showTooltip(tooltipEl);
- // })
- // }
-
// Add to Favorites
if(this.options?.addToFavorites && typeof this.addToFavFn === "function") prodEl.querySelector(".product__favorite")?.addEventListener("click", this.handleAddToFav);
// Compare
if(this.options?.addToCompare) prodEl.querySelector(".idm-products-banner__compare-btn")?.addEventListener("click", this.handleAddToCompare);
+
+ // Second image on hover
+ if(this.options?.showSecondImage){
+ const prodIconEl = prodEl.querySelector(".product__icon");
+ if(prodIconEl.querySelector(".product__image.--second")){
+ prodIconEl?.addEventListener("mouseover", this.handleShowSecondImage);
+ prodIconEl?.addEventListener("mouseleave", this.handleHideSecondImage);
+ }
+ }
}
/**
diff --git a/ramka.txt b/ramka.txt
index 32468b4..c075c70 100644
--- a/ramka.txt
+++ b/ramka.txt
@@ -9,12 +9,20 @@
- stary szablon
- cena za kg
- blokowanie dodawania do koszyka jeśli ilość jest maksymalna
+- informacje o producencie albo serri gdzieś nad produktem
+- czy zapisywać wszystkie hotspoty do jakiegoś app_shop.fn.idmHotspots = {"#idmMainHotspot1": {}}
- własne klasy
-- aplikacja do zarządania dodatkiem od obiektów hotspot
Stara ramka
- getProductXML=t
-- slick
\ No newline at end of file
+- slick
+
+
+
+cos: any[] = []
+
+cos ?? ''
+cos?? false
\ No newline at end of file
diff --git a/style.less b/style.less
index d335fa2..9a0868a 100644
--- a/style.less
+++ b/style.less
@@ -1,3 +1,7 @@
+.idm__hotspot .btn.add_to_basket__link{
+ margin-top: 0;
+}
+
.idm__hotspot .add_to_basket{
display: flex;
}
@@ -151,7 +155,7 @@
opacity: 0.6;
}
}
-
+/* COMPARE */
.idm-products-banner__compare-btn{
.idm-products-banner__compare-icon{
height: 100%;
@@ -173,7 +177,10 @@
opacity: 0.6;
}
}
-
+.idm-products-banner__compare-btn.--success {
+ display: flex;
+ align-items: end;
+}
/* opinions */
.product__opinions{
@@ -187,4 +194,30 @@
}
.product__opinions .icon-star:not(.--active)::before{
content: "\f006";
-}
\ No newline at end of file
+}
+
+/* second image */
+.product__image.--second{
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.product__icon{
+ .product__image{
+ transition: opacity .25s;
+ }
+ .product__image.--second{
+ opacity: 0;
+ }
+
+ &.--toggle-icon:has(.product__image.--second){
+ .product__image.--first{
+ opacity: 0;
+ }
+ .product__image.--second{
+ opacity: 1;
+ }
+ }
+}