PageSourceSearch

https://www.aila.org/store/js/combos.js?1789390028

js aila.org collected 2026-09-24 08:39:06 UTC 10,039 bytes, 243 lines download raw bytes

1/* global $ */
2/* global postData */
3/* global API_ENDPOINT_ADD_TO_CART */
4/* global throwError */
5/* global handleError */
6
7const API_ENDPOINT_ADD_COMBO = window.location.origin + '/api/shopping/v1/cart/combos/add.json';
8
9document.addEventListener("DOMContentLoaded", function (event) {
10    "use strict";
11
12    let comboKeeper = {
13        combos: {},
14
15        addToCart: function(comboId, $modal = null) {
16            if (this.hasOwnProperty("combos") && this.combos.hasOwnProperty(comboId)) {
17                let quantity = $(`input[type="number"][name="${comboId}"]`).val();
18                if (!quantity) {
19                    quantity = 1;
20                }
21
22                postData(API_ENDPOINT_ADD_COMBO, {
23                    combo_id: comboId,
24                    quantity: quantity,
25                    options: comboKeeper.combos[comboId].options
26                }).then(response => {
27                    if (response.hasOwnProperty("success") && response.success) {
28                        if ($modal) {
29                            $modal.find(".success").show();
30                            $modal.find(".add-to-cart-button").addClass("btn-dark").addClass("disabled").
31                                removeClass("btn-primary").attr("disabled", "disabled").
32                                html(LABEL_ALREADY_IN_CART);
33                        }
34                        $(`.add-combo[data-combo-id="${comboId}"]`).addClass("btn-dark").removeClass("btn-primary").
35                            attr("disabled", "disabled").html(LABEL_ALREADY_IN_CART);
36                    } else {
37                        handleError(response, "combo");
38                    }
39
40                    let added = {};
41                    if (response.hasOwnProperty("added")) {
42                        added = response.added;
43                    }
44                    document.dispatchEvent(new CustomEvent('oecommerce-added-combo', {
45                        detail: {
46                            added: added
47                        }
48                    }));
49
50                    let cartResponse = {};
51                    if (response.cart) {
52                        cartResponse = response.cart;
53                    }
54
55                    document.dispatchEvent(new CustomEvent('oecommerce-update-ui', {
56                        detail: {
57                            reload: false,
58                            cart: cartResponse
59                        }
60                    }));
61                });
62            } else {
63                throwError(`Attempted to add comboId ${comboId} but it does not exist in comboKeeper.`);
64            }
65        },
66
67        init: function() {
68            $(".combo-modals").each(function () {
69                let $combo = $(this);
70                let comboId = $combo.attr("data-combo-id");
71                if (!comboId) {
72                    throwError("No combo ID specified on combo collection.");
73                }
74                if (!comboKeeper.combos.hasOwnProperty(comboId)) {
75                    comboKeeper.combos[comboId] = {};
76                    comboKeeper.combos[comboId].options = {};
77                }
78                comboKeeper.combos[comboId].$modals = $combo.find(".modal");
79                comboKeeper.setupModals(comboId);
80            });
81
82            $("button.add-combo").on("click", function () {
83                let $button = $(this);
84                let comboId = $button.attr("data-combo-id");
85                if (!comboId) {
86                    throwError("No combo ID specified on combo add to cart button.");
87                }
88                comboKeeper.openCombo(comboId);
89            });
90
91            return this;
92        },
93
94        openCombo: function(comboId) {
95            if (this.hasOwnProperty("combos") && this.combos.hasOwnProperty(comboId)) {
96                this.combos[comboId].options = {};
97                if (this.combos[comboId].$modals.hasOwnProperty(0)) {
98                    $(this.combos[comboId].$modals[0]).modal("show");
99                } else {
100                    this.addToCart(comboId);
101                }
102            } else {
103                throwError("Invalid combo ID specified.");
104            }
105
106            return this;
107        },
108
109        setupAttestationModal: function ($modal, $nextModal = null) {
110            let $button = $modal.find(".modal-body button");
111            if ($button.length === 0) {
112                $button = $modal.find("a.add-to-cart-button");
113            }
114            if ($button.length > 0) {
115                if ($button.is("button")) {
116                    $button.attr("type", "button");
117                }
118                $button.removeAttr("data-ecommerce-action").addClass("btn-primary").removeClass("disabled").
119                    removeClass("btn-dark").removeAttr("disabled");
120                if ($nextModal) {
121                    $button.attr("data-toggle", "modal");
122                    $button.attr("data-target", "#" + $nextModal.attr("id"));
123                    $button.on("click", function () {
124                        $modal.off("hidden.bs.modal").on("hidden.bs.modal", function () {
125                            $nextModal.modal("show");
126                        }).modal("hide");
127                    });
128                } else {
129                    $button.addClass("add-to-cart-button").on("click", function() {
130                        comboKeeper.addToCart($modal.data("comboId"), $modal);
131                    });
132                }
133            } else {
134                throwError("Unable to find submit button for combo attestation modal");
135            }
136        },
137
138        setupModals: function(comboId) {
139            if (this.combos.hasOwnProperty(comboId) && this.combos[comboId].hasOwnProperty("$modals")) {
140                let $modals = this.combos[comboId].$modals;
141
142                $modals.each(function (index) {
143                    let $modal = $(this);
144                    $modal.data("comboId", comboId);
145                    $modal.on("show.bs.modal", function () {
146                        let $activeModal = $(this);
147                        $activeModal.find(".success").hide();
148                        $activeModal.find("div.input.error").removeClass("error");
149                        $activeModal.find("input, select").val("").removeClass("form-error").removeClass("is-invalid");
150                        $activeModal.find("div.invalid-feedback").remove();
151                    });
152
153                    let $nextModal;
154                    if ($modals.hasOwnProperty(index + 1)) {
155                        $nextModal = $($modals[index + 1]);
156                    }
157
158                    if ($modal.hasClass("options-modal")) {
159                        comboKeeper.setupOptionsModal($modal, $nextModal);
160                    } else if ($modal.hasClass("attestation-modal")) {
161                        comboKeeper.setupAttestationModal($modal, $nextModal);
162                    }
163                });
164            }
165
166            return this;
167        },
168
169        setupOptionsModal: function($modal, $nextModal = null) {
170            let $button = $modal.find(".add-to-cart-button");
171            if ($button.length > 0) {
172                if ($nextModal) {
173                    $button.html("Submit");
174                }
175                $button.removeAttr("data-ecommerce-action").addClass("btn-primary").removeClass("disabled").
176                    removeClass("btn-dark").removeAttr("disabled").html("Add to Cart");
177
178                let productId = $button.attr("data-product-id");
179                if (!productId) {
180                    throw "Missing product ID on cart button";
181                }
182                let priceId = $button.attr("data-price-id");
183                if (!priceId) {
184                    throw "Missing price ID on cart button";
185                }
186
187                $button.on("click", function() {
188                    let $formFields = $modal.find("select, input");
189                    let options = {};
190                    $formFields.each(function () {
191                        let $field = $(this);
192                        let optionId = $field.attr("name").match(/\[([A-Z0-9-]+)]/);
193                        if (optionId.length === 2) {
194                            optionId = optionId[1];
195                            options[optionId] = $field.val();
196                        }
197                    });
198
199                    comboKeeper.validateProduct(productId, priceId, options, $modal, $nextModal);
200                });
201            } else {
202                throwError("Unable to find submit button for combo modals");
203            }
204
205            return this;
206        },
207
208        validateProduct: function(productId, priceId, options, $modal, $nextModal = null) {
209            let success = false;
210
211            postData(API_ENDPOINT_ADD_TO_CART, {
212                product_id: productId,
213                quantity: 1,
214                price_id: priceId,
215                validate_only: 1,
216                options: options
217            }).then(response => {
218                if (response.hasOwnProperty("success") && response.success) {
219                    let comboId = $modal.data("comboId");
220                    if (comboKeeper.combos.hasOwnProperty(comboId)) {
221                        if (options) {
222                            for (const property in options) {
223                                comboKeeper.combos[comboId].options[property] = options[property];
224                            }
225                        }
226                        if ($nextModal) {
227                            $modal.off("hidden.bs.modal").on("hidden.bs.modal", function() {
228                                $nextModal.modal("show");
229                            }).modal("hide");
230                        } else {
231                            comboKeeper.addToCart(comboId, $modal);
232                        }
233                    }
234                } else {
235                    handleError(response, "combo");
236                }
237            });
238
239            return success;
240        }
241    };
242    comboKeeper.init();
243});

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.