dodanie pobierania produktow z linku
This commit is contained in:
@@ -93,6 +93,7 @@ new IdmHotspot({
|
|||||||
|
|
||||||
|
|
||||||
* @property {object} source - Dane źródłowe dla hotspotu.
|
* @property {object} source - Dane źródłowe dla hotspotu.
|
||||||
|
* @property {string} [source.link] - link do listingu z którego mają być pobierane produkty (NIEZALECANE)
|
||||||
* @property {string} [source.hotspotType] - Typ hotspotu (np. "promotion").
|
* @property {string} [source.hotspotType] - Typ hotspotu (np. "promotion").
|
||||||
* @property {number[]} [source.productsId] - Tablica ID produktów.
|
* @property {number[]} [source.productsId] - Tablica ID produktów.
|
||||||
* @property {number} [source.productsMenu] - Identyfikator menu produktów.
|
* @property {number} [source.productsMenu] - Identyfikator menu produktów.
|
||||||
@@ -162,6 +163,7 @@ new IdmHotspot({
|
|||||||
* @property {string} id - Identyfikator elementu (np. "idmBlogHotspot1").
|
* @property {string} id - Identyfikator elementu (np. "idmBlogHotspot1").
|
||||||
* @property {string} class - Klasy CSS używane do stylowania.
|
* @property {string} class - Klasy CSS używane do stylowania.
|
||||||
*
|
*
|
||||||
|
* @attribute {string} data-link - link do listingu z którego mają być pobierane produkty (NIEZALECANE)
|
||||||
* @attribute {string} data-hotspots-type - Typ hotspotu (np. "promotion").
|
* @attribute {string} data-hotspots-type - Typ hotspotu (np. "promotion").
|
||||||
* @attribute {number[]} data-products-id - Lista ID produktów (rozdzielona przecinkami).
|
* @attribute {number[]} data-products-id - Lista ID produktów (rozdzielona przecinkami).
|
||||||
* @attribute {number} data-products-menu - Identyfikator menu produktów.
|
* @attribute {number} data-products-menu - Identyfikator menu produktów.
|
||||||
|
|||||||
615
klasa.js
615
klasa.js
@@ -438,6 +438,13 @@ class IdmHotspot{
|
|||||||
// DOMYŚLNE OPCJE HOTSPOTA
|
// DOMYŚLNE OPCJE HOTSPOTA
|
||||||
// ============================
|
// ============================
|
||||||
static idmDefaultHotspotOptions = {
|
static idmDefaultHotspotOptions = {
|
||||||
|
cssVariables: {
|
||||||
|
version: {
|
||||||
|
columnDesktop: 5,
|
||||||
|
columnTablet: 3,
|
||||||
|
columnMobile: 4,
|
||||||
|
}
|
||||||
|
},
|
||||||
options: {
|
options: {
|
||||||
lazy: true,
|
lazy: true,
|
||||||
devMode: false,
|
devMode: false,
|
||||||
@@ -467,7 +474,7 @@ class IdmHotspot{
|
|||||||
* Konstruktor
|
* Konstruktor
|
||||||
* @param {object} object - Dane konfiguracyjne hotspotu
|
* @param {object} object - Dane konfiguracyjne hotspotu
|
||||||
*/
|
*/
|
||||||
constructor({id, title, classes, placement, source, query, options = {}, hotspotEl, products}){
|
constructor({id, title, classes, placement, source, query, options = {}, hotspotEl, products, cssVariables}){
|
||||||
this.id = id || "";
|
this.id = id || "";
|
||||||
this.title = title || "";
|
this.title = title || "";
|
||||||
this.classes = classes || "";
|
this.classes = classes || "";
|
||||||
@@ -484,6 +491,10 @@ class IdmHotspot{
|
|||||||
...IdmHotspot.idmDefaultHotspotOptions.options,
|
...IdmHotspot.idmDefaultHotspotOptions.options,
|
||||||
...options,
|
...options,
|
||||||
};
|
};
|
||||||
|
this.cssVariables = {
|
||||||
|
...IdmHotspot.idmDefaultHotspotOptions.cssVariables,
|
||||||
|
...cssVariables,
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// this.hotspots = {};
|
// this.hotspots = {};
|
||||||
@@ -568,15 +579,21 @@ class IdmHotspot{
|
|||||||
async getHotspotData(){
|
async getHotspotData(){
|
||||||
if(this.products) return;
|
if(this.products) return;
|
||||||
try{
|
try{
|
||||||
const res = await fetch(`/graphql/v1/`, {
|
let products;
|
||||||
method: "POST",
|
if(this.source?.link){
|
||||||
headers: {
|
products = await this.xmlGetData();
|
||||||
"Content-Type": "application/json",
|
}else{
|
||||||
},
|
const res = await fetch(`/graphql/v1/`, {
|
||||||
body: this.query.graphFn(this.query.string),
|
method: "POST",
|
||||||
});
|
headers: {
|
||||||
const data = await res.json();
|
"Content-Type": "application/json",
|
||||||
const products = data?.data?.[this.query.graphFn === IDM_HOTSPOTS_GQL ? "hotspots" : "products"]?.products;
|
},
|
||||||
|
body: this.query.graphFn(this.query.string),
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
products = data?.data?.[this.query.graphFn === IDM_HOTSPOTS_GQL ? "hotspots" : "products"]?.products;
|
||||||
|
}
|
||||||
|
|
||||||
if(!products || !products.length) throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]);
|
if(!products || !products.length) throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]);
|
||||||
|
|
||||||
this.products = products;
|
this.products = products;
|
||||||
@@ -671,7 +688,14 @@ class IdmHotspot{
|
|||||||
markupVersions(prod){
|
markupVersions(prod){
|
||||||
if(!this.options?.selectVersion || !prod.group?.versions || prod.group?.versions?.length === 1 ) return "";
|
if(!this.options?.selectVersion || !prod.group?.versions || prod.group?.versions?.length === 1 ) return "";
|
||||||
|
|
||||||
const MAX_VERION_AMOUNT = 5;
|
let MAX_VERSION_AMOUNT = 5;
|
||||||
|
if(app_shop.vars.view > 2){
|
||||||
|
MAX_VERSION_AMOUNT = this.cssVariables.version.columnDesktop;
|
||||||
|
}else if(app_shop.vars.view === 2){
|
||||||
|
MAX_VERSION_AMOUNT = this.cssVariables.version.columnTablet;
|
||||||
|
}else if(app_shop.vars.view === 1){
|
||||||
|
MAX_VERSION_AMOUNT = this.cssVariables.version.columnMobile;
|
||||||
|
}
|
||||||
|
|
||||||
const sortedVersions = prod.group.versions.sort(function (a, b) {
|
const sortedVersions = prod.group.versions.sort(function (a, b) {
|
||||||
if (a.name < b.name) {
|
if (a.name < b.name) {
|
||||||
@@ -686,9 +710,9 @@ class IdmHotspot{
|
|||||||
|
|
||||||
return `<div class="product__versions">
|
return `<div class="product__versions">
|
||||||
${sortedVersions.reduce((acc, val, index)=>{
|
${sortedVersions.reduce((acc, val, index)=>{
|
||||||
if(index + 1 > MAX_VERION_AMOUNT) return acc;
|
if(index + 1 > MAX_VERSION_AMOUNT) return acc;
|
||||||
|
|
||||||
if(index + 1 === MAX_VERION_AMOUNT && prod.group.versions.length > MAX_VERION_AMOUNT) return acc + `<a class="product__version_more" href="${prod.link}" aria-label="${idmHotspotTextObject["Zobacz więcej"]}">+${(prod.group.versions.length - MAX_VERION_AMOUNT) + 1}</a>`;
|
if(index + 1 === MAX_VERSION_AMOUNT && prod.group.versions.length > MAX_VERSION_AMOUNT) return acc + `<a class="product__version_more" href="${prod.link}" aria-label="${idmHotspotTextObject["Zobacz więcej"]}">+${(prod.group.versions.length - MAX_VERSION_AMOUNT) + 1}</a>`;
|
||||||
|
|
||||||
return acc + `<a class="product__version_single ${prod.id === val.id ? "--active" : ""}" href="${val.link}" data-product-id="${val.id}"><img class="product__version_img" src="${val.icon}" alt="${val.name}"/></a>`;
|
return acc + `<a class="product__version_single ${prod.id === val.id ? "--active" : ""}" href="${val.link}" data-product-id="${val.id}"><img class="product__version_img" src="${val.icon}" alt="${val.name}"/></a>`;
|
||||||
},"")}
|
},"")}
|
||||||
@@ -1112,6 +1136,24 @@ class IdmHotspot{
|
|||||||
observer.observe(this.hotspotEl);
|
observer.observe(this.hotspotEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// USTAWIANIE ZMIENNYCH CSS DLA RAMKI
|
||||||
|
// ========================================================
|
||||||
|
cssSetAllVariables(){
|
||||||
|
this.cssVariableVersionColumnCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
cssVariableVersionColumnCount(){
|
||||||
|
this.cssSetVariable("--version-desktop-columns", this.cssVariables?.version?.columnDesktop || 5)
|
||||||
|
this.cssSetVariable("--version-tablet-columns", this.cssVariables?.version?.columnTablet || 3)
|
||||||
|
this.cssSetVariable("--version-mobile-columns", this.cssVariables?.version?.columnMobile || 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cssSetVariable(name, value){
|
||||||
|
this.hotspotEl.style.setProperty(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// FUNKCJE POMOCNICZE
|
// FUNKCJE POMOCNICZE
|
||||||
// ========================================================
|
// ========================================================
|
||||||
@@ -1196,6 +1238,338 @@ class IdmHotspot{
|
|||||||
prodEl.classList.remove("--loading");
|
prodEl.classList.remove("--loading");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// XML to GraphQL
|
||||||
|
// ========================================================
|
||||||
|
xmlGetGrossNetPrices({priceNode, name}){
|
||||||
|
return {
|
||||||
|
gross: {
|
||||||
|
value: priceNode?.getAttribute(`${name}`) !== null ? +priceNode.getAttribute(`${name}`) : undefined,
|
||||||
|
formatted: priceNode?.getAttribute(`${name}_formatted`) ?? undefined,
|
||||||
|
},
|
||||||
|
net: {
|
||||||
|
value: priceNode?.getAttribute(`${name}_net`) !== null ? +priceNode.getAttribute(`${name}_net`) : undefined,
|
||||||
|
formatted: priceNode?.getAttribute(`${name}_net_formatted`) ?? undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlGetPriceFromNode(priceNode){
|
||||||
|
const priceObj = {
|
||||||
|
price: {
|
||||||
|
gross: {
|
||||||
|
value: priceNode?.getAttribute("value") !== null ? +priceNode.getAttribute("value") : undefined,
|
||||||
|
formatted: priceNode?.getAttribute("price_formatted") ?? undefined,
|
||||||
|
},
|
||||||
|
net: {
|
||||||
|
value: priceNode?.getAttribute("price_net") !== null ? +priceNode.getAttribute("price_net") : undefined,
|
||||||
|
formatted: priceNode?.getAttribute("price_net_formatted") ?? undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rebateCodeActive: priceNode?.getAttribute("rebate_code_active") === "y" ? true : false,
|
||||||
|
omnibusPrice: {
|
||||||
|
...this.xmlGetGrossNetPrices({priceNode, name: "omnibus_price"})
|
||||||
|
},
|
||||||
|
// depositPrice: {},
|
||||||
|
// depositPriceUnit: {},
|
||||||
|
// totalDepositPrice: {},
|
||||||
|
// totalDepositPriceUnit: {},
|
||||||
|
omnibusPriceDetails: {
|
||||||
|
// unit: {},
|
||||||
|
youSave: {
|
||||||
|
...this.xmlGetGrossNetPrices({priceNode, name: "omnibus_yousave"})
|
||||||
|
},
|
||||||
|
youSavePercent: priceNode?.getAttribute("price_net") !== null ? +priceNode.getAttribute("omnibus_yousave_percent") : undefined,
|
||||||
|
omnibusPriceIsHigherThanSellingPrice: priceNode?.getAttribute("omnibus_price_is_higher_than_selling_price") === "true" ? true : false,
|
||||||
|
// newPriceEffectiveUntil: {},
|
||||||
|
},
|
||||||
|
tax: {
|
||||||
|
// worth: {},
|
||||||
|
vatPercent: priceNode?.getAttribute("tax") !== null ? +priceNode.getAttribute("tax") : undefined,
|
||||||
|
// vatString: ""
|
||||||
|
},
|
||||||
|
beforeRebate: {
|
||||||
|
...this.xmlGetGrossNetPrices({priceNode, name: "beforerebate"})
|
||||||
|
},
|
||||||
|
// beforeRebateDetails: {
|
||||||
|
// youSave: {
|
||||||
|
|
||||||
|
// },
|
||||||
|
// youSavePercent: "",
|
||||||
|
// unit: {}
|
||||||
|
// },
|
||||||
|
// crossedPrice: {},
|
||||||
|
youSave: {
|
||||||
|
...this.xmlGetGrossNetPrices({priceNode, name: "yousave"})
|
||||||
|
},
|
||||||
|
youSavePercent: priceNode?.getAttribute("yousave_percent") !== null ? +priceNode.getAttribute("yousave_percent") : undefined,
|
||||||
|
// unit: {},
|
||||||
|
max: {
|
||||||
|
...this.xmlGetGrossNetPrices({priceNode, name: "maxprice"})
|
||||||
|
},
|
||||||
|
// maxPriceUnit: {},
|
||||||
|
// suggested: {},
|
||||||
|
unitConvertedPrice: {
|
||||||
|
...this.xmlGetGrossNetPrices({priceNode, name: "unit_converted_price"})
|
||||||
|
},
|
||||||
|
// rebateNumber: {},
|
||||||
|
lastPriceChangeDate: priceNode?.getAttribute("last_price_change_date") ?? undefined,
|
||||||
|
// advancePrice: {},
|
||||||
|
promotionDuration: {
|
||||||
|
promotionTill: {
|
||||||
|
date: {
|
||||||
|
date: priceNode?.getAttribute("last_price_change_date")?.split("-")?.[2] ?? undefined,
|
||||||
|
month: priceNode?.getAttribute("last_price_change_date")?.split("-")?.[1] ?? undefined,
|
||||||
|
year: priceNode?.getAttribute("last_price_change_date")?.split("-")?.[0] ?? undefined,
|
||||||
|
// weekDay: "",
|
||||||
|
// formatted: ""
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
hour: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[0] ?? undefined,
|
||||||
|
minutes: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[1] ?? undefined,
|
||||||
|
seconds: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[2] ?? undefined,
|
||||||
|
},
|
||||||
|
// timestamp: ""
|
||||||
|
},
|
||||||
|
// discountTill: {},
|
||||||
|
// distinguishedTill: {},
|
||||||
|
// specialTill: {},
|
||||||
|
},
|
||||||
|
// subscriptionPrice: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
return priceObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlGetTraitsFromNode(node){
|
||||||
|
const awardedParameters = [];
|
||||||
|
|
||||||
|
node.querySelectorAll(":scope > trait").forEach(trait=>{
|
||||||
|
const currParameter = awardedParameters.find(param=>param.id === trait.getAttribute("groupid")) || {
|
||||||
|
id: trait.getAttribute("groupid") ?? undefined,
|
||||||
|
name: trait.getAttribute("groupdescription") ?? undefined,
|
||||||
|
// description: "",
|
||||||
|
values: [],
|
||||||
|
// contextValue: "",
|
||||||
|
// search: {
|
||||||
|
// icon: "",
|
||||||
|
// },
|
||||||
|
}
|
||||||
|
|
||||||
|
currParameter.values.push({
|
||||||
|
id: trait.getAttribute("traitid") ?? undefined,
|
||||||
|
name: trait.getAttribute("traitid") ?? undefined,
|
||||||
|
link: trait.getAttribute("link") ?? undefined,
|
||||||
|
// description: "",
|
||||||
|
// search: {
|
||||||
|
// icon: ""
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if(currParameter.values.length === 1) awardedParameters.push(currParameter);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return awardedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
async xmlGetData(){
|
||||||
|
if(!this.source?.link) return null;
|
||||||
|
try{
|
||||||
|
const res = await fetch(`${this.source?.link}${this.source?.link.includes("?") ? "&getProductXML=t" : "?getProductXML=t"}`);
|
||||||
|
const str = await res.text();
|
||||||
|
const xml = new window.DOMParser().parseFromString(str, "text/xml");
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
const allProducts = xml.querySelectorAll("product");
|
||||||
|
if(allProducts.length === 0) throw new Error("Nie znaleziono produktów");
|
||||||
|
|
||||||
|
const data = [];
|
||||||
|
|
||||||
|
|
||||||
|
allProducts.forEach(prod=>{
|
||||||
|
|
||||||
|
// NODES
|
||||||
|
const priceNode = prod.querySelector(":scope >price");
|
||||||
|
const firmNode = prod.querySelector(":scope > firm");
|
||||||
|
const categoryNode = prod.querySelector(":scope > category");
|
||||||
|
const seriesNode = prod.querySelector(":scope > series");
|
||||||
|
const commentsNode = prod.querySelector(":scope > comments");
|
||||||
|
const sizesNode = prod.querySelector(":scope > sizes");
|
||||||
|
const versionsNode = prod.querySelector(":scope > versions");
|
||||||
|
|
||||||
|
// STREFY
|
||||||
|
const zones = [];
|
||||||
|
|
||||||
|
if(prod.getAttribute("promo") === "yes") zones.push("promotion");
|
||||||
|
if(prod.getAttribute("discount") === "yes") zones.push("discount");
|
||||||
|
if(prod.getAttribute("distinguished") === "yes") zones.push("distinguished");
|
||||||
|
if(prod.getAttribute("special") === "yes") zones.push("special");
|
||||||
|
if(prod.getAttribute("new") === "yes") zones.push("new");
|
||||||
|
if(prod.getAttribute("bestseller") === "yes") zones.push("bestseller");
|
||||||
|
if(prod.getAttribute("subscription") === "yes") zones.push("subscription");
|
||||||
|
|
||||||
|
// ZDJĘCIA
|
||||||
|
const enclosuresImages = [];
|
||||||
|
prod.querySelectorAll(":scope > enclosures > images > enclosure").forEach(img=>{
|
||||||
|
enclosuresImages.push({
|
||||||
|
position: img.getAttribute("position") ?? undefined,
|
||||||
|
type: img.getAttribute("type") ?? undefined,
|
||||||
|
typeSecond: img.getAttribute("type_second") ?? undefined,
|
||||||
|
url: img.getAttribute("url") ?? undefined,
|
||||||
|
urlSecond: img.getAttribute("url_second") ?? undefined,
|
||||||
|
width: img.getAttribute("width") ?? undefined,
|
||||||
|
height: img.getAttribute("height") ?? undefined,
|
||||||
|
iconUrl: img.getAttribute("icon") ?? undefined,
|
||||||
|
iconUrlSecond: img.getAttribute("icon_second") ?? undefined,
|
||||||
|
iconWidth: img.getAttribute("icon_width") ?? undefined,
|
||||||
|
iconHeight: img.getAttribute("icon_height") ?? undefined,
|
||||||
|
mediumUrl: img.getAttribute("medium") ?? undefined,
|
||||||
|
mediumUrlSecond: img.getAttribute("medium_second") ?? undefined,
|
||||||
|
mediumWidth: img.getAttribute("medium_width") ?? undefined,
|
||||||
|
mediumHeight: img.getAttribute("medium_height") ?? undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// SIZES
|
||||||
|
const sizes = [];
|
||||||
|
sizesNode.querySelectorAll(":scope > size").forEach(size=>{
|
||||||
|
const availabilityNode = size.querySelector(":scope > availability");
|
||||||
|
const shippingTimeNode = availabilityNode.querySelector(":scope > shipping_time");
|
||||||
|
const sizePriceNode = size.querySelector(":scope > price");
|
||||||
|
const weightNode = size.querySelector(":scope > weight");
|
||||||
|
|
||||||
|
sizes.push({
|
||||||
|
id: size?.getAttribute("type") ?? undefined,
|
||||||
|
name: size?.getAttribute("name") ?? undefined,
|
||||||
|
code: size?.getAttribute("code") ?? undefined,
|
||||||
|
codeProducer: size?.getAttribute("code_producer") ?? undefined,
|
||||||
|
codeExtern: size?.getAttribute("code_extern") ?? undefined,
|
||||||
|
amount: size?.getAttribute("amount") !== null ? +size.getAttribute("amount") : undefined,
|
||||||
|
amount_mo: size?.getAttribute("amount_mo") !== null ? +size.getAttribute("amount_mo") : undefined,
|
||||||
|
amount_mw: size?.getAttribute("amount_mw") !== null ? +size.getAttribute("amount_mw") : undefined,
|
||||||
|
amount_mp: size?.getAttribute("amount_mp") !== null ? +size.getAttribute("amount_mp") : undefined,
|
||||||
|
weight: weightNode?.getAttribute("g") !== null ? +weightNode.getAttribute("g") : undefined,
|
||||||
|
availability: {
|
||||||
|
visible: availabilityNode?.getAttribute("visible") === "y" ? true : false,
|
||||||
|
description: availabilityNode?.getAttribute("status_description") ?? undefined,
|
||||||
|
status: availabilityNode?.getAttribute("status") ?? undefined,
|
||||||
|
icon: availabilityNode?.getAttribute("status_gfx") ?? undefined,
|
||||||
|
deliveryDate: shippingTimeNode?.getAttribute("today") === "true" ? `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate().toString().padStart(2, 0)}` : availabilityNode?.getAttribute("delivery_date"),
|
||||||
|
minimumStockOfProduct: availabilityNode?.getAttribute("minimum_stock_of_product") ?? undefined,
|
||||||
|
// descriptionTel: "",
|
||||||
|
// iconTel: "",
|
||||||
|
},
|
||||||
|
shipping: {
|
||||||
|
today: shippingTimeNode?.getAttribute("today") === "true" ? true : false,
|
||||||
|
},
|
||||||
|
price: this.xmlGetPriceFromNode(sizePriceNode),
|
||||||
|
// amountWholesale: "",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// VERSIONS
|
||||||
|
const versions = [];
|
||||||
|
versionsNode.querySelectorAll(":scope > version").forEach(ver=>{
|
||||||
|
versions.push({
|
||||||
|
id: ver?.getAttribute("id") !== null ? +ver?.getAttribute("id") : undefined,
|
||||||
|
name: ver?.getAttribute("name") ?? undefined,
|
||||||
|
icon: ver?.getAttribute("gfx") ?? undefined,
|
||||||
|
iconSecond: ver?.getAttribute("gfx_second") ?? undefined,
|
||||||
|
iconSmall: ver?.getAttribute("gfx_small") ?? undefined,
|
||||||
|
iconSmallSecond: ver?.getAttribute("gfx_small_second") ?? undefined,
|
||||||
|
productIcon: ver?.getAttribute("icon") ?? undefined,
|
||||||
|
productIconSecond: ver?.getAttribute("icon_second") ?? undefined,
|
||||||
|
productIconSmall: ver?.getAttribute("icon_small") ?? undefined,
|
||||||
|
productIconSmallSecond: ver?.getAttribute("icon_small_second") ?? undefined,
|
||||||
|
link: ver?.getAttribute("link") ?? undefined,
|
||||||
|
// parameterValues: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// DATA
|
||||||
|
const typeParts = prod.getAttribute("product_type");
|
||||||
|
data.push({
|
||||||
|
id: prod?.getAttribute("id") !== null ? +prod?.getAttribute("id") : undefined,
|
||||||
|
type: typeParts[1] === "item" ? typeParts[0] : typeParts[1],
|
||||||
|
code: prod?.getAttribute("code") ?? undefined,
|
||||||
|
name: prod.querySelector(":scope > name")?.textContent ?? undefined,
|
||||||
|
versionName: prod.querySelector(":scope > versions")?.getAttribute("name") ?? undefined,
|
||||||
|
description: prod.querySelector(":scope > description")?.textContent ?? undefined,
|
||||||
|
// longDescription: prod.querySelector("vlongdescription")?.textContent ?? undefined,
|
||||||
|
// longDescriptionSections: "",
|
||||||
|
link: prod?.getAttribute("link"),
|
||||||
|
zones,
|
||||||
|
icon: prod.querySelector(":scope > icon")?.textContent ?? undefined,
|
||||||
|
iconSecond: prod.querySelector(":scope > icon_second")?.textContent ?? undefined,
|
||||||
|
iconSmall: prod.querySelector(":scope > icon_small")?.textContent ?? undefined,
|
||||||
|
iconSmallSecond: prod.querySelector(":scope > icon_small_second")?.textContent ?? undefined,
|
||||||
|
price: this.xmlGetPriceFromNode(priceNode),
|
||||||
|
unit: {
|
||||||
|
id: sizesNode?.getAttribute("unit_id") ?? undefined,
|
||||||
|
// name: "",
|
||||||
|
singular: sizesNode?.getAttribute("unit_single") !== null ? +sizesNode?.getAttribute("unit_single") : undefined,
|
||||||
|
plural: sizesNode?.getAttribute("unit_plural") ?? undefined,
|
||||||
|
fraction: sizesNode?.getAttribute("unit_fraction") ?? undefined,
|
||||||
|
sellBy: sizesNode?.getAttribute("unit_sellby") !== null ? +sizesNode?.getAttribute("unit_sellby") : undefined,
|
||||||
|
precision: sizesNode?.getAttribute("unit_precision") !== null ? +sizesNode?.getAttribute("unit_precision") : undefined,
|
||||||
|
unitConvertedFormat: sizesNode?.getAttribute("unit_converted_format") ?? undefined,
|
||||||
|
},
|
||||||
|
producer: {
|
||||||
|
id: firmNode?.getAttribute("id") !== null ? +firmNode?.getAttribute("id") : undefined,
|
||||||
|
name: firmNode?.getAttribute("name") ?? undefined,
|
||||||
|
link: firmNode?.getAttribute("productslink") ?? undefined,
|
||||||
|
searchIcons: {
|
||||||
|
icon: firmNode?.getAttribute("icon") ?? undefined,
|
||||||
|
},
|
||||||
|
// projectorIcons: {},
|
||||||
|
},
|
||||||
|
category: {
|
||||||
|
id: categoryNode?.getAttribute("id") !== null ? +categoryNode?.getAttribute("id") : undefined,
|
||||||
|
name: categoryNode?.getAttribute("name") ?? undefined,
|
||||||
|
link: categoryNode?.getAttribute("productslink") ?? undefined
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
id: versionsNode?.getAttribute("id") !== null ? +versionsNode?.getAttribute("id") : undefined,
|
||||||
|
name: versionsNode?.getAttribute("name") ?? undefined,
|
||||||
|
displayAll: versionsNode?.getAttribute("display_all") === "true" ? true : false,
|
||||||
|
link: versionsNode?.getAttribute("link") ?? undefined,
|
||||||
|
versions,
|
||||||
|
groupParameters: this.xmlGetTraitsFromNode(versionsNode.querySelector(":scope > groupParameters"))
|
||||||
|
},
|
||||||
|
opinion: {
|
||||||
|
rating: commentsNode?.getAttribute("avg") !== null ? +commentsNode?.getAttribute("avg") : undefined,
|
||||||
|
count: commentsNode?.getAttribute("count") !== null ? +commentsNode?.getAttribute("count") : undefined,
|
||||||
|
link: commentsNode?.getAttribute("link") ?? undefined
|
||||||
|
},
|
||||||
|
enclosuresImages,
|
||||||
|
// enclosuresAttachments: [],
|
||||||
|
series: {
|
||||||
|
id: seriesNode?.getAttribute("id") !== null ? +seriesNode?.getAttribute("id") : undefined,
|
||||||
|
name: seriesNode?.getAttribute("name") ?? undefined,
|
||||||
|
link: seriesNode?.getAttribute("link") ?? undefined
|
||||||
|
},
|
||||||
|
awardedParameters: this.xmlGetTraitsFromNode(prod.querySelector(":scope > traits")),
|
||||||
|
// parameteresWithContext: [],
|
||||||
|
sizes,
|
||||||
|
points: priceNode?.getAttribute("points") !== null ? +priceNode?.getAttribute("points") : undefined,
|
||||||
|
pointsReceive: priceNode?.getAttribute("points_recive") !== null ? +priceNode?.getAttribute("points_recive") : undefined,
|
||||||
|
// subscription: {},
|
||||||
|
// bundled: [],
|
||||||
|
// responsibleEntity: {},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}catch(err){
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// INICJALIZACJA
|
// INICJALIZACJA
|
||||||
// ========================================================
|
// ========================================================
|
||||||
@@ -1225,6 +1599,10 @@ class IdmHotspot{
|
|||||||
this.initEvents();
|
this.initEvents();
|
||||||
console.log(`Initialized hotspot #${this.id}`);
|
console.log(`Initialized hotspot #${this.id}`);
|
||||||
|
|
||||||
|
// Ustawienie wszystkich zmiennych CSS
|
||||||
|
this.cssSetAllVariables();
|
||||||
|
|
||||||
|
// ca
|
||||||
if(typeof this.options?.callbackFn === "function") this.options?.callbackFn();
|
if(typeof this.options?.callbackFn === "function") this.options?.callbackFn();
|
||||||
}catch(err){
|
}catch(err){
|
||||||
console.error(idmHotspotTextObject["Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"], err);
|
console.error(idmHotspotTextObject["Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"], err);
|
||||||
@@ -1243,7 +1621,7 @@ class IdmHotspot{
|
|||||||
this.initExternalFunctions();
|
this.initExternalFunctions();
|
||||||
try{
|
try{
|
||||||
if(!this.products){
|
if(!this.products){
|
||||||
if(!this?.query?.graphFn || !this?.query?.string) this.setQueryData();
|
if((!this?.query?.graphFn || !this?.query?.string) && !this.source?.link) this.setQueryData();
|
||||||
|
|
||||||
// pobranie danych o produktach
|
// pobranie danych o produktach
|
||||||
await this.getHotspotData();
|
await this.getHotspotData();
|
||||||
@@ -1371,109 +1749,110 @@ class IdmHotspot{
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class IdmSwiperProgress {
|
class IdmSwiperProgress {
|
||||||
constructor(swiper, selector) {
|
constructor(swiper, selector) {
|
||||||
this.swiper = swiper?.slider?.slider ?? swiper?.slider ?? swiper;
|
this.swiper = swiper?.slider?.slider ?? swiper?.slider ?? swiper;
|
||||||
this.selector = selector;
|
this.selector = selector;
|
||||||
this.scrollbarEl = null;
|
this.scrollbarEl = null;
|
||||||
this.progressEl = null;
|
this.progressEl = null;
|
||||||
this.isDragging = false;
|
|
||||||
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
const el = document.querySelector(this.selector);
|
|
||||||
if (!el || el.querySelector(".idm-scrollbar")) return;
|
|
||||||
|
|
||||||
el.insertAdjacentHTML(
|
|
||||||
"beforeend",
|
|
||||||
`<div class="idm-scrollbar swiper-scrollbar"><div class="idm-progress"></div></div>`
|
|
||||||
);
|
|
||||||
|
|
||||||
this.scrollbarEl = el.querySelector(".idm-scrollbar");
|
|
||||||
this.progressEl = this.scrollbarEl.querySelector(".idm-progress");
|
|
||||||
|
|
||||||
this.updateBarWidth();
|
|
||||||
this.addDragTracking();
|
|
||||||
|
|
||||||
this.swiper.on("progress", () => this.updateProgress());
|
|
||||||
this.swiper.on("breakpoint", () => {this.updateBarWidth()});
|
|
||||||
}
|
|
||||||
|
|
||||||
updateBarWidth() {
|
|
||||||
const { slidesPerGroup, slidesPerView } = this.swiper.params;
|
|
||||||
const totalSlides = this.swiper.slides.length;
|
|
||||||
|
|
||||||
const progressWidth = 100 / (((totalSlides - slidesPerView) / slidesPerGroup) + 1);
|
|
||||||
this.progressEl.style.width = `${progressWidth}%`;
|
|
||||||
|
|
||||||
if (progressWidth >= 100 || progressWidth <= 0) this.scrollbarEl.style.display = "none";
|
|
||||||
else this.scrollbarEl.style.display = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
updateProgress() {
|
|
||||||
const progress = this.swiper.progress;
|
|
||||||
const { slidesPerGroup, slidesPerView } = this.swiper.params;
|
|
||||||
const totalSlides = this.swiper.slides.length;
|
|
||||||
|
|
||||||
const progressWidth = 100 / (((totalSlides - slidesPerView) / slidesPerGroup) + 1);
|
|
||||||
const newLeft = (100 - progressWidth) * progress;
|
|
||||||
this.progressEl.style.left = `${Math.min(
|
|
||||||
100 - progressWidth,
|
|
||||||
Math.max(0, newLeft)
|
|
||||||
)}%`;
|
|
||||||
}
|
|
||||||
|
|
||||||
addDragTracking() {
|
|
||||||
const handle = this.progressEl;
|
|
||||||
let grabOffset = 0;
|
|
||||||
let scrollbarWidth = 0;
|
|
||||||
let handleWidth = 0;
|
|
||||||
|
|
||||||
const startDrag = (e) => {
|
|
||||||
this.isDragging = true;
|
|
||||||
this.scrollbarEl.classList.add("--drag-start");
|
|
||||||
|
|
||||||
const rect = this.scrollbarEl.getBoundingClientRect();
|
|
||||||
const handleRect = handle.getBoundingClientRect();
|
|
||||||
scrollbarWidth = rect.width;
|
|
||||||
handleWidth = handleRect.width;
|
|
||||||
|
|
||||||
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
|
|
||||||
grabOffset = clientX - handleRect.left;
|
|
||||||
|
|
||||||
document.addEventListener("mousemove", handleDrag);
|
|
||||||
document.addEventListener("mouseup", stopDrag);
|
|
||||||
document.addEventListener("touchmove", handleDrag);
|
|
||||||
document.addEventListener("touchend", stopDrag);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDrag = (e) => {
|
|
||||||
if (!this.isDragging) return;
|
|
||||||
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
|
|
||||||
const rect = this.scrollbarEl.getBoundingClientRect();
|
|
||||||
let newLeftPx = clientX - rect.left - grabOffset;
|
|
||||||
const maxLeft = scrollbarWidth - handleWidth;
|
|
||||||
newLeftPx = Math.max(0, Math.min(maxLeft, newLeftPx));
|
|
||||||
const progress = newLeftPx / maxLeft;
|
|
||||||
this.swiper.setProgress(progress, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
const stopDrag = () => {
|
|
||||||
if (!this.isDragging) return;
|
|
||||||
this.isDragging = false;
|
this.isDragging = false;
|
||||||
document.removeEventListener("mousemove", handleDrag);
|
|
||||||
document.removeEventListener("mouseup", stopDrag);
|
|
||||||
document.removeEventListener("touchmove", handleDrag);
|
|
||||||
document.removeEventListener("touchend", stopDrag);
|
|
||||||
this.scrollbarEl.classList.remove("--drag-start");
|
|
||||||
this.swiper.slideReset(400);
|
|
||||||
};
|
|
||||||
|
|
||||||
handle.addEventListener("mousedown", startDrag);
|
this.init();
|
||||||
handle.addEventListener("touchstart", startDrag);
|
}
|
||||||
}
|
|
||||||
|
init() {
|
||||||
|
const el = document.querySelector(this.selector);
|
||||||
|
if (!el || el.querySelector(".idm-scrollbar")) return;
|
||||||
|
|
||||||
|
el.insertAdjacentHTML(
|
||||||
|
"beforeend",
|
||||||
|
`<div class="idm-scrollbar swiper-scrollbar"><div class="idm-progress"></div></div>`
|
||||||
|
);
|
||||||
|
|
||||||
|
this.scrollbarEl = el.querySelector(".idm-scrollbar");
|
||||||
|
this.progressEl = this.scrollbarEl.querySelector(".idm-progress");
|
||||||
|
|
||||||
|
this.updateBarWidth();
|
||||||
|
this.addDragTracking();
|
||||||
|
|
||||||
|
this.swiper.on("progress", () => this.updateProgress());
|
||||||
|
this.swiper.on("breakpoint", () => {this.updateBarWidth()});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBarWidth() {
|
||||||
|
const { slidesPerGroup, slidesPerView } = this.swiper.params;
|
||||||
|
const totalSlides = this.swiper.slides.length;
|
||||||
|
|
||||||
|
const progressWidth = 100 / (((totalSlides - slidesPerView) / slidesPerGroup) + 1);
|
||||||
|
this.progressEl.style.width = `${progressWidth}%`;
|
||||||
|
|
||||||
|
if (progressWidth >= 100 || progressWidth <= 0) this.scrollbarEl.style.display = "none";
|
||||||
|
else this.scrollbarEl.style.display = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
updateProgress() {
|
||||||
|
const progress = this.swiper.progress;
|
||||||
|
const { slidesPerGroup, slidesPerView } = this.swiper.params;
|
||||||
|
const totalSlides = this.swiper.slides.length;
|
||||||
|
|
||||||
|
const progressWidth = 100 / (((totalSlides - slidesPerView) / slidesPerGroup) + 1);
|
||||||
|
const newLeft = (100 - progressWidth) * progress;
|
||||||
|
this.progressEl.style.left = `${Math.min(
|
||||||
|
100 - progressWidth,
|
||||||
|
Math.max(0, newLeft)
|
||||||
|
)}%`;
|
||||||
|
}
|
||||||
|
|
||||||
|
addDragTracking() {
|
||||||
|
const handle = this.progressEl;
|
||||||
|
let grabOffset = 0;
|
||||||
|
let scrollbarWidth = 0;
|
||||||
|
let handleWidth = 0;
|
||||||
|
|
||||||
|
const startDrag = (e) => {
|
||||||
|
this.isDragging = true;
|
||||||
|
this.scrollbarEl.classList.add("--drag-start");
|
||||||
|
|
||||||
|
const rect = this.scrollbarEl.getBoundingClientRect();
|
||||||
|
const handleRect = handle.getBoundingClientRect();
|
||||||
|
scrollbarWidth = rect.width;
|
||||||
|
handleWidth = handleRect.width;
|
||||||
|
|
||||||
|
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
|
||||||
|
grabOffset = clientX - handleRect.left;
|
||||||
|
|
||||||
|
document.addEventListener("mousemove", handleDrag);
|
||||||
|
document.addEventListener("mouseup", stopDrag);
|
||||||
|
document.addEventListener("touchmove", handleDrag);
|
||||||
|
document.addEventListener("touchend", stopDrag);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDrag = (e) => {
|
||||||
|
if (!this.isDragging) return;
|
||||||
|
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
|
||||||
|
const rect = this.scrollbarEl.getBoundingClientRect();
|
||||||
|
let newLeftPx = clientX - rect.left - grabOffset;
|
||||||
|
const maxLeft = scrollbarWidth - handleWidth;
|
||||||
|
newLeftPx = Math.max(0, Math.min(maxLeft, newLeftPx));
|
||||||
|
const progress = newLeftPx / maxLeft;
|
||||||
|
this.swiper.setProgress(progress, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopDrag = () => {
|
||||||
|
if (!this.isDragging) return;
|
||||||
|
this.isDragging = false;
|
||||||
|
document.removeEventListener("mousemove", handleDrag);
|
||||||
|
document.removeEventListener("mouseup", stopDrag);
|
||||||
|
document.removeEventListener("touchmove", handleDrag);
|
||||||
|
document.removeEventListener("touchend", stopDrag);
|
||||||
|
this.scrollbarEl.classList.remove("--drag-start");
|
||||||
|
this.swiper.slideReset(400);
|
||||||
|
};
|
||||||
|
|
||||||
|
handle.addEventListener("mousedown", startDrag);
|
||||||
|
handle.addEventListener("touchstart", startDrag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// TOOLTIP
|
// TOOLTIP
|
||||||
// ========================================================
|
// ========================================================
|
||||||
@@ -1511,6 +1890,7 @@ function idmShowTooltip(tooltipEl){
|
|||||||
function idmHideTooltipTimer(tooltipEl){
|
function idmHideTooltipTimer(tooltipEl){
|
||||||
return setTimeout(() => idmHideTooltip(tooltipEl), 1500);
|
return setTimeout(() => idmHideTooltip(tooltipEl), 1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
function idmHideTooltip(tooltipEl){
|
function idmHideTooltip(tooltipEl){
|
||||||
const tooltipContentEl = tooltipEl.querySelector(".idm_tooltip__content");
|
const tooltipContentEl = tooltipEl.querySelector(".idm_tooltip__content");
|
||||||
if (!tooltipContentEl) return;
|
if (!tooltipContentEl) return;
|
||||||
@@ -1526,7 +1906,6 @@ function idmHideTooltip(tooltipEl){
|
|||||||
delete tooltipEl._onScroll;
|
delete tooltipEl._onScroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", ()=>{
|
document.addEventListener("DOMContentLoaded", ()=>{
|
||||||
document.body.addEventListener("click", e=>{
|
document.body.addEventListener("click", e=>{
|
||||||
const tooltipEl = e.target.closest(".idm_tooltip");
|
const tooltipEl = e.target.closest(".idm_tooltip");
|
||||||
@@ -1582,8 +1961,8 @@ async function idmPrepareHotspotObject(selectedContainerEl){
|
|||||||
selectedContainerEl.classList.add("--init");
|
selectedContainerEl.classList.add("--init");
|
||||||
const source = {};
|
const source = {};
|
||||||
|
|
||||||
|
if(selectedContainerEl.dataset?.link) source.link = selectedContainerEl.dataset.link;
|
||||||
if(selectedContainerEl.dataset?.hotspotsType) source.hotspotsType = selectedContainerEl.dataset.hotspotsType;
|
else if(selectedContainerEl.dataset?.hotspotsType) source.hotspotsType = selectedContainerEl.dataset.hotspotsType;
|
||||||
else {
|
else {
|
||||||
if(selectedContainerEl.dataset?.productsId) source.productsId = selectedContainerEl.dataset.productsId.split(",");
|
if(selectedContainerEl.dataset?.productsId) source.productsId = selectedContainerEl.dataset.productsId.split(",");
|
||||||
if(selectedContainerEl.dataset?.productsMenu) source.productsMenu = selectedContainerEl.dataset.productsMenu;
|
if(selectedContainerEl.dataset?.productsMenu) source.productsMenu = selectedContainerEl.dataset.productsMenu;
|
||||||
@@ -1593,7 +1972,6 @@ async function idmPrepareHotspotObject(selectedContainerEl){
|
|||||||
if(selectedContainerEl.dataset?.priceFrom && selectedContainerEl.dataset?.priceTo) source.priceRange = {from: +selectedContainerEl.dataset.priceFrom, to: +selectedContainerEl.dataset.priceTo};
|
if(selectedContainerEl.dataset?.priceFrom && selectedContainerEl.dataset?.priceTo) source.priceRange = {from: +selectedContainerEl.dataset.priceFrom, to: +selectedContainerEl.dataset.priceTo};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(Object.keys(source).length === 0){
|
if(Object.keys(source).length === 0){
|
||||||
console.error();
|
console.error();
|
||||||
selectedContainerEl?.remove();
|
selectedContainerEl?.remove();
|
||||||
@@ -1611,7 +1989,6 @@ async function idmPrepareHotspotObject(selectedContainerEl){
|
|||||||
new IdmHotspot(idmHotspotObj)
|
new IdmHotspot(idmHotspotObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
document.querySelectorAll(".hotspot__wrapper.idm__hotspot").forEach(currentHotspot=>{
|
document.querySelectorAll(".hotspot__wrapper.idm__hotspot").forEach(currentHotspot=>{
|
||||||
idmPrepareHotspotObject(currentHotspot)
|
idmPrepareHotspotObject(currentHotspot)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user