Samsung Galaxy A13 4GB/64GB (Light Blue) Details

  • The best price of Samsung Galaxy A13 4GB/64GB (Light Blue) by grandstores in UAE is 659 AED
  • This product is reviewed by 1 users, and its average rating is
      (4/5)
    • Similar products to Samsung Galaxy A13 4GB/64GB (Light Blue) are sold at grandstores with prices starting at 659 AED
    • The first appearance of this product was on Dec 07, 2022

    Similar Products

    Store

    Payment methods

    Delivery Time

    Delivery Fees

    grandstores's Description

    function initPrice6323() { return { regularPriceKey: 'oldPrice', finalPriceKey: 'finalPrice', activeProductsPriceData: false, initialFinalPrice: 589, calculatedFinalPrice: false, calculatedFinalPriceWithCustomOptions: false, initialTierPrices: [], showRegularPriceLabel: true, customOptionPrices: [], activeCustomOptions: [], qty: 1, updateCustomOptionActive(data) { let activeCustomOptions = this.activeCustomOptions; const customOptionId = data.customOptionId; if (data.active) { if (!activeCustomOptions.includes(customOptionId)) { activeCustomOptions.push(data.customOptionId); } } else { if (customOptionId && activeCustomOptions.includes(customOptionId)) { let index = activeCustomOptions.indexOf(customOptionId); activeCustomOptions.splice(index, 1); } } this.calculateFinalPriceWithCustomOptions() }, updateCustomOptionPrices(prices) { if (prices) { this.customOptionPrices = prices; } this.calculateFinalPriceWithCustomOptions(); }, calculateFinalPrice() { let finalPrice = this.initialFinalPrice; if (this.activeProductsPriceData && this.activeProductsPriceData.tierPrices) { finalPrice = this.activeProductsPriceData.tierPrices.reduce((finalValue, tierPrice) => { if (this.qty >= tierPrice.qty) { return tierPrice.price < finalValue ? tierPrice.price : finalValue; } return finalValue; }, this.activeProductsPriceData[this.finalPriceKey].amount); } else { finalPrice = Object.values(this.initialTierPrices).reduce((finalValue, tierPrice) => { if (this.qty >= tierPrice.price_qty) { return parseFloat(tierPrice.website_price) < finalValue ? parseFloat(tierPrice.website_price) : finalValue; } return finalValue; }, finalPrice); } this.calculatedFinalPrice = finalPrice; window.dispatchEvent( new CustomEvent( "update-product-final-price", {detail: this.calculatedFinalPrice} ) ); }, calculatePriceLabelVisibility() { this.showRegularPriceLabel = ( (this.calculatedFinalPrice === this.activeProductsPriceData[this.regularPriceKey].amount) && this.activeProductsPriceData.isMinimalPrice ); }, calculateFinalPriceWithCustomOptions() { let finalPrice = this.calculatedFinalPrice || this.initialFinalPrice; this.calculatedFinalPriceWithCustomOptions = finalPrice + this.getCustomOptionPrice(); }, getCustomOptionPrice() { return this.activeCustomOptions.reduce((priceAccumulator, activeCustomOptionId) => { const customOptionPrice = this.customOptionPrices[activeCustomOptionId]; if (customOptionPrice) { return Number.parseFloat(priceAccumulator) + Number.parseFloat(customOptionPrice); } return priceAccumulator; }, 0); }, getFormattedFinalPrice() { return hyva.formatPrice( this.calculatedFinalPriceWithCustomOptions || this.calculatedFinalPrice || this.initialFinalPrice ) }, isPriceHidden() { const finalPrice = this.calculatedFinalPriceWithCustomOptions || this.calculatedFinalPrice || this.initialFinalPrice; return false && finalPrice === 0; }, eventListeners: { ['@update-prices-6323.window'](event) { this.activeProductsPriceData = event.detail; this.calculateFinalPrice(); this.calculateFinalPriceWithCustomOptions(); this.calculatePriceLabelVisibility(); }, ['@update-qty-6323.window'](event) { this.qty = event.detail; this.calculateFinalPrice(); this.calculateFinalPriceWithCustomOptions(); }, ['@update-custom-option-active.window'](event) { this.updateCustomOptionActive(event.detail); }, ['@update-custom-option-prices.window'](event) { this.updateCustomOptionPrices(event.detail); } } } }
    AED 659.00
    AED 589.00Save 10%
    function initPrice6323() { return { regularPriceKey: 'oldPrice', finalPriceKey: 'finalPrice', activeProductsPriceData: false, initialFinalPrice: 589, calculatedFinalPrice: false, calculatedFinalPriceWithCustomOptions: false, initialTierPrices: [], showRegularPriceLabel: true, customOptionPrices: [], activeCustomOptions: [], qty: 1, updateCustomOptionActive(data) { let activeCustomOptions = this.activeCustomOptions; const customOptionId = data.customOptionId; if (data.active) { if (!activeCustomOptions.includes(customOptionId)) { activeCustomOptions.push(data.customOptionId); } } else { if (customOptionId && activeCustomOptions.includes(customOptionId)) { let index = activeCustomOptions.indexOf(customOptionId); activeCustomOptions.splice(index, 1); } } this.calculateFinalPriceWithCustomOptions() }, updateCustomOptionPrices(prices) { if (prices) { this.customOptionPrices = prices; } this.calculateFinalPriceWithCustomOptions(); }, calculateFinalPrice() { let finalPrice = this.initialFinalPrice; if (this.activeProductsPriceData && this.activeProductsPriceData.tierPrices) { finalPrice = this.activeProductsPriceData.tierPrices.reduce((finalValue, tierPrice) => { if (this.qty >= tierPrice.qty) { return tierPrice.price < finalValue ? tierPrice.price : finalValue; } return finalValue; }, this.activeProductsPriceData[this.finalPriceKey].amount); } else { finalPrice = Object.values(this.initialTierPrices).reduce((finalValue, tierPrice) => { if (this.qty >= tierPrice.price_qty) { return parseFloat(tierPrice.website_price) < finalValue ? parseFloat(tierPrice.website_price) : finalValue; } return finalValue; }, finalPrice); } this.calculatedFinalPrice = finalPrice; window.dispatchEvent( new CustomEvent( "update-product-final-price", {detail: this.calculatedFinalPrice} ) ); }, calculatePriceLabelVisibility() { this.showRegularPriceLabel = ( (this.calculatedFinalPrice === this.activeProductsPriceData[this.regularPriceKey].amount) && this.activeProductsPriceData.isMinimalPrice ); }, calculateFinalPriceWithCustomOptions() { let finalPrice = this.calculatedFinalPrice || this.initialFinalPrice; this.calculatedFinalPriceWithCustomOptions = finalPrice + this.getCustomOptionPrice(); }, getCustomOptionPrice() { return this.activeCustomOptions.reduce((priceAccumulator, activeCustomOptionId) => { const customOptionPrice = this.customOptionPrices[activeCustomOptionId]; if (customOptionPrice) { return Number.parseFloat(priceAccumulator) + Number.parseFloat(customOptionPrice); } return priceAccumulator; }, 0); }, getFormattedFinalPrice() { return hyva.formatPrice( this.calculatedFinalPriceWithCustomOptions || this.calculatedFinalPrice || this.initialFinalPrice ) }, isPriceHidden() { const finalPrice = this.calculatedFinalPriceWithCustomOptions || this.calculatedFinalPrice || this.initialFinalPrice; return false && finalPrice === 0; }, eventListeners: { ['@update-prices-6323.window'](event) { this.activeProductsPriceData = event.detail; this.calculateFinalPrice(); this.calculateFinalPriceWithCustomOptions(); this.calculatePriceLabelVisibility(); }, ['@update-qty-6323.window'](event) { this.qty = event.detail; this.calculateFinalPrice(); this.calculateFinalPriceWithCustomOptions(); }, ['@update-custom-option-active.window'](event) { this.updateCustomOptionActive(event.detail); }, ['@update-custom-option-prices.window'](event) { this.updateCustomOptionPrices(event.detail); } } } }
    AED 659.00
    AED 589.00Save 10%

    In stock

    SKU: 102-1276-000598
    function initQtyField() { function findPathParam(key) { // get all path pairs after BASE_URL/front_name/action_path/action const baseUrl = (BASE_URL.substr(0, 2) === '//' ? 'http:' : '') + BASE_URL; const baseUrlParts = (new URL(baseUrl)).pathname.replace(/\/$/, '').split('/'); const pathParts = window.location.pathname.split('/').slice(baseUrlParts.length + 3); for (let i = 0; i < pathParts.length; i += 2) { if (pathParts[i] === key && pathParts.length > i) { return pathParts[i + 1]; } } } return { qty: 1, itemId: (new URLSearchParams(window.location.search)).get('id') || findPathParam('id'), productId: '6323', onGetCartData: function onGetCartData(data, $dispatch) { const cart = data && data.data && data.data.cart; if (this.itemId && cart && cart.items) { const cartItem = cart.items.find((item) => { return item.item_id === this.itemId && item.product_id === this.productId; }); if (cartItem && cartItem.qty) { this.qty = cartItem.qty; $dispatch('update-qty-' + this.productId, this.qty); } } } }; }
    Qty
    +
    function initWishlist_64546d9190180() { return { addToWishlist(productId) { const postParams = { action: BASE_URL + "wishlist/index/add/", data: { product: productId, uenc: hyva.getUenc() } } postParams.data['form_key'] = hyva.getFormKey(); postParams.data['qty'] = document.getElementById(`qty[${productId}]`) ? document.getElementById(`qty[${productId}]`).value || 1 : 1; let postData = Object.keys(postParams.data).map(key => { return `${key}=${postParams.data[key]}`; }).join('&';; // take the all the input fields that configure this product // includes custom, configurable, grouped and bundled options Array.from(document.querySelectorAll( '[name^=options], [name^=super_attribute], [name^=bundle_option], [name^=super_group], [name^=links]') ).map(input => { if (input.type === "select-multiple") { Array.from(input.selectedOptions).forEach(option => { postData += `&${input.name}=${option.value}` }) } else { // skip "checkable inputs" that are not checked if(!(['radio', 'checkbox', 'select'].includes(input.type) && !input.checked)) { postData += `&${input.name}=${input.value}` } } }); fetch(postParams.action, { "headers": { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", }, "body": postData, "method": "POST", "mode": "cors", "credentials": "include" }).then((response) => { if (response.redirected) { window.location.href = response.url; } else if (response.ok) { return response.json(); } else { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "warning", text: "Could not add item to wishlist." }], 5000 ); } }).then((response) => { if (!response) { return; } typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: (response.success) ? "success" : "error", text: (response.success) ? "Product has been added to your Wish List." : response.error_message }], 5000 ); const reloadCustomerDataEvent = new CustomEvent("reload-customer-section-data"); window.dispatchEvent(reloadCustomerDataEvent); }).catch((error) => { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "error", text: error }], 5000 ); }); } } } function initCompareOnProductView() { return { addToCompare: function (productId) { const formKey = hyva.getFormKey(); const postUrl = BASE_URL + 'catalog/product_compare/add/'; fetch(postUrl, { "headers": { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", }, "body": "form_key=" + formKey + "&product=" + productId + "&uenc=" + hyva.getUenc(), "method": "POST", "mode": "cors", "credentials": "include" }).then(function (response) { if (response.redirected) { window.location.href = response.url; } }).catch(function (error) { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "error", text: error }], 5000 ); }); } }; } compare
    shareable icon
    • Facebook iconFacebook
    • Tweet iconTweet
    • Email iconEmail

    Product Details

    Samsung Galaxy A13

    Minimalist design with striking style

    Galaxy A13 combines soft colours with a look and feel that’s gentle to the touch. Refined curves make it comfortable to hold and provides easy screen navigation. Choose from Black, White, Blue, and Peach colours.

    More display means more room to play

    Expand your view to the 6.6-inch Infinity-V Display of Galaxy A13 and see what you've been missing. And with FHD+ technology, your everyday content looks sharp, crisp and clear.

    Multi Camera System

    Upgrade your mobile photography with Quad Camera

    Snap memorable moments in clear detail with the 50MP Main Camera. Expand viewing angle with Ultra Wide Camera. Customise focus with Depth Camera, or get closer to details with Macro Camera.

    Front camera

    Stylish selfies

    With the Galaxy A13's 8MP Front Camera and bokeh effect, it's easy to snap stunning selfies that feature more you and less background.

    Depth Camera

    Bring the focus to the front with Depth Camera

    The 2MP Depth Camera lets you adjust the depth of field in your photos. Adjust the background blur for high-quality portrait shots that make your subject truly stand out.

    Macro Camera

    Capture smaller details with Macro Camera

    Galaxy A03 combines classic colors with a look and feel thats gentle to the touch. Refined curves make it comfortable to hold and provide easy screen navigation. Choose from Black, White, Red or Blue colors.

    Ultra Wide Camera

    Ultra wide experiences

    Similar to human eyesight, the 5MP Ultra Wide Camera sees the world with a 123-degree angle of view, adding more perspective to everything you shoot.

    Multi Camera System

    Upgrade your mobile photography with Quad Camera

    Snap memorable moments in clear detail with the 50MP Main Camera. Expand viewing angle with Ultra Wide Camera. Customise focus with Depth Camera, or get closer to details with Macro Camera.

    Awesome battery, lasts two days

    Stay ahead of the day with a battery that won't slow you down. The 5,000mAh (typical) battery lets you keep doing what you do, for hours on end.

    Speed up and store more

    The Galaxy A13 combines Octa-core processing power with up to 3GB/4GB/6GB of RAM for fast and efficient performance for the task at hand. Enjoy 32GB/64GB/128GB of internal storage and add up to 1TB more with MicroSD card.

    Samsung Members

    Keep your device in tip-top condition with us

    When you buy a Samsung Galaxy smartphone, it comes with perks. Samsung Members app gives you interactive diagnostics and optimisation features to tune up your device's performance, while our helpline talks you through troubleshooting problems when you need the extra assistance.

    <

    One UI

    Your Galaxy. Your Way

    Own something truly yours. Customise your Galaxy with One UI Core 4 and give your phone an edgy look to match your vibes. Create a bespoke tool that assists your tasks seamlessly and makes your favorite features readily accessible.

    Security

    Protect what matters to you

    Built into the phone's hardware and software from the start, Samsung Knox protects your phone from the minute it's turned on. Offering multi-layered security, it defends your most sensitive information from malware and malicious threats.

    Dolby Atmos

    Simply plug in your earphones to be transported to the middle of your music and movies. With Dolby Atmos, you'll hear sound that's full, rich, and spatial, as if you're inside the scene.

    More Information

    ColoursLight Blue
    Item Weight340g
    Write Your Own Review
    Only registered users can write reviews. Please Sign in or create an account
    "use strict"; function initMobileSticky() { return { cartItemCount: 0, getCartItemCount(data) { if (data.cart) { this.cartItemCount = data.cart.summary_count; } } } }
    • compare
    • wishlist
    • account
    {"@context":"http:\/\/schema.org","@type":"Product","name":"Samsung Galaxy A13 4GB\/64GB (Light Blue)","sku":"102-1276-000598","model":"Samsung Galaxy A13 4GB\/64GB (Light Blue)","description":"\r\n\r\n\r\n\r\nModel:\r\n\r\n\r\nSM-A137FLBGMEA\r\n\r\n\r\n\r\n\r\nBattery Capacity:\r\n\r\n\r\n5000 mAh\r\n\r\n\r\n\r\n\r\nProcessor:\r\n\r\n\r\nMediaTek G80\r\n\r\n\r\n\r\n\r\nRear \/ Front Camera:\r\n\r\n\r\n50 + 5 + 2 + 2 MP \/ 8 MP\r\n\r\n\r\n\r\n\r\nScreen Size: \r\n\r\n\r\n6.6 Inches\r\n\r\n\r\n\r\n\r\nCPU:       \r\n\r\n\r\nOcta-Core 2.2 GHz\r\n\r\n\r\n\r\n","gtin8":"102-1276-000598","offers":{"@type":"Offer","url":"https:\/\/shop.grandstores.ae\/en\/samsung-galaxy-a13-4gb-64gb-sm-a137flbgmea-light-blue.html","price":"589.00","priceCurrency":"AED","priceValidUntil":"2023-05-31 ","sku":"102-1276-000598","gtin":"102-1276-000598"}}
    'use strict'; function initSliderComponent() { return { active: 0, itemCount: 0, shown: false, getSlider() { return this.$el.querySelector('.js_slides'); }, pageSize: 4, pageFillers: 0, calcPageSize() { const slider = this.getSlider(); if (slider) { this.itemCount = slider.querySelectorAll('.js_slide').length; this.pageSize = Math.round(slider.clientWidth / slider.querySelector('.js_slide').clientWidth); this.pageFillers = ( this.pageSize * Math.ceil(this.itemCount / this.pageSize) ) - this.itemCount; } }, calcActive() { const slider = this.getSlider(); if (slider) { const sliderItems = this.itemCount + this.pageFillers; const calculatedActiveSlide = slider.scrollLeft / (slider.scrollWidth / sliderItems); this.active = Math.round(calculatedActiveSlide / this.pageSize) * this.pageSize; } }, scrollPrevious() { this.scrollTo(this.active - this.pageSize); }, scrollNext() { this.scrollTo(this.active + this.pageSize); }, scrollTo(idx) { const slider = this.getSlider(); if (slider) { const slideWidth = slider.scrollWidth / (this.itemCount + this.pageFillers); slider.scrollLeft = Math.floor(slideWidth) * idx; this.active = idx; } } } }

    Related Products

    Quick View
    (0)
    BELKIN 1.2M Universal Cable (3 IN 1) - Lighning - Micro & Type C - BLACK
    function initPriceBox__64546b8f36dd2() { return { updatePrice(priceData) { const regularPriceLabel = this.$el.querySelector('.normal-price .price-label'); const regularPriceElement = this.$el.querySelector('.normal-price .price-wrapper .price'); if (priceData.finalPrice.amount < priceData.oldPrice.amount) { regularPriceLabel.classList.add('hidden'); } else { regularPriceLabel.classList.remove('hidden'); } regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount); } } }
    AED 79.00
    Add to Wish List Add to Compare
    AED 79.00

    Availability: In stock

    Add to Cart
    Free Delivery
    Quick View
    (0)
    Kenu Airframe Magnetic Car Vent Smartphone Mount - (AF5-KK-NA )
    function initPriceBox__64546d91a058f() { return { updatePrice(priceData) { const regularPriceLabel = this.$el.querySelector('.normal-price .price-label'); const regularPriceElement = this.$el.querySelector('.normal-price .price-wrapper .price'); if (priceData.finalPrice.amount < priceData.oldPrice.amount) { regularPriceLabel.classList.add('hidden'); } else { regularPriceLabel.classList.remove('hidden'); } regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount); } } }
    AED 69.00
    Add to Wish List Add to Compare
    AED 69.00

    Availability: In stock

    Add to Cart
    Quick View
    (0)
    BELKIN Boost Charge Dual USB-A Port Car Charger 24W - Black (BKN-CCB001BTBK)
    function initPriceBox__64546d91a6752() { return { updatePrice(priceData) { const regularPriceLabel = this.$el.querySelector('.normal-price .price-label'); const regularPriceElement = this.$el.querySelector('.normal-price .price-wrapper .price'); if (priceData.finalPrice.amount < priceData.oldPrice.amount) { regularPriceLabel.classList.add('hidden'); } else { regularPriceLabel.classList.remove('hidden'); } regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount); } } }
    AED 49.00
    Add to Wish List Add to Compare
    AED 49.00

    Availability: In stock

    Add to Cart
    Quick View
    (0)
    BELKIN Boost Charge Dual USB-A Car Charger 24W + 1Meter Lightning to USB-A Cable - Black (BKN-CCD001BT1MBK)
    function initPriceBox__64546d91ab1fe() { return { updatePrice(priceData) { const regularPriceLabel = this.$el.querySelector('.normal-price .price-label'); const regularPriceElement = this.$el.querySelector('.normal-price .price-wrapper .price'); if (priceData.finalPrice.amount < priceData.oldPrice.amount) { regularPriceLabel.classList.add('hidden'); } else { regularPriceLabel.classList.remove('hidden'); } regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount); } } }
    AED 99.00
    Add to Wish List Add to Compare
    AED 99.00

    Availability: In stock

    Add to Cart
    prev arrownext arrow
    'use strict'; window.addEventListener('DOMContentLoaded', function() { if (! window.productSliderEventHandlerInitialized) { window.productSliderEventHandlerInitialized = true; window.addEventListener('product-add-to-wishlist', (event) => { const formKey = hyva.getFormKey(); const postUrl = BASE_URL + 'wishlist/index/add/'; const productId = event.detail.productId; fetch(postUrl, { "headers": { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", }, "body": "form_key=" + formKey + "&product=" + productId + "&uenc=" + hyva.getUenc(), "method": "POST", "mode": "cors", "credentials": "include" }).then(function (response) { if (response.redirected) { window.location.href = response.url; } else if (response.ok) { return response.json(); } else { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "warning", text: "Could not add item to wishlist." }], 5000 ); } }).then(function (result) { if (!result) { return } typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: (result.success) ? "success" : "error", text: (result.success) ? "Product has been added to your Wish List." : result.error_message }], 5000 ); window.dispatchEvent(new CustomEvent("reload-customer-section-data")); }).catch(function (error) { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "error", text: error }], 5000 ); }); }) window.addEventListener('product-add-to-compare', (event) => { const productId = event.detail.productId; hyva.postForm({ action: BASE_URL + 'catalog/product_compare/add/', data: {product: productId} }) }) } });
    'use strict'; function initSliderComponent() { return { active: 0, itemCount: 0, shown: false, getSlider() { return this.$el.querySelector('.js_slides'); }, pageSize: 4, pageFillers: 0, calcPageSize() { const slider = this.getSlider(); if (slider) { this.itemCount = slider.querySelectorAll('.js_slide').length; this.pageSize = Math.round(slider.clientWidth / slider.querySelector('.js_slide').clientWidth); this.pageFillers = ( this.pageSize * Math.ceil(this.itemCount / this.pageSize) ) - this.itemCount; } }, calcActive() { const slider = this.getSlider(); if (slider) { const sliderItems = this.itemCount + this.pageFillers; const calculatedActiveSlide = slider.scrollLeft / (slider.scrollWidth / sliderItems); this.active = Math.round(calculatedActiveSlide / this.pageSize) * this.pageSize; } }, scrollPrevious() { this.scrollTo(this.active - this.pageSize); }, scrollNext() { this.scrollTo(this.active + this.pageSize); }, scrollTo(idx) { const slider = this.getSlider(); if (slider) { const slideWidth = slider.scrollWidth / (this.itemCount + this.pageFillers); slider.scrollLeft = Math.floor(slideWidth) * idx; this.active = idx; } } } }

    Customer Also Viewed

    11% OFF
    Quick View
    (0)
    Samsung Galaxy A53 6GB/128GB (Awesome Blue)
    function initPriceBox__64546d91b1ace() { return { updatePrice(priceData) { const regularPriceLabel = this.$el.querySelector('.normal-price .price-label'); const regularPriceElement = this.$el.querySelector('.normal-price .price-wrapper .price'); if (priceData.finalPrice.amount < priceData.oldPrice.amount) { regularPriceLabel.classList.add('hidden'); } else { regularPriceLabel.classList.remove('hidden'); } regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount); } } }
    Special PriceAED 1,376.00Regular PriceAED 1,549.00
    Add to Wish List Add to Compare
    Special PriceAED 1,376.00Regular PriceAED 1,549.00

    Availability: In stock

    Add to Cart
    9% OFF
    Quick View
    (0)
    Samsung Galaxy A53 5G 8GB/256GB (Awesome Blue)
    function initPriceBox__64546d91b5b84() { return { updatePrice(priceData) { const regularPriceLabel = this.$el.querySelector('.normal-price .price-label'); const regularPriceElement = this.$el.querySelector('.normal-price .price-wrapper .price'); if (priceData.finalPrice.amount < priceData.oldPrice.amount) { regularPriceLabel.classList.add('hidden'); } else { regularPriceLabel.classList.remove('hidden'); } regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount); } } }
    Special PriceAED 1,576.00Regular PriceAED 1,749.00
    Add to Wish List Add to Compare
    Special PriceAED 1,576.00Regular PriceAED 1,749.00

    Availability: In stock

    Add to Cart
    11% OFF
    Quick View
    (0)
    Samsung Galaxy A53 6GB/128GB (Awesome Black)
    function initPriceBox__64546d91b9c39() { return { updatePrice(priceData) { const regularPriceLabel = this.$el.querySelector('.normal-price .price-label'); const regularPriceElement = this.$el.querySelector('.normal-price .price-wrapper .price'); if (priceData.finalPrice.amount < priceData.oldPrice.amount) { regularPriceLabel.classList.add('hidden'); } else { regularPriceLabel.classList.remove('hidden'); } regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount); } } }
    Special PriceAED 1,376.00Regular PriceAED 1,549.00
    Add to Wish List Add to Compare
    Special PriceAED 1,376.00Regular PriceAED 1,549.00

    Availability: In stock

    Add to Cart
    prev arrownext arrow
    'use strict'; window.addEventListener('DOMContentLoaded', function() { if (! window.productSliderEventHandlerInitialized) { window.productSliderEventHandlerInitialized = true; window.addEventListener('product-add-to-wishlist', (event) => { const formKey = hyva.getFormKey(); const postUrl = BASE_URL + 'wishlist/index/add/'; const productId = event.detail.productId; fetch(postUrl, { "headers": { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", }, "body": "form_key=" + formKey + "&product=" + productId + "&uenc=" + hyva.getUenc(), "method": "POST", "mode": "cors", "credentials": "include" }).then(function (response) { if (response.redirected) { window.location.href = response.url; } else if (response.ok) { return response.json(); } else { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "warning", text: "Could not add item to wishlist." }], 5000 ); } }).then(function (result) { if (!result) { return } typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: (result.success) ? "success" : "error", text: (result.success) ? "Product has been added to your Wish List." : result.error_message }], 5000 ); window.dispatchEvent(new CustomEvent("reload-customer-section-data")); }).catch(function (error) { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "error", text: error }], 5000 ); }); }) window.addEventListener('product-add-to-compare', (event) => { const productId = event.detail.productId; hyva.postForm({ action: BASE_URL + 'catalog/product_compare/add/', data: {product: productId} }) }) } });
    .cmsb233-mb-4 { margin-bottom: 1rem } .cmsb233-border-b { border-bottom-width: 1px } .cmsb233-border-444444 { --tw-border-opacity: 1; border-color: rgba(68, 68, 68, var(--tw-border-opacity)) } .cmsb233-py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem } .cmsb233-pb-4 { padding-bottom: 1rem } .cmsb233-text-14 { font-size: 0.875rem } .cmsb233-font-bold { font-weight: 700 } .cmsb233-capitalize { text-transform: capitalize } .cmsb233-text-888888 { --tw-text-opacity: 1; color: rgba(136, 136, 136, var(--tw-text-opacity)) } .cmsb233-text-white { --tw-text-opacity: 1; color: rgba(255, 255, 255, var(--tw-text-opacity)) } @media (min-width: 768px) { .cmsb233-md\:pointer-events-none { pointer-events: none } .cmsb233-md\:mb-6 { margin-bottom: 1.5rem } .cmsb233-md\:border-0 { border-width: 0px } .cmsb233-md\:py-0 { padding-top: 0px; padding-bottom: 0px } .cmsb233-md\:pb-0 { padding-bottom: 0px } }
    Categories
    • Photos and Videos
    • Mobiles
    • IT & Multimedia
    • Home Appliances
    • Luggage
    .cmsb235-mb-4 { margin-bottom: 1rem } .cmsb235-border-b { border-bottom-width: 1px } .cmsb235-border-444444 { --tw-border-opacity: 1; border-color: rgba(68, 68, 68, var(--tw-border-opacity)) } .cmsb235-py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem } .cmsb235-pb-4 { padding-bottom: 1rem } .cmsb235-text-14 { font-size: 0.875rem } .cmsb235-font-bold { font-weight: 700 } .cmsb235-capitalize { text-transform: capitalize } .cmsb235-text-888888 { --tw-text-opacity: 1; color: rgba(136, 136, 136, var(--tw-text-opacity)) } .cmsb235-text-white { --tw-text-opacity: 1; color: rgba(255, 255, 255, var(--tw-text-opacity)) } @media (min-width: 768px) { .cmsb235-md\:pointer-events-none { pointer-events: none } .cmsb235-md\:mb-6 { margin-bottom: 1.5rem } .cmsb235-md\:border-0 { border-width: 0px } .cmsb235-md\:border-b-0 { border-bottom-width: 0px } .cmsb235-md\:py-0 { padding-top: 0px; padding-bottom: 0px } .cmsb235-md\:pb-0 { padding-bottom: 0px } }
    Customer Services
    • About Us
    • Contact Us
    • FAQ
    • Store Location
    • Advanced Search
    .cmsb234-mb-4 { margin-bottom: 1rem } .cmsb234-border-b { border-bottom-width: 1px } .cmsb234-border-444444 { --tw-border-opacity: 1; border-color: rgba(68, 68, 68, var(--tw-border-opacity)) } .cmsb234-py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem } .cmsb234-pb-4 { padding-bottom: 1rem } .cmsb234-text-14 { font-size: 0.875rem } .cmsb234-font-bold { font-weight: 700 } .cmsb234-capitalize { text-transform: capitalize } .cmsb234-text-888888 { --tw-text-opacity: 1; color: rgba(136, 136, 136, var(--tw-text-opacity)) } .cmsb234-text-white { --tw-text-opacity: 1; color: rgba(255, 255, 255, var(--tw-text-opacity)) } @media (min-width: 768px) { .cmsb234-md\:pointer-events-none { pointer-events: none } .cmsb234-md\:mb-6 { margin-bottom: 1.5rem } .cmsb234-md\:border-0 { border-width: 0px } .cmsb234-md\:border-b-0 { border-bottom-width: 0px } .cmsb234-md\:py-0 { padding-top: 0px; padding-bottom: 0px } .cmsb234-md\:pb-0 { padding-bottom: 0px } }
    Information
    • My Account
    • Order Tracking
    • Wish List
    • Terms and Condition
    • Payment Methods
    • Grand Times Magazine
    .cmsb232-mb-4 { margin-bottom: 1rem } .cmsb232-py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem } .cmsb232-pb-4 { padding-bottom: 1rem } .cmsb232-text-14 { font-size: 0.875rem } .cmsb232-font-bold { font-weight: 700 } .cmsb232-capitalize { text-transform: capitalize } .cmsb232-text-888888 { --tw-text-opacity: 1; color: rgba(136, 136, 136, var(--tw-text-opacity)) } .cmsb232-text-white { --tw-text-opacity: 1; color: rgba(255, 255, 255, var(--tw-text-opacity)) } @media (min-width: 768px) { .cmsb232-md\:pointer-events-none { pointer-events: none } .cmsb232-md\:mb-6 { margin-bottom: 1.5rem } .cmsb232-md\:py-0 { padding-top: 0px; padding-bottom: 0px } .cmsb232-md\:pb-0 { padding-bottom: 0px } }
    Policies
    • Privacy Policy
    • Exchange & Return Policy
    • Orders and Returns
    .cmsb223-relative { position: relative } .cmsb223-mb-5 { margin-bottom: 1.25rem } .cmsb223-mb-7 { margin-bottom: 1.75rem } .cmsb223-mb-4 { margin-bottom: 1rem } .cmsb223-mb-1 { margin-bottom: 0.25rem } .cmsb223-pl-6 { padding-left: 1.5rem } .cmsb223-pl-8 { padding-left: 2rem } .cmsb223-text-20 { font-size: 1.25rem } .cmsb223-text-12 { font-size: 0.75rem } .cmsb223-text-14 { font-size: 0.875rem } .cmsb223-font-bold { font-weight: 700 } .cmsb223-text-white { --tw-text-opacity: 1; color: rgba(255, 255, 255, var(--tw-text-opacity)) } .cmsb223-text-888888 { --tw-text-opacity: 1; color: rgba(136, 136, 136, var(--tw-text-opacity)) } @media (min-width: 768px) { .cmsb223-md\:pl-8 { padding-left: 2rem } .cmsb223-md\:pl-9 { padding-left: 2.25rem } .cmsb223-md\:text-24 { font-size: 1.5rem } .cmsb223-md\:text-14 { font-size: 0.875rem } }
    Grand Stores LLC
    • Grand Stores, 'M'Level , Saleh Bin Lahej Building, Al Garhoud, Dubai, UAE, P.O.Box 2144
    • hello@grandstores.ae

    To inquire, please call us on

    800 Grands

    800 472637

    Copyrights © 2023 All rights reserved for GrandStores
    function initAuthenticationBss() { return { open: false, openLogin : false, openRegister : false, openForgot : false, openCreate : true, passwordsMatching: true, openMessage: false, errors: 0, message: "", hasCaptchaToken: 0, openButtonLogin : false, openButtonRegister : false, openSuccessMessage : false, checkPasswordsMatch() { if (document.getElementById('password').value === document.getElementById('password-confirmation').value) { this.passwordsMatching = true; return true; } this.passwordsMatching = false; return false; }, submitForm: function () { const $form = document.querySelector('#login-form'); if (this.errors === 0) { this.dispatchLoginRequest($form); } }, submitForgotForm : function () { const $form = document.querySelector('#fotgot-form'); if (this.errors === 0) { this.dispatchForgotRequest($form); } }, submitRegisterForm : function () { const $form = document.querySelector('#create-form'); if (this.errors === 0) { this.dispatchRegisterRequest($form); } }, validateCaptcha : function () { return new Promise((resolve, reject) => { var executeGreCaptcha = () => { grecaptcha.ready(function () { grecaptcha.execute('', {action: 'submit'}).then(function (token) { return resolve(token); }); }); } if (window.grecaptcha) { executeGreCaptcha(); } else { const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=&hl=en"; const script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script.setAttribute('src', recaptchaUrl); document.head.appendChild(script); script.addEventListener("load", executeGreCaptcha, false); } }); }, dispatchLoginRequest:async function (form) { let token = await this.validateCaptcha(); if(token) { document.getElementById("g-recaptcha-response").setAttribute('value',token); } const username = this.$refs['customer-email'].value; const password = this.$refs['customer-password'].value; const recaptchaValue = document.getElementById("g-recaptcha-response").value; const postUrl = "https://shop.grandstores.ae/en/sociallogin/popup/login/"; fetch(postUrl, { headers: { contentType: "application/x-www-form-urlencoded; charset=UTF-8", }, body: new URLSearchParams({ username: username, password: password, ['g-recaptcha-response']: recaptchaValue, form_key: hyva.getFormKey(), }), method: "POST", mode: "cors", credentials: "include", }).then(response => { return response.json() } ).then(data => { this.isLoading = false; if (data.error) { this.message = data.message; this.openMessage = true; this.errors = 1; this.hasCaptchaToken = 0; } else { this.message = data.message; this.openMessage = false; this.openSuccessMessage = true; if (data.redirect !== '' && data.redirect != null) { window.location.href = data.redirect; } else { location.reload(true); } } }); }, dispatchForgotRequest:async function (form) { let token = await this.validateCaptcha(); if (token) { document.getElementById("g-recaptcha-response").setAttribute('value', token); } const email = form.querySelector("#email_address").value; const recaptchaValue = document.getElementById("g-recaptcha-response").value; const postUrl = "https://shop.grandstores.ae/en/sociallogin/popup/forgot/"; fetch(postUrl, { headers: { contentType: "application/x-www-form-urlencoded; charset=UTF-8", }, body: new URLSearchParams({ email: email, ['g-recaptcha-response']: recaptchaValue, form_key: hyva.getFormKey(), }), method: "POST", mode: "cors", credentials: "include", }).then(response => { return response.json() } ).then(data => { this.isLoading = false; if (data.error) { this.message = data.message; this.openMessage = true; this.errors = 1; this.hasCaptchaToken = 0; } else { if (data.redirect !== '' && data.redirect != null) { window.location.href = data.redirect; } else { location.reload(true); } } }); }, dispatchRegisterRequest:async function (form) { let token = await this.validateCaptcha(); if (token) { document.getElementById("g-recaptcha-response").setAttribute('value', token); } const firstname = form.querySelector("#firstname").value; const lastname = form.querySelector("#lastname").value; const email = form.querySelector("#email_address").value; const password = form.querySelector("#password").value; const passwordConfirmation = form.querySelector("#password-confirmation").value; const recaptchaValue = document.getElementById("g-recaptcha-response").value; const postUrl = "https://shop.grandstores.ae/en/sociallogin/popup/create/"; fetch(postUrl, { headers: { contentType: "application/x-www-form-urlencoded; charset=UTF-8", }, body: new URLSearchParams({ ['g-recaptcha-response']: recaptchaValue, firstname: firstname, lastname: lastname, email: email, password: password, password_confirmation: passwordConfirmation, form_key: hyva.getFormKey(), }), method: "POST", mode: "cors", credentials: "include", }).then(response => { return response.json() } ).then(data => { this.isLoading = false; if (data.error) { this.message = data.message; this.openMessage = true; this.hasCaptchaToken = 0; } else { this.message = data.message; this.openMessage = false; this.openSuccessMessage = true; if (data.redirect !== '' && data.redirect != null) { window.location.href = data.redirect; } else { location.reload(true); } } }); } } }

    Social Login

    • Login with Facebook
    • Login with Google

    Social Register

    • Register with Facebook
    • Register with Google
    var classLogin = ["#login-main-social-login","#login-popup-social-login","#registration-main-social-login"]; var classRegister = [".form-create-accountss"]; // classLogin = classLogin[0].trim().split(/\s+/); classRegister = classRegister[0].trim().split(/\s+/); if(classLogin && classLogin.length > 0 && classLogin[0]){ classLogin.forEach(element => { var classLoginElement = document.querySelector(element); var loginSocialButton = document.getElementById('add_button_login_byclass'); if (classLoginElement && loginSocialButton) { const cloneLoginSocialButton = loginSocialButton.cloneNode(true); classLoginElement.appendChild(cloneLoginSocialButton); cloneLoginSocialButton.style.display='block'; } }); } if(classRegister && classRegister.length > 0 && classRegister[0]){ classRegister.forEach(element => { var classRegisterElement = document.querySelector(element); var registerSocialButton = document.getElementById('add_button_register_byclass'); if (classRegisterElement && registerSocialButton) { const cloneRegisterSocialButton = registerSocialButton.cloneNode(true); classRegisterElement.appendChild(cloneRegisterSocialButton); cloneRegisterSocialButton.style.display='block'; } }); } function bssButtonSocial() { return { renderShowmore : function (element) { var socialButton = element.querySelector('.sociallogin-clearfix').getElementsByTagName("li"); for (let i = 0; i <= socialButton.length - 1; i++) { socialButton[i].style.display = 'block'; } element.querySelector('.sociallogin-showmore').style.display = 'none'; }, popupSocial: function (element) { var href = element.getAttribute('data-href'); var width = element.getAttribute('data-width'); var height = element.getAttribute('data-height'); var popup_window = null; if (!width) { width = 650; } if(!height) { height = 350; } var left = parseInt((window.innerWidth- width) / 2); var top = parseInt((window.innerHeight - height) / 2); var params = [ 'resizable=yes', 'scrollbars=no', 'toolbar=no', 'menubar=no', 'location=no', 'directories=no', 'status=yes', 'width='+ width, 'height='+ height, 'left='+ left, 'top='+ top ]; if(popup_window) { popup_window.close(); } if(href) { popup_window = window.open(href,'',params.join(',')); popup_window.focus(); }else{ alert('This Login Application was not configured correctly. Please contact our customer support.'); } return false; } } } if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/' + "service-worker.js"); } Add to Home Screen window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); const addBtn = document.getElementById("ad2hs-prompt"); let deferredPrompt = e; addBtn.style.display = 'block'; addBtn.addEventListener('click', (e) => { // hide our user interface that shows our A2HS button addBtn.style.display = 'none'; // Show the prompt deferredPrompt.prompt(); // Wait for the user to respond to the prompt deferredPrompt.userChoice.then((choiceResult) => { if (choiceResult.outcome === 'accepted') { console.log('User accepted the A2HS prompt'); } else { console.log('User dismissed the A2HS prompt'); } deferredPrompt = null; }); }); }); var Tawk_API={}; var Tawk_LoadStart=new Date(); (function(){ var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0]; s1.async=true; s1.src='https://embed.tawk.to/5d52a98f77aa790be32eb2ca/default'; s1.charset='UTF-8'; s1.setAttribute('crossorigin','*'); s0.parentNode.insertBefore(s1,s0); })(); (function () { "use strict"; const DIRECTIVE = "intersect"; const X_ATTR_RE = /^x-([a-z-]*)\b/i; function parseHtmlAttribute(reference) { const name = reference.name; const value = reference.value; const typeMatch = name.match(X_ATTR_RE); const valueMatch = name.match(/:([a-zA-Z0-9\-:]+)/); const modifiers = name.match(/\.[^.\]]+(?=[^\]]*$)/g) || []; return { type: typeMatch ? typeMatch[1] : null, value: valueMatch ? valueMatch[1] : null, modifiers: modifiers.map((i) => i.replace(".", "")), expression: value, }; } function getXDirectives(el) { return Array.from(el.attributes) .filter(function (attr) { return X_ATTR_RE.test(attr.name); }) .map(parseHtmlAttribute); } if (window.Alpine) { console.error("Intersect plugin must be included before AlpineJs, x-intersect will not work."); } const getLengthValue = (rawValue) => { // Supported: -10px, -20 (implied px), 30 (implied px), 40px, 50% let match = rawValue.match(/^(-?[0-9]+)(px|%)?$/) return match ? match[1] + (match[2] || 'px') : undefined } const getRootMargin = (modifiers) => { const key = 'margin' const fallback = '0px 0px 0px 0px' const index = modifiers.indexOf(key) // If the modifier isn't present, use the default. if (index === -1) return fallback // Grab the 4 subsequent length values after it: x-intersect.margin.300px.0.50%.0 let values = [] for (let i = 1; i < 5; i++) { values.push(getLengthValue(modifiers[index + i] || '')) } // Filter out undefined values (not a valid length) values = values.filter((v) => v !== undefined) return values.length ? values.join(' ').trim() : fallback } const getThreshhold = (modifiers) => { if (modifiers.includes("full")) return 0.8; if (modifiers.includes("half")) return 0.5; return 0; }; const AlpineIntersectionDirective = { start: function start() { Alpine.onBeforeComponentInitialized(function (component) { const legacyResolveBoundAttributes = component.resolveBoundAttributes; component.resolveBoundAttributes = function (el, initialUpdate, extraVars) { if (initialUpdate === void 0) { initialUpdate = false; } if (initialUpdate) { const attrs = getXDirectives(el); attrs.forEach(function (reference) { const type = reference.type; const expression = reference.expression; const value = reference.value; const modifiers = reference.modifiers; if (type === DIRECTIVE) { const options = { rootMargin: getRootMargin(modifiers), threshold: getThreshhold(modifiers), }; if ("IntersectionObserver" in window) { const observer = new IntersectionObserver((elements) => { elements.forEach((element) => { // Ignore element if intersecting in leave mode, // or not intersecting in enter mode if (element.isIntersecting === (value === 'leave')) return component.evaluateReturnExpression(el, expression, extraVars); modifiers.includes("once") && observer.disconnect(); }); }, options); observer.observe(el); } else { component.evaluateReturnExpression(el, expression, extraVars); } } }); } return legacyResolveBoundAttributes.bind(component)(el, initialUpdate, extraVars); }; }); }, }; const initAlpine = window.deferLoadingAlpine || ((callback) => callback()); window.deferLoadingAlpine = (callback) => { AlpineIntersectionDirective.start(); initAlpine(callback); }; })(); 'use strict'; function dispatchMessages(messages, hideAfter) { const messagesEvent = new CustomEvent("messages-loaded", { detail: { messages: messages, hideAfter: hideAfter } }); window.dispatchEvent(messagesEvent); } if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); } (function( hyva, undefined ) { hyva.initFormKey = () => { const inputSelector = 'input[name="form_key"]', formKey = hyva.getFormKey(); Array.from(document.querySelectorAll(inputSelector)).map(function (input) { input.value = formKey }); } hyva.initMessages = () => { try { const messages = hyva.getCookie('mage-messages'); window.mageMessages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : []; dispatchMessages(window.mageMessages); // empty `mage-messages` cookie const skipSetDomain = true; hyva.setCookie('mage-messages','', -1, skipSetDomain); } catch (error) { console.warn('Error parsing Cookie Messages:', error); } } window.addEventListener('DOMContentLoaded', hyva.initFormKey); window.addEventListener('load', hyva.initMessages); }( window.hyva = window.hyva || {} )); 'use strict'; { const private_content_key = 'mage-cache-storage'; const private_content_expire_key = 'mage-cache-timeout'; const private_content_version_key = 'private_content_version'; const section_data_ids_key = 'section_data_ids'; const mage_cache_session_id_key = 'mage-cache-sessid'; const last_visited_store_key = 'last_visited_store'; const ttl = 3600; if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); } function loadSectionData () { const browserStorage = hyva.getBrowserStorage(); if (!browserStorage) { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "warning", text: "Please enable LocalStorage in your browser." }] ); return; } try { let isInvalid = false; if (hyva.getCookie(last_visited_store_key) !== CURRENT_STORE_CODE) { isInvalid = true; } hyva.setCookie(last_visited_store_key, CURRENT_STORE_CODE, false, false); if (!hyva.getCookie(mage_cache_session_id_key)) { isInvalid = true; const skipSetDomain = true; const days = false; hyva.setCookie(mage_cache_session_id_key, true, days, skipSetDomain) } const cookieVersion = hyva.getCookie(private_content_version_key); const storageVersion = browserStorage.getItem(private_content_version_key); if (cookieVersion && !storageVersion || cookieVersion !== storageVersion) { isInvalid = true; } const privateContentExpires = browserStorage.getItem(private_content_expire_key); if (privateContentExpires && new Date(privateContentExpires) < new Date()) { browserStorage.removeItem(private_content_key); } if (isInvalid) { fetchPrivateContent([]); } else if (cookieVersion && storageVersion && cookieVersion === storageVersion) { const privateContent = JSON.parse(browserStorage.getItem(private_content_key)); if ( privateContent && privateContentExpires && privateContent.cart && privateContent.customer ) { dispatchPrivateContent(privateContent); } else { fetchPrivateContent([]); } } else { dispatchPrivateContent({}); } } catch (error) { console.warn('Error retrieving Private Content:', error); } } window.addEventListener('load', loadSectionData); window.addEventListener('reload-customer-section-data', loadSectionData); function dispatchPrivateContent(data) { const privateContentEvent = new CustomEvent("private-content-loaded", { detail: { data: data } }); window.dispatchEvent(privateContentEvent); } function fetchPrivateContent(sections) { fetch(`${BASE_URL}customer/section/load/?sections=${encodeURIComponent(sections.join(','))}`, { method: 'GET', headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => response.json()) .then( data => { if (data) { try { const browserStorage = hyva.getBrowserStorage(); // merge new data preserving non-invalidated sections const oldSectionData = JSON.parse(browserStorage.getItem(private_content_key) || '{}'); if ((! data.cart || ! data.cart.cartId) && oldSectionData['checkout-data']) { delete oldSectionData['checkout-data']; } const newSectionData = Object.assign(oldSectionData, data); dispatchPrivateContent(newSectionData); // don't persist messages, they've been dispatched already if (newSectionData.messages && newSectionData.messages.messages ) { newSectionData.messages.messages = []; } browserStorage.setItem(private_content_key, JSON.stringify(newSectionData)); const expiresAt = new Date(Date.now() + (ttl * 1000)).toISOString(); browserStorage.setItem(private_content_expire_key, expiresAt); const newCookieVersion = hyva.getCookie(private_content_version_key); browserStorage.setItem(private_content_version_key, newCookieVersion); // We don't need the section_data_ids in Hyvä, but we store them for compatibility // with Luma Fallback. Otherwise, not all sections are loaded in Luma Checkout hyva.setCookie( section_data_ids_key, JSON.stringify( Object.keys(data).reduce((sectionDataIds, sectionKey) => { sectionDataIds[sectionKey] = data[sectionKey]['data_id']; return sectionDataIds; }, {}) ), false, true ); } catch (error) { console.warn("Couldn't store privateContent", error); } } } ); } } (() => { document.addEventListener('submit', event => event.target.action = event.target.action.replace('%25uenc%25', hyva.getUenc())); })() function initCompareOnProductList() { return { addToCompare(productId) { const formKey = hyva.getFormKey(); const postUrl = BASE_URL + 'catalog/product_compare/add/'; fetch(postUrl, { "headers": { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", }, "body": "form_key=" + formKey + "&product=" + productId + "&uenc=" + hyva.getUenc(), "method": "POST", "mode": "cors", "credentials": "include" }).then(function (response) { if (response.redirected) { window.location.href = response.url; } }).catch(function (error) { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "error", text: error }], 5000 ); }); } }; } function initWishlist() { return { addToWishlist(productId) { const formKey = hyva.getFormKey(); const postUrl = BASE_URL + 'wishlist/index/add/'; fetch(postUrl, { "headers": { "content-type": "application/x-www-form-urlencoded; charset=UTF-8", }, "body": "form_key=" + formKey + "&product=" + productId + "&uenc=" + hyva.getUenc(), "method": "POST", "mode": "cors", "credentials": "include" }).then(function (response) { if (response.redirected) { window.location.href = response.url; } else if (response.ok) { return response.json(); } else { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "warning", text: "Could not add item to wishlist." }], 5000 ); } }).then(function (response) { if (!response) { return } typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: (response.success) ? "success" : "error", text: (response.success) ? "Product has been added to your Wish List." : response.error_message }], 5000 ); const reloadCustomerDataEvent = new CustomEvent("reload-customer-section-data"); window.dispatchEvent(reloadCustomerDataEvent); }).catch(function (error) { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( [{ type: "error", text: error }], 5000 ); }); } } } function initConfigurableOptions(productId, optionConfig) { function findPathParam(key) { const baseUrl = (BASE_URL.substr(0, 2) === '//' ? 'http:' : '') + BASE_URL; const baseUrlParts = (new URL(baseUrl)).pathname.replace(/\/$/, '').split('/'); const pathParts = window.location.pathname.split('/').slice(baseUrlParts.length + 3); for (let i = 0; i < pathParts.length; i += 2) { if (pathParts[i] === key && pathParts.length > i) { return pathParts[i + 1]; } } } return { optionConfig, productId, itemId: (new URLSearchParams(window.location.search)).get('id') || findPathParam('id'), allowedAttributeOptions: [], selectedValues: [], init() { this.findAllowedAttributeOptions(); this.$nextTick(() => { if (typeof this.optionConfig.defaultValues === 'object') { for (const [optionId, value] of Object.entries(this.optionConfig.defaultValues)) { this.changeOption(optionId, value + ''); } } }); }, findSimpleIndex() { this.productIndex = this.calculateSimpleIndexForPartialSelection(this.selectedValues); }, calculateSimpleIndexForPartialSelection(selectedValues) { if (selectedValues.length === 0) return 0; let productIndexIds = Object.keys(this.optionConfig.index); Object.keys(this.optionConfig.attributes).forEach((attribute) => { const productsWithAttributeMatch = selectedValues[attribute] ? productIndexIds.filter((productIndex) => { return this.optionConfig.index[productIndex][attribute] === this.selectedValues[attribute] }) : []; productIndexIds = productsWithAttributeMatch.length ? productsWithAttributeMatch : productIndexIds }) return productIndexIds[0]; }, calculateSimpleIndexForFullSelection(selectedValues) { const productIndexes = this.optionConfig.index; return Object.keys(productIndexes).find(productIndex => { const productCandidateOptions = productIndexes[productIndex]; for (const productOption in productCandidateOptions) { if ( ! selectedValues[productOption] || selectedValues[productOption] !== productCandidateOptions[productOption] ) { return false; } } return productIndex; }); }, productIndex: 0, findAllowedAttributeOptions() { this.allowedAttributeOptions = this.calculateAllowedAttributeOptions(this.selectedValues); }, calculateAllowedAttributeOptions(selectedValues) { const allAttributes = this.optionConfig.attributes; const allAttributesSorted = Object.values(allAttributes).sort((a,b) => { return a.position - b.position }); const productIndexes = this.optionConfig.index; let previousOption = false; let availableIndexes = Object.keys(productIndexes); const newAllowedAttributeOptions = []; allAttributesSorted.forEach(attribute => { if (previousOption && selectedValues[previousOption]) { availableIndexes = availableIndexes.filter(availableIndex => { return productIndexes[availableIndex][previousOption] === selectedValues[previousOption] }) } newAllowedAttributeOptions[attribute.id] = allAttributes[attribute.id].options.filter(option => { return !!option.products.find(product => { return availableIndexes.includes(product); }) }); previousOption = attribute.id; }); return newAllowedAttributeOptions; }, findAttributeByOptionId(optionId) { for (const attributeId in this.optionConfig.attributes) { const attributeOptions = this.optionConfig.attributes[attributeId].options || []; if (attributeOptions.find(option => option.id === optionId)) { return attributeId; } } }, getAllowedAttributeOptions(attributeId) { return this.allowedAttributeOptions[attributeId] || [] }, getProductIdsForOption(option) { const attributeId = this.findAttributeByOptionId(option.id); const allOptions = this.optionConfig.attributes[attributeId]; const opt = (allOptions && allOptions.options || []).find(o => o.id === option.id); return opt && opt.products ? opt.products : []; }, findProductIdsForPartialSelection(optionSelection) { const candidateProducts = Object.values(optionSelection).reduce((candidates, optionId) => { const newCandidates = this.getProductIdsForOption({id: optionId}); return candidates === null ? newCandidates : candidates.filter(productId => newCandidates.includes(productId)); }, null); return candidateProducts || []; }, findCheapestProductForPartialSelection(optionSelection) { const candidateProducts = this.findProductIdsForPartialSelection(optionSelection); return candidateProducts.reduce((cheapest, simpleIdx) => { // in the first iteration we start with simpleIdx as the currently cheapest product if (! this.optionConfig.optionPrices[cheapest]) return simpleIdx; const knownCheapestPrice = this.optionConfig.optionPrices[cheapest].finalPrice.amount; return knownCheapestPrice > this.optionConfig.optionPrices[simpleIdx].finalPrice.amount ? simpleIdx : cheapest; }, 0) }, findProductIdToUseForOptionPrice(option) { // try to find a product for a complete selection const attributeId = this.findAttributeByOptionId(option.id); const optionSelection = Object.assign({}, this.selectedValues, {[attributeId]: option.id}); const matchingSimpleIndex = this.calculateSimpleIndexForFullSelection(optionSelection); // if there is no complete selection, use the cheapest product for the option return matchingSimpleIndex || this.findCheapestProductForPartialSelection(optionSelection); }, getAttributeOptionLabel(option) { const optionProduct = this.findProductIdToUseForOptionPrice(option); if ((! optionProduct) || (optionProduct === this.productIndex)) { return option.label; } const currentPrice = this.getOptionPriceAdjustmentBasePrice(); if (this.optionConfig.optionPrices[optionProduct]) { const optionPrice = this.optionConfig.optionPrices[optionProduct].finalPrice.amount; if (optionPrice !== currentPrice){ return option.label + ' ' + hyva.formatPrice(optionPrice - currentPrice, true); } } return option.label; }, getOptionPriceAdjustmentBasePrice() { if (this.optionConfig.optionPrices[this.productIndex]) { return this.optionConfig.optionPrices[this.productIndex].finalPrice.amount } const cheapestForSelection = this.findCheapestProductForPartialSelection(this.selectedValues); return this.optionConfig.optionPrices[cheapestForSelection] ? this.optionConfig.optionPrices[cheapestForSelection].finalPrice.amount : this.optionConfig.prices.finalPrice.amount; // default price if no option selection }, changeOption(optionId, value) { if (value === '') { // create new array so the length property is reset if no option is selected (avoiding delete) this.selectedValues = this.selectedValues.reduce((newSelection, val, opt) => { if (opt !== optionId) { newSelection[opt] = val; } return newSelection; }, []); } else { this.selectedValues[optionId] = value; } this.findSimpleIndex(); this.findAllowedAttributeOptions(); this.updatePrices(); this.updateGallery(); window.dispatchEvent( new CustomEvent( 'configurable-selection-changed', { detail: { productId: this.productId, optionId: optionId, value: value, productIndex: this.productIndex, selectedValues: this.selectedValues, candidates: this.findProductIdsForPartialSelection(this.selectedValues), } } ) ); }, calculateIsMinimalPrice() { return ( this.selectedValues.filter(value => !!value).length < Object.keys(this.optionConfig.attributes).length ); }, updatePrices() { const value = this.productIndex ? this.optionConfig.optionPrices[this.productIndex] : this.optionConfig.prices; window.dispatchEvent( new CustomEvent( "update-prices-" + this.productId, { detail: Object.assign( value, { isMinimalPrice: this.calculateIsMinimalPrice() } ) } ) ); }, updateGallery () { if (this.productIndex) { const images = this.optionConfig.images[this.productIndex]; images && window.dispatchEvent(new CustomEvent( "update-gallery", { detail: this.sortImagesByPosition(images) } )); } else { window.dispatchEvent(new Event("reset-gallery")); } }, sortImagesByPosition(images) { return images.sort((x, y) => { return x.position === y.position ? 0 : (parseInt(x.position) > parseInt(y.position) ? 1 : -1) }); }, onGetCartData(data) { this.preselectCartItems(data); this.preselectQuerystringItems(); this.preselectLocationHashItems(); }, preselectCartItems(data) { // pre-select options based on cart data for current (quote) itemId const cart = data && data.cart; if (cart && cart.items) { const cartItem = cart.items.find((item) => { return ( item.item_id === this.itemId && item.product_id === this.productId ) }); if (cartItem && cartItem.options && cartItem.options.length) { cartItem.options.map(option => { this.changeOption(option.option_id, option.option_value); }) } } }, preselectQuerystringItems() { // pre-select option like ?size=167 const urlQueryParams = new URLSearchParams(window.location.search.replace('?','')); Object.values(this.optionConfig.attributes).map(attribute => { urlQueryParams.get(attribute.code) && this.changeOption(attribute.id, urlQueryParams.get(attribute.code)); }); }, preselectLocationHashItems() { // pre-select option like #144=167 const urlHashParams = new URLSearchParams(window.location.hash.replace('#','')); Object.values(this.optionConfig.attributes).map(attribute => { urlHashParams.get(attribute.id) && this.changeOption(attribute.id, urlHashParams.get(attribute.id)); }); } } } function initSwatchOptions(swatchConfig) { return { swatchConfig, getAttributeSwatchData(attributeId) { const swatchConfig = Object.assign({}, this.swatchConfig[attributeId]); swatchConfig['details'] = JSON.parse(swatchConfig['additional_data']); return swatchConfig; }, getAllAttributeOptions(attributeId) { return ( this.optionConfig.attributes[attributeId] && this.optionConfig.attributes[attributeId].options ) || [] }, optionIsActive(attributeId, optionId) { // return true if a product with this option is in stock return !!this.getAllowedAttributeOptions(attributeId).find( option => option.id === optionId ) }, optionIsEnabled(attributeId, optionId) { // return true if a product with this option is enabled for (const productId in this.optionConfig.index) { if (this.optionConfig.index[productId][attributeId] === optionId) { return true; } } return false; }, mapSwatchTypeNumberToTypeCode(typeNumber) { switch ("" + typeNumber) { case "1": return "color" case "2": return "image" case "3": return "empty" case "0": default: return "text" } }, getTypeOfFirstOption(attributeId) { for (const optionId in this.swatchConfig[attributeId]) { const option = this.swatchConfig[attributeId][optionId]; if (typeof option.type !== 'undefined') { return this.mapSwatchTypeNumberToTypeCode(option.type); } } }, getVisualSwatchType(attributeId, targetOptionId) { // If a type configuration is present for the given option id, use it const config = this.swatchConfig[attributeId]; if (config[targetOptionId] && typeof config[targetOptionId].type !== 'undefined') { return this.mapSwatchTypeNumberToTypeCode(config[targetOptionId].type); } // Otherwise - if no config is present for the target option - use the type of the first option // with a type property from the attribute, thus assuming its the same type as the target option. // (This edge case condition can occur on single swatch products if some options are not salable) return this.getTypeOfFirstOption(attributeId); }, getSwatchType(attributeId, optionId) { // Deserialize the attribute details the first time they are used if (this.swatchConfig[attributeId] && ! this.swatchConfig[attributeId].details) { this.swatchConfig[attributeId] = this.getAttributeSwatchData(attributeId); } const type = this.swatchConfig[attributeId] && this.swatchConfig[attributeId].details && this.swatchConfig[attributeId].details.swatch_input_type || "empty"; return type === 'visual' ? this.getVisualSwatchType(attributeId, optionId) : type; }, isTextSwatch(attributeId, optionId) { return this.getSwatchType(attributeId, optionId) === 'text'; }, isVisualSwatch(attributeId, optionId) { const type = this.getSwatchType(attributeId, optionId); return ['image', 'color'].includes(type); }, getSwatchBackgroundStyle(attributeId, optionId) { const config = this.getSwatchConfig(attributeId, optionId); const type = this.getSwatchType(attributeId, optionId); if (type === "color") { return 'background-color:' + config.value; } else if (type === "image") { return "background: #ffffff url('" + config.value + "') no-repeat center"; } else { return ''; } }, getSwatchText(attributeId, optionId) { const config = this.getSwatchConfig(attributeId, optionId); return config.label || config.value || this.getOptionLabelFromOptionConfig(attributeId, optionId); }, getOptionLabelFromOptionConfig(attributeId, optionId) { // Fallback if no value is present in swatchConfig data // Reference issue https://gitlab.hyva.io/hyva-themes/magento2-default-theme/-/issues/190 const option = this.getAllAttributeOptions(attributeId).filter(option => option.id === optionId); return option && option[0] && option[0].label ||''; }, getSwatchConfig(attributeId, optionId) { return this.swatchConfig[attributeId] && this.swatchConfig[attributeId][optionId] ? this.swatchConfig[attributeId][optionId] : false; }, activeTooltipItem: false, tooltipPositionElement: false, isTooltipVisible() { return this.activeTooltipItem && this.getSwatchConfig( this.activeTooltipItem.attribute, this.activeTooltipItem.item ); }, getTooltipImageStyle(attributeId, optionId) { const config = this.getSwatchConfig(attributeId, optionId); const type = this.getSwatchType(attributeId, optionId); if (type === "color") { return 'background-color:' + config.value + '; width: 110px; height: 90px;'; } else if (type === "image") { return "background: #ffffff url('" + config.thumb + "') center center no-repeat; width: 110px; height: 90px;"; } else { return 'display:none'; } }, getTooltipPosition() { return this.tooltipPositionElement ? `top: ${this.tooltipPositionElement.offsetTop}px;` + `left: ${ this.tooltipPositionElement.offsetLeft - ( this.tooltipPositionElement.closest('.snap') && this.tooltipPositionElement.closest('.snap').scrollLeft || 0 ) }px;` : '' }, getTooltipLabel() { return this.getSwatchConfig(this.activeTooltipItem.attribute, this.activeTooltipItem.item).label }, focusedLabel: false, focusLabel(optionId) { this.focusedLabel = optionId; }, blurLabel() { this.focusedLabel = false; }, showSwatches: false, initShowSwatchesIntersect() { if ('IntersectionObserver' in window && !window.scrollY) { const io = new IntersectionObserver( entries => { entries.map(entry => { if (entry.isIntersecting) { this.showSwatches = true; io.unobserve(this.$el); } }) } ); io.observe(this.$el); } else { this.showSwatches = true } } } } 'use strict'; (() => { const equalizeButtonWidths = (buttons) => { const buttonList = buttons.querySelectorAll('[data-element="link"], [data-element="empty_link"]'); let buttonMinWidth = 0; buttonList.forEach(button => { const buttonWidth = button.offsetWidth; if (buttonWidth > buttonMinWidth) { buttonMinWidth = buttonWidth; } }); buttonList.forEach(button => { button.style.minWidth = `${buttonMinWidth}px`; }); }; window.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('[data-content-type="buttons"][data-same-width="true"]').forEach(buttons => { equalizeButtonWidths(buttons); }); }); })(); 'use strict'; (() => { const initCarousels = (elements) => { if (!Glider) { return; } const initProductCarousel = (carousel) => { const gliderElement = carousel.querySelector('[data-role="glider-content"]'); if (!gliderElement) { return; } const gliderDots = carousel.querySelector('.glider-dots'); const gliderPrev = carousel.querySelector('.glider-prev'); const gliderNext = carousel.querySelector('.glider-next'); const glider = new Glider(gliderElement, { slidesToShow: 2, slidesToScroll: 2, scrollLock: true, draggable: true, dragVelocity: 2.5, dots: gliderDots, arrows: { prev: gliderPrev, next: gliderNext, }, responsive: [ { breakpoint: 768, settings: { slidesToShow: 3, slidesToScroll: 3, } }, { breakpoint: 1024, settings: { slidesToShow: 4, slidesToScroll: 4, } }, ], }); carousel.classList.remove('overflow-x-scroll'); gliderPrev.classList.remove('hidden'); gliderNext.classList.remove('hidden'); if (carousel.dataset.autoplay !== 'false') { gliderAutoplay( glider, carousel.dataset.autoplaySpeed, carousel.dataset.infiniteLoop ); } }; const initSliderCarousel = (slider) => { slider.innerHTML = `
    ${slider.innerHTML}
    `; slider.classList.add('glider-contain'); slider.insertAdjacentHTML( 'beforeend', '\u000A\u003Cdiv\u0020class\u003D\u0022carousel\u002Dnav\u0020flex\u0020items\u002Dcenter\u0020justify\u002Dcenter\u0020flex\u002D1\u0020p\u002D4\u0022\u003E\u000A\u0020\u0020\u0020\u0020\u003Cbutton\u000A\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020aria\u002Dlabel\u003D\u0022Previous\u0022\u000A\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020class\u003D\u0022glider\u002Dprev\u0020w\u002D8\u0020h\u002D8\u0020mr\u002D1\u0020text\u002Dblack\u0020rounded\u002Dfull\u0020outline\u002Dnone\u0020focus\u003Aoutline\u002Dnone\u0020hidden\u0022\u003E\u000A\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u003Csvg\u0020xmlns\u003D\u0022http\u003A\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\u0022\u0020fill\u003D\u0022none\u0022\u0020viewBox\u003D\u00220\u00200\u002024\u002024\u0022\u0020stroke\u003D\u0022currentColor\u0022\u0020width\u003D\u002224\u0022\u0020height\u003D\u002224\u0022\u003E\u000A\u0020\u0020\u003Cpath\u0020stroke\u002Dlinecap\u003D\u0022round\u0022\u0020stroke\u002Dlinejoin\u003D\u0022round\u0022\u0020stroke\u002Dwidth\u003D\u00222\u0022\u0020d\u003D\u0022M15\u002019l\u002D7\u002D7\u00207\u002D7\u0022\u002F\u003E\u000A\u003C\u002Fsvg\u003E\u000A\u0020\u0020\u0020\u0020\u003C\u002Fbutton\u003E\u000A\u0020\u0020\u0020\u0020\u003Cdiv\u0020role\u003D\u0022tablist\u0022\u0020class\u003D\u0022glider\u002Ddots\u0020select\u002Dnone\u0020flex\u0020flex\u002Dwrap\u0020mx\u002D1\u0020justify\u002Dcenter\u0020p\u002D0\u0020focus\u003Aoutline\u002Dnone\u0022\u003E\u003C\u002Fdiv\u003E\u000A\u0020\u0020\u0020\u0020\u003Cbutton\u000A\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020aria\u002Dlabel\u003D\u0022Next\u0022\u000A\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020class\u003D\u0022glider\u002Dnext\u0020w\u002D8\u0020h\u002D8\u0020ml\u002D1\u0020text\u002Dblack\u0020rounded\u002Dfull\u0020outline\u002Dnone\u0020focus\u003Aoutline\u002Dnone\u0020hidden\u0022\u003E\u000A\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u003Csvg\u0020xmlns\u003D\u0022http\u003A\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\u0022\u0020fill\u003D\u0022none\u0022\u0020viewBox\u003D\u00220\u00200\u002024\u002024\u0022\u0020stroke\u003D\u0022currentColor\u0022\u0020width\u003D\u002224\u0022\u0020height\u003D\u002224\u0022\u003E\u000A\u0020\u0020\u003Cpath\u0020stroke\u002Dlinecap\u003D\u0022round\u0022\u0020stroke\u002Dlinejoin\u003D\u0022round\u0022\u0020stroke\u002Dwidth\u003D\u00222\u0022\u0020d\u003D\u0022M9\u00205l7\u00207\u002D7\u00207\u0022\u002F\u003E\u000A\u003C\u002Fsvg\u003E\u000A\u0020\u0020\u0020\u0020\u003C\u002Fbutton\u003E\u000A\u003C\u002Fdiv\u003E\u000A' ); const gliderElement = slider.querySelector('[data-role="glider-content"]'); const gliderDots = slider.querySelector('.glider-dots'); const gliderPrev = slider.querySelector('.glider-prev'); const gliderNext = slider.querySelector('.glider-next'); const glider = new Glider(gliderElement, { slidesToShow: 1, slidesToScroll: 1, scrollLock: true, scrollLockDelay: 250, draggable: true, dragVelocity: 2.5, dots: gliderDots, arrows: { prev: gliderPrev, next: gliderNext, }, }); slider.classList.add('glider-initialized'); if (slider.dataset.showArrows === 'true') { gliderPrev.classList.remove('hidden'); gliderNext.classList.remove('hidden'); } if (slider.dataset.autoplay !== 'false') { gliderAutoplay( glider, slider.dataset.autoplaySpeed, slider.dataset.infiniteLoop ); } }; const gliderAutoplay = (glider, milliseconds, loop) => { const pagesCount = glider.track.childElementCount; let slideTimeout = null; let nextIndex = 1; let paused = false; const slide = () => { slideTimeout = setTimeout( () => { if (loop && nextIndex >= pagesCount) { nextIndex = 0; } glider.scrollItem(nextIndex); }, parseInt(milliseconds) ); }; glider.ele.addEventListener('glider-animated', () => { nextIndex = glider.slide + glider.opt.slidesToScroll; window.clearInterval(slideTimeout); if (!paused && (loop || nextIndex < pagesCount)) { slide(); } }); const pause = () => { if (!paused) { clearInterval(slideTimeout); paused = true; } }; const unpause = () => { if (paused) { slide(); paused = false; } }; glider.ele.parentElement.addEventListener('mouseover', pause, {passive: true}); glider.ele.parentElement.addEventListener('touchstart', pause, {passive: true}); glider.ele.parentElement.addEventListener('mouseout', unpause, {passive: true}); glider.ele.parentElement.addEventListener('touchend', unpause, {passive: true}); slide(); }; elements.forEach(element => { if (element.dataset.contentType === 'products') { initProductCarousel(element); } if (element.dataset.contentType === 'slider') { initSliderCarousel(element); } }); }; window.addEventListener('DOMContentLoaded', () => { const carouselElements = document.querySelectorAll( `[data-content-type="products"][data-appearance="carousel"], [data-content-type="slider"]` ); if (carouselElements.length > 0) { const script = document.createElement('script'); script.type = 'text/javascript'; script.addEventListener('load', () => { initCarousels(carouselElements); }); script.src = 'https\u003A\u002F\u002Fshop.grandstores.ae\u002Fstatic\u002Fversion1679967781\u002Ffrontend\u002FAureatelabs\u002Fgrandstores\u002Fen_US\u002FMagento_PageBuilder\u002Fjs\u002Fglider.min.js'; document.head.appendChild(script); } }); })(); 'use strict'; (() => { const initMaps = (elements) => { const renderMap = (element) => { const dataLocations = element.dataset.locations; // Hide map if no locations set if (!dataLocations || dataLocations === '[]') { element.classList.add('hidden'); return; } const map = new google.maps.Map( element, getMapOptions( element.dataset.showControls !== 'true', element.dataset.showControls === 'true' ) ); const locations = JSON.parse(dataLocations); const latitudeLongitudeBounds = new google.maps.LatLngBounds(); const bounds = []; locations.forEach(location => { const position = { lat: parseFloat(location.position.latitude), lng: parseFloat(location.position.longitude), }; bounds.push(position); const infowindow = new google.maps.InfoWindow({ content: getInfoWindowContent(location), }); const marker = new google.maps.Marker({ position: position, map, title: location.location_name, }); marker.addListener('click', () => { infowindow.open(map, marker); }); }); // Set bounds if multiple locations if (bounds.length > 1) { bounds.forEach(function (bound) { latitudeLongitudeBounds.extend(bound); }); map.fitBounds(latitudeLongitudeBounds); } // Center if single location if (bounds.length === 1) { map.setCenter(bounds[0]); } }; const getMapOptions = (disableDefaultUI, mapTypeControl) => { const style = ''; return { zoom: 8, scrollwheel: false, disableDoubleClickZoom: false, mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DEFAULT, }, styles: style ? JSON.parse(style) : [], disableDefaultUI: disableDefaultUI, mapTypeControl: mapTypeControl, }; }; const getInfoWindowContent = (location) => { const title = location.location_name ? `

    ${location.location_name}

    ` : ''; const comment = location.comment ? `

    ${location.comment}

    ` : ''; const phone = location.phone ? `

    Phone: ${location.phone}

    ` : ''; const street = location.address ? `${location.address}` : ''; const city = location.city ? `${location.city}` : ''; const state = location.state ? `${location.state}` : ''; const zipCode = location.zipcode ? `${location.zipcode}` : ''; const country = location.country ? location.country : ''; return `
    ${title} ${comment} ${phone}

    ${street} ${city} ${state} ${zipCode} ${country}

    `; }; const hideAllMaps = () => { document.querySelectorAll('[data-content-type="map"]').forEach(element => { element.classList.add('hidden'); }); }; window.gm_authFailure = () => { hideAllMaps(); }; if (typeof google.maps === 'undefined') { hideAllMaps(); return; } elements.forEach(element => { if (element.dataset.contentType === 'map') { renderMap(element); } }); }; window.addEventListener('DOMContentLoaded', () => { const mapElements = document.querySelectorAll('[data-content-type="map"]'); if (mapElements.length > 0) { const script = document.createElement('script'); script.type = 'text/javascript'; script.addEventListener('load', () => { initMaps(mapElements); }); script.src = 'https\u003A\u002F\u002Fmaps.googleapis.com\u002Fmaps\u002Fapi\u002Fjs\u003Fv\u003D3\u0026key\u003D'; document.head.appendChild(script); } }); })(); 'use strict'; (() => { const initParallaxImage = (element) => { if (!window.jarallax) { return; } element.classList.add('jarallax'); element.dataset.jarallax = ''; const parallaxSpeed = parseFloat(element.dataset.parallaxSpeed) || 0.5; const elementStyle = window.getComputedStyle(element); window.jarallax(element, { imgPosition: elementStyle.backgroundPosition || '50% 50%', imgRepeat: elementStyle.backgroundRepeat || 'no-repeat', imgSize: elementStyle.backgroundSize || 'cover', speed: parallaxSpeed, }); }; const initVideoBackground = (element) => { if (!window.jarallax) { return; } let slider = null; if (element.classList.contains('pagebuilder-slide-wrapper')) { const viewportElement = document.createElement('div'); slider = element.closest('[data-content-type=slider]'); viewportElement.classList.add('jarallax-viewport-element'); element.dataset.elementInViewport = '.jarallax-viewport-element'; element.appendChild(viewportElement); } element.classList.add('jarallax'); element.dataset.jarallax = ''; const parallaxSpeed = parseFloat(element.dataset.parallaxSpeed) || 0.5; window.jarallax(element, { imgSrc: element.dataset.videoFallbackSrc, speed: parallaxSpeed, videoLoop: element.dataset.videoLoop, videoPlayOnlyVisible: element.dataset.videoPlayOnlyVisible, videoLazyLoading: element.dataset.videoLazyLoad, disableVideo: false, elementInViewport: element.dataset.elementInViewport && element.querySelector(element.dataset.elementInViewport), }); if (slider) { if (slider.dataset.afterChangeIsSet) { return; } slider.addEventListener('glider-loaded', () => { slider.querySelectorAll('.jarallax').forEach(videoSlide => { videoSlide.jarallax && videoSlide.jarallax.onScroll(); }); }); slider.addEventListener('glider-animated', () => { slider.querySelectorAll('.jarallax').forEach(videoSlide => { videoSlide.jarallax && videoSlide.jarallax.onScroll(); }); }); slider.dataset.afterChangeIsSet = true; } }; window.addEventListener('DOMContentLoaded', () => { const parallaxImageElements = document.querySelectorAll( `[data-content-type="row"][data-background-type="image"][data-enable-parallax="1"], [data-content-type="row"] > [data-background-type="image"][data-enable-parallax="1"]` ); const videoBackgroundsElements = document.querySelectorAll( `[data-content-type="row"][data-background-type="video"][data-enable-parallax="1"], [data-content-type="row"] > [data-background-type="video"][data-enable-parallax="1"], [data-content-type="banner"] [data-background-type="video"], [data-content-type="slide"] [data-background-type="video"]` ); if (parallaxImageElements.length > 0 || videoBackgroundsElements.length > 0) { const jarallaxScript = document.createElement('script'); jarallaxScript.type = 'text/javascript'; jarallaxScript.addEventListener('load', () => { parallaxImageElements.forEach(row => { initParallaxImage(row); }); const jarallaxVideoScript = document.createElement('script'); jarallaxVideoScript.type = 'text/javascript'; jarallaxVideoScript.addEventListener('load', () => { videoBackgroundsElements.forEach(element => { initVideoBackground(element); }); }); jarallaxVideoScript.src = 'https\u003A\u002F\u002Fshop.grandstores.ae\u002Fstatic\u002Fversion1679967781\u002Ffrontend\u002FAureatelabs\u002Fgrandstores\u002Fen_US\u002FMagento_PageBuilder\u002Fjs\u002Fjarallax\u002Dvideo.min.js'; document.head.appendChild(jarallaxVideoScript); }); jarallaxScript.src = 'https\u003A\u002F\u002Fshop.grandstores.ae\u002Fstatic\u002Fversion1679967781\u002Ffrontend\u002FAureatelabs\u002Fgrandstores\u002Fen_US\u002FMagento_PageBuilder\u002Fjs\u002Fjarallax.min.js'; document.head.appendChild(jarallaxScript); } }); })(); 'use strict'; (() => { const applyShowOnHover = (element) => { const showOverlayOnHover = (element) => { const overlay = element.querySelector('.pagebuilder-overlay'); const color = overlay.dataset.overlayColor; element.addEventListener('mouseover', () => { overlay.style.backgroundColor = color; }); element.addEventListener('mouseout', () => { overlay.style.backgroundColor = 'transparent'; }); }; const showButtonOnHover = (element) => { const button = element.querySelector('.pagebuilder-banner-button'); element.addEventListener('mouseover', () => { button.style.opacity = '1'; button.style.visibility = 'visible'; }); element.addEventListener('mouseout', () => { button.style.opacity = '0'; button.style.visibility = 'hidden'; }); }; if (element.dataset.showOverlay === 'hover') { showOverlayOnHover(element); } if (element.dataset.showButton === 'hover') { showButtonOnHover(element); } }; window.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('[data-content-type="banner"],[data-content-type="slider"]').forEach(element => { applyShowOnHover(element); }); }); })(); 'use strict'; (() => { document.querySelectorAll('[data-content-type="tab-item"]').forEach(tabItem => { tabItem.setAttribute('x-show', `tab === '${tabItem.id}'`); }); document.querySelectorAll('[data-content-type="tabs"]').forEach(tab => { const defaultActiveTab = parseInt(tab.dataset.activeTab) || 0; tab.querySelectorAll('.tab-header').forEach((tabHeader, index) => { const tabLink = tabHeader.querySelector('a'); const tabId = tabLink.getAttribute('href').replace('#', ''); tabHeader.setAttribute(':class', `{ 'active': tab === '${tabId}' }`); tabLink.setAttribute('x-on:click.prevent', `tab = '${tabId}'`); if (index === defaultActiveTab) { tab.setAttribute('x-data', `{ tab: '${tabId}' }`); } }); }); })(); 'use strict'; const grecaptchaV2LoadCallbacks = []; function executeRecaptchaLoadCallbacks () { while (window.grecaptcha && grecaptchaV2LoadCallbacks.length > 0) { const callback = grecaptchaV2LoadCallbacks.pop(); typeof callback === 'string' ? window[callback]() : callback(); } } (function() { const loadRecaptchaScript = (event) => { if (window.grecaptcha || !event.target.form) { return; } const url = 'https://www.google.com/recaptcha/api.js?onload=executeRecaptchaLoadCallbacks'; const siteKey = ''; const script = document.createElement('script'); script.type = 'text/javascript'; script.src = siteKey ? `${url}&render=${siteKey}` : `${url}&render=explicit`; script.async = true; document.head.appendChild(script); if (event.target.form.querySelector) { script.addEventListener('load', () => { Array.from(event.target.form.querySelectorAll('button[disabled]')).forEach(btn => btn.disabled && btn.removeAttribute('disabled')); }); } } window.forceLoadRecaptchaScript = (form) => { loadRecaptchaScript({target: {form: form || 'dummy'}}); executeRecaptchaLoadCallbacks(); }; document.body.addEventListener('input', loadRecaptchaScript, { once: true }); document.body.addEventListener('focus', loadRecaptchaScript, { once: true }); }()); 'use strict'; (function () { const modals = []; const excludedFromFocusTrapping = new Set(); function loadInertPolyfill(callback) { // undocumented "feature", should not be used unless inert attribute support is guaranteed if (window.hyva.modal.disableInertPolyfill) { callback && callback(); } else { const polyfill = document.createElement('script'); polyfill.src = 'https\u003A\u002F\u002Fshop.grandstores.ae\u002Fstatic\u002Fversion1679967781\u002Ffrontend\u002FAureatelabs\u002Fgrandstores\u002Fen_US\u002FHyva_Theme\u002Fjs\u002Fwicg\u002Dinert\u002D3.1.1\u002Finert.min.js'; callback && polyfill.addEventListener('load', callback); const firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(polyfill, firstScriptTag); } } let isInertPolyfillLoaded = 0; function setSiblingsInert(dialogElement, toState) { if (isInertPolyfillLoaded === 0) { isInertPolyfillLoaded = 1; loadInertPolyfill(() => { isInertPolyfillLoaded = 2; setSiblingsInert(dialogElement, toState) }) return; } if (isInertPolyfillLoaded === 1) { return; } // Walk up the DOM, toggle inert attribute the siblings at each level let el = dialogElement; while (el && (el = el.parentElement)) { if (el === document.body || el.parentElement === null) continue; Array.from(el.parentElement.children).forEach(sibling => { if (sibling !== el) { sibling.inert = toState; } }) } // Walk down the DOM, toggle inert attribute to opposite of toState. // This is needed if a nested dialog is rendered as a sibling of the opening dialog. (function setChildrenInert(el, toState) { if (el) { el.inert = toState; Array.from(el.children).forEach(child => setChildrenInert(child, toState)); } })(findParentWithOverlaySpread(dialogElement), ! toState) excludedFromFocusTrapping.forEach(selector => { Array.from(document.querySelectorAll(selector)).map(el => el.inert = false); }) } function findParentWithOverlaySpread(el) { while (el && (el = el.parentElement)) { if (el === document.body || el.parentElement === null) continue; if (el.hasAttribute('x-spread') && el.getAttribute('x-spread').indexOf('overlay(') !== -1) { return el; } } } function freeFocusFromModalTrap(modal) { const dialogElement = modal.viewModel.$refs[modal.name]; isOverlayDisabled(dialogElement) || modal.viewModel.$nextTick(() => setSiblingsInert(dialogElement, false)); } function trapFocusInNextModalWithOverlay() { for (let idx = modals.length -1; idx >= 0; idx--) { const nextOnStack = modals[idx]; const nextDialogElement = nextOnStack.viewModel.$refs[nextOnStack.name]; if (! isOverlayDisabled(nextDialogElement)) { nextOnStack.viewModel.$nextTick(() => setSiblingsInert(nextDialogElement, true)); break; } } } function focusables(dialogElement) { const selector = 'a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'; return Array.from(dialogElement.querySelectorAll(selector)) .filter(el => !el.hasAttribute('disabled')); } function firstVisible(elements) { const a = Array.from(elements); for (let i = 0; i < a.length; i++) { if (a[i].offsetWidth || a[i].offsetHeight || a[i].getClientRects().length) return a[i]; } return null; } function isInViewport(element) { const rect = element && element.getBoundingClientRect(); return rect && rect.top >= 0 && rect.left >= 0 && rect.right <= window.innerWidth && rect.bottom <= window.innerHeight; } function setFocusAfterTransition(dialogElement, duration) { window.setTimeout(() => { const focusElement = firstVisible(dialogElement.querySelectorAll('[x-focus-first]')) || focusables(dialogElement)[0] || null; focusElement && isInViewport(focusElement) && focusElement.focus(); }, duration + 1); } function ucFirst(s) { return s.substr(0, 1).toUpperCase() + s.substr(1); } function isOpenProp(dialogName) { return 'is' + ucFirst(dialogName) + 'Open'; } function determineTrigger($refs, dialog, trigger) { // if show() was called without arguments use the event target as open trigger if (typeof trigger === 'undefined' && typeof dialog === 'object' && dialog.target && dialog.target.focus) { return dialog.target; } // if show('name', $event) was called with the event as the second argument use the event target as trigger if (typeof dialog === 'string' && typeof trigger === 'object' && trigger.target && trigger.target.focus) { return trigger.target; } // if show('name', 'trigger') was called with the ref name of the trigger element use that as the trigger if (typeof trigger === 'string' && $refs[trigger]) { return $refs[trigger]; } else { // unknown trigger - no focus will be set when the dialog is hidden. return null; } } function isOverlayDisabled(dialog) { return dialog && dialog.hasAttribute('x-no-overlay') } function areRemainingModalsWithoutOverlay(modals) { const overflowDisabled = modals.map(modal => modal.viewModel.$refs[modal.name]).filter(isOverlayDisabled); return overflowDisabled.length === modals.length; } window.hyva.modal = function(options) { const config = Object.assign({ dialog: 'dialog', // default dialog ref name duration: 300, // ms before allowing subsequent hiding of modals for nested modals (see transition duration) transitionEnter: 'transition ease-out duration-300', transitionEnterStart: 'opacity-0', transitionEnterEnd: 'opacity-100', transitionLeave: 'transition ease-in duration-300', transitionLeaveStart: 'opacity-100', transitionLeaveEnd: 'opacity-0', }, options); let lastHide = 0; return { show(dialog, trigger) { const focusTargetAfterHide = determineTrigger(this.$refs, dialog, trigger); const name = typeof dialog === 'string' ? dialog : config.dialog; const dialogElement = this.$refs[name]; if (! dialogElement) { return; } const useOverlay = ! dialogElement.hasAttribute('x-no-overlay'); dialogElement.scrollTop = 0; // Prevent adding the same modal on the stack twice if (this[isOpenProp(name)]) { return; } this[isOpenProp(name)] = true; useOverlay && this.$nextTick(() => setSiblingsInert(dialogElement, true)); setFocusAfterTransition(dialogElement, config.duration); const frame = {name, viewModel: this, focusTarget: focusTargetAfterHide, time: Date.now()}; modals.push(frame); if (useOverlay) { document.body.classList.add('overflow-hidden'); } return new Promise(resolve => frame.resolve = resolve); }, cancel() { this.hide(false); }, ok() { this.hide(true); }, hide(value) { // Guard against Escape being pressed multiple times before a transition is finished, otherwise // this function will pop further dialogs from the stack but the display will not update. if (Date.now() - lastHide < config.duration) { return; } lastHide = Date.now(); const modal = modals.pop() || {}; const name = modal.name; this[isOpenProp(name)] = false; freeFocusFromModalTrap(modal) trapFocusInNextModalWithOverlay(); const nextFocusAfterHide = modal.focusTarget; nextFocusAfterHide && this.$nextTick(() => nextFocusAfterHide.focus()); if (modals.length === 0 || areRemainingModalsWithoutOverlay(modals)) { document.body.classList.remove('overflow-hidden'); } modal.resolve(value); }, [isOpenProp(config.dialog)]: false, overlay(dialog) { const name = typeof dialog === 'string' ? dialog : config.dialog; return { ['x-show']() { return this[isOpenProp(name)]; }, ['x-transition:enter']: config.transitionEnter, ['x-transition:enter-start']: config.transitionEnterStart, ['x-transition:enter-end']: config.transitionEnterEnd, ['x-transition:leave']: config.transitionLeave, ['x-transition:leave-start']: config.transitionLeaveStart, ['x-transition:leave-end']: config.transitionLeaveEnd, ['@hyva-modal-show'](event) { event.detail && event.detail.dialog === name && this.show(name) } }; } }; } window.hyva.modal.pop = function () { if (modals.length > 0) { const modal = modals[modals.length -1]; modal.viewModel.hide(); } } window.hyva.modal.excludeSelectorsFromFocusTrap = function (selectors) { typeof selectors === 'string' || selectors instanceof String ? excludedFromFocusTrapping.add(selector) : selectors.map(selector => excludedFromFocusTrapping.add(selector)); } window.hyva.modal.eventListeners = { keydown: event => { if (event.key === 'Escape') { window.hyva.modal.pop(); } }, // generic modal @click.away handler click: event => { if (modals.length > 0) { const modal = modals[modals.length -1]; const dialog = modal.viewModel.$refs[modal.name]; if (modal.time + 10 < Date.now() && // if last click processing is more than 10ms ago ! isOverlayDisabled(dialog) && // if dialog has overlay ! dialog.contains(event.target)) { // if click is outside of dialog modal.viewModel.hide(); } } } }; document.addEventListener('keydown', window.hyva.modal.eventListeners.keydown); document.addEventListener('click', window.hyva.modal.eventListeners.click); })(); .is-loading > :not(.loader) { visibility: hidden; } function initAddToCart() { return { showLoader: false, showBox: false, addToCart(formID, productID) { let outerThis = this; const delay = 500; let form = document.querySelector('#' + formID + "[product-id='" + productID + "']"); const data = new URLSearchParams(new FormData(form).entries()), button = this.$el; let cartText = button.querySelector('#add-to-cart-btn').__x.$data.btnText; button.querySelector('#add-to-cart-btn').__x.$data.btnText = ''; outerThis.showLoader = true; button.disabled = true; data.set('uenc', hyva.getUenc()); data.set('form_key', hyva.getFormKey()); fetch(BASE_URL + "checkout/cart/add/product/" + productID, { method: 'POST', body: data, headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', 'X-Requested-With': 'XMLHttpRequest' }, "mode": "cors", "credentials": "include" }) .then(res => { if (!res.ok) { return form.submit(); } if (res.redirected) { return []; } return res.json(); }) .then(data => { if (data.length == 0) { outerThis.showLoader = false; outerThis.showBox = true; setTimeout(() => { const reloadCustomerDataEvent = new CustomEvent("reload-customer-section-data"); window.dispatchEvent(reloadCustomerDataEvent); button.querySelector('#add-to-cart-btn').__x.$data.btnText = 'Added to cart'; setTimeout(() => { button.querySelector('#add-to-cart-btn').__x.$data.btnText = cartText; outerThis.showLoader = false; outerThis.showBox = false; document.getElementById('menu-cart-icon').click(); }, 2000); }, 1000); } else { const reloadCustomerDataEvent = new CustomEvent("reload-customer-section-data"); window.dispatchEvent(reloadCustomerDataEvent); button.querySelector('#add-to-cart-btn').__x.$data.btnText = 'Not available'; outerThis.showLoader = false; setTimeout(() => { button.querySelector('#add-to-cart-btn').__x.$data.btnText = cartText; }, 2000); } }) .catch(err => { window.dispatchEvent(new CustomEvent('product-addtocart-error')); setMessage({ text: 'There was a problem adding your item to the cart.', type: 'error' }); }) .finally(() => { try { var messages = hyva.getCookie('mage-messages'); messages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : []; document.cookie = 'mage-messages=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; } catch (error) { console.warn('Error parsing Cookie Messages:', error); return; } setTimeout(() => { button.disabled = false; messages.forEach(message => { setMessage(message); }); }, delay); }); } } } /** * Set Message */ function setMessage(message) { typeof window.dispatchMessages !== "undefined" && window.dispatchMessages([ message ], 1000); } 'use strict'; function GoogleAnalytics () { let self = this; this.config = { isCookieRestrictionModeEnabled: 0, currentWebsite: 1, cookieName: "user_allowed_save_cookie", ordersTrackingData: [], pageTrackingData: {"optPageUrl":"","isAnonymizedIpActive":false,"accountId":"UA-161894558-1"}, } this.initGoogleAnalytics = function () { let allowServices = false, allowedCookies, allowedWebsites; if (self.config.isCookieRestrictionModeEnabled) { allowedCookies = hyva.getCookie(self.config.cookieName); if (allowedCookies !== null) { allowedWebsites = JSON.parse(decodeURIComponent(allowedCookies)); if (allowedWebsites[self.config.currentWebsite] === 1) { allowServices = true; } } } else { allowServices = true; } if (allowServices) { (function (i, s, o, g, r, a, m) { i.GoogleAnalyticsObject = r; i[r] = i[r] || function () { (i[r].q = i[r].q || []).push(arguments) }, i[r].l = 1 * new Date(); a = s.createElement(o), m = s.getElementsByTagName(o)[0]; a.defer = 1; a.src = g; m.parentNode.insertBefore(a, m) })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); // Process page info ga('create', self.config.pageTrackingData.accountId, 'auto'); if (self.config.pageTrackingData.isAnonymizedIpActive) { ga('set', 'anonymizeIp', true); } // Process orders data if (self.config.ordersTrackingData.hasOwnProperty('currency')) { ga('require', 'ec', 'ec.js'); ga('set', 'currencyCode', self.config.ordersTrackingData.currency); // Collect product data for GA if (self.config.ordersTrackingData.products) { self.config.ordersTrackingData.products.forEach(function (value) { ga('ec:addProduct', value); }); } // Collect orders data for GA if (self.config.ordersTrackingData.orders) { self.config.ordersTrackingData.orders.forEach(function (value) { ga('ec:setAction', 'purchase', value); }); } ga('send', 'pageview'); } else { // Process Data if not orders ga('send', 'pageview' + self.config.pageTrackingData.optPageUrl); } } }; } window.addEventListener("load", new GoogleAnalytics().initGoogleAnalytics);
    Loading...
    document.addEventListener( 'DOMContentLoaded', function () { var quickViewModal = document.getElementById("quickview-modal-popup"); var quickViewCloseButton = document.getElementById("quickview-close-btn"); var quickviewOverlay = document.getElementById("quickview-overlay"); var quickviewContent = document.getElementById("quickview-content"); var quickLoading = document.getElementById("quick-loading"); var isNone = quickLoading.style.display == "none"; initializeQuickView = function (event) { if(isNone) { quickLoading.style.display = "block"; } fetch("https://shop.grandstores.ae/en/alquickview/catalog_product/view/", { method: 'POST', "body": "product_id=" + event.getAttribute('data-product-id'), headers: { 'Content-Type': 'application/x-www-form-urlencoded', "X-Requested-With": "XMLHttpRequest", 'Accept': '*/*' }, isAjax: true, }).then(function (response) { return response.text(); }).then(function (response) { // Replaced the product form from quickview response to fix the quickview add to cart issue in product detail page quickviewContent.innerHTML = response.replace(/product_addtocart_form/g, 'quickview_product_addtocart_form'); // Remove all the old quick view popup scripts with class name quick-view-product-js before initializing document.querySelectorAll('head .quick-view-product-js').forEach(e => e.remove()); // Run the javascript codes in quick view popup by adding in head var scriptElements = quickviewContent.getElementsByTagName('script'); for (let i = 0; i < scriptElements.length; i ++) { var scriptElement = document.createElement('script'); scriptElement.classList.add('quick-view-product-js'); if (!scriptElements[i].src) { scriptElement.innerHTML = scriptElements[i].innerHTML; } else { scriptElement.src = scriptElements[i].src; } document.head.appendChild(scriptElement); } quickviewOverlay.style.display = "flex"; quickViewModal.style.display = "flex"; quickLoading.style.display = "none"; quickViewModal.classList.add('overflow-y-auto'); }); // When the user clicks on close button, close the modal quickViewCloseButton.onclick = function() { closeQuickViewModal(); var element = document.getElementById('html-body'); element.classList.remove('overflow-hidden'); quickViewModal.classList.remove('overflow-y-auto'); } quickviewOverlay.onclick = function() { // TODO: Need to fix overlay design issue to get proper click outside modal to get modal closed closeQuickViewModal(); } } // Close Quick view popup modal function closeQuickViewModal() { quickviewOverlay.style.display = "none"; quickViewModal.style.display = "none"; } });

    Samsung Galaxy A13 4GB/64GB (Light Blue) Price insights and history

    • The cheapest price of Samsung Galaxy A13 4GB/64GB (Light Blue) in UAE was 49 AED from grandstores within the past 8 months
    • The highest price of Samsung Galaxy A13 4GB/64GB (Light Blue) in UAE was 659 AED from grandstores within the past 8 months
    • The price difference between the cheapest and highest price of Samsung Galaxy A13 4GB/64GB (Light Blue) in UAE is 610 AED from grandstores within the past 8 months
    • The average price of Samsung Galaxy A13 4GB/64GB (Light Blue) in UAE is 489 AED from grandstores within the past 8 months

    Top Products in Smartphonesmore

      Reviews of Samsung Galaxy A13 4GB/64GB (Light Blue)

      • khaled assem

          (6 months ago)

          هاتف Samsung Galaxy A13 الهاتف الاقتصادي المثالي بل قد يكون الأفضل في فئته السعرية خاصة وأنه مقدم من سامسونج وهو ما يضعه في مكانة أعلى من المنافسين، والهاتف لا يفتقد للكثير من المواصفات التي تتمتع بها هواتف أعلى سواء من سامسونج أو أي شركة أخرى، فبغض النظر عن أن شاشته ليست AMOLED إلا أن باقي مواصفاته جيدة للغاية فالهاتف بشاشة بجودة Full HD وقطرها كبير نسبيًا، ويمتاز الهاتف بمعالج قوي بشكل ملحوظ مقابل منافسيه، كما يتمتع بكاميرا أكثر من رائعة وإن كانت تلك الروعة تقل قليلًا على مستوى الكاميرا الامامية، بطارية الهاتف أيضًا متميزة سواء على مستوى سعة البطارية أو تقنية الشحن السري وإن كانت ليست الأقوى ولكنها مقبولة

        Video Reviews of Samsung Galaxy A13 4GB/64GB (Light Blue)

        • loading video reviews