1import NiuBase from "niu-base"; 2 3class NiuQuickBuy extends NiuBase{ 4 static Selectors = { 5 wrapper:(id='')=>{return'[data-niu-sidebar-quickbuy'+(id!==''?'='+id:'')+']'}, 6 wrapperType:'[data-niu-sidebar-content]', 7 productKey:'[data-niu-sidebar-productpreview-trigger]', 8 type:'[data-niu-sidebar-productpreview-type]', 9 currentProduct:"[data-niu-sidebar-currentproduct]", 10 11 variation: "[data-niu-variation]", 12 variationType:"[data-niu-variation-type]", 13 productPreviewImage:"[data-niu-sidebar-productpreview-image]", 14 productPreviewPrice:"[data-niu-sidebar-productpreview-price]", 15 productCheckoutContainer:"[data-niu-sidebar-productpreview-checkout-container]", 16 productPreviewBasket:"[data-niu-sidebar-productpreview-checkout]", 17 productVariationTitle:'[data-niu-sidebar-productpreview-variation-title]', 18 productCheckoutTitle:'[data-niu-sidebar-productpreview-checkout-title]', 19 variationContainer:"[data-niu-sidebar-variation-container]", 20 variationItem: "[data-niu-variation-item]", 21 qtyInput: "[data-niu-sidebar-productpreview-checkout-qtyinput]", 22 qtyUp:"[data-niu-sidebar-productpreview-checkout-qtyupbutton]", 23 qtyDown:"[data-niu-sidebar-productpreview-checkout-qtydownbutton]", 24 pluginSlot:"[data-niu-sidebar-plugin-slot]" 25 26 } 27 28 constructor(wrapper) { 29 super(wrapper); 30 this.type = wrapper.dataset[NiuBase.select(NiuQuickBuy.Selectors.wrapperType)] 31 this.sidebarId = wrapper.dataset[NiuBase.select(NiuQuickBuy.Selectors.wrapper())]; 32 this.product = false; 33 this.productId = ''; 34 this.variations = {}; 35 this.cartButton = ""; 36 this.priceWrapper = ""; 37 this.productImageContainer = ""; 38 this.productPriceContainer = ""; 39 this.productCheckoutContainer = ""; 40 this.productCheckoutBasket = ""; 41 this.productVariationContainer = ""; 42 this.productVariationTitle = ""; 43 this.productCheckoutTitle = ""; 44 this.qtyInput = ""; 45 this.qtyUpBtn = ""; 46 this.qtyDownBtn = ""; 47 } 48 49 init(){ 50 super.init(); 51 this.register(); 52 } 53 54 async getQuickBuyProduct(trigger){ 55 if(!trigger.dataset || !trigger.dataset[NiuBase.select(NiuQuickBuy.Selectors.productKey)]){ 56 this.postError('No productKey in trigger'); 57 return; 58 } 59 60 this.dispatch(dzm.events.sidebar.startLoading); 61 62 const productKey = trigger.dataset[NiuBase.select(NiuQuickBuy.Selectors.productKey)]; 63 64 const body = { 65 kArtikel:productKey 66 }; 67 const endpoint = `${niu.controller.basicData.shopUrl}?niuapi=true&jtl_token=${niu.controller.basicData.jtlToken}&request_type=getProductPreview`; 68 69 let res = await fetch( 70 endpoint,{ 71 method:'POST', 72 body:JSON.stringify(body) 73 }); 74 const contentType = res.headers.get('content-type') 75 76 let result; 77 if(contentType && contentType.includes('application/json')){ 78 result = await res.json() 79 //console.warn('RESULT', result) 80 }else{ 81 result = await res.text() 82 this.postError(result); 83 return 84 } 85 86 87 if(result.data && result.data !== ''){ 88 this.wrapper.innerHTML = result.data; 89 this.initCurrentProduct(true); 90 this.dispatch(dzm.events.quickbuy.loaded) 91 92 }else{ 93 this.postError('unknown template error') 94 } 95 96 this.dispatch(dzm.events.sidebar.stopLoading) 97 98 } 99 100 async getQuickViewProduct(trigger){ 101 if(!trigger.dataset || !trigger.dataset[NiuBase.select(NiuQuickBuy.Selectors.productKey)]){ 102 this.postError('No productKey in trigger'); 103 return; 104 } 105 106 this.dispatch(dzm.events.sidebar.startLoading); 107 108 const productKey = trigger.dataset[NiuBase.select(NiuQuickBuy.Selectors.productKey)]; 109 110 const body = { 111 kArtikel:productKey 112 }; 113 const endpoint = `${niu.controller.basicData.shopUrl}?niuapi=true&jtl_token=${niu.controller.basicData.jtlToken}&request_type=getProductQuickView`; 114 115 let res = await fetch( 116 endpoint,{ 117 method:'POST', 118 body:JSON.stringify(body) 119 }); 120 const contentType = res.headers.get('content-type') 121 122 let result; 123 if(contentType && contentType.includes('application/json')){ 124 result = await res.json() 125 //console.warn('RESULT', result) 126 }else{ 127 result = await res.text() 128 this.postError(result); 129 return 130 } 131 132 133 if(result.data && result.data !== ''){ 134 this.wrapper.innerHTML = result.data; 135 this.dispatch(dzm.events.quickView.loaded, trigger) 136 }else{ 137 this.postError('unknown template error') 138 } 139 140 this.dispatch(dzm.events.sidebar.stopLoading) 141 142 } 143
144 initCurrentProduct(first = false){ 145 this.product = this.wrapper.querySelector(NiuQuickBuy.Selectors.currentProduct); 146 this.productId = this.product.dataset[NiuBase.select(NiuQuickBuy.Selectors.currentProduct)]; 147 this.productImageContainer = this.product.querySelector(NiuQuickBuy.Selectors.productPreviewImage) 148 this.productPriceContainer = this.product.querySelector(NiuQuickBuy.Selectors.productPreviewPrice) 149 this.productCheckoutBasket = this.product.querySelector(NiuQuickBuy.Selectors.productPreviewBasket) 150 this.productCheckoutContainer = this.product.querySelector(NiuQuickBuy.Selectors.productCheckoutContainer) 151 this.productVariationContainer = this.product.querySelector(NiuQuickBuy.Selectors.variationContainer) 152 this.productVariationTitle = this.product.querySelector(NiuQuickBuy.Selectors.productVariationTitle) 153 this.productCheckoutTitle = this.product.querySelector(NiuQuickBuy.Selectors.productCheckoutTitle) 154 // Slot fuer Beitraege von Zusatzplugins - optional, nicht jede Sidebar hat ihn 155 this.pluginSlot = this.product.querySelector(NiuQuickBuy.Selectors.pluginSlot) 156 157 this.getAllVariations(); 158 159 if(first){ 160 this.initQtyBtns() 161 //this is just a trick to trigger first time a variation selection, so if there is only one choice, it should load the child with this option 162 this.variationSelected(null,null,'SELECTBOX').then(result =>{ 163 return result 164 }) 165 } 166 167 } 168 169 getAllVariations(){ 170 const variations = this.product.querySelectorAll(NiuQuickBuy.Selectors.variation) 171 variations.forEach(v =>{ 172 const variation = v.dataset[NiuBase.select(NiuQuickBuy.Selectors.variation)] 173 const variationType = v.dataset[NiuBase.select(NiuQuickBuy.Selectors.variationType)] 174 175 this.variations['v'+variation] = v 176 this.variations['v'+variation].variationType = variationType 177 this.variations['v'+variation].variationItems = { } 178 const variationItems = v.querySelectorAll(NiuQuickBuy.Selectors.variationItem) 179 if(variationType === 'SELECTBOX'){ 180 v.addEventListener('change',async (e)=>{ 181 182 await this.variationSelected(e,null,variationType) 183 }) 184 } 185 variationItems.forEach(vi=>{ 186 const variationItem = vi.dataset[NiuBase.select(NiuQuickBuy.Selectors.variationItem)]; 187 if(variationItem){ 188 this.variations['v'+variation].variationItems['vi'+variationItem.split(':')[1]] = vi 189 190 } 191 if(variationType !== 'SELECTBOX'){ 192 vi.addEventListener('click',async (e)=>{ 193 194 await this.variationSelected(e,vi,variationType) 195 }) 196 } 197 198 }) 199 }) 200 } 201 202 initQtyBtns(){ 203 this.qtyInput = this.product.querySelector(NiuQuickBuy.Selectors.qtyInput) 204 this.qtyUpBtn = this.product.querySelector(NiuQuickBuy.Selectors.qtyUp) 205 if(this.qtyUpBtn){ 206 this.qtyUpBtn.addEventListener('click',(e)=>{ 207 this.updateQty(e,'up') 208 }) 209 } 210 211 this.qtyDownBtn = this.product.querySelector(NiuQuickBuy.Selectors.qtyDown) 212 if(this.qtyDownBtn){ 213 this.qtyDownBtn.addEventListener('click',(e)=>{ 214 this.updateQty(e,'down') 215 }) 216 } 217 } 218 219 updateQty(e,type){ 220 let step = 1 221 if(this.qtyInput.step === 'any'){ 222 if(type === 'up'){ 223 this.qtyInput.value++; 224 }else{ 225 this.qtyInput.value--; 226 } 227 228 }else{ 229 if(type === 'up'){ 230 this.qtyInput.stepUp(); 231 }else{ 232 this.qtyInput.stepDown(); 233 } 234 } 235 236 } 237 238 async variationSelected(e,vi,type){ 239 let body = {} 240 body.kArtikel = this.productId 241 body.selectedVariations = {} 242 243 244 245 246 247 248 if(type !== 'SELECTBOX'){ 249 vi.checked = true 250 } 251
252 Object.values(this.variations).forEach(vg=>{ 253 const variationType = vg.dataset[NiuBase.select(NiuQuickBuy.Selectors.variationType)] 254 255 if(variationType === 'SELECTBOX' && vg.selectedOptions && vg.selectedOptions.length > 0){ 256 257 const variationItem = vg.selectedOptions[0].dataset[NiuBase.select(NiuQuickBuy.Selectors.variationItem)] 258 if(variationItem){ 259 let variationSelection = variationItem.split(':') 260 body.selectedVariations[variationSelection[0]] = variationSelection[1] 261 } 262 263 }else{ 264 Object.values(vg.variationItems).forEach(vi=>{ 265 const variationItem = vi.dataset[NiuBase.select(NiuQuickBuy.Selectors.variationItem)] 266 // Pessimistische Vormarkierung: Alle Varianten gelten als nicht 267 // waehlbar, bis die Antwort unten sagt, welche moeglich sind. 268 // 'not-in-stock' und nicht 'sold-out' - der Kern trifft dieselbe 269 // Unterscheidung (jtl.article.js:1592: notExists -> not-in-stock, 270 // sonst sold-out). Hier geht es immer um "gibt es in dieser 271 // Kombination nicht", nie um echten Ausverkauf. 272 vi.parentElement.classList.add('swatches-not-in-stock') 273 if(vi.checked){ 274 vi.parentElement.classList.add('active') 275 let variationSelection = variationItem.split(':') 276 body.selectedVariations[variationSelection[0]] = variationSelection[1] 277 }else{ 278 vi.parentElement.classList.remove('active') 279 } 280 281 //vi.disabled = true 282 283 }) 284 } 285 286 287 }) 288 289 290 291 292 const endpoint = `${niu.controller.basicData.shopUrl}?niuapi=true&jtl_token=${niu.controller.basicData.jtlToken}&request_type=variationSelected`; 293 294 let res = await fetch(endpoint,{ 295 method:'POST', 296 body:JSON.stringify(body) 297 }) 298 299 const contentType = res.headers.get('content-type') 300 let result; 301 if(contentType && contentType.includes('application/json')){ 302 result = await res.json() 303 //console.log(result) 304 }else{ 305 result = await res.text(); 306 //console.error(result) 307 return; 308 } 309 310 //window.response = result 311 312 if('data' in result && 'childProductImage' in result.data && 'childProductPrice' in result.data && 'childProductBasket' in result.data){ 313 this.productImageContainer.innerHTML = result.data.childProductImage; 314 this.productPriceContainer.innerHTML = result.data.childProductPrice; 315 this.productCheckoutBasket.innerHTML = result.data.childProductBasket; 316 this.productVariationContainer.innerHTML = result.data.childProductVariations; 317 this.productCheckoutTitle.innerHTML = result.data.childProductTitle; 318 if(this.pluginSlot && 'childProductPluginSlot' in result.data){ 319 this.pluginSlot.innerHTML = result.data.childProductPluginSlot; 320 } 321 if(this.productVariationTitle){ 322 this.productVariationTitle.innerHTML = result.data.childProductVariationTitleBox; 323 } 324 this.initCurrentProduct(); 325 this.initQtyBtns(); 326 327 //(NiuTemplateController.getInstance()).reInitScripts(constants.scriptSets.io); 328 console.log('REAL SELECTION') 329 this.dispatch(dzm.events.quickbuy.variationSelected) 330 331 332 } 333 334 Object.entries(result.data.possibleVariations).forEach((v)=>{ 335 336 v[1].forEach(val=>{ 337 this.variations['v'+v[0]].variationItems['vi'+val].parentElement.classList.remove('swatches-not-in-stock') 338 //this.variations['v'+v[0]].variationItems['vi'+val].disabled = false 339 }) 340 }) 341 342 if(result.data.hasInvalidSelection){ 343 document.querySelector('[data-niu-sidebar-currentproduct-variationwarning]')?.classList.remove('d-none'); 344 }else{ 345 document.querySelector('[data-niu-sidebar-currentproduct-variationwarning]')?.classList.add('d-none'); 346 347 } 348 349 //Needed for custom select box
350 $.evo.article().variationRefreshAll(); 351 } 352 353 postError(message){ 354 this.wrapper.innerHTML = '<div class="container"><strong>Ups...da ist etwas schief gelaufen</strong></div>' 355 console.error(message); 356 this.dispatch(dzm.events.sidebar.stopLoading) 357 } 358 359 register(){ 360 if(this.type === 'quickBuy'){ 361 NiuBase.listenTo([ 362 dzm.events.quickbuy.triggered 363 ],async (data)=>{ 364 if('content' in data && (data.content === 'quickBuy')){ 365 if('trigger' in data && data.trigger !== null){ 366 console.log('FIRE GETQUICKBUYPRODUCT') 367 await this.getQuickBuyProduct(data.trigger); 368 }else{ 369 console.error('No trigger element in data') 370 } 371 } 372 373 }); 374 }else if(this.type === 'quickView'){ 375 376 NiuBase.listenTo([ 377 dzm.events.quickView.triggered 378 ],async (data)=>{ 379 if('content' in data && (data.content === 'quickView')){ 380 if('trigger' in data && data.trigger !== null){ 381 await this.getQuickViewProduct(data.trigger); 382 }else{ 383 console.error('No trigger element in data') 384 } 385 } 386 387 }); 388 }else{ 389 console.error('â ï¸ unknown type for quickbuy sidebar', this.type, this) 390 } 391 } 392} 393 394NiuBase.listenTo([ 395 dzm.events.controller.initialized 396],()=>{ 397 NiuQuickBuy.Scan(); 398})
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.