PageSourceSearch

https://shop-assets.awc.org/wp-content/plugins/advanced-dynamic-pr…/assets/js/dynamic-price.js?ver=4.9.2

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

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.