Compare commits
2 Commits
1c3c5e8334
...
2d4cb1c44e
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d4cb1c44e | |||
| 49ff211062 |
24
README.md
24
README.md
@@ -96,11 +96,17 @@ new IdmHotspot({
|
||||
* @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 {number[]} [source.producersId] - Tablica ID producentów.
|
||||
* @property {number[]} [source.seriesId] - Tablica ID serii.
|
||||
* @property {number[]} [source.parametersId] - Tablica ID grup parametrów.
|
||||
* @property {object} [source.priceRange] - Obiekt z ceną od do.
|
||||
* @property {number} [source.priceRange.from] - cena od
|
||||
* @property {number} [source.priceRange.to] - cena do
|
||||
|
||||
|
||||
* @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} [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).
|
||||
@@ -144,9 +150,6 @@ new IdmHotspot({
|
||||
</h3>
|
||||
</div>
|
||||
</section>
|
||||
<script>
|
||||
idmInsertHotspotElement(document.getElementByid("idmBlogHotspot1"));
|
||||
</script>
|
||||
```
|
||||
|
||||
Żeby zmienić resztę ustawień trzeba zmieniać defaultowe ustawienia!
|
||||
@@ -159,9 +162,14 @@ new IdmHotspot({
|
||||
* @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 {number[]} data-products-id - Lista ID produktów (rozdzielona przecinkami).
|
||||
* @attribute {number} data-products-menu - Identyfikator menu produktów.
|
||||
* @attribute {number[]} data-producers-id - Lista id producentów (rozdzielona przecinkami).
|
||||
* @attribute {number[]} data-series-id - Lista id serii (rozdzielona przecinkami).
|
||||
* @attribute {number[]} data-parameters-id - Lista id grup parametrów (rozdzielona przecinkami).
|
||||
* @attribute {number} data-price-from - "cena od" produktów w hotspocie
|
||||
* @attribute {number} data-price-to - "cena do" produktów w hotspocie
|
||||
* @attribute {boolean} data-lazy - Czy sekcja ma być ładowana w trybie lazy.
|
||||
*
|
||||
* @example
|
||||
|
||||
144
klasa.js
144
klasa.js
@@ -191,6 +191,7 @@ const IDM_PRODUCT_QUERY = `id
|
||||
iconSecond
|
||||
iconSmall
|
||||
iconSmallSecond
|
||||
link
|
||||
}
|
||||
}
|
||||
opinion{
|
||||
@@ -508,26 +509,44 @@ class IdmHotspot{
|
||||
/**
|
||||
* Przygotowuje funkcję i zapytanie GraphQL w zależności od typu danych.
|
||||
*/
|
||||
getQueryData({productsID, productsMenu, hotspotsType}){
|
||||
getQueryData(){
|
||||
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){
|
||||
let queryMarkup = "";
|
||||
|
||||
if(this.source?.hotspotsType){
|
||||
graphFn = IDM_HOTSPOTS_GQL;
|
||||
query = `searchInput: {hotspot: ${hotspotsType}, limit: 16}`;
|
||||
queryMarkup += `hotspot: ${this.source.hotspotsType}, limit: 16`;
|
||||
}else{
|
||||
graphFn = IDM_PRODUCTS_GQL;
|
||||
if(this.source?.productsId){
|
||||
queryMarkup += `productsId: [${this.source.productsId}],`;
|
||||
}
|
||||
if(this.source?.productsMenu){
|
||||
queryMarkup += `navigation: ${this.source.productsMenu},`;
|
||||
}
|
||||
if(this.source?.producersId){
|
||||
queryMarkup += `producers: [${this.source.producersId}],`;
|
||||
}
|
||||
if(this.source?.seriesId){
|
||||
queryMarkup += `series: [${this.source.seriesId}],`;
|
||||
}
|
||||
if(this.source?.parametersId){
|
||||
queryMarkup += `parameters: [${this.source.parametersId.reduce((acc,val)=> acc + `{id: ${val}}`,"")}],`;
|
||||
}
|
||||
if(this.source?.priceRange){
|
||||
queryMarkup += `priceRange: {from: ${+this.source.priceRange?.from || 0}, to: ${+this.source.priceRange?.to || 0}},`;
|
||||
}
|
||||
}
|
||||
|
||||
query = `searchInput: { ${queryMarkup} }`
|
||||
|
||||
return [graphFn, query];
|
||||
}
|
||||
/**
|
||||
* Ustawia dane zapytania GraphQL wewnątrz instancji.
|
||||
*/
|
||||
setQueryData(queryObj){
|
||||
const [graphFn, queryString] = this.getQueryData(queryObj);
|
||||
setQueryData(){
|
||||
const [graphFn, queryString] = this.getQueryData();
|
||||
this.query.graphFn = graphFn;
|
||||
this.query.string = queryString;
|
||||
}
|
||||
@@ -591,18 +610,19 @@ class IdmHotspot{
|
||||
${this.markupAdditional(prod)}
|
||||
</div>
|
||||
<a class="product__icon d-flex justify-content-center align-items-center" tabindex="-1" href="${prod.link}">
|
||||
${this.markupImage(prod)}
|
||||
<strong class="label_icons">
|
||||
${this.markupLabel(prod)}
|
||||
</strong>
|
||||
${this.markupImage(prod)}
|
||||
<strong class="label_icons">
|
||||
${this.markupLabel(prod)}
|
||||
</strong>
|
||||
</a>
|
||||
<div class="product__content_wrapper">
|
||||
${this.markupOpinions(prod)}
|
||||
<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,"")}">
|
||||
${this.markupPrice(prod, prodExchangedData)}
|
||||
</div>
|
||||
${this.markupAddToBasket(prod)}
|
||||
${this.markupVersions(prod)}
|
||||
${this.markupOpinions(prod)}
|
||||
<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,"")}">
|
||||
${this.markupPrice(prod, prodExchangedData)}
|
||||
</div>
|
||||
${this.markupAddToBasket(prod)}
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
@@ -633,6 +653,16 @@ class IdmHotspot{
|
||||
data-product-size="${prod.sizes?.[0]?.id || 'uniw'}" aria-label="${idmHotspotTextObject["Dodaj do ulubionych"]}">
|
||||
</span>`;
|
||||
}
|
||||
|
||||
markupVersions(prod){
|
||||
if(!this.options?.selectVersion || !prod.group?.versions || prod.group?.versions?.length === 1 ) return "";
|
||||
|
||||
return `<div class="product__versions">
|
||||
${prod.group.versions.reduce((acc, val)=>{
|
||||
return acc + `<a class="product__version_single" href="${val.link}"><img class="product__version_img" src="${val.icon}" alt="${val.name}"/></a>`;
|
||||
},"")}
|
||||
</div>`
|
||||
}
|
||||
|
||||
markupImage(prod){
|
||||
let markup = "";
|
||||
@@ -824,17 +854,20 @@ class IdmHotspot{
|
||||
<span class="headline"><span class="headline__name" aria-label="${this.title}">${this.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>
|
||||
${this.markupHotspotSwiperContainer()}
|
||||
</div>
|
||||
</section>`;
|
||||
}
|
||||
markupHotspotSwiperContainer(productsHTML=""){
|
||||
return `<div class="products__wrapper swiper">
|
||||
<div class="products hotspot__products swiper-wrapper">
|
||||
${productsHTML}
|
||||
</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>`;
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// HANDLERY ZDARZEŃ
|
||||
@@ -1131,11 +1164,7 @@ class IdmHotspot{
|
||||
this.initExternalFunctions();
|
||||
try{
|
||||
if(!this.products){
|
||||
if(!this?.query?.graphFn || !this?.query?.string) this.setQueryData({
|
||||
productsID: this?.source?.productsId,
|
||||
productsMenu: this?.source?.productsMenu,
|
||||
hotspotsType: this?.source?.hotspotsType
|
||||
});
|
||||
if(!this?.query?.graphFn || !this?.query?.string) this.setQueryData();
|
||||
|
||||
// pobranie danych o produktach
|
||||
await this.getHotspotData();
|
||||
@@ -1144,7 +1173,15 @@ class IdmHotspot{
|
||||
|
||||
|
||||
// Wstawienie markupa na strone
|
||||
this.hotspotEl.querySelector(".products.hotspot__products")?.insertAdjacentHTML("beforeend", this.markup());
|
||||
if(this.hotspotEl.querySelector(".products.hotspot__products")) this.hotspotEl.querySelector(".products.hotspot__products").insertAdjacentHTML("beforeend", this.markup());
|
||||
else if(this.hotspotEl.querySelector(".hotspot")){
|
||||
this.hotspotEl.querySelector(".hotspot")?.insertAdjacentHTML("beforeend", this.markupHotspotSwiperContainer(this.markup()));
|
||||
}
|
||||
else{
|
||||
throw new Error("Nie udało się wstawić produktów! Zła struktura HTML")
|
||||
}
|
||||
|
||||
|
||||
this.hotspotEl.classList.remove("idm-loading");
|
||||
|
||||
// init swiper + add to basket
|
||||
@@ -1407,7 +1444,7 @@ function idmHideTooltip(tooltipEl){
|
||||
}
|
||||
|
||||
|
||||
// document.addEventListener("DOMContentLoaded", ()=>{
|
||||
document.addEventListener("DOMContentLoaded", ()=>{
|
||||
document.body.addEventListener("click", e=>{
|
||||
const tooltipEl = e.target.closest(".idm_tooltip");
|
||||
if(!e.target.closest(".idm_tooltip__info_icon") || !tooltipEl) return;
|
||||
@@ -1415,18 +1452,30 @@ function idmHideTooltip(tooltipEl){
|
||||
e.preventDefault();
|
||||
idmShowTooltip(tooltipEl);
|
||||
});
|
||||
// });
|
||||
});
|
||||
// new IdmHotspot({
|
||||
// id: "idmTestHotspot1",
|
||||
// title: "tescik",
|
||||
// products: [] // Tablica produktów
|
||||
// placement: {
|
||||
// selector: "#content",
|
||||
// insert: "beforeend",
|
||||
// },
|
||||
// source: {
|
||||
// productsMenu: 1649
|
||||
// productsMenu: 1649,
|
||||
// producersId: [],
|
||||
// seriesId: [],
|
||||
// parametersId: [],
|
||||
// priceRange: {
|
||||
// from: 0,
|
||||
// to: 150,
|
||||
// }
|
||||
// }
|
||||
// products: [] // Tablica produktów
|
||||
// options: {
|
||||
// lazy: true,
|
||||
// addToBasket: "range",
|
||||
// swiper: true,
|
||||
// }
|
||||
// });
|
||||
// {
|
||||
// id: "idmMainHotspot2",
|
||||
@@ -1450,10 +1499,19 @@ async function idmPrepareHotspotObject(selectedContainerEl){
|
||||
selectedContainerEl.classList.add("--init");
|
||||
const source = {};
|
||||
|
||||
if(selectedContainerEl?.dataset?.productsId) source.productsId = selectedContainerEl?.dataset?.productsId.split(",");
|
||||
else if(selectedContainerEl?.dataset?.hotspotsType) source.hotspotsType = selectedContainerEl?.dataset?.hotspotsType;
|
||||
else if(selectedContainerEl?.dataset?.productsMenu) source.productsMenu = selectedContainerEl?.dataset?.productsMenu;
|
||||
else{
|
||||
|
||||
if(selectedContainerEl.dataset?.hotspotsType) source.hotspotsType = selectedContainerEl.dataset.hotspotsType;
|
||||
else {
|
||||
if(selectedContainerEl.dataset?.productsId) source.productsId = selectedContainerEl.dataset.productsId.split(",");
|
||||
if(selectedContainerEl.dataset?.productsMenu) source.productsMenu = selectedContainerEl.dataset.productsMenu;
|
||||
if(selectedContainerEl.dataset?.producersId) source.producersId = selectedContainerEl.dataset.producersId;
|
||||
if(selectedContainerEl.dataset?.seriesId) source.seriesId = selectedContainerEl.dataset.seriesId;
|
||||
if(selectedContainerEl.dataset?.parametersId) source.seriesId = selectedContainerEl.dataset.parametersId;
|
||||
if(selectedContainerEl.dataset?.priceFrom && selectedContainerEl.dataset?.priceTo) source.priceRange = {from: +selectedContainerEl.dataset.priceFrom, to: +selectedContainerEl.dataset.priceTo};
|
||||
}
|
||||
|
||||
|
||||
if(Object.keys(source).length === 0){
|
||||
console.error();
|
||||
selectedContainerEl?.remove();
|
||||
return;
|
||||
|
||||
@@ -7,7 +7,6 @@ wersja max 5 zdjęć i później + może????
|
||||
- Wybór kolorystyczny???
|
||||
- AAAAA - banner na hotspocie
|
||||
- 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": {}}
|
||||
|
||||
34
style.less
34
style.less
@@ -1,7 +1,3 @@
|
||||
.idm__hotspot .btn.add_to_basket__link{
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.idm__hotspot .add_to_basket{
|
||||
display: flex;
|
||||
}
|
||||
@@ -227,3 +223,33 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// WERSJE
|
||||
.idm__hotspot:has(.product__versions){
|
||||
.product__versions{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 1rem;
|
||||
z-index: 1;
|
||||
background: #fff;
|
||||
clip-path: inset(0% 0 100% 0);
|
||||
padding: 0.3rem 1rem;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.product__content_wrapper{
|
||||
position: relative;
|
||||
}
|
||||
.label_icons, .product__versions{
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.product:hover{
|
||||
.product__versions, .label_icons{
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
.product__versions{
|
||||
clip-path: inset(0 0 0 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user