PageSourceSearch

https://refreshaestheticcenter.com/wp-content/plugins/advanced-dyn…/assets/js/dynamic-price.js?ver=4.10.3

js refreshaestheticcenter.com collected 2026-10-02 16:02:00 UTC 22,235 bytes, 696 lines download raw bytes

1/**
2 * @property {object} wdp_script_data_pro
3 * @property {string} wdp_script_data_pro.ajaxurl
4 * @property {string} wdp_script_data_pro.update_price_with_qty
5 * @property {string} wdp_script_data_pro.highlight_range_qty_changed
6 * @property {string} wdp_script_data_pro.higlight_background_color
7 * @property {string} wdp_script_data_pro.higlight_text_color
8 * @property {string} wdp_script_data_pro.js_init_trigger
9 * @property {boolean} wdp_script_data_pro.replace_variable_price
10 * @property {string} wdp_script_data_pro.variable_price_selector
11 * @property {object} wdp_script_data_pro.page_data
12 * @property {boolean} wdp_script_data_pro.create_on_load
13 * @property {boolean} wdp_script_data_pro.show_spinner
14 * @property {string} wdp_script_data_pro.security
15 * @property {string} wdp_script_data_pro.security_param
16 */
17
18/**
19 * @class
20 */
21var DynamicPrice = (function () {
22    /**
23     * @constructs DynamicPrice
24     * @param {jQuery} $form
25     * @param {object} $opts
26     */
27    function DynamicPrice($form, $opts) {
28        /**
29         * @type {Boolean}
30         * @private
31         */
32        this.__isEnable = false;
33
34        /**
35         * @type {Object}
36         * @private
37         */
38        this.__pageData = {};
39
40        /**
41         * @type {String}
42         * @private
43         */
44        this.__ajaxUrl = "";
45
46        /**
47         * @name DynamicPrice#form
48         * @type {jQuery}
49         */
50        this.form = null;
51
52        /**
53         * @type {number}
54         * @private
55         */
56        this.__inputTimerId = null;
57
58        /**
59         * @type {Array}
60         * @private
61         */
62        this.__price_destinations = [];
63
64        /**
65         * @type {Array}
66         * @private
67         */
68        this.__subtotal_destinations = [];
69
70        /**
71         * @type {Array}
72         * @private
73         */
74        this.__total_price_destinations = [];
75
76        this.__priceHtmlTemplate = "{{price_html}}";
77
78        this.__priceSuffix = "";
79
80        // for input observing
81        this.__lastChange = null;
82        this.__lastValue = null;
83
84      /**
85       * @type {Boolean}
86       * @private
87       */
88      this.__show_spinner = true;
89
90        if (typeof $opts === 'undefined') {
91            $opts = wdp_script_data_pro;
92        }
93
94        if (typeof $opts.price_html_template !== 'undefined') {
95            this.__priceHtmlTemplate = $opts.price_html_template;
96        }
97
98        if (typeof $opts.dynamic_price_enable !== 'undefined') {
99          this.__isEnable = !!$opts.dynamic_price_enable;
100        } else if (typeof $opts.update_price_with_qty !== 'undefined') {
101          this.__isEnable = $opts.update_price_with_qty === "1";
102        }
103        if (typeof $opts.page_data !== 'undefined') {
104            this.__pageData = $opts.page_data;
105        }
106
107        if (typeof $opts.price_suffix !== 'undefined') {
108            this.__priceSuffix = $opts.price_suffix;
109        }
110
111        if (typeof $opts.ajaxurl !== 'undefined') {
112            this.__ajaxUrl = $opts.ajaxurl;
113        } else {
114            logError("Empty ajaxurl");
115            return;
116        }
117
118        if (typeof $form !== 'undefined' && $form.is('form')) {
119            this.form = $form
120        } else {
121            logError("Incorrect form provided");
122        }
123
124      this.clickableBulkRows();
125
126      if (typeof $opts.show_spinner !== 'undefined') {
127        this.__show_spinner = !! $opts.show_spinner;
128      }
129
130      /**
131       *
132       * @returns {function(): {price: number, value: string}[]}
133       * @private
134       */
135      this.__addons_supplier = function () {
136        return []
137      };
138    }
139
140    function getTimestamp() {
141        return Math.floor(Date.now() / 1000);
142    }
143
144    DynamicPrice.prototype.stopObserve = function () {
145        if (this.__inputTimerId) {
146            clearInterval(this.__inputTimerId);
147        }
148    };
149
150    DynamicPrice.prototype.__getQty = function () {
151        var $input = this.form.find('input[name="quantity"]');
152        if ($input.length === 0) {
153            $input = this.form.find('select[name="quantity"]');
154            if ($input.length === 0) {
155                return 0;
156            }
157        }
158
159        return $input.val();
160    };
161
162    DynamicPrice.prototype.observe = function () {
163        this.stopObserve();
164
165        this.__lastChange = null;
166        this.__lastValue = this.__getQty();
167
168        this.__inputTimerId = setInterval(this.__watch.bind(this), 300);
169
170        if (document.getElementById('asnp_easy_product_bundle')) {
171          setTimeout(() => {
172            this.__update(this.__lastValue);
173          }, 500);
174        }
175    };
176
177    DynamicPrice.prototype.__watch = function () {
178        var $qty = this.__getQty();
179
180        if ($qty && this.__lastValue !== $qty) {
181            this.__lastValue = $qty;
182            this.__lastChange = getTimestamp();
183        } else if (this.__lastValue && this.__lastValue === $qty && this.__lastChange) {
184            this.__lastChange = null;
185            this.__update(this.__lastValue);
186        }
187    };
188
189    DynamicPrice.prototype.__getProductId = function () {
190        var variationIdEl = this.form.find('[name="variation_id"]');
191        var productIdEl = this.form.find('[name="add-to-cart"]');
192
193        if (variationIdEl.length) {
194            return parseInt(variationIdEl.val());
195        } else if (productIdEl.length) {
196            return parseInt(productIdEl.val());
197        }
198
199        return false;
200    };
201
202  DynamicPrice.prototype.__getVariationAttributes = function () {
203    let attributes = {};
204
205    this.form.find('select').each(function (index, item) {
206      if (jQuery(item).attr("data-attribute_name")) {
207        attributes[jQuery(item).attr("data-attribute_name")] = jQuery(this).val();
208      }
209    });
210
211    return attributes;
212  };
213
214  /**
215   *
216   * @param {string} $qty
217   * @param {string|undefined} $customPrice
218   * @returns {jQuery|null}
219   * @private
220   */
221    DynamicPrice.prototype.__update = function ($qty, $customPrice = undefined) {
222
223        if (typeof $qty === 'undefined' || !$qty) {
224          logError("Empty qty");
225          return null;
226        } else {
227          $qty = parseFloat($qty);
228        }
229
230        if (wdp_script_data_pro.highlight_range_qty_changed) {
231          this.__highlightRange($qty);
232        }
233
234        if (!this.__isEnable) {
235            return null;
236        }
237
238        if (typeof $customPrice === 'undefined') {
239            $customPrice = null;
240        }
241
242        var $existTotalPriceDestinations = [];
243        jQuery.each(this.__total_price_destinations, function (_, $selector) {
244          var $el = jQuery($selector).first();
245          if ($el.length !== 0) {
246            $existTotalPriceDestinations.push($el);
247          }
248        });
249
250
251        var $productId = this.__getProductId();
252        if (!$productId) {
253            replaceDestinations($existTotalPriceDestinations, '');
254
255            logError("Empty product ID");
256            return null;
257        }
258
259        var $existPriceDestinations = [];
260        jQuery.each(this.__price_destinations, function (_, $selector) {
261            var $el = jQuery($selector).first();
262            if ($el.length !== 0) {
263                $existPriceDestinations.push($el);
264            }
265        });
266
267        var $existSubtotalDestinations = [];
268        jQuery.each(this.__subtotal_destinations, function (_, $selector) {
269            var $el = jQuery($selector).first();
270            if ($el.length !== 0) {
271                $existSubtotalDestinations.push($el);
272            }
273        });
274
275
276        if ($existPriceDestinations.length === 0 && $existSubtotalDestinations.length === 0 && $existTotalPriceDestinations.length === 0) {
277            return null;
278        }
279
280        var data = {
281            action: 'get_price_product_with_bulk_table',
282            product_id: $productId,
283            attributes: this.__getVariationAttributes(),
284            qty: $qty,
285            page_data: this.__pageData,
286            ...jQuery('form.cart').triggerHandler('wdp_get_custom_data')
287        };
288
289        data[wdp_script_data_pro.security_param] = wdp_script_data_pro.security;
290
291        var $spinner_price = "<div id=\"spinner_price\"><img class=\"spinner_img\"></div>";
292        var pricePreloaded = false;
293
294        if ($customPrice !== null) {
295            data.custom_price = $customPrice;
296        } else {
297            var $price_html = this.__tryToGetPreLoadedPrice($productId, $qty);
298            if ($price_html) {
299                replaceDestinations($existPriceDestinations, $price_html);
300
301                if ($existSubtotalDestinations.length === 0 && $existTotalPriceDestinations.length === 0) {
302                  return;
303                }
304
305                pricePreloaded = true;
306            }
307        }
308
309        if ( this.__show_spinner ) {
310          if (!pricePreloaded) {
311            replaceDestinations($existPriceDestinations, $spinner_price);
312          }
313          replaceDestinations($existSubtotalDestinations, $spinner_price);
314          replaceDestinations($existTotalPriceDestinations, $spinner_price);
315        }
316
317        data.addons = this.__addons_supplier();
318
319        return jQuery.ajax({
320            url: this.__ajaxUrl,
321            data: data,
322            dataType: 'json',
323            type: 'POST',
324            success: function (response) {
325                if (response.success) {
326                    if ( !pricePreloaded ) {
327                      replaceDestinations($existPriceDestinations, response.data.price_html);
328                    }
329                    replaceDestinations($existSubtotalDestinations, response.data.subtotal_html);
330                    replaceDestinations($existTotalPriceDestinations, response.data.total_price_html);
331
332                    if (response.data.external_plugins) {
333                      response.data.external_plugins.forEach((external_plugin) => {
334                        if (external_plugin.destination && external_plugin.html)
335                          jQuery(external_plugin.destination).replaceWith(external_plugin.html);
336                        })
337                    }
338                } else {
339                    if ( !pricePreloaded ) {
340                      clearDestinations($existPriceDestinations);
341                    }
342                    clearDestinations($existSubtotalDestinations);
343                    clearDestinations($existTotalPriceDestinations);
344                }
345            },
346            error: function (response) {
347                if ( !pricePreloaded ) {
348                  clearDestinations($existPriceDestinations);
349                }
350                clearDestinations($existSubtotalDestinations);
351                clearDestinations($existTotalPriceDestinations);
352            }
353        });
354    };
355
356    DynamicPrice.prototype.__highlightRange = function ($qty) {
357      var $productContainer = this.form.closest('.product');
358      var $table = $productContainer.find('.bulk_table .wdp_pricing_table tbody');
359      if (!$table.length) return;
360      $qty = parseFloat($qty);
361
362      $table.find('tr td').each(function () {
363        this.style.setProperty('background-color', '');
364        this.style.setProperty('color', '');
365      });
366
367      $table.find('tr').each(function () {
368        var $row = jQuery(this);
369        var rangeText = $row.find('td').first().text().trim();
370        var match = rangeText.match(/(\d+)(?:\s*-\s*(\d+))?/);
371
372        if (match) {
373          var from = parseFloat(match[1]);
374          var to = match[2] ? parseFloat(match[2]) : Infinity;
375
376          if ($qty >= from && $qty <= to) {
377            $row.find('td').each(function () {
378              this.style.setProperty('background-color', wdp_script_data_pro.higlight_background_color, 'important');
379              this.style.setProperty('color', wdp_script_data_pro.higlight_text_color, 'important');
380            });
381          }
382        }
383      });
384    };
385
386    DynamicPrice.prototype.__clearTotalPrice = function() {
387        var $existTotalPriceDestinations = [];
388        jQuery.each(this.__total_price_destinations, function (_, $selector) {
389          var $el = jQuery($selector).first();
390          if ($el.length !== 0) {
391            $existTotalPriceDestinations.push($el);
392          }
393        });
394
395        var $productId = this.__getProductId();
396
397        if (!$productId) {
398            replaceDestinations($existTotalPriceDestinations, '');
399        }
400    };
401
402    DynamicPrice.prototype.__tryToGetPreLoadedPrice = function ($productId, $qty) {
403        if ( typeof wdp_script_data_pro.preLoaded === 'undefined' ) {
404            return null;
405        }
406
407        var $preLoaded = wdp_script_data_pro.preLoaded;
408
409        $qty = parseFloat($qty);
410        if ( ! $qty ) {
411            return null;
412        }
413
414        $productId = $productId.toString();
415
416        var _this = this;
417
418        var $html = null;
419        jQuery.each($preLoaded, function ($preLoadedProductId, $data) {
420            if ( typeof $data.ranges === 'undefined' || typeof $data.price_html === 'undefined' || typeof $data.price_html_view === 'undefined' || typeof $data.index_number === 'undefined' ) {
421                return; // continue
422            }
423            var $ranges = $data.ranges;
424            var $price_html = $data.price_html;
425            var $current_qty = $data.index_number + $qty;
426            var $qty_already_in_cart = $data.qty_already_in_cart;
427
428            if ( $preLoadedProductId === $productId ) {
429                jQuery.each($ranges, function (_, $range) {
430                    if (compareFloats($range['from'], '<=', $current_qty) && compareFloats($current_qty, '<=', $range['to'])
431                        || (compareFloats($range['from'], '<=', $current_qty) && $range['to'] === "")
432                        || ($range['from'] === "" && compareFloats($current_qty, '<=', $range['to']))
433                    ) {
434                        $html = _this.__formatPriceHtml($range['striked_price_html'], $current_qty, $qty_already_in_cart, $range['regular_price_striked']);
435                        return false;
436                    }
437                });
438
439                if ( ! $html ) {
440                  if ( $current_qty === 1 ) {
441                    $html = $data.price_html_view;
442                  } else{
443                    $html = _this.__formatPriceHtml($price_html, $current_qty, $qty_already_in_cart, "");
444                  }
445                }
446            }
447            if ( $html ) {
448                return false;
449            }
450        });
451
452        return $html;
453    };
454
455    function compareFloats($a, $op, $b) {
456        $a = Math.floor(parseFloat($a) * 100);
457        $b = Math.floor(parseFloat($b) * 100);
458
459        switch ($op) {
460            case "=":
461                return $a === $b;
462            case ">":
463                return $a > $b;
464            case ">=":
465                return $a >= $b;
466            case "<":
467                return $a < $b;
468            case "<=":
469                return $a <= $b;
470        }
471
472        return null;
473    }
474
475    function replaceDestinations($targets, $priceHtml) {
476        jQuery.each($targets, function (_, $target) {
477            $target.html($priceHtml);
478            jQuery(document).trigger('wdp_price_product_updated', $priceHtml);
479        })
480    }
481
482    DynamicPrice.prototype.clickableBulkRows = function () {
483      if (!wdp_script_data_pro.clickable_bulk_rows) {
484        return
485      }
486
487      let $table = jQuery('.bulk_table .wdp_pricing_table');
488      let $input = jQuery('input[name="quantity"]');
489      if (!$table || !$input || $table.data('measurement') !== 'qty' || $table.data('layout') !== 'verbose') return
490
491      // let $targets = $table.data('layout') === 'verbose' ? $table.find('tbody tr') : $table.find('thead td');
492      let $targets = $table.find('tbody tr');
493
494      $targets.addClass('clickable_bulk');
495      $targets.css('--highlight-range-bg', wdp_script_data_pro.higlight_background_color);
496      $targets.css('--highlight-range-text', wdp_script_data_pro.higlight_text_color);
497      $targets.each((i) => {
498        jQuery($targets[i]).on('click', () => {
499          let min = jQuery($targets[i]).data('min');
500          $input.val(min);
501        })
502      })
503    }
504
505    function clearDestinations($targets) {
506        jQuery.each($targets, function (_, $target) {
507            $target.html("");
508            jQuery(document).trigger('wdp_price_product_updated', "");
509        })
510    }
511
512    DynamicPrice.prototype.addPriceDestination = function ($dest) {
513        if (typeof $dest === 'string') {
514            this.__price_destinations.push($dest);
515        } else if (Array.isArray($dest)) {
516            Array.prototype.push.apply(this.__price_destinations, $dest);
517        }
518    };
519
520    DynamicPrice.prototype.addSubtotalDestination = function ($dest) {
521        if (typeof $dest === 'string') {
522            this.__subtotal_destinations.push($dest);
523        } else if (Array.isArray($dest)) {
524            Array.prototype.push.apply(this.__subtotal_destinations, $dest);
525        }
526    };
527
528    DynamicPrice.prototype.addTotalPriceDestination = function ($dest) {
529      if (typeof $dest === 'string') {
530        this.__total_price_destinations.push($dest);
531      } else if (Array.isArray($dest)) {
532        Array.prototype.push.apply(this.__total_price_destinations, $dest);
533      }
534    };
535
536  /**
537   *
538   * @param {function(): {price: number, value: string}[]}  callback
539   */
540  DynamicPrice.prototype.withAddonsSupplier = function (callback) {
541      this.__addons_supplier = callback;
542    };
543
544    DynamicPrice.prototype.update = function ($args) {
545        var $qty = null;
546        var $customPrice = null;
547
548        if (typeof $args !== 'undefined') {
549            if (typeof $args.qty !== 'undefined') {
550                $qty = parseFloat($args.qty);
551            } else {
552                $qty = this.__getQty();
553            }
554
555            if (typeof $args.custom_price !== 'undefined') {
556                $customPrice = $args.custom_price;
557            }
558        }
559
560        return this.__update($qty, $customPrice);
561    };
562
563
564    DynamicPrice.prototype.disable = function () {
565        this.__isEnable = false;
566    };
567
568    DynamicPrice.prototype.enable = function () {
569        this.__isEnable = true;
570    };
571
572    DynamicPrice.prototype.__formatPriceHtml = function ($priceHtml, $indexNumber, $qtyAlreadyInCart, regularPriceStriked) {
573        return this.__priceHtmlTemplate
574            .replace("{{price_html}}", $priceHtml)
575            .replace("{{Nth_item}}", addSuffixOf($indexNumber))
576            .replace("{{qty_already_in_cart}}", $qtyAlreadyInCart)
577            .replace("{{price_suffix}}", this.__priceSuffix)
578            .replace("{{regular_price_striked}}", regularPriceStriked);
579    };
580
581    function addSuffixOf($value) {
582        var mod10 = $value % 10,
583            mod100 = $value % 100;
584
585        if (mod10 === 1 && mod100 !== 11) {
586            return $value + "st";
587        }
588        if (mod10 === 2 && mod100 !== 12) {
589            return $value + "nd";
590        }
591        if (mod10 === 3 && mod100 !== 13) {
592            return $value + "rd";
593        }
594        return $value + "th";
595    }
596
597    function logError($text) {
598        console.error("DynamicPrice error: %s", $text);
599    }
600
601    return DynamicPrice;
602})();
603
604var dynamicPrices = [];
605
606function createDynamicPrice() {
607    var dynamicPrices = [];
608
609    jQuery('form.cart').each(function () {
610        var $form = jQuery(this);
611        var isVariation = $form.hasClass("variations_form");
612        var $targets = [];
613        var $productId = $form.find('[name="add-to-cart"]').val();
614
615        if (!$productId) {
616            return false;
617        }
618
619        if (isVariation) {
620            $targets.push('.product.post-' + $productId + ' .woocommerce-variation-price .price');
621
622            if (wdp_script_data_pro.replace_variable_price) {
623                $targets.push('.product.post-' + $productId + ' ' + wdp_script_data_pro.variable_price_selector);
624            }
625        } else {
626            $targets.push('.product.post-' + $productId + ' .price');
627        }
628
629        var optFirst = Object.assign({}, wdp_script_data_pro);
630        optFirst.dynamic_price_enable = true;
631        var dynamicPrice = new DynamicPrice($form, optFirst);
632
633        if ( optFirst.update_price_with_qty === "1" ) {
634            dynamicPrice.addPriceDestination($targets);
635        }
636
637        dynamicPrice.addTotalPriceDestination(["div.adp-total-price"]);
638
639        dynamicPrice.observe();
640        dynamicPrices.push(dynamicPrice);
641    });
642
643    return dynamicPrices;
644}
645
646if (wdp_script_data_pro.js_init_trigger) {
647    jQuery(document).on(wdp_script_data_pro.js_init_trigger, function () {
648        dynamicPrices = createDynamicPrice();
649    });
650}
651
652if (wdp_script_data_pro.create_on_load) {
653    jQuery(document).ready(function () {
654        dynamicPrices = createDynamicPrice();
655
656        jQuery('.variations_form').on('found_variation', {variationForm: this},
657            function (event, variation) {
658                if (typeof variation !== 'undefined') {
659                    setTimeout(function () {
660                        dynamicPrices.forEach(function (dynamicPrice) {
661                            if (dynamicPrice.form[0] !== undefined && dynamicPrice.form[0] === event.target) {
662                                dynamicPrice.__update(dynamicPrice.__getQty())
663                            }
664                        });
665                    }, 0);
666                }
667
668                return true;
669            });
670
671        jQuery('form.cart').on('adp_found_variation', function () {
672            setTimeout(function () {
673                dynamicPrices.forEach(function (dynamicPrice) {
674                    if (dynamicPrice.form[0] !== undefined) {
675                        dynamicPrice.__update(dynamicPrice.__getQty())
676                    }
677                });
678            }, 0);
679            return true;
680        });
681
682        jQuery('.variations_form').on('reset_data', {variationForm: this},
683            function (event) {
684                setTimeout(function () {
685                  dynamicPrices.forEach(function (dynamicPrice) {
686                      if (dynamicPrice.form[0] !== undefined && dynamicPrice.form[0] === event.target) {
687                          dynamicPrice.__clearTotalPrice();
688                      }
689                  });
690
691                }, 0);
692
693                return true;
694            });
695    });
696}

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.