1//=== trigger custom 2(function() { 3 var CustomEvent; 4 5 if (typeof window.CustomEvent !== 'function') { 6 CustomEvent = function(event, params) { 7 var evt; 8 params = params || { 9 bubbles: false, 10 cancelable: false, 11 detail: void 0 12 }; 13 evt = document.createEvent('CustomEvent'); 14 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 15 return evt; 16 }; 17 CustomEvent.prototype = window.Event.prototype; 18 window.CustomEvent = CustomEvent; 19 } 20 21 $.fn['triggerCustom'] = function(type, data, options) { 22 if (options == null) { 23 options = {}; 24 } 25 options = $.extend({}, { 26 bubbles: true, 27 cancelable: true, 28 detail: data 29 }, { 30 bubbles: options.bubbles, 31 cancelable: options.cancelable 32 }); 33 return this.each(function() { 34 var e; 35 e = new window.CustomEvent(type, options); 36 return this.dispatchEvent(e); 37 }); 38 }; 39 40}).call(this); 41 42 43//=== Global functions === 44function compact(array) { 45 var new_array = []; 46 for (var i = 0; i < array.length; i++) { 47 if ( array[i] ) new_array.push(array[i]); 48 } 49 return new_array; 50} 51 52function calculate_total_cost(product, variant, quantity) { 53 if(product.using_price_types) { 54 var price = variant.price; 55 var price_type; 56 for(var j in product.price_types) { 57 if ( product.price_types[j].min_quantity > quantity ) 58 break; 59 price_type = product.price_types[j]; 60 } 61 if (price_type) { 62 for(var i in variant.prices) { 63 if ( variant.prices[i].price_type_id == price_type.id ) { 64 price = variant.prices[i].price; 65 break; 66 } 67 } 68 } 69 return price*quantity; 70 } else { 71 var price = variant.price; 72 var price_kind; 73 var price_kinds = product.price_kinds.sort(function(a,b){ 74 return a.value - b.value; 75 }); 76 77 for(var j in price_kinds) { 78 if ( price_kinds[j].value > quantity ) 79 break; 80 if( variant.prices[product.price_kinds[j].price_index - 1] ){ 81 price_kind = product.price_kinds[j]; 82 } 83 } 84 if (price_kind) { 85 price = variant.prices[price_kind.price_index - 1]; 86 } 87 return price*quantity; 88 } 89} 90 91function get_prices(product, variant) { 92 if(product.using_price_types) { 93 var price_by_type = {}; 94 for(var i in variant.prices) { 95 var price = variant.prices[i]; 96 price_by_type[price.price_type_id] = price; 97 } 98 var previous = null; 99 var table = [] 100 for(var j in product.price_types) { 101 var price_type = product.price_types[j]; 102 var price = variant.price; 103 var to = price_type.min_quantity - 1; 104 var from = 1; 105 if (previous) { 106 price = price_by_type[previous.id].price; 107 from = previous.min_quantity; 108 } 109 table.push({ from: from, to: to, price: price}); 110 previous = price_type; 111 } 112 if (previous) { 113 table.push({ from: previous.min_quantity, to: null, price: price_by_type[previous.id].price}); 114 return table; 115 } else { 116 return false; 117 } 118 } else { 119 var prices = variant.prices; 120 var previous = null; 121 var table = []; 122 var price_kinds = product.price_kinds.sort(function(a,b){ 123 return a.value - b.value; 124 }); 125 126 for(var j in price_kinds) { 127 var price_kind = price_kinds[j]; 128 if(prices[price_kind.price_index - 1]){ 129 var price = variant.price; 130 var to = price_kind.value - 1; 131 var from = 1; 132 if (previous) { 133 price = prices[previous.price_index-1]; 134 from = previous.value; 135 } 136 table.push({ from: from, to: to, price: price}); 137 previous = price_kind; 138 } 139 } 140 if (previous) { 141 table.push({ from: previous.value, to: null, price: prices[previous.price_index - 1]}); 142 return table; 143 } else { 144 return false; 145 } 146 } 147} 148 149function floatToString(numeric, decimals) { 150 numeric = parseFloat(numeric) || 0; 151 var amount = numeric.toFixed(decimals).toString(); 152 if(amount.match(/^\.\d+/)) {return "0"+amount;} 153 else {return amount;} 154}; 155 156// ÐниÑиализиÑоваÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑоваÑа в коÑзин
156Ñ ÑеÑез Ajax. 157function initAjaxAddToCartButton(handle, onAddToCart) { 158 jQuery(handle).click(function(e){ 159 e.preventDefault(); 160 jQuery(this).triggerCustom('clicked:insales:add_to_cart_button'); 161 addOrderItem( jQuery(this).parents("form:first"), onAddToCart); 162 }); 163} 164 165// Ðобавление ÑоваÑа в коÑÐ·Ð¸Ð½Ñ 166function addOrderItem(form, onAddToCart, dontShowPreloader) { 167 var fields = form.serialize(); 168 var action = form.attr("action").split("?"); 169 var url = action[0] + ".json"; 170 var lang = action[1] ? "?"+action[1] : ""; 171 var path = url + lang; 172 if (!dontShowPreloader) { 173 jQuery(document).one('before_additem:insales:cart', function(e){ 174 if (!e.isDefaultPrevented()) { 175 show_preloader(); 176 } 177 }); 178 jQuery(document).triggerCustom('before_additem:insales:cart'); 179 } 180 jQuery.ajax({ 181 url: path, 182 type: 'post', 183 data: fields, 184 dataType: 'json', 185 success: function() { 186 jQuery(document).triggerCustom('add_item:insales:cart'); 187 jQuery(document).triggerCustom('insales:cart:add_item'); 188 onAddToCart.apply(this, arguments); 189 }, 190 error: hide_preloader 191 }); 192} 193 194// ÑÑнкÑÐ¸Ñ Ð²ÑÑаÑÐºÐ¸Ð²Ð°ÐµÑ ÑообÑÐµÐ½Ð¸Ñ Ð¾Ð± оÑибке из Ñ ÑÑа в маÑÑив. 195function errors_to_arr(errors){ 196 arr = []; 197 $.each( errors, function(obj, msg){ 198 arr.push(msg); 199 }); 200 return arr; 201} 202 203 204// ÐÑвеÑÑи индикаÑÐ¾Ñ ÑабоÑÑ (колеÑико) 205function show_preloader() { 206 var preloader = jQuery("#own_preloader"); 207 if ( !preloader.attr("id") ) { 208 jQuery("body").append('<div id="own_preloader"><img src="/served_assets/loading.gif"/></div>'); 209 preloader = jQuery("#own_preloader"); 210 } 211 preloader.show(); 212 213 changeCss(preloader); 214 jQuery(window).bind("resize", function(){ 215 changeCss(preloader); 216 }); 217 jQuery(window).bind("scroll", function(){ 218 changeCss(preloader); 219 }); 220} 221 222// СкÑÑÑÑ Ð¸Ð½Ð´Ð¸ÐºÐ°ÑÐ¾Ñ 223function hide_preloader() { 224 var preloader = jQuery("#own_preloader"); 225 if ( !preloader.attr("id") ) return; 226 jQuery(window).unbind("resize"); 227 jQuery(window).unbind("scroll"); 228 preloader.remove(); 229} 230 231// ÐамениÑÑ Ð¸Ð½Ð´Ð¸ÐºÐ°ÑÐ¾Ñ Ð½Ð° ÑообÑение 232function set_preloaders_message(message) { 233 var preloader = jQuery("#own_preloader"); 234 if ( !preloader.attr("id") ) return; 235 preloader.html(message); 236} 237 238function changeCss(OBJ){ 239 var imageHeight = OBJ.height(); 240 var imageWidth = OBJ.width(); 241 var windowWidth = jQuery(window).width(); 242 var windowHeight = jQuery(window).height(); 243 OBJ.css({ 244 "position" : "absolute", 245 "left" : windowWidth / 2 - imageWidth / 2, 246 "top" : getPageScroll()[1] + (getPageHeight() - imageHeight) / 2 247 }); 248}; 249 250// getPageScroll() by quirksmode.com 251function getPageScroll() { 252 var xScroll, yScroll; 253 if (self.pageYOffset) { 254 yScroll = self.pageYOffset; 255 xScroll = self.pageXOffset; 256 } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict 257 yScroll = document.documentElement.scrollTop; 258 xScroll = document.documentElement.scrollLeft; 259 } else if (document.body) {// all other Explorers 260 yScroll = document.body.scrollTop; 261 xScroll = document.body.scrollLeft; 262 } 263 return new Array(xScroll,yScroll) 264} 265 266// Adapted from getPageSize() by quirksmode.com 267function getPageHeight() { 268 var windowHeight 269 if (self.innerHeight) { // all except Explorer 270 windowHeight = self.innerHeight; 271 } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode 272 windowHeight = document.documentElement.clientHeight; 273 } else if (document.body) { // other Explorers 274 windowHeight = document.body.clientHeight; 275 } 276 return windowHeight 277} 278 279// === InSales === 280 281if ((typeof InSales) == 'undefined' || !InSales.Cart) { 282 if (typeof InSales == 'undefined') { 283 InSales = null; 284 } 285 InSales = jQuery.extend(InSales, (function($){ 286 var slice = [].slice 287
288 var $on = function() { 289 var args, jq; 290 jq = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; 291 if (jq.on != null) { 292 return jq.on.apply(jq, args); 293 } else if (args.length > 2) { 294 // delegate пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ ÑелекÑÐ¾Ñ Ð² пеÑвом аÑгÑменÑе, 295 // а ÑобÑÑие - во вÑоÑом 296 ref = [args[0], args[1]], args[1] = ref[0], args[0] = ref[1]; 297 return jq.delegate.apply(jq, args); 298 } else { 299 return jq.bind.apply(jq, args); 300 } 301 }; 302 303 var $off = function() { 304 var args, jq; 305 jq = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; 306 if (jq.off != null) { 307 return jq.off.apply(jq, args); 308 } else { 309 return jq.unbind.apply(jq, args); 310 } 311 }; 312 313 var InSales = {}; 314 var cart = null; 315 316 InSales.isDefined = function(obj) { 317 return ((typeof obj == 'undefined') ? false : true); 318 }; 319 320 InSales.money_format = "{{amount}} "+"ÑÑб."; 321 322 /* 323 number - number to add delimiter 324 delimiter - value to use as digits delimiter (e.g. delimiter = '-'; 1000 -> 1-000) 325 */ 326 InSales.numberWithDelimiter = function(number, delimiter) { 327 if (delimiter == undefined) delimiter = ' '; 328 number+='' 329 var split = number.split('.'); 330 split[0] = split[0].replace( 331 /(\d)(?=(\d\d\d)+(?!\d))/g, 332 '$1'+delimiter 333 ); 334 return split.join('.'); 335 } 336 337 // СÑаÑÐ°Ñ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии formatMoney, оÑÑавлена Ð´Ð»Ñ ÑовмеÑÑимоÑÑи 338 InSales.formatMoneyOld = function(amount, format) { 339 var patt = /\{\{\s*(\w+)\s*\}\}/; 340 var formatString = (format || this.money_format); 341 // ÑоÑÐ¼Ð°Ñ Ð²Ñвода должен ÑовпадаÑÑ c ÑоÑмаÑом вÑвода в Liquid 342 value = floatToString(amount, 2).replace(/,00/, '').replace(/\.00/, ''); 343 return formatString.replace(patt, value); 344 } 345 346 // в ÑÑаÑой веÑÑии ÑÑнкÑии паÑамеÑÑÑ Ð¿ÑÐ¸Ñ Ð¾Ð´Ð¸Ð»Ð¸ ÑеÑез string, в новой в виде JSON 347 InSales.formatMoneyIsOld = function(params) { 348 var oldFormat = false; 349 // пÑовеÑка ÑÑо в params JSON ÑеÑез try Ð´Ð»Ñ jQuery > 1.9 350 try { 351 var moneyParams = $.parseJSON(params); 352 // пÑовеÑка ÑÑаÑÑм ÑпоÑобом Ð´Ð»Ñ jQuery <= 1.9 353 if ( moneyParams == null || typeof moneyParams != 'object') oldFormat = true; 354 } catch(err) { 355 oldFormat = true; 356 } 357 return oldFormat; 358 } 359 360 InSales.formatMoney = function(amount, params) { 361 if (amount == null) return ''; 362 if (params == null && window.CURRENCY_FORMAT) params = CURRENCY_FORMAT; 363 if (params == null && window.cv_currency_format) params = cv_currency_format; 364 //FIXME оÑÑавлено Ð´Ð»Ñ ÑовмеÑÑимоÑÑи 365 // еÑли пÑÐ¸Ñ Ð¾Ð´Ð¸Ñ JSON - иÑполÑзÑем ÑÑÑ ÑÑнкÑие, еÑли Ð½ÐµÑ - ÑÑаÑÑÑ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии 366 if (this.formatMoneyIsOld(params)) return this.formatMoneyOld(amount, params); 367 368 amount = parseFloat(amount).toFixed(2) || 0; 369 if (typeof amount == 'string') amount = amount.replace(/\.00/, ''); 370 371 var moneyParams = $.parseJSON(params); 372 value = moneyParams['show_price_without_cents'] ? Math.round(amount) : amount; 373 value = this.numberWithDelimiter(value, moneyParams['delimiter']); 374 value = value.replace(/\./, moneyParams['separator']); 375 return moneyParams['format'].replace('%n', value).replace('%u',moneyParams['unit']); 376 }; 377 378 InSales.OrderLine = function(options) { 379 this.init = function(options) { 380 var line = this; 381 $.each(options, function(key,value) { line[key] = value; }); 382 if (options.title) this.title = options.title.replace(/\+/g, ' '); 383 if (options.sku) this.sku = options.sku.replace(/\+/g, ' '); 384 this.url = '/product/?product_id=' + options.product_id; 385 } 386 387 this.image = function(format) { 388 return this.image_url.replace('thumb', format); 389 } 390 391 this.init(options); 392 return this; 393 } 394 395 InSales.Cart = function(drawCallback, format) { 396 // singleton 397 if (cart) { 398 return cart; 399 } 400 401 if (!(this instanceof InSales.Cart)) { 402 return new InSales.Cart(drawCallback, format); 403 } 404 405 cart = this; 406 this.get_text = function(text) { 407 if (!text) return text; 408 return text.replace(/\+/g, ' '); 409 } 410 411 this.setCart = function(order) { 412 if (!order) { 413 this.total_price = 0; 414 this.items_price = 0; 415 this.order_lines = []; 416 this.items_count = 0; 417 this.discounts = []; 418 return; 419 } 420 this.total_price = order.total_price; 421 this.items_price = order.items_price; 422 var items_count = 0; 423 var order_lines = []; 424 $(order.order_lines).each(function(index, order_line) { 425 items_count += order_line.quantity; 426 order_lines[index] = new InSales.OrderLine(order_line); 427 }); 428 this.order_lines = order_lines; 429 this.items_count = items_count; 430 this.discounts = order.discounts; 431 this.discount_code = order.discount_code; 432 } 433 434 this.reloadCart = function(callback) { 435 InSales.Cart.loadCartData(function(order){ 436 cart.setCart(order); 437 jQuery(document).triggerCustom('reloaded:insales:cart', cart); 438 callback() 439 }); 440 } 441 442 this.removeItemTrigger = function(){ 443 $('[id^="delete_"]').each(function(i) { 444 if ( $(this).attr('processed') ) { return; } 445 $(this).attr('processed',true); 446 var link = $(this); 447 var variant_id = link.attr("id").replace("delete_",""); 448 449 $(this).click(function(e){ 450 e.preventDefault(); 451 cart.removeItem(variant_id); 452 }); 453 }); 454 } 455 456 this.removeItem = function(variant_id) { 457 var fields = new Object; 458 fields['_method'] = 'delete'; 459 var path = '/cart_items/' + variant_id + '.json'; 460 show_preloader(); 461 $.ajax({ 462 url: path, 463 type: 'post', 464 data: fields, 465 dataType: 'json', 466 success: function(response) { 467 cart.reloadCart(function(){ 468 hide_preloader(); 469 cart.draw(); 470 $(document).triggerCustom('remove_item:insales:cart'); 471 }); 472 }, 473 error: function(response) { 474 hide_preloader(); 475 console.log("Cant remove item from cart"); 476 } 477 }); 478 } 479 480 this.addCallback = function() { 481 this.reloadCart(function(){ 482 cart.draw(); 483 set_preloaders_message('<div id="add_product_notification">
483'+"Ð¢Ð¾Ð²Ð°Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ в коÑзинÑ"+'</div>'); 484 window.setTimeout( hide_preloader, 1000); 485 }); 486 } 487 488 this.draw = function() { 489 this.drawCallback(this); 490 this.removeItemTrigger(); 491 } 492 493 this.refresh = function() { 494 this.reloadCart( function() { cart.draw() } ); 495 } 496 497 this.init = function(options) { 498 if (!options) options = {}; 499 this.drawCallback = options.draw || (function(){}); 500 this.selector = options.selector; 501 this.format = format; 502 this.reloadCart(function(){ 503 cart.draw(); 504 initAjaxAddToCartButton(cart.selector, function(response){ cart.addCallback(); }); 505 }); 506 $on($(document), 'insales:cart:refresh', function(){ cart.refresh() }); 507 $on($(document), 'refresh:insales:cart', function(){ cart.refresh() }); 508 } 509 510 this.init(drawCallback); 511 } 512 513 InSales.Cart.loadCartData = function(callback) { 514 if ($.cookie('cart') && $.cookie('cart') != 'json') { 515 try { 516 var cart_json = $.parseJSON($.cookie('cart')); 517 } catch(e) { 518 var cart_json = null; 519 } 520 callback(cart_json); 521 } else { 522 $.ajax({ 523 url: "/cart_items.json", 524 dateType: 'json', 525 success: callback 526 }); 527 } 528 }; 529 530 InSales.Cart.isEmpty = function(callback) { 531 if (cart) { 532 return callback(cart.items_count == 0); 533 } 534 535 InSales.Cart.loadCartData(function(order) { 536 for (var i = 0; i < order.order_lines.length; i++) { 537 if (order.order_lines[i].quantity > 0) { 538 return callback(false); 539 } 540 } 541 callback(true); 542 }); 543 }; 544 545 InSales.QueryString = function () { 546 // This function is anonymous, is executed immediately and 547 // the return value is assigned to QueryString! 548 var query_string = {}; 549 var query = window.location.search.substring(1); 550 var vars = query.split("&"); 551 for (var i=0;i<vars.length;i++) { 552 var pair = vars[i].split("="); 553 // If first entry with this name 554 if (typeof query_string[pair[0]] === "undefined") { 555 query_string[pair[0]] = pair[1]; 556 // If second entry with this name 557 } else if (typeof query_string[pair[0]] === "string") { 558 var arr = [ query_string[pair[0]], pair[1] ]; 559 query_string[pair[0]] = arr; 560 // If third or later entry with this name 561 } else { 562 query_string[pair[0]].push(pair[1]); 563 } 564 } 565 return query_string; 566 } (); 567 /* 568 Ñвои ÑообÑÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ пеÑедаÑÑ ÑеÑез options 569 { _textAdd: '', _textLink: '', _textRepeat: '', _textCompareEnd: '' } 570 */ 571 InSales.Compare = function(options) { 572 /* СообÑÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ */ 573 var textAdd = "Ð¢Ð¾Ð²Ð°Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ к ÑÑавнениÑ"; 574 var textLink = "СÑавниÑÑ"; 575 var textRepeat = "ÐÑÐ¾Ñ ÑÐ¾Ð²Ð°Ñ Ñже добавлен"; 576 var textCompareEnd = "СÑавниваÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ не более 4-Ñ ÑоваÑов"; 577 578 var compare = this; 579 var productsCounter = 0; 580 var ProductId = 0; 581 var ProductIdRepeat = false; 582 583 this.otherText = function() { 584 if(this._textAdd) { 585 textAdd = this._textAdd; 586 } 587 if(this._textLink) { 588 textLink = this._textLink; 589 } 590 if(this._textRepeat) { 591 textRepeat = this._textRepeat; 592 } 593 if(this._textCompareEnd) { 594 textCompareEnd = this._textCompareEnd; 595 } 596 } 597 598 this.get_text = function(text) { 599 if (!text) return text; 600 return text.replace(/\+/g, ' '); 601 } 602 603 this.reload = function() { 604 try { 605 this.products = $.parseJSON($.cookie('compare')); 606 } catch(e) { 607 this.products = null; 608 } 609 610 if (!this.products) { 611 this.products = []; 612 return; 613 } 614 615 productsCounter = this.products.length; 616 617 $(this.products).each(function(index, product) { 618 $('a[rel='+this.id+']').not('.del_compare').text(""+textAdd+"").addClass('compare-added'); 619 product['title'] = compare.get_text(product['title']); 620 }); 621 } 622 623 this.removeItemTrigger = function(){ 624 $('.remove_compare').each(function(i) { 625 if ( $(this).attr('processed') ) { return; } 626 $(this).attr('processed',true); 627 var product_id = $(this).attr('rel'); 628 629 $(this).click(function(e){ 630 e.preventDefault(); 631 compare.removeItem(product_id); 632 }); 633 }); 634 } 635 636 this.removeItem = function(product_id) { 637 var fields = new Object; 638 fields['_method'] = 'delete'; 639 if (InSales.QueryString["lang"]) { 640 fields["lang"] = InSales.QueryString["lang"]; 641 } 642 var path = '/compares/' + product_id + '.json'; 643 show_preloader(); 644 $.ajax({ 645 url: path, 646 type: 'post', 647 data: fields, 648 dataType: 'json', 649 success: function(response) { 650 $('.compare_' + product_id).remove(); 651 $('a[rel='+product_id+']').text(""+textLink+"").removeClass('compare-added'); 652 compare.reload(); 653 hide_preloader(); 654 compare.draw(); 655 }, 656 error: function(response) { 657 hide_preloader(); 658 } 659 }); 660 } 661 662 this.addItemTrigger = function() { 663 handler = function(e){ 664 if (e.addedToCompare) { return; } 665 e.addedToCompare = true; 666 productsCounter = productsCounter+1 667 var product_id = $(this).attr('rel'); 668 var path = '/compares.json'; 669 670 ProductId = product_id; 671 672 compare.checkIsRepeated(); 673 show_preloader(); 674 675 if(productsCounter > 4) { 676 set_preloaders_message('<div id="add_product_notification">'+textCompareEnd+'</div>'); 677 window.setTimeout(hide_preloader, 3000); 678 } else { 679 $(this).text(""+textAdd+"").addClass('compare-added'); 680 var data = {'product[id]': product_id}; 681 if (InSales.QueryString["lang"]) { 682 data["lang"] = InSales.QueryString["lang"]; 683 } 684 $.ajax({ 685 url: path, 686 type: 'post', 687 data: data, 688 dataType: 'json', 689 success: function(response) { 690 compare.reload(); 691 compare.draw(); 692 if (ProductIdRepeat == true) { 693 set_preloaders_message('<div id="add_product_notification">'+textRepeat+'</div>'); 694 window.setTimeout(hide_preloader, 3000); 695 } else { 696 set_preloaders_message('<div id="add_product_notification">'+textAdd+'</div>'); 697 window.setTimeout(hide_preloader, 3000); 698 } 699 }, 700 error: function(response) { 701 hide_preloader(); 702 } 703 }); 704 } 705 }; 706 707 $on($(this.selector), 'click', handler); 708 $on($(document), this.selector, 'click', handler); 709 } 710 711 this.draw = function() { 712 this.drawCallback(this.products); 713 this.removeItemTrigger(); 714 } 715 716 this.checkIsRepeated = function() { 717 ProductIdRepeat = false;
718 $.each(this.products, function() { 719 if(ProductId == this.id) { 720 ProductIdRepeat = true; 721 return false; 722 } else { 723 ProductIdRepeat = false; 724 } 725 }); 726 } 727 728 this.init = function(options) { 729 this.drawCallback = options.draw; 730 this.selector = options.selector; 731 this._textAdd = options._textAdd; 732 this._textLink = options._textLink; 733 this._textRepeat = options._textRepeat; 734 this._textCompareEnd = options._textCompareEnd; 735 this.otherText(); 736 this.reload(); 737 this.draw(); 738 this.addItemTrigger(); 739 } 740 741 this.init(options); 742 } 743 744 InSales.Product = function(json) { 745 746 // ÐÑпомогаÑелÑнÑе меÑÐ¾Ð´Ñ Ð¸ÑполÑзÑемÑе пÑи иниÑиализаÑии 747 this.addOption = function(option) { 748 this.options_by_id[option['id']] = { 749 title: option['title'], 750 values: [] 751 }; 752 }; 753 754 this.addVariant = function(variant) { 755 var option_values = variant['option_values']; 756 for (var value in option_values) {this.addValue(option_values[value]);}; 757 }; 758 759 this.addValue = function(value) { 760 var option = this.options_by_id[value['option_name_id']]; 761 option['values'][value['position']] = value; 762 }; 763 764 // ÐниÑиализаÑÐ¸Ñ 765 this.init = function(json) { 766 for (property in json) {this[property] = json[property];} 767 this.options_by_id = {}; 768 for (var option in this.option_names) {this.addOption(this.option_names[option]);} 769 for (var variant in this.variants) {this.addVariant(this.variants[variant]);}; 770 jQuery.each(this.options_by_id, function(index,option) {option['values'] = compact(option['values']);}); 771 772 }; 773 774 // returns array of option names for product 775 this.optionNames = function() { 776 return this.option_names; 777 }; 778 779 // returns array of all option values (in order) for a given option name index 780 this.optionValues = function(index) { 781 var option = this.option_names[index]; 782 if (!option) {return null;} 783 return this.options_by_id[option['id']]['values']; 784 }; 785 786 // return the variant object if exists with given values, otherwise return null 787 this.getVariant = function(selectedValues) { 788 for (var i in this.variants) { 789 var variant = this.variants[i]; 790 var satisfied = true; 791 jQuery.each(variant['option_values'], function(index,value) { 792 if (selectedValues[value['option_name_id']] != value['id']) { 793 satisfied = false; 794 } 795 }); 796 if (satisfied == true) {return variant;} 797 } 798 return null; 799 }; 800 801 this.variantById = function(id) { 802 for (var i in this.variants) { 803 if (parseInt(this.variants[i].id) == parseInt(id)) { 804 return this.variants[i]; 805 } 806 } 807 808 return null; 809 }; 810 811 this.init(json); 812 }; 813 814 InSales.OptionSelectors = function(existingSelectorId, options) { 815 if ($("#"+existingSelectorId).attr("id") == undefined) return false; 816 817 // insert new multi-selectors and hide original selector 818 this.replaceSelector = function(domId) { 819 var oldSelector = document.getElementById(domId); 820 var parent = oldSelector.parentNode; 821 jQuery.each(this.buildSelectors(), function(index,el) { 822 parent.insertBefore(el, oldSelector); 823 }); 824 oldSelector.style.display = 'none'; 825 this.variantIdField = oldSelector; 826 }; 827 828 // buildSelectors(index) 829 // create and return new selector element for given option 830 this.buildSelectors = function() { 831 // build selectors 832 for (var i = 0; i < this.product.optionNames().length; i++) { 833 var sel = new InSales.SingleOptionSelector(this, i, this.product.optionNames()[i], this.product.optionValues(i)); 834 sel.element.disabled = false; 835 this.selectors.push(sel); 836 } 837 838 // replace existing selector with new selectors, new hidden input field, new hidden messageElement 839 var divClass = this.selectorDivClass; 840 var divId = this.optionIdFieldIdPrefix 841 var optionNames = this.product.optionNames(); 842 var elements = []; 843 jQuery.each(this.selectors, function(index,selector) { 844 var div = document.createElement('div'); 845 div.setAttribute('class', divClass); 846 div.setAttribute('id', divId + selector.option_id) 847 // create label if more than 1 option (ie: more than one drop down) 848 // безопаÑно ли пеÑеименовÑваÑÑ? 849 if (optionNames.length > 1 || optionNames[0].title != 'ÐаÑианÑ' || optionNames[0].title != 'ÐодиÑикаÑиÑ') { 850 // create and appened a label into div 851 var label = document.createElement('label'); 852 label.innerHTML = selector.name; 853 div.appendChild(label); 854 } 855 div.appendChild(selector.element); 856 elements.push(div); 857 }); 858 return elements; 859 }; 860 861 // returns array of currently selected values from all multiselectors 862 this.selectedValues = function() { 863 var currValues = {}; 864 for (var i = 0; i < this.selectors.length; i++) { 865 var selector = this.selectors[i] 866 var thisValue = selector.element.value; 867 currValues[selector.option_id] = thisValue; 868 } 869 return currValues; 870 }; 871 872 this.getCurrVariant = function() { 873 var currValues = this.selectedValues(); // get current values 874 return this.product.getVariant(currValues); 875 }; 876 877 // callback when a selector is updated. 878 this.updateSelectors = function(index) { 879 var variant = this.getCurrVariant(); 880 if (variant) { 881 this.variantIdField.disabled = false;
882 this.variantIdField.value = variant.id; // update hidden selector with new variant id 883 } else { 884 this.variantIdField.disabled = true; 885 } 886 this.onVariantSelected(variant, this); // callback 887 }; 888 889 this.selectAvailableVariant = function() { 890 var values = {}; 891 for (var i = 0; i < this.product.variants.length; i++) { 892 var variant = this.product.variants[i]; 893 if (!variant.available) continue; 894 jQuery.each(variant.option_values, function(index,option_value) { 895 values[option_value.option_name_id] = option_value.id; 896 }); 897 break; 898 } 899 jQuery.each(this.selectors, function(index,selector) { 900 selector.selectValue(values[selector.option_id]); 901 }); 902 this.selectors[0].element.onchange(); // init the new dropdown 903 }; 904 905 this.filterOptionValues = function(){ 906 // СоздаÑм маÑÑив знаÑений Ñв-в каждого ваÑианÑа 907 var variants_option_values = []; 908 for (var i = 0; i < this.product.variants.length; i++) { 909 var variant = this.product.variants[i]; 910 //if (!variant.available) continue; 911 var variant_option_values = [] 912 jQuery.each(variant.option_values, function(index,option_value) { 913 variant_option_values.push(option_value); 914 }); 915 variants_option_values.push(variant_option_values) 916 } 917 918 var id_prefix = 'variant-select-option-'; 919 var max_option_name_index = jQuery('.single-option-selector').size() - 1; 920 // ÐÑи вÑбоÑе знаÑÐµÐ½Ð¸Ñ Ñв-ва Ñ ÑледÑÑÑего Ñв-ва оÑÑавлÑем ÑолÑко Ñе знаÑениÑ, коÑоÑÑе могÑÑ Ð±ÑÑÑ Ñ ÑоваÑа пÑи вÑбÑаннÑÑ Ð¿ÑедÑдÑÑÐ¸Ñ Ð·Ð½Ð°ÑениÑÑ 921 $on($('.single-option-selector'), 'change', function() { 922 var selected_option_value_id = $(this).val(); 923 var id = $(this).attr('id'); 924 var option_name_index = parseInt(id.replace(id_prefix,'')); 925 if (option_name_index == max_option_name_index) return; 926 var next_option_name_index = option_name_index + 1; 927 var option_values = []; 928 $.each(variants_option_values, function(index,variant_option_values){ 929 var current_option_value = variant_option_values[option_name_index]; 930 if (current_option_value.id == selected_option_value_id) { 931 var allowed_option_value = true 932 // пÑÐ¾Ñ Ð¾Ð´Ð¸Ð¼ÑÑ Ð¿Ð¾ Ñанее вÑбÑаннÑм знаÑениÑм Ñв-в 933 for (var i=option_name_index; i >= 0; i--){ 934 var prev_current_option_value_id = $("#"+id_prefix+i).val(); 935 if (variant_option_values[i].id != prev_current_option_value_id) allowed_option_value = false; 936 } 937 if (allowed_option_value){ 938 var next_option_value = variant_option_values[next_option_name_index]; 939 option_values = $.grep(option_values, function (option_value) {return option_value.id != next_option_value.id;}); 940 option_values.push(next_option_value); 941 } 942 } 943 }); 944 945 var next_option_values_select = $("#"+id_prefix+next_option_name_index); 946 var next_selected_option_value_id = next_option_values_select.val(); 947 948 var options = ""; 949 $.each(option_values, function(){ 950 var selected = ""; 951 if (this.id == next_selected_option_value_id) selected = "selected='selected'"; 952 options += "<option value='"+this.id+"' "+ selected +">"+this.title+"</option>"; 953 }); 954 955 next_option_values_select.html(options); 956 next_option_values_select.trigger('change'); 957 }); 958 959 $("#"+id_prefix+0).trigger('change'); 960 } 961 962 this.getUrlParameter = function(name) { 963 return decodeURI((RegExp(name + '=' + '(.+?)(&|$)').exec(location.search) || [0, null])[1]); 964 }; 965 966 // еÑли ваÑÐ¸Ð°Ð½Ñ Ñказан в URL, вÑбиÑаем его 967 this.selectVariantFromUrl = function() { 968 var variant_id = this.getUrlParameter('variant_id'); 969 if (variant_id == null) return; 970 971 // if(variant_id != 'null') { 972 // $('select option[value="'+ this.getUrlParameter('variant_id') +'"]').attr('selected', 'selected').change(); 973 // } 974 975 var variant = this.product.variantById(variant_id); 976 if (variant == null) return; 977 978 for (var i in variant.option_values) { 979 var opt_id = variant.option_values[i].id; 980 $(this.variantIdField).parent().find('select option[value="' + opt_id + '"]').attr('selected', 'selected'); 981 } 982 983 this.updateSelectors(); 984 }; 985 986 this.selectorDivClass = 'selector-wrapper'; 987 this.selectorClass = 'single-option-selector'; 988 this.variantIdFieldIdSuffix = '-variant-id'; 989 this.optionIdFieldIdPrefix = 'selector-option-id-'; 990 991 this.variantIdField = null; 992 this.selectors = []; 993 this.domIdPrefix = existingSelectorId; 994 this.product = new InSales.Product(options['product']); 995 996 this.onVariantSelected = InSales.isDefined(options.onVariantSelected) ? options.onVariantSelected : function(){}; 997 998 this.replaceSelector(existingSelectorId); // create the dropdowns 999 1000 this.selectAvailableVariant(); 1001 this.selectVariantFromUrl(); 1002 1003 if (options['filterOptionValues']) this.filterOptionValues(); // ÐооÑеÑÑÐ´Ð½Ð°Ñ ÑилÑÑÑаÑÐ¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ñв-в. 1004 1005 return true; 1006 }; 1007 1008 1009 InSales.SingleOptionSelector = function(multiSelector, index, option, values) { 1010 this.selectValue = function(value) { 1011 $(this.element).find('option[value="'+value+'"]').each(function(){ 1012 $(this).attr("selected","selected") 1013 }); 1014 }; 1015 1016 this.multiSelector = multiSelector; 1017 this.values = values; 1018 this.index = index; 1019 this.name = option['title']; 1020 this.option_id = option['id']; 1021 this.element = document.createElement('select'); 1022 for (var i = 0; i < values.length; i++) { 1023 var opt = document.createElement('option'); 1024 opt.value = values[i].id; 1025 opt.innerHTML = values[i].title; 1026 this.element.appendChild(opt); 1027 } 1028 this.element.setAttribute('class', this.multiSelector.selectorClass);
1029 this.element.id = multiSelector.domIdPrefix + '-option-' + index; 1030 this.element.onchange = function() { 1031 multiSelector.updateSelectors(index); 1032 }; 1033 1034 return true; 1035 }; 1036 1037 return InSales; 1038 })(jQuery)); 1039} 1040 1041// ÑÐ°Ð±Ð¼Ð¸Ñ ÑоÑÐ¼Ñ Ð¾ÑзÑва 1042jQuery(function($) { 1043 $("#feedback_commit").click(function(e){ 1044 e.preventDefault(); 1045 var form = $('#feedback_form'); 1046 var fields = form.serialize(); 1047 $.ajax({ 1048 url: form.attr('action') + '.json', 1049 type: 'post', 1050 data: fields, 1051 dataType: 'json', 1052 beforeSend: function() {show_preloader();}, 1053 complete: function() {hide_preloader();}, 1054 success: function(response) { 1055 if ( response.status == 'ok' ) { 1056 $("textarea[name='feedback[content]']").val(""); 1057 var thanks = $("#thanks"); 1058 thanks.html(response.notice); 1059 thanks.show(); 1060 window.setTimeout(function() { 1061 thanks.fadeOut("slow", function(){thanks.hide();}); 1062 }, 6000); 1063 } else { 1064 alert(errors_to_arr(response.errors).join("\n")); 1065 } 1066 } 1067 }); 1068 }); 1069}) 1070 1071;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.