| Current Path : /var/www/magento.test.indacotrentino.com/www/pub/media/buybutton/ |
| Current File : /var/www/magento.test.indacotrentino.com/www/pub/media/buybutton/init.js |
(function(d, $) {
// Define our constructor
window.wkBuyButtonRegistry = {};
window.wkaddTocartLabel = {
text: 'Aggiungi al carrello'
}
let cart = {
cartItems: [],
isVisible: 'bb-hide'
};
this.BuyButton = function() {
this.options = null;
// Define option defaults
var defaults = {
template: '<div class=buybutton-container id=buybutton-container-id> <div class=buybutton-head> <div class=buybutton-cart @click=showCart> <i class=rango-cart><i class=bb-cart-count>{{itemsCount}}</i></i><i class=icon-cart><i>{{childData.miniCartText}}</i></i> <mini-cart></mini-cart> </div><div class=clear-float></div></div><div class=buybutton-body> <div class=buybutton-items> <div class=buybutton-item v-for="(value, key) in products"> <div class=buybutton-item-container v-if="designTemplate==1"> <div class=buybutton-item-image><img :src=value.images[0].url @click=view(value)></div><div class=buybutton-item-name @click=redirect(value)><span>{{value.name}}</span></div><div class=buybutton-item-price v-if="value.price_info.final_price > 0"><b v-html=value.price_info.formatted_prices.final_price></b></div><div class=buybutton-item-view><button @click=view(value) class="buybutton-primary buybutton-view-product" type=button><span>{{childData.vButtonText}}</span></button></div></div><div class=buybutton-item-container v-if="designTemplate==2"> <div class="bb-option-wrapper"><options-wrapper :options=value.extension_attributes.custom_options></options-wrapper></div><div class=bb-configurable-option-wrapper><configurable-options :coptions=value.extension_attributes.super_attributes?JSON.parse(value.extension_attributes.super_attributes):{}></configurable-options></div><div class="buybutton-item-view buybutton-add" v-if="value.price_info.final_price > 0">' +
'<div class="quantity-control"><button @click="decreaseQuantity(value)" class="quantity-button">-</button><input :id="\'quantity-\' + value.extension_attributes.sku" class="quantity-input" type="number" min="1" value="1"><button @click="increaseQuantity(value)" class="quantity-button">+</button></div>' +
'<button @click=addToCart(value) class="buybutton-primary buybutton-view-product"type=button><span>{{childData.addToCartText}}</span></button></div></div><div class=buybutton-item-container v-if="designTemplate==3"><div class=buybutton-item-image-container><div class=buybutton-item-image><img :src=item.image></div><div class="buybutton-item-view buybutton-add" v-if="value.price_info.final_price > 0">' +
'<div class="quantity-control"><button @click="decreaseQuantity(value)" class="quantity-button">-</button><input :id="\'quantity-\' + value.extension_attributes.sku" class="quantity-input" type="number" min="1" value="1"><button @click="increaseQuantity(value)" class="quantity-button">+</button></div>' +
'<button @click=addToCart(value) class="buybutton-primary buybutton-view-product"type=button><span>{{childData.addToCartText}}</span></button></div></div><div class=buybutton-attr-container><div class=buybutton-product-name @click=redirect(value)><span>{{value.name}}</span></div><div class=buybutton-product-price v-if="value.price_info.final_price > 0"><span v-html=formattedPrice></span></div><div class=buybutton-product-description><span v-html=value.extension_attributes.description></span></div><div class="bb-option-wrapper"><options-wrapper :options=value.extension_attributes.custom_options></options-wrapper></div><div class=bb-configurable-option-wrapper><configurable-options :coptions=value.extension_attributes.super_attributes?JSON.parse(value.extension_attributes.super_attributes):{}></configurable-options></div></div></div></div><div class=buybutton-message v-if="products.length === 0"><b>Al momento non ci sono prodotti online</b></div></div></div></div></div>',
isCheckoutEnable: false,
baseUrl: '',
// pathStore: (self.parent.location.pathname).replace("BBGet", 'BB'),
pathStore: 'buy/'+self.parent.pathStore+'/indaco-BB.php',
checkoutUrl: '',
staticUrl:'',
redirectToProduct: false,
checkoutTemplate: '',
cartTemplate:'<div class=bb-mini-cart-container :class=childData.cart.isVisible><div class=bb-cart-wrapper v-if=childData.cart.cartItems.length><div class=bb-mini-cart-head><div class=bb-cart-details><div class=bb-cart-items-summary><span class=bb-strong>{{itemsCount}} </span><span>{{childData.itemInCartText}}</span></div><div class=bb-cart-subtotal><span>{{childData.subTotalText}}: </span><span class=bb-strong>{{subTotal}}</span></div></div><div class=bb-cart-checkout><button @click=checkout() class=button>{{childData.cButtonText}}</button></div><div id="buybutton-modal-close-action" class="buybutton-modal-close"><i class="rango-cross"></i></div></div><div class=bb-mini-cart-body><div class=bb-cart-items><div class=bb-cart-item v-for="(value, key) in childData.cart.cartItems"><div class=bb-cart-item-image><img :src=value.image ></div><div class=bb-cart-item-details><div class=bb-cart-item-name>{{value.name}}<custom-options :options=value></custom-options></div><div class="bb-strong bb-cart-item-price"v-html=value.formattedPrice></div><div class=bb-cart-item-qty><span>{{childData.qtyText}}: </span><input class=bb-item-qty-text v-model=value.qty v-on:focus="takeBackup(value)" @change="updateItem(value)"></div><div class=bb-cart-item-actions><i @click=removeItem(value.id) class="bb-delete-item rango-delete"></i></div></div></div></div></div></div><p class=no-data-found v-else>{{childData.noItemFoundText}}</p></div>',
quickViewTemplate: '<div class=buybutton-modal-container id=buybutton-modal-container-action><div class=buybutton-modal><div class=buybutton-modal-left><div class=buybutton-modal-image><img :src=item.image class=buybutton-modal-img></div></div><div class=buybutton-modal-right><div class=buybutton-product-details><div class=buybutton-product-name><span>{{item.name}}</span></div><div class=buybutton-item-price v-if="item.price == 0"><b>Al momento questo prodotto non è vendibile online</b></div><div class=buybutton-product-price v-if="item.price > 0"><span>{{formattedPrice}}</span></div><div class="buybutton-product-addtocart buybutton-add" v-if="item.price > 0">' +
'<div class="quantity-control"><button @click="decreaseQuantity(item)" class="quantity-button">-</button><input :id="\'quantity-\' + item.sku" class="quantity-input" type="number" min="1" value="1"><button @click="increaseQuantity(item)" class="quantity-button">+</button></div>' +
'<button @click=addToCart(item) class=buybutton-primary type=button><span>{{addToCartLabel}}</span></button></div><div class=buybutton-product-description><span v-html=item.description></span></div><div class="bb-option-wrapper"><options-wrapper :options=item.custom_option></options-wrapper></div><div class=bb-configurable-option-wrapper><configurable-options :coptions=item.super_attributes></configurable-options></div></div></div><div class=buybutton-modal-close id=buybutton-modal-close-action><i class=rango-cross></i></div></div></div>',
products: {},
styles:'',
productIds: [],
element: 'buybutton-init',
viewButton: 'buybutton-view-product',
styleUrl: '/style.css',
handlebarUrl: '/handlebars.min.js',
vueUrl: '/vue.min.js',
jqueryUrl: '/jquery.min.js',
miniCartText: 'Cart',
addToCartText: 'Aggiungi al carrello',
buyNowText: 'Buy Now',
vButtonText: 'View Details',
itemInCartText: 'Item In Cart',
cButtonText: 'Proceed To Checkout',
noItemFoundText: 'No items found in cart.',
qtyText: 'Qty',
subTotalText: 'Cart Subtotal',
currency_code: 'USD',
locale: 'en-us',
designTemplate: 1,
storeId: self.parent.storeId
};
// Create options by extending defaults with the passed in arugments
if (arguments[0] && typeof arguments[0] === "object") {
this.options = extendDefaults(defaults, arguments[0]);
} else {
this.options = defaults;
}
//include necessary js and css files
this.initialize();
}
/**
* initializing the plugin
*/
BuyButton.prototype.initialize = function() {
var self = this;
/**
* get promises array for loading js
*/
let promises = self.extraIncludes();
wkBuyButtonRegistry.currenctObject = self;
promises[0].then(function(resolve) {
return promises[1];
}).then(function(resolve1) {
return promises[2];
}).then(function() {
/**
* start loading components
*/
self.load();
});
}
/**
* include js and css in the head
*/
BuyButton.prototype.extraIncludes = function() {
var self = this;
//include css
var style = d.getElementsByTagName('head')[0];
var link = d.createElement('link');
link.href = self.options.staticUrl+self.options.styleUrl;
link.rel = 'stylesheet';
link.type = 'text/css';
style.appendChild(link);
var jsScripts = d.getElementsByTagName('head')[0];
var promises = [];
/**
* function to load srcipts
*
* @param string type
*/
let loadJs = function(type) {
let promise = new Promise(function(resolve, reject) {
var script = d.createElement('script');
script.async = true;
script.onload = function () {
resolve(1);
};
switch(type) {
case 'jquery':
script.src = self.options.staticUrl+self.options.jqueryUrl;
break;
case 'vue':
script.src = self.options.staticUrl+self.options.handlebarUrl;
break;
case 'handlebar':
script.src = self.options.staticUrl+self.options.vueUrl;
break;
default:
//
}
jsScripts.appendChild(script, jsScripts);
});
return promise;
};
//load jquery
if (typeof jQuery == 'undefined') {
promises.push(loadJs('jquery'));
}
//include handlebar js
if (typeof Handlebars == 'undefined') {
promises.push(loadJs('handlebar'));
}
//include vuejs
if (typeof Vue == 'undefined') {
promises.push(loadJs('vue'));
}
return promises;
}
/**
* load the plugin with vue components
*/
BuyButton.prototype.load = function() {
var self = this;
if (typeof jQuery != 'undefined') {
$ = jQuery;
}
setupAjaxLoader();
/**
* product custom options component
*/
Vue.component('options-wrapper', {
props: {
options:
{
type: Array,
required: true
}
},
data: function() {
return {
parentItem: this.$parent.item
};
},
methods: {
updatePrice: function(event, item) {
let optionId = item.option_id;
let changePricesArray = this.$parent.changedPrice;
let flag = -1;
for (var i = 0; i < changePricesArray.length; i++) {
if (changePricesArray[i].optionId == optionId) {
flag = i;
break;
}
}
if (item.type == 'drop_down' || item.type == 'radio') {
let optionValues = item.values;
let optionTypeId = 0;
if (item.type == 'drop_down') {
let tempVal = $(event.target).val().split("_");
optionTypeId = tempVal[0];
} else if (item.type == 'radio') {
optionTypeId = $(event.target).val();
}
for (var j=0; j< optionValues.length; j++) {
if (optionValues[j].option_type_id == optionTypeId) {
if (flag == -1) {
this.$parent.changedPrice.push(
{
optionId: optionId,
optionPrice : this.actualPrice(optionValues[j])
}
);
} else {
changePricesArray[flag].optionPrice = this.actualPrice(optionValues[j]);
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
}
}
}
} else if (item.type == 'file' || item.type == 'area' || item.type == 'field') {
if (flag == -1) {
this.$parent.changedPrice.push(
{
optionId: optionId,
optionPrice : this.actualPrice(item)
}
);
} else {
if ($(event.target).val().length > 0) {
changePricesArray[flag].optionPrice = this.actualPrice(item);
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
} else {
changePricesArray[flag].optionPrice = 0;
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
}
}
} else if (item.type == 'multiple') {
let optionTypeId = $(event.target).val();
let tempP = 0;
if (optionTypeId && optionTypeId.length) {
for (var i=0; i < optionTypeId.length; i++ ) {
let p = optionTypeId[i].split("_");
tempP += parseFloat(p[1]);
}
}
if (flag == -1) {
this.$parent.changedPrice.push(
{
optionId: optionId,
optionPrice : tempP
}
);
} else {
changePricesArray[flag].optionPrice = tempP;
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
}
} else if (item.type == 'checkbox') {
let optionValues = item.values;
let checkboxes = $(".bb-input-text-control > .checkbox");
let optionTypeId = $(event.target).val();
for (var j=0; j< optionValues.length; j++) {
if (optionValues[j].option_type_id == optionTypeId) {
if (flag == -1) {
this.$parent.changedPrice.push(
{
optionId: optionId,
optionPrice : this.actualPrice(optionValues[j])
}
);
} else {
if ($(event.target).is(":checked")) {
changePricesArray[flag].optionPrice += this.actualPrice(optionValues[j]);
} else {
changePricesArray[flag].optionPrice -= this.actualPrice(optionValues[j]);
}
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
}
}
}
} else if (item.type == 'date') {
let dateOptions = $(event.target).parent().find("select");
let sFlag = true;
for (var i=0; i < dateOptions.length; i++) {
if (!dateOptions[i].value) {
sFlag = false;
break;
}
}
if (flag == -1 && sFlag) {
this.$parent.changedPrice.push(
{
optionId: optionId,
optionPrice : this.actualPrice(item)
}
);
} else if (flag != -1) {
if (sFlag) {
changePricesArray[flag].optionPrice = this.actualPrice(item);
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
} else {
changePricesArray[flag].optionPrice = 0;
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
}
}
} else if (item.type == 'date_time') {
let dateTimeOptions = $(event.target).parent().find("select");
let sFlag = true;
for (var i=0; i < dateTimeOptions.length; i++) {
if (!dateTimeOptions[i].value) {
sFlag = false;
break;
}
}
if (flag == -1 && sFlag) {
this.$parent.changedPrice.push(
{
optionId: optionId,
optionPrice : this.actualPrice(item)
}
);
} else if (flag != -1) {
if (sFlag) {
changePricesArray[flag].optionPrice = this.actualPrice(item);
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
} else {
changePricesArray[flag].optionPrice = 0;
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
}
}
} else if(item.type == 'time') {
let timeOptions = $(event.target).parent().find("select");
let sFlag = true;
for (var i=0; i < timeOptions.length; i++) {
if (!timeOptions[i].value) {
sFlag = false;
break;
}
}
if (flag == -1 && sFlag) {
this.$parent.changedPrice.push(
{
optionId: optionId,
optionPrice : this.actualPrice(item)
}
);
} else if (flag != -1) {
if (sFlag) {
changePricesArray[flag].optionPrice = this.actualPrice(item);
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
} else {
changePricesArray[flag].optionPrice = 0;
this.$parent.changedPrice = [];
this.$parent.changedPrice = changePricesArray;
}
}
}
},
actualPrice: function(item) {
let itemPrice = 0;
if (item.default_price_type == 'percent') {
itemPrice = this.parentItem.fixedPrice*(parseFloat(item.default_price)/100);
} else {
itemPrice = parseFloat(item.default_price);
}
return itemPrice;
}
},
render: function (createElement) {
const that = this;
const nameSeparator = '||';
let months = ['-','01','02','03','04','05','06','07','08','09','10','11','12'],
hours = ['-','01','02','03','04','05','06','07','08','09','10','11','12','13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '00'];
let minutes = [];
minutes.push('-');
for(var m=1; m<=60; m++) {
if (m.toString().length == 1) {
minutes.push(("0" + m).slice(-2));
} else {
minutes.push(m.toString());
}
}
let days = [];
days.push('-');
for(var m=1; m<=31; m++) {
if (m.toString().length == 1) {
days.push(("0" + m).slice(-2));
} else {
days.push(m.toString());
}
}
let years = [];
years.push('-');
years.push((new Date()).getFullYear());
var actualPrice = function(item) {
return that.actualPrice(item);
};
var textArea = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements bb-option'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locate, that.parentItem.currenyCode, actualPrice(item))),
createElement('div', {class: 'bb-input-text-control'}, [
createElement('textarea', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
class:'textarea', attrs:{dataId:item.option_id, dataValidate: dataValidate, name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`, rows:'5', cols:'25'}}),
createElement('div', {class: 'bb-option-notice'}, [
createElement('p', 'Maximum number of characters: '+item.max_characters),
])
])
]
)};
var textField = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
createElement('div', {class: 'bb-input-text-control'}, [
createElement('input', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataId:item.option_id, dataValidate:dataValidate, type: 'text',name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`}, class:'text-input'}),
createElement('div', {class: 'bb-option-notice'}, [
createElement('p', 'Maximum number of characters: '+item.max_characters),
])
])
]
)};
var multipleField = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title),
createElement('div', {class: 'bb-input-text-control'}, [
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
class:'select multiple',
attrs: {dataId:item.option_id, dataValidate:dataValidate, multiple: 'multiple', name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`},
}, [
item.values.map(function(v, i) {
return createElement('option', {domProps: {value: v.option_type_id+'_'+actualPrice(v)} }, v.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(v)))
})
])
])
]
)};
var timeField = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
createElement('div', {class: 'bb-input-text-control'}, [
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataId:item.option_id, dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}hours`}, class:'date-time-options'}, [
hours.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
]),
createElement("b", ':'),
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataId:item.option_id, dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}minutes`}, class:'date-time-options'}, [
minutes.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
])
])
]
)};
var dateTimeField = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
createElement('div', {class: 'bb-input-text-control'}, [
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}year`}, class:'date-time-options'}, [
years.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
]),
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}month`}, class:'date-time-options'}, [
months.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
]),
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}day`}, class:'date-time-options'}, [
days.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
]),
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}hours`}, class:'date-time-options'}, [
hours.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
]),
createElement("b", ':'),
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}minutes`}, class:'date-time-options'}, [
minutes.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
])
])
]
)};
var dateField = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
createElement('div', {class: 'bb-input-text-control'}, [
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}year`}, class:'date-time-options'}, [
years.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
]),
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}month`}, class:'date-time-options'}, [
months.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
]),
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}day`}, class:'date-time-options'}, [
days.map( (v, i) => {
return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
})
])
])
]
)};
var selectField = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title),
createElement('div', {class: 'bb-input-text-control'}, [
createElement('select', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
}, class:'select', attrs: {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
dataValidate:dataValidate, name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`}}, [
item.values.map(function(v, i) {
return createElement('option', {domProps: {value: v.option_type_id+'_'+actualPrice(v)}}, v.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(v)))
})
])
])
]
)};
var checkboxField = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title),
item.values.map((v, i)=> {
return createElement('div', {class: 'bb-options-container'},[
createElement('div', {class: 'bb-input-text-control'}, [
createElement('input', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
domProps: {value: v.option_type_id}, attrs: {dataValidate:dataValidate, type: 'checkbox', name:`option${nameSeparator}${item.type}${nameSeparator}${v.option_id}`}, class:'checkbox'}),
createElement('label', v.default_title+' + '+ getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(v)))
])
])
})
]
)};
var radioField = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title),
item.values.map((v, i)=> {
return createElement('div', {class: 'bb-options-container'},[
createElement('div', {class: 'bb-input-text-control'}, [
createElement('input', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
domProps: {value: v.option_type_id}, attrs: {dataValidate:dataValidate, type: 'radio', name:`option${nameSeparator}${item.type}${nameSeparator}${v.option_id}`}, class:'radio'}),
createElement('label', v.default_title+' + '+ getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(v)))
]),
]);
})
]
)};
var fileField = function(item) {
let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
return createElement('div', {class: 'option-elements'},
[
createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+ getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
createElement('div', {class: 'bb-input-text-control'}, [
createElement('input', {
on: {
input: (e) => {
that.updatePrice(e, item)
}
},
attrs:{dataValidate:dataValidate, type:'file', name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`},class:'file bb-file-type-option'}),
createElement('div', {class: 'bb-option-notice'}, [
createElement('p', 'Compatible file extensions to upload: '+item.file_extension),
createElement('p', 'Maximum image width: '+item.image_size_x),
createElement('p', 'Maximum image height: '+item.image_size_y)
])
])
]
)};
return createElement('div', {class: 'options-wrapper'},
[
createElement("form", {attrs: {id: 'options-wrapper-form', encType: 'multipart/form-data'}}, [
that.options.map((jsonitem, i) => {
let item = JSON.parse(jsonitem);
let type = item.type;
switch(type) {
case 'file':
return createElement('div', {class: 'option-wrapper'}, [fileField(item)]);
case 'drop_down':
return createElement('div', {class: 'option-wrapper'}, [selectField(item)]);
case 'multiple':
return createElement('div', {class: 'option-wrapper'}, [multipleField(item)]);
break;
case 'date':
return createElement('div', {class: 'option-wrapper'}, [dateField(item)]);
break;
case 'date_time':
return createElement('div', {class: 'option-wrapper'}, [dateTimeField(item)]);
break;
case 'time':
return createElement('div', {class: 'option-wrapper'}, [timeField(item)]);
break;
case 'checkbox':
return createElement('div', {class: 'option-wrapper'}, [checkboxField(item)]);
break;
case 'radio':
return createElement('div', {class: 'option-wrapper'}, [radioField(item)]);
break;
case 'area':
return createElement('div', {class: 'option-wrapper'}, [textArea(item)]);
break;
case 'field':
return createElement('div', {class: 'option-wrapper'}, [textField(item)]);
break;
}
})
])
],
);
}
});
/**
* component for showing custom option and configurable attributes in cart
*/
Vue.component('custom-options', {
props: {
options: {
type: Object,
required: true
}
},
methods: {
getFormattedOptions: function() {
/**
* array for containing options label and value for showing
*/
let o = [];
let products = self.options.products.items;
let sku = this.options.sku;
if (this.options.custom_options.length > 0) {
for(var i=0; i< products.length; i++) {
if (products[i].extension_attributes.sku == sku || sku.indexOf(products[i].extension_attributes.sku) == 0) {
for (var j = 0; j < this.options.custom_options.length; j++) {
for (var k=0; k<products[i].extension_attributes.custom_options.length;k++) {
let co = JSON.parse(products[i].extension_attributes.custom_options[k]);
let opV = '';
let opA = [];
if (co.values) {
if (co.type == 'checkbox' || co.type == 'multiple') {
let tempV = this.options.custom_options[j].option_value.split(",");
for(m=0; m<co.values.length; m++) {
if ($.inArray(co.values[m].option_type_id, tempV) != -1) {
opA.push(co.values[m].default_title);
}
}
opV = opA.join(",");
} else {
let tempV = this.options.custom_options[j].option_value;
for(m=0; m<co.values.length; m++) {
if (parseInt(co.values[m].option_type_id) == parseInt(tempV)) {
opV = co.values[m].default_title;
}
}
}
} else {
if (co.type == 'file') {
let fileData = this.options.custom_options[j].option_value.split(",");
opV = fileData[1];
} else if (co.type == 'date') {
let d = new Date(this.options.custom_options[j].option_value);
opV = d.toLocaleDateString(self.options.locale, {weekday: 'short', year: 'numeric',month: 'short',day: 'numeric'});
} else if (co.type == 'date_time') {
let d = new Date(this.options.custom_options[j].option_value);
opV = d.toLocaleString(self.options.locale, {weekday: 'short', year: 'numeric',month: 'short',day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric'});
} else if (co.type == 'time') {
let d = new Date(this.options.custom_options[j].option_value);
opV = d.toLocaleTimeString(self.options.locale, {hour: 'numeric', minute: 'numeric', second: 'numeric'});
} else {
opV = this.options.custom_options[j].option_value;
}
}
if (co.option_id == this.options.custom_options[j].option_id) {
o.push({option_id: co.default_title, option_value: opV});
break;
}
}
}
break;
}
}
}
/**
* creating label value array for configuarble products
*/
if (this.options.super_attributes.length > 0) {
let fl = 0;
if (this.options.super_attributes.length > 0) {
for (key in this.options.super_attributes) {
for(var i=0; i< products.length; i++) {
if (products[i].extension_attributes.super_attributes) {
let superAttr = JSON.parse(products[i].extension_attributes.super_attributes);
let attrs = superAttr.attributes;
for (key1 in attrs) {
if (parseInt(key1) == parseInt(this.options.super_attributes[key].option_id)) {
o.push({option_id: attrs[key1].label, option_value: attrs[key1].options.map((v, i)=>{
if (this.options.super_attributes[key].option_value == v.id) {
return v.label;
}
})});
fl = 1;
}
}
if (fl == 1) {
fl = 0;
break;
}
}
}
}
}
}
return o;
}
},
/**
* render component html
*/
render: function(ce) {
/**
* render html for label values for product options
*/
if (this.options.custom_options.length > 0 || this.options.super_attributes.length || this.options.product_option.length) {
// if (this.options.product_option.length > 0) {
return ce("div", {class: 'bb-item-options-details'}, [
ce("span", {
on: {
click: function(event) {
$(event.target).next().slideToggle(1000);
}},
class: 'bb-view-options-details-show'
}, "View Details"),
ce("div", {class:"bb-view-options-details-container bb-hide"}, [
this.options.product_option.map( (v, i) => {
return ce('div', {class: 'bb-option-details'}, [
ce("b", v.option_id+' : '),
ce("b", v.option_value)
])
}),
this.options.custom_options.map( (v, i) => {
return ce('div', {class: 'bb-option-details'}, [
ce("b", v.option_id+' : '),
ce("b", v.option_value)
])
})
])
]);
// }
}
}
});
/**
* component for building configurable options for product add to cart form
*/
Vue.component('configurable-options', {
props: {
/**
* used to get data from parent component
*/
coptions: {
type: Object,
required: true
}
},
/**
* executes after the component and template both loaded
*/
mounted: function() {
this.$nextTick( () => {
this.updatePriceAndImage();
})
},
methods: {
updatePriceAndImage: function() {
let fields = $(".configuarbele-options").find(':input');
let selectedOptions = [];
let productId = 0;
let images = {};
let prices = {};
$.each (fields, function(index, value) {
selectedOptions.push(value.value);
});
for (key in this.coptions.index) {
if (selectedOptions.sort().join(",") === Object.values(this.coptions.index[key]).sort().join(",")) {
productId = key;
break;
}
}
if (productId) {
for (key in this.coptions.images) {
if (productId == key) {
images = this.coptions.images[key];
break;
}
}
for (key in this.coptions.optionPrices) {
if (productId == key) {
prices = this.coptions.optionPrices[key];
}
}
if (Object.keys(prices).length) {
this.$parent.item.price = prices.finalPrice.amount;
if (images) {
this.$parent.item.image = images[0].img;
}
}
}
}
},
render: function (createElement) {
let that = this;
var selectField = function(item) {
let nameSeparator = "-";
let dataValidate = '{"required":"1"}';
return createElement('div', {class: 'configurable-option-elements'},
[
createElement('label', {class:'label required'}, item.label),
createElement('div', {class: 'bb-input-text-control'}, [
createElement('select', {
on: {
input: (e) => {
that.updatePriceAndImage();
}
},
class:'select', attrs: {
dataValidate:dataValidate, name:`option${nameSeparator}${item.id}`}}, [
item.options.map(function(v, i) {
return createElement('option', {domProps: {value: v.id}}, v.label)
})
])
])
]
)};
if (this.coptions.attributes) {
return createElement('div', {class:'configuarbele-options'}, [
Object.values(this.coptions.attributes).map((v, i) => {
return selectField(v)
})
]);
}
}
});
/**
* product is passed in the plugin
*/
var pIds = self.options.productIds;
/**
* rest url to get the product details from magento
*/
var getProductsUrl = self.options.baseUrl+"rest/V1/products-render-info?"+
`storeId=${self.options.storeId}¤cyCode=${self.options.currency_code}&`+
"searchCriteria[filter_groups][0][filters][0][field]=entity_id&"+
"searchCriteria[filter_groups][0][filters][0][value]="+pIds+"&"+
"searchCriteria[filter_groups][0][filters][0][condition_type]=in";
/**
* making request for products details with promises
*/
var getProductsData = getRequestPromise({
url: getProductsUrl,
method: 'GET'
});
getProductsData.then(
(function(response) {
var self = this;
//console.log(response.items[3].extension_attributes.super_attributes);
self.options.products = response;
if (localStorage) {
localStorage.setItem('bb-mage-products', self.options.products);
}
/**
* after successfull api request render vue components
*/
self.renderVue();
}).bind(self),
function(error) {
console.log(error);
}
);
},
/**
* render vue components and child components
*/
BuyButton.prototype.renderVue = function() {
var self = this;
d.getElementById('buybutton-init').insertAdjacentHTML( 'beforeend', self.options.template );
var productsObject = self.options.products;
/**
* initialize cart data for the current website
*/
getCartInitialData.call(this);
/**
* init vue component for products
*/
self.vueContainerModel = new Vue({
el: '#buybutton-container-id',
data: function() {
let cartItem = {};
if (productsObject.items.length == 1) {
let item = productsObject.items[0];
cartItem = {
name: item.name,
price: item.price_info.final_price,
currenyCode: item.currency_code,
type: item.type,
description: item.extension_attributes.description,
custom_option: item.extension_attributes.custom_options,
super_attributes: item.extension_attributes.super_attributes?JSON.parse(item.extension_attributes.super_attributes):{},
sku: item.extension_attributes.sku,
image: item.images[0].url,
fixedPrice: item.price_info.final_price,
qty: item.qty,
id: item.id,
};
}
return {
products: productsObject.items,
cart: cart,
styles: self.options.styles,
designTemplate: self.options.designTemplate,
childData: {
miniCartText: self.options.miniCartText,
addToCartText: self.options.addToCartText,
buyNowText: self.options.buyNowText,
itemInCartText: self.options.itemInCartText,
cButtonText: self.options.cButtonText,
vButtonText: self.options.vButtonText,
noItemFoundText:self.options.noItemFoundText,
qtyText:self.options.qtyText,
subTotalText: self.options.subTotalText,
cart:cart
},
changedPrice: [],
item: cartItem
};
},
watch: {
designTemplate: {
handler: function(oldV, newV) {
if (oldV == 3) {
$(".buybutton-items > .buybutton-item").width("100%");
$(".buybutton-item-image > img").css("border", "none");
} else {
$(".buybutton-items > .buybutton-item").removeAttr("style");
$(".buybutton-item-image > img").css("border-bottom", "1px solid #ccc");
}
}
},
changedPrice : {
handler: function(priceArray, changedValue) {
let totalPrice = 0;
for (var i=0; i < changedValue.length; i++) {
totalPrice += parseFloat(changedValue[i].optionPrice);
}
this.item.price = totalPrice + this.item.fixedPrice;
}
}
},
mounted: function() {
this.$nextTick( () => {
this.addStyleTag;
if (this.products.length == 1) {
$(".buybutton-items > .buybutton-item").addClass("buybutton-item-full");
$(".buybutton-item-image img").css("border", "none");
} else {
let width = $("#buybutton-init").width();
setResponsiveWith(width);
}
})
},
methods: {
addToCart: function(cartItem) {
if (validateData.call(this)) {
let postData = buildAddToCartData.call(this, cartItem);
addProductsToCart.call(this, postData, self);
}
},
increaseQuantity(key) {
const quantityInput = document.getElementById("quantity-" + key.extension_attributes.sku);
if (quantityInput) {
let currentValue = parseInt(quantityInput.value);
currentValue++;
quantityInput.value = currentValue;
}
},
decreaseQuantity(key) {
const quantityInput = document.getElementById("quantity-" + key.extension_attributes.sku);
if (quantityInput) {
let currentValue = parseInt(quantityInput.value);
if (currentValue > 1) {
currentValue--;
quantityInput.value = currentValue;
}
}
},
view: function(data) {
self.modalOpen(data);
},
redirect: function (data) {
if (parseInt(self.options.redirectToProduct)) {
window.top.location.href = data.url;
} else {
this.view(data);
}
},
showCart: function(event) {
const cartContainer = document.querySelector('.bb-mini-cart-body');
if (!cartContainer.contains(event.target)) {
if (cart.isVisible == 'bb-show') {
cart.isVisible = 'bb-hide';
} else {
cart.isVisible = 'bb-show';
}
}
},
closeCheckout: function() {
document.getElementById("bb-checkout-iframe").removeEventListener('load', function(){});
$("#bb-checkout-iframe").remove();
$("#bb-checkout-container").hide();
}
},
computed: {
addStyleTag: function() {
let css = this.styles.trim();
var head = document.head || document.getElementsByTagName('head')[0];
if (document.getElementById("dynamicCss")) {
document.getElementById("dynamicCss").innerText = css;
} else {
var style = document.createElement('style');
style.type = 'text/css';
style.id = 'dynamicCss';
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
}
return css;
},
itemsCount: function() {
let cartData = this.cart.cartItems;
let itemCount = 0;
if (cartData.length > 0) {
cartData.forEach(function(value, index) {
let qty = parseInt(value.qty)?parseInt(value.qty):0;
itemCount = itemCount + qty;
});
}
return itemCount;
},
formattedPrice: function() {
return getFormattedPrice(self.options.locale, this.item.currenyCode, this.item.price)
}
},
/**
* adding mini cart child component inside products template
*/
components: {
'mini-cart': {
template: self.options.cartTemplate,
data: function () {
return {
childData: this.$parent.childData
};
},
methods: {
removeItem: function(itemId) {
var currentThis = this;
let token = localStorage.getItem("magento-cart-id");
let removeFromCart = getRequestPromise({
url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items/'+itemId,
method: 'DELETE'
});
removeFromCart.then(function(response) {
cart.cartItems.forEach(function(value, index) {
if (value.id == itemId) {
cart.cartItems.splice(index, 1);;
}
});
});
},
takeBackup: function(item) {
this._beforeEditingCache = item.qty;
},
updateItem: function(item) {
if (item.qty > 0) {
var currentThis = this;
let token = localStorage.getItem("magento-cart-id");
let updateCart = getRequestPromise({
url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items/'+item.id,
method: 'PUT',
data: JSON.stringify({
cartItem: {
item_id: item.id,
qty: parseInt(item.qty),
quote_id: token
}
})
});
updateCart.then(function(response) {
this._beforeEditingCache = item.qty;
}, function(reject) {
item.qty = this._beforeEditingCache;
}
);
} else {
item.qty = this._beforeEditingCache;
}
//return updateCart;
},
checkout: function() {
//jQuery('#bb-checkout-container').show();
let checkoutSrc = self.options.baseUrl+`bb/index/index/?access=${localStorage.getItem("magento-cart-quote-id")}`;
var dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : window.screenX;
var dualScreenTop = window.screenTop != undefined ? window.screenTop : window.screenY;
var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
var left = ((width / 2) - (700 / 2)) + dualScreenLeft;
var top = ((height / 2) - (700 / 2)) + dualScreenTop;
if (window.innerWidth <= 700) {
window.open(checkoutSrc, 'popup', 'scrollbars=yes, width=700px, height=1000px, top=' + top + ', left=' + left);
} else {
left = ((width / 2) - (500 / 2)) + dualScreenLeft;
window.open(checkoutSrc, 'popup', 'scrollbars=yes, width=500px, height=500px, top=' + top + ', left=' + left);
}
},
getOptions() {
return getFormattedOptions.call(self, cartItem, );
}
},
computed: {
subTotal: function() {
let cartData = cart.cartItems;
let subTotal = 0;
if (cartData.length > 0) {
cartData.forEach(function(value, index) {
subTotal = subTotal+(value.price*value.qty);
});
}
return getFormattedPrice.call(self, self.options.locale, self.options.currency_code, subTotal);
},
itemsCount: function() {
let cartData = cart.cartItems;
let itemCount = 0;
if (cartData.length > 0) {
cartData.forEach(function(value, index) {
let qty = parseInt(value.qty)?parseInt(value.qty):0;
itemCount = itemCount + qty;
});
}
return itemCount;
}
}
}
}
});
}
/**
* product quick vue modal
*/
BuyButton.prototype.modalOpen = function() {
var self = this;
let item = arguments[0];
let template = this.options.quickViewTemplate;
this.optionsData = {
extensionAttributes: {
customOptions: []
}
};
this.optionsPrice = [];
d.getElementById('buybutton-init').insertAdjacentHTML( 'beforeend', template );
/**
* quick view component
*/
self.vueQuickModel = new Vue({
el: '.buybutton-modal-container',
data: {
item: {
name: item.name,
price: item.price_info.final_price,
currenyCode: item.currency_code,
type: item.type,
description: item.extension_attributes.description,
custom_option: item.extension_attributes.custom_options,
super_attributes: item.extension_attributes.super_attributes?JSON.parse(item.extension_attributes.super_attributes):{},
sku: item.extension_attributes.sku,
image: item.images[0].url,
fixedPrice: item.price_info.final_price,
id: item.id,
},
changedPrice:[],
addToCartLabel: window.wkaddTocartLabel.text
},
watch: {
changedPrice : {
handler: function(priceArray, changedValue) {
let totalPrice = 0;
for (var i=0; i < changedValue.length; i++) {
totalPrice += parseFloat(changedValue[i].optionPrice);
}
this.item.price = totalPrice + this.item.fixedPrice;
}
}
},
methods: {
addToCart: function(cartItem) {
if (validateData.call(this)) {
let postData = buildAddToCartData.call(this, cartItem);
addProductsToCart.call(this, postData, self);
fetch(self.options.baseUrl+self.options.pathStore, {
method: 'POST',
body: JSON.stringify({productId: this.item.id, action: 2}),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {})
.then(data => {})
.catch(error => {});
}
},
increaseQuantity(key) {
const quantityInput = document.getElementById("quantity-" + key.sku);
if (quantityInput) {
let currentValue = parseInt(quantityInput.value);
currentValue++;
quantityInput.value = currentValue;
}
},
decreaseQuantity(key) {
const quantityInput = document.getElementById("quantity-" + key.sku);
if (quantityInput) {
let currentValue = parseInt(quantityInput.value);
if (currentValue > 1) {
currentValue--;
quantityInput.value = currentValue;
}
}
},
},
computed: {
formattedPrice: function() {
return getFormattedPrice(self.options.locale, this.item.currenyCode, this.item.price)
}
}
});
d.getElementById("buybutton-modal-close-action").addEventListener('click', function() {self.modalClose() });
// let scrollTop = window.top.scrollY - parent.document.getElementById('indacoContainer').getBoundingClientRect().y;//document.body.scrollTop;
scrollTop = 0;
if (parent.document.getElementById('indacoContainer')) {
scrollTop = (parent.document.getElementById('indacoContainer').getBoundingClientRect().y * -1) + 20;
if (scrollTop<0) { scrollTop = 10; }
if (scrollTop>(parent.document.getElementById('indacoContainer').getBoundingClientRect().height-document.getElementsByClassName("buybutton-modal")[0].scrollHeight)) {
scrollTop = parent.document.getElementById('indacoContainer').getBoundingClientRect().height-document.getElementsByClassName("buybutton-modal")[0].scrollHeight;
}
d.getElementsByClassName("buybutton-modal")[0].style.maxHeight = (parent.document.getElementById('indacoContainer').getBoundingClientRect().height - 40) + 'px';
}
if (scrollTop<0) { scrollTop = 10; }
scrollTop = scrollTop + 'px';
d.getElementsByClassName("buybutton-modal")[0].style.marginTop = scrollTop;
fetch(self.options.baseUrl+self.options.pathStore, {
method: 'POST',
body: JSON.stringify({productId: item.id, action: 1}),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {})
.then(data => {})
.catch(error => {});
}
BuyButton.prototype.modalClose = function() {
d.getElementById("buybutton-modal-container-action").remove();
}
/** extend default parameters */
function extendDefaults(source, properties) {
var property;
for (property in properties) {
if (properties.hasOwnProperty(property)) {
source[property] = properties[property];
}
}
return source;
}
/**
* initialize cart data using magento rest
*/
function getCartInitialData()
{
var self = this;
let token = localStorage.getItem("magento-cart-id");
if (!token) {
getRequestPromise({
url: self.options.baseUrl+'rest/V1/guest-carts'
}).then(function (response) {
token = response
localStorage.setItem("magento-cart-id", response);
getRequestPromise({
url: self.options.baseUrl+'rest/V1/guest-carts/'+token,
method: 'GET'
}).then(
function (response) {
cart.quoteId = response.quote_id;
localStorage.setItem("magento-cart-quote-id", response.id);
},
function (error) {
localStorage.removeItem("magento-cart-quote-id");
localStorage.removeItem("magento-cart-id");
}
);
}, function (error) {
localStorage.removeItem("magento-cart-quote-id");
localStorage.removeItem("magento-cart-id");
});
} else {
getRequestPromise({
url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items?currency_code='+self.options.currency_code,
method: 'GET'
}).then(
function (response) {
if(response.length > 0) {
updateCart.call(self, response);
}
},
function (error) {
localStorage.removeItem("magento-cart-quote-id");
localStorage.removeItem("magento-cart-id");
}
);
}
}
/**
* update cart data
*
* @param object response
*/
function updateCart(response) {
let self = this;
if (cart.cartItems.length > 0) {
cart.cartItems = [];
}
if (cart.cartItems.length == 0) {
if (response.length > 0) {
response.forEach( function(value, key) {
let customOptions = [];
let superAttributes = [];
let productOptions = [];
if (value.product_option && value.product_option.extension_attributes && value.product_option.extension_attributes.custom_options) {
customOptions = value.product_option.extension_attributes.custom_options;
}
if (value.product_option && value.product_option.extension_attributes && value.product_option.extension_attributes.configurable_item_options) {
superAttributes = value.product_option.extension_attributes.configurable_item_options;
}
if (value.product_option && value.product_option.extension_attributes && value.product_option.extension_attributes.configurable_item_options) {
productOptions = value.product_option.extension_attributes.configurable_item_options;
}
cart.cartItems.push({
id: value.item_id,
image: '',
sku:value.sku,
name: value.name,
price: value.price,
formattedPrice: getFormattedPrice.call(self, self.options.locale, self.options.currency_code, value.price),
qty: value.qty,
custom_options: customOptions,
super_attributes: superAttributes,
product_option: productOptions
});
cart.quoteId = value.quote_id;
$.each(cart.cartItems, function(k, value) {
let selfScope = self;
var getProductsUrl = self.options.baseUrl+"rest/V1/products-render-info?"+
`storeId=${self.options.storeId}¤cyCode=${self.options.currency_code}&`+
"searchCriteria[filter_groups][0][filters][0][field]=sku&"+
"searchCriteria[filter_groups][0][filters][0][value]="+value.sku+"&"+
"searchCriteria[filter_groups][0][filters][0][condition_type]=eq";
/**
* making request for products details with promises
*/
var getProductsData = getRequestPromise({
url: getProductsUrl,
method: 'GET'
});
getProductsData.then(
(function(response) {
if (response.items.length == 0) {
var getProductsUrl = selfScope.options.baseUrl+"rest/V1/products-render-info?"+
`storeId=${selfScope.options.storeId}¤cyCode=${selfScope.options.currency_code}&`+
"searchCriteria[filter_groups][0][filters][0][field]=name&"+
"searchCriteria[filter_groups][0][filters][0][value]="+value.name+"&"+
"searchCriteria[filter_groups][0][filters][0][condition_type]=eq";
var getProductData = getRequestPromise({
url: getProductsUrl,
method: 'GET'
});
getProductData.then(
(function(response) {
var item = response.items;
url = item[0].images[0].url;
value.image = url;
if (value.super_attributes.length > 0) {
let fl = 0;
let o = [];
for (key in value.super_attributes) {
for(var i=0; i< item.length; i++) {
if (item[i].extension_attributes.super_attributes) {
let superAttr = JSON.parse(item[i].extension_attributes.super_attributes);
let attrs = superAttr.attributes;
for (key1 in attrs) {
if (parseInt(key1) == parseInt(value.super_attributes[key].option_id)) {
o.push({option_id: attrs[key1].label, option_value: attrs[key1].options.map((v, i)=>{
if (value.super_attributes[key].option_value == v.id) {
return v.label;
}
})});
fl = 1;
}
}
if (fl == 1) {
fl = 0;
break;
}
}
}
}
value.product_option = o;
}
if (value.custom_options.length > 0) {
let fl = 0;
let co = [];
for (key in value.custom_options) {
for(var i=0; i< item.length; i++) {
if (item[i].extension_attributes.custom_options) {
let customOpt = JSON.parse(item[i].extension_attributes.custom_options);
// let attrs = customOpt.attributes;
// for (key1 in attrs) {
if (parseInt(customOpt.option_id) == parseInt(value.custom_options[key].option_id)) {
co.push({option_id: customOpt.title, option_value: customOpt.values.map((v, i)=>{
if (value.custom_options[key].option_value == v.option_type_id) {
return v.title;
}
})});
fl = 1;
}
// }
if (fl == 1) {
fl = 0;
break;
}
}
}
}
if (co.length) {
value.custom_options = co;
}
}
})
);
} else {
var self = this;
var item = response.items[0];
url = item.images[0].url;
value.image = url;
if (value.custom_options.length > 0) {
let fl = 0;
let co = [];
for (key in value.custom_options) {
for(var i=0; i< item.extension_attributes.custom_options.length; i++) {
if (item.extension_attributes.custom_options) {
let customOpt = JSON.parse(item.extension_attributes.custom_options[i]);
// let attrs = customOpt.attributes;
// for (key1 in attrs) {
if (parseInt(customOpt.option_id) == parseInt(value.custom_options[key].option_id)) {
co.push({option_id: customOpt.title, option_value: customOpt.values.map((v, i)=>{
if (value.custom_options[key].option_value == v.option_type_id) {
return v.title;
}
})});
fl = 1;
}
// }
if (fl == 1) {
fl = 0;
break;
}
}
}
}
if (co.length) {
value.custom_options = co;
}
}
}
})
);
});
});
} else {
cart = {
cartItems: [],
isVisible: 'bb-hide',
quoteId: 0
};
}
}
}
/**
* build add to cart data
*/
function buildAddToCartData(cartItem) {
let optionsData = {
extensionAttributes: {
customOptions: []
}
};
let optionsFormData = $("#options-wrapper-form").serializeArray();
$.each(optionsFormData, function(index, value) {
let nameInfo = value.name.split("||");
let type = nameInfo[1];
let val = value.value;
let valInfo = val.split("_");
// if (cartItem.custom_option) {
// nameInfo[2] = JSON.parse(cartItem.custom_option[index]).title;
// valArr = JSON.parse(cartItem.custom_option[index]).values;
// } else {
// nameInfo[2] = JSON.parse(cartItem.extension_attributes.custom_options[index]).title;
// valArr = JSON.parse(cartItem.extension_attributes.custom_options[index]).values;
// }
// $.each(valArr, function(ind, v) {
// if (v.option_type_id == value.value) {
// val = v.title;
// }
// });
let checkKeyExists = function(opId) {
let isExist = 'not_exists';
for (var keys = 0; keys < optionsData.extensionAttributes.customOptions.length; keys++) {
if (optionsData.extensionAttributes.customOptions[keys].option_id == opId) {
isExist = keys;
break;
}
}
return isExist;
};
switch(type) {
case 'drop_down':
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: valInfo[0]}
);
break;
case 'checkbox':
if (optionsData.extensionAttributes.customOptions.length > 0 ) {
let i = checkKeyExists(nameInfo['2']);
if (i == 'not_exists') {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: val}
);
} else {
optionsData.extensionAttributes.customOptions[i].option_value+=','+val;
}
} else {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: val}
);
}
break;
case 'multiple':
if (optionsData.extensionAttributes.customOptions.length > 0 ) {
let i = checkKeyExists(nameInfo['2']);
if (i == 'not_exists') {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: valInfo[0]}
);
} else {
optionsData.extensionAttributes.customOptions[i].option_value+=','+valInfo[0];
}
} else {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: valInfo[0]}
);
}
break;
case 'date':
if (optionsData.extensionAttributes.customOptions.length > 0 ) {
let i = checkKeyExists(nameInfo['2']);
let seperator = '-';
if (i == 'not_exists') {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: val}
);
} else {
optionsData.extensionAttributes.customOptions[i].option_value+=`${seperator}${val}`;
if (nameInfo['3'] == 'day') {
optionsData.extensionAttributes.customOptions[i].option_value =`${optionsData.extensionAttributes.customOptions[i].option_value} 00:00:00`
}
}
} else {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: val}
);
}
break;
case 'date_time':
if (optionsData.extensionAttributes.customOptions.length > 0 ) {
let i = checkKeyExists(nameInfo['2']);
let seperator = '-';
//console.log(i);
if (i == 'not_exists') {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: val}
);
} else {
if (nameInfo['3'] == 'hours') {
seperator = ' ';
}
if (nameInfo['3'] == 'minutes') {
seperator = ':';
}
// if (nameInfo['3'] == 'day_part') {
// seperator = ' ';
// }
optionsData.extensionAttributes.customOptions[i].option_value+=`${seperator}${val}`;
if (nameInfo['3'] == 'minutes') {
optionsData.extensionAttributes.customOptions[i].option_value =`${optionsData.extensionAttributes.customOptions[i].option_value}:00`;
}
}
} else {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: val}
);
}
break;
case 'time':
if (optionsData.extensionAttributes.customOptions.length > 0 ) {
let i = checkKeyExists(nameInfo['2']);
let seperator = ":";
if (i == 'not_exists') {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: val}
);
} else {
// if (nameInfo['3'] == 'day_part') {
// seperator = ' ';
// }
optionsData.extensionAttributes.customOptions[i].option_value+=`${seperator}${val}`;
if (nameInfo['3'] == 'minutes') {
let today = new Date();
optionsData.extensionAttributes.customOptions[i].option_value =`${today.getFullYear()}-${today.getMonth()}-${today.getDate()} ${optionsData.extensionAttributes.customOptions[i].option_value}:00`;
}
}
} else {
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: val}
);
}
break;
default:
optionsData.extensionAttributes.customOptions.push(
{option_id: nameInfo['2'], option_value: val}
);
}
});
let fileTypeOptions = $("#options-wrapper-form").find(".bb-file-type-option");
if (fileTypeOptions.length > 0) {
$.each (fileTypeOptions, function(i, v) {
let fileInputNameInfo = $(v).attr("name").split("||");
let file = $(v).prop('files')[0];
var fr = new FileReader();
fr.addEventListener("load", function(e) {
optionsData.extensionAttributes.customOptions.push(
{
option_id: fileInputNameInfo['2'],
option_value: "file",
extensionAttributes: {
file_info: {
type: file.type,
name: file.name,
base64_encoded_data: e.target.result.replace(/^data:image\/(.*?);base64,/, "")
}
}
}
);
});
fr.readAsDataURL( file );
});
}
if (cartItem.type == 'configurable') {
optionsData.extensionAttributes.configurableItemOptions = [];
let fields = $(".configuarbele-options").find(':input');
$.each (fields, function(index, value) {
let opId = $(value).attr('name').split("-");
optionsData.extensionAttributes.configurableItemOptions.push({optionId: opId[1],optionValue:value.value});
});
}
cartItem.sku = cartItem.sku?cartItem.sku:cartItem.extension_attributes.sku;
cartItem.product_option = optionsData;
//console.log(optionsData);
return cartItem;
}
/**
* validate add to cart data
*/
function validateData() {
let fields = $(".bb-option-wrapper").find(':input');
let isValid = true;
let optionsData = {
extensionAttributes: {
customOptions: []
}
};
$.each(fields, function(index, value) {
let validation = JSON.parse($(value).attr('datavalidate'));
if (validation.required) {
if ($(value).attr('type') == 'checkbox' || $(value).attr('type') == 'radio') {
switch ($(value).attr('type')) {
case 'checkbox':
if (!$('input[name="'+$(value).attr('name')+'"]').is(":checked")) {
if ($(value).next(".bb-option-notice").find(".error").length == 0) {
$(value).after($("<div></div>").addClass('bb-option-notice').html($('<p></p>').addClass("error").text("This option is required")));
}
} else {
if ($(value).next(".bb-option-notice").find(".error").length > 0) {
$(value).next(".bb-option-notice").find(".error").parent().remove();
}
}
break;
case 'radio':
if (!$('input[name="'+$(value).attr('name')+'"]').is(":checked")) {
if ($(value).next(".bb-option-notice").find(".error").length == 0) {
$(value).after($("<div></div>").addClass('bb-option-notice').html($('<p></p>').addClass("error").text("This option is required")));
}
} else {
if ($(value).next(".bb-option-notice").find(".error").length > 0) {
$(value).next(".bb-option-notice").find(".error").parent().remove();
}
}
break
}
} else {
if (!$(value).val() || $(value).val().length == 0) {
isValid = false;
if ($(value).next(".bb-option-notice").find(".error").length == 0) {
$(value).after($("<div></div>").addClass('bb-option-notice').html($('<p></p>').addClass("error").text("This option is required")));
}
} else {
if ($(value).next(".bb-option-notice").find(".error").length > 0) {
$(value).next(".bb-option-notice").find(".error").parent().remove();
}
}
}
}
if (validation.max_charecters > 0) {
if ($(value).val().length > validation.max_charecters) {
isValid = false;
if ($(value).next(".bb-option-notice").find(".error").length == 0) {
$(value).after($("<div></div>").addClass('bb-option-notice').html($('<p></p>').addClass("error").text("maximum "+validation.max_charecters+" charecters are allowed")));
}
}
}
});
return isValid;
}
/**
* add product to the cart
*
* object cartItem
*/
function addProductsToCart(cartItem, self) {
/**
* get current cart items
*
* @param string token
*/
let getCartItems = function(token) {
let cartItemsPromise = getRequestPromise({
url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items',
method: 'GET'
});
return cartItemsPromise;
};
/**
* function to add product to cart
*
* @param int cartId
* @param string token
* @param array params
*/
let addProductToCart = function(cartId, token, params) {
let addCartPromise = getRequestPromise({
url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items',
method: 'POST',
data: JSON.stringify(params)
});
return addCartPromise;
};
/**
* token to interact with user cart
*/
let token = localStorage.getItem("magento-cart-id");
if (!token) {
/**
* create cart if no token available
*/
let promise = getRequestPromise({
url: self.options.baseUrl+'rest/V1/guest-carts'
});
promise.then(
function(resolve) {
token = resolve;
localStorage.setItem("magento-cart-id", token);
/**
* get cart items after token created
*/
let cartItemsPromise = getCartItems(token);
cartItemsPromise.then(
function(response) {
if (response) {
/**
* save quote id
*/
localStorage.setItem("magento-quote-id", token);
/**
* create params to add product to the cart
*/
let params = {
cartItem: {
sku: cartItem.sku,
qty: 1,
quoteId: token,
product_option: cartItem.product_option
}
};
/**
* add to product to the cart function call
*/
let addCartPromise = addProductToCart(response.id, token, params);
addCartPromise.then(function(resolve) {
if (resolve) {
localStorage.setItem("magento-cart-quote-id", resolve.quote_id);
let cartItemsPromise = getCartItems(token);
cartItemsPromise.then(function(response) {
updateCart.call(self, response);
});
}
}, function(reject) {
if (reject.responseJSON.message) {
close = false;
message = reject.responseJSON.message;
if (message == 'Richiesto un cambio di stato non valido') {
message = 'Ops, qualcosa non è andato a buon fine. Inserisci nuovamente il prodotto in carrello';
}
alert(message);
}
let jqXHR = reject;
let error = JSON.parse(jqXHR.responseText);
if (error.message && (error.message == 'Invalid state change requested' || error.message == 'Richiesto un cambio di stato non valido')) {
localStorage.removeItem("magento-cart-quote-id");
localStorage.removeItem("magento-cart-id");
cart.cartItems = [];
getCartInitialData.call(self);
console.log(error);
}
});
}
},
function(error) {
localStorage.removeItem("magento-cart-quote-id");
localStorage.removeItem("magento-cart-id");
}
);
},
function(reject) {
localStorage.removeItem("magento-cart-quote-id");
localStorage.removeItem("magento-cart-id");
}
);
} else {
let cartItemsPromise = getCartItems(token);
cartItemsPromise.then(
function(response) {
if (response) {
let params = {
cartItem: {
sku: cartItem.sku,
qty: document.getElementById("quantity-"+cartItem.sku).value,
quoteId: token,
product_option: cartItem.product_option
}
};
let addCartPromise = addProductToCart(response.id, token, params);
let close = true;
addCartPromise.then(function(resolve) {
if (resolve) {
localStorage.setItem("magento-cart-quote-id", resolve.quote_id);
let cartItemsPromise = getCartItems(token);
cartItemsPromise.then(function(response) {
updateCart.call(self, response);
});
}
}, function(reject) {
if (reject.responseJSON.message) {
close = false;
message = reject.responseJSON.message;
if (message == 'Richiesto un cambio di stato non valido') {
message = 'Ops, qualcosa non è andato a buon fine. Inserisci nuovamente il prodotto in carrello';
}
alert(message);
}
let jqXHR = reject;
let error = JSON.parse(jqXHR.responseText);
if (error.message && (error.message == 'Invalid state change requested' || error.message == 'Richiesto un cambio di stato non valido')) {
localStorage.removeItem("magento-cart-quote-id");
localStorage.removeItem("magento-cart-id");
cart.cartItems = [];
getCartInitialData.call(self);
console.log(error);
}
});
setTimeout(function() {
if (close) {
document.getElementById("buybutton-modal-container-action").remove();
}
}, 500);
}
},
function(error) {
localStorage.removeItem("magento-cart-quote-id");
localStorage.removeItem("magento-cart-id");
}
);
}
}
/**
* get formatted price
*/
function getFormattedPrice(locale = '', currency = '', price) {
var self = this;
if (!locale) {
locale = this.locale;
}
if (!currency) {
currency = this.currency_code;
}
monetary_value = price;
var format = new Intl.NumberFormat(locale, {
style: 'currency',
currency: currency,
minimumFractionDigits: 2,
}).format(monetary_value);
// return format;
return price.toLocaleString('en-US', {style: 'currency', currency: currency});
}
/**
* general function to get promise for any ajax request
*
* @param object requestObj
*/
function getRequestPromise(requestObj) {
let ajaRequestObj = {
url: '',
crossDomain: true,
headers: {
'Accept': "application/json",
'Content-Type' : "application/json"
},
useLoader: true,
method: 'POST',
processData: false,
};
let promise = new Promise(function(resolve, reject) {
ajaRequestObj = extendDefaults(ajaRequestObj, requestObj);
ajaRequestObj.success = function(response) {
resolve(response);
};
ajaRequestObj.error = function(jqXHR, textStatus, errorThrown) {
reject(jqXHR);
};
$.ajax(ajaRequestObj);
});
return promise;
}
/**
* set responsive width
*/
function setResponsiveWith(width) {
if (width < 890) {
$(".buybutton-item").addClass("width-less-then-890");
}
if (width < 638) {
$(".buybutton-item").addClass("width-less-then-638");
}
if (width < 383) {
$(".buybutton-item").addClass("width-less-then-383");
}
}
/**
* general function to start and stop loader for any ajax request on the page
*/
function setupAjaxLoader() {
$(d).ajaxStart( function(event, xhr, options) {
let ajaxTemplate = '<div class=bb-ajax-loader><div class=bb-loader><div class="cp-spinner cp-skeleton"></div></div></div>';
$("body").append(ajaxTemplate);
});
$(d).ajaxComplete( function(event, xhr, options) {
$("body").find(".bb-ajax-loader").remove();
});
}
/**
* is vue js loaded
*/
function isVueLoaded() {
var self = this;
setTimeout(function() {
if (window.Vue != null) {
self.load();
} else {
isVueLoaded.call(self);
}
}, 50);
}
}(document, ''));