PageSourceSearch

https://genesis.kemba.org/VirtualCapture/Views/Products/Aksw.Products.js?version=230016

js kemba.org collected 2026-10-03 19:15:38 UTC 34,487 bytes, 797 lines download raw bytes

1var Aksw = Aksw ? Aksw : Aksw = {};
2
3Aksw.Products = function () {
4    var internal = {
5
6        deviceBreak: 768,
7        deviceWidth: 0,
8        loanType: 31,
9        isAccountProductsReachMaxiumResult: false,
10
11        setDeviceWidth: function () {
12            internal.deviceWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
13        },
14
15        isSmallDevice: function () {
16            return (internal.deviceWidth < internal.deviceBreak);
17        },
18
19        toggleApplyNow: function () {
20            if (external.model.useShoppingCart) {
21                if (external.model.products.length == 0) {
22                    $('.apply-now').attr('disabled', 'disabled');
23                }
24                else {
25                    $('.apply-now').prop('disabled', false);
26                }
27            }
28        },
29
30        addProduct: function (elem) {
31            /*********************************************************************************
32            The following IF block of code is to make sure in the no shopping cart scenario,  
33            every time user click apply now button, only one account or one loan is selected
34            for initial application. Without it,  we could have multiple products selected if
35            user click PRODUCTs and click apply now button again in product list screen. 
36            **********************************************************************************/
37            if (!external.model.useShoppingCart) {
38                if (Aksw.AddProducts === undefined) {
39
40                    if (external.model.products !== undefined) {
41                        external.model.products.splice(0, external.model.products.length)
42                    }
43                }
44            }
45
46            external.model.products.push({
47                category: elem.data('category'),
48                subCategory: elem.data('subcategory'),
49                name: elem.data('name'),
50                type: elem.data('type'),
51                id: elem.data('id'),
52                objectid: elem.data('objectid')
53            });
54
55            internal.toggleApplyNow();
56        },
57
58        doSyncHeight: function () {
59            var sync = false;
60            if (external.model.syncHeightOnLarge && !internal.isSmallDevice()) {
61                sync = true;
62            }
63            if (external.model.syncHeightOnSmall && internal.isSmallDevice()) {
64                sync = true;
65            }
66            return sync;
67        },
68       
69        showProducts: function (category, subCategory) {
70            // hide the current products tab and show the tab 
71            //for the currently selected subcategory for this category
72            $('.products-wrap.active').removeClass('active');
73            var category = $(this).parent().data('category');
74            var id = $('.subcategory-tabs > li.active[data-category="' + category + '"] > a').data('id');
75            $('#' + id).addClass('active');
76        },
77
78        removeProduct: function (id) {
79            var product;
80            var data = external.model.products;
81
82            for (var i = 0; i < data.length; i++) {
83                if (data[i].id === id) {
84                    product = data[i];
85                    break;
86                }
87            }
88            if (product) {
89                data.splice(data.indexOf(product), 1);
90            }
91
92            //if Aksw.AddProducts exists we are inside an application, so we need to see if the update products button should be enabled.
93            if (Aksw.AddProducts) {
94
95                Aksw.AddProducts.ToggleUpdateProductsButton();
96            }
97
98            internal.toggleApplyNow();
99
100            return product;
101        },
102   
103        selectButtonRefresh: function (id, count) {
104
105            // this is not necessary unless we have account products 
106            // because buttons don't change if loans only
107            if (external.model.hasAccountProducts) {
108                $('.product .select-wrap div[data-id=' + id + ']').each(function () {
109                    var elem = $(this);
110
111                    elem.data('selected', count);
112
113                    if (elem.hasClass('select-wrap-spinner')) {
114                        // refresh the spinner
115                        elem.find('div').html(count);
116                        if (count > 0) {
117                            elem.find('button').addClass('btn-success');
118                        } else if (count === 0) {
119                            elem.find('button').removeClass('btn-success');
120                        }
121                        elem.find('button:first-child').prop('disabled', (count === 0));
122                        elem.find('button:last-child').prop('disabled', (count === elem.data('maxallowed')));
123                    } else {
124                        // refresh the button
125                     
126                        var btn = elem.find('> button').not('.prequalifyproduct')
127                        if (count === 0) {
128
129                            if (!external.model.useShoppingCart) {
130                                btn.html(external.model.addProductsNoCartSelectText);
131                                btn.attr('alt', external.model.addProductsNoCartSelectText)
132                                btn.removeClass('btn-success');
133
134                            }
135                            else {
136                                btn.html(external.model.singleSelectText);
137                                btn.attr('alt', external.model.singleSelectText)
138                                btn.removeClass('btn-success');
139                            }
140                        } else {
141
142                            if (!external.model.useShoppingCart) {
143                                btn.html(external.model.addProductsNoCartSelectedText);
144                                btn.attr('alt', external.model.addProductsNoCartSelectedText)
145                                btn.addClass('btn-success');
146                            }
147                            else {
148                                btn.html(external.model.singleSelectedText);
149                                btn.attr('alt', external.model.singleSelectedText)
150                                btn.addClass('btn-success');
151                            }
152                        }
153                    }
154                });
155            }
156        },
157        
158        selectButtonClick: function (elem, value) {
159
160            var count = parseInt(elem.data('selected'));
161            var id = elem.data('id');
162
163            if (count === 0 && value === -1) {
164                //do nothing
165                return;
166            }
167            // define the steps to take if we move forward
168            var continueAction = function (elem2, id2, value2) {
169                var count2 = elem2.data('selected');
170
171                if (value2 === 1) {
172                    // add it to the model
173                    internal.addProduct(elem2);
174
175                    // are we ready to create the app?
176                    if (!external.model.useShoppingCart || !external.model.hasAccountProducts) {
177                        // only one loan or not using shopping cart - create it now
178                        if (Aksw.AddProducts === undefined) {
179                            external.applyNow();
180                        }
181                        else {
182                            'we are inside a application, we just need to save the new account'
183
184                            Aksw.AddProducts.AddProducts();
185                        }
186
187                    }
188
189                } else {
190                    internal.removeProduct(id2);
191                }
192
193                // special UI handling for button
194                count2 = count2 + value2;
195               
196                internal.selectButtonRefresh(id2, count2);
197            }
198
199            if (elem.data('type') === internal.loanType) {
200                var loan = internal.getLoanFromModel();
201                if (loan){
202                    if (loan.id === elem.data('id')) {
203                        continueAction(elem, id, value);
204                    } else {
205                        Aksw.Dialog.showConfirm({                     
206                            text: external.model.loanAlreadySelectedText,
207                            buttons: [loan.name.toString(),elem.data('name').toString()],
208                            callback: function (choice) {
209                                var elem2 = $('.select-wrap div[data-id="' + loan.id + '"]');
210                                if (choice === loan.name.toString()) {
211                                    //keep the existing'
212                                    continueAction(elem2, elem.data("id"), -1);
213                                    internal.remove(elem.data("id"), elem.data('category'));
214                                } else {
215                                    // remove the existing and then continue with the new
216                                    continueAction(elem2, loan.id, -1);
217                                    internal.remove(loan.id, elem2.data('category'));
218                                    continueAction(elem, id, value);
219                                    internal.updateBadge();
220                                }
221                            }
222                        });
223                        $(document).ready(function () {
224                            $('.modal-dialog .close').click(function () {
225                                var selectedCart = $('.cart .group .selected-products-summary');
226                                var id = $(selectedCart[selectedCart.length - 1]).data('id');
227                                var category = $(selectedCart[selectedCart.length - 1]).data('category');
228                                internal.removeProduct(id);
229                                internal.removeGroupElement(id, category);
230                            });
231                        });
232                    }
233                } else {
234                    continueAction(elem, id, value);
235                }
236            } else {
237                continueAction(elem, id, value);
238            }
239
240            //if Aksw.AddProducts exists we are inside an application, so we need to see if the update products button should be enabled.
241            if (Aksw.AddProducts) {
242               
243                Aksw.AddProducts.ToggleUpdateProductsButton();
244            }
245        },
246
247        getLoanFromModel: function () {
248            var loan;
249            var data = external.model.products;
250            for (var i = 0; i < data.length; i++) {
251                if (data[i].type === internal.loanType) {
252                    loan = data[i];
253                    break;
254                }
255            }
256            return loan;
257        },
258        cartHasProduct: function (category, subCategory) {
259            var ret = false;
260            var data = external.model.products;
261            for (var i = 0; i < data.length; i++) {
262                if (data[i].category === category || data[i].category != category) {
263                    if (subCategory) {
264                        if (data[i].subCategory === subCategory || data[i].subCategory != subCategory) {
265                            ret = true;
266                            break;
267                        }
268                    } else {
269                        ret = true;
270                        break;
271                    }
272
273                }
274            }
275            return ret;
276        },
277        setActiveClass: function (category, subCategory) {
278
279            if (category != undefined && category != null) {
280                $('.category-tabs a[data-toggle="tab"]').parent().each(function (ind, elem) {
281                    $(elem).removeClass("active");
282                });
283                $('.category-tabs a[data-toggle="tab"][data-category="' + category + '"]').parent().addClass("active")
284
285                $('.subcategory-tabs').parent().each(function (ind, elem) {
286                    $(elem).removeClass("active");
287                });
288                $('.subcategory-tabs[data-category="' + category + '"]').parent().addClass("active")
289            }
290
291            if (subCategory != undefined && subCategory != null) {
292                $('.subcategory-tabs a[data-toggle="tab"]').parent().each(function (ind, elem) {
293                    $(elem).removeClass("active");
294                });
295                $('.subcategory-tabs a[data-toggle="tab"][data-category="' + category + '"][data-subcategory="' + subCategory + '"]').parent().addClass("active")
296
297
298                $('.products-wrap').each(function (ind, elem) {
299                    $(elem).removeClass("active");
300                });
301
302                $('.tab-pane.products-wrap[data-category="' + category + '"][data-subcategory="' + subCategory + '"]').addClass("active")
303            }
304            internal.updateMobileCategoryPath(category, subCategory);
305        },
306        cartShowHide: function (id, category, subcategory, val) {
307
308            $('.row .group-name').each(function (ind, elem) {
309                if ($(elem).html() == category) {
310                    if (val == 1 && internal.cartHasProduct(category, subcategory)) {
311                        internal.addGroupElement(id, category, subcategory, elem);
312                        $(elem).parent().show();
313                    }
314                    else if (val == -1)
315                        internal.removeGroupElement(id, category);
316                }
317            });
318            internal.updateBadge();
319            internal.updateEmptyText();
320        },
321        addGroupElement: function (id, category, subcategory, elem) {
322            var html = [];
323            for (var i = 0; i < allProductsArr.length; i++) {
324                var obj = allProductsArr[i];
325                if (obj.id == id && obj.category == category && obj.subcategory == subcategory) {
326                    var classarr = []
327                    classarr.push("alert selected-products-summary");
328                    if (obj.objecttypeid == 31) {
329                        classarr.push("alert-success");
330                    }
331                    else {
332                        classarr.push("alert-info");
333                    }
334                    html.push("<div class='" + classarr.join(" ") + "' data-id=" + obj.id + " data-category='" + category + "' data-subcategory='" + subcategory + "'>");
335                    html.push("<div class='value'>" + obj.name + "</div>");
336                    html.push("<div class='glyphicon glyphicon-remove remove'></div>");
337                    html.push("</div>");
338                    break;
339                }
340
341            }
342            $(html.join('')).appendTo($(elem).parent());
343        },
344        remove: function (id, category) {
345            internal.removeProduct(id);
346            internal.removeGroupElement(id, category);
347        },
348        removeGroupElement: function (id, category) {
349            var group = $('.selected-products-summary[data-id=' + id + ']').parent();
350            $('.selected-products-summary[data-id="' + id + '"]').each(function (ind, elem) {
351                $(elem).remove();
352                return false;
353            });
354            if ($('.selected-products-summary[data-category="' + category + '"]').length == 0) {
355                group.hide();
356            }
357            internal.updateBadge();
358            internal.updateEmptyText();
359        },
360        updateEmptyText: function () {
361            if (external.model.products.length == 0) {
362                $('.empty-cart').show();
363            }
364            else {
365                $('.empty-cart').hide();
366            }
367        },
368        updateMobileCategoryPath: function (category, subcategory) {
369            $('.category-name').html(category + " > " + subcategory);
370        },
371        
372        updateBadge: function () {
373           
374            var count = 0;
375            $('.selected .badge').each(function (ind, elem) {
376                if (count == 0) {
377                    if (external.model.products.length == 1) {
378                        $(elem).show();
379                    }
380                    else {
381                        $(elem).hide();
382                    }
383                }
384                else {
385                    if (external.model.products.length != 1) {
386                        $(elem).show();
387                    }
388                    else {
389                        $(elem).hide();
390                    }
391                }
392                $(elem).html(external.model.products.length.toString() + " " + external.model.cartProductTermNamePlural);
393                count++;
394            });
395            $('.cart-mobile .badge').each(function (ind, elem) {
396                $(elem).html(external.model.products.length.toString() + " " + external.model.cartProductTermNamePlural);
397            });
398        },
399        isAccountProductsReachMaximum: function (productid) {
400            internal.isAccountProductsReachMaxiumResult = false;
401            if (!productSelectionModel.useShoppingCart && Aksw.App != undefined && Aksw.App != null) {
402
403                var config = {};
404                config.url = Aksw.Util.siteRoot + 'Products/CheckAccountProductMaximum?ApplicationId=' + Aksw.App.applicationId + '&Id=' + productid;
405                config.maskMessage = 'Loading...';
406                config.callback = internal.isAccountProductsReachMaximumCallBack;
407                config.showSuccessDialog = false;
408                config.async = false;
409                Aksw.Ajax.post(config);
410            }
411        },
412        isAccountProductsReachMaximumCallBack: function (data) {
413            internal.isAccountProductsReachMaxiumResult = false;
414            if (data.Result === true && data.ReturnValues.length > 0) {
415                if (data.ReturnValues[0].Name == "CANADD" && data.ReturnValues[0].Value == "FALSE") {
416                    internal.isAccountProductsReachMaxiumResult = true;
417                }
418            }
419        }
420    };
421
422    var external = {
423        model: {},
424
425        prequalify: function () {
426            external.prequalifyProduct(-1); // No product selected, try to prequalify for everything.
427        },
428
429        prequalifyProduct: function (webOriginationProductId) {
430
431            Aksw.Ajax.post({
432                url: Aksw.Util.siteRoot + 'Products/SetPrequalifyProduct',
433                maskLeaveOn: true,
434                showSuccessDialog: false,
435                data: {
436                    ProductId: webOriginationProductId
437                },
438                callback: function (res) {
439
440                    $.ajax({
441                        url: Aksw.Util.siteRoot + 'Login/NavigateAfterProducts?FromPrequal=True',
442                        data: res
443                    }).done(function (url) {
444                        if (url.length > 0) {
445                            window.location.href = url
446                        } else {
447                            var url = Aksw.Util.siteRoot;
448                            url += 'Promotions/Prequalification?ProductId=' + webOriginationProductId;
449                            window.location.href = url;
450                            return false;
451                        }
452                    })
453                }
454            });
455        },
456
457        applyNow: function () {
458            var ids = [];
459            for (var i = 0; i < external.model.products.length; i++) {
460                ids.push(external.model.products[i].id);
461            }
462
463            Aksw.Ajax.post({
464                url: Aksw.Util.siteRoot + 'Products/SetSelectedProducts',
465                maskMessage: 'Creating application...',
466                maskLeaveOn: true,
467                showSuccessDialog: false,
468                data: {
469                    ProductIds: ids.join(',')
470                },
471                callback: function (res) {
472
473                    $.ajax({
474                        url: Aksw.Util.siteRoot + 'Login/NavigateAfterProducts',
475                        data: res
476                    }).done(function (url) {
477                        if (url.length > 0) {
478                            window.location.href = url
479                        } else {
480                            Aksw.Ajax.post({
481                                url: Aksw.Util.siteRoot + 'Application/CreateNewApplication',
482                                mask: false,
483                                showSuccessDialog: false,
484                                callback: function (data) {
485                                    //return of true just means the call completed
486                                    if (data.Result) {
487                                        //the Screen controller, Nav action will determine actual screen to load
488                                        var url = Aksw.Util.siteRoot;
489                                        url += 'Screen/Nav?ownerid=' + data.ApplicationId;
490                                        window.location.href = url;
491                                        return false;
492                                    }
493                                }
494                            });
495                        }
496                    })
497                }
498            });
499
500        },
501
502        syncCardHeight: function () {
503          
504            if (internal.doSyncHeight()) {
505                var elem = $('.products-wrap:visible');
506                var bodies = elem.find('.product .body');
507                var headers = elem.find('.product .heading');
508                if (!elem.data('heightsynced')) {
509                    //console.log('sync height');
510                    var maxHeightHeader = 0;
511                    var maxHeightBody = 0;
512                    headers.each(function () {
513                        if ($(this).height() > maxHeightHeader) {
514                            maxHeightHeader = $(this).height();
515                        }
516                    });
517                    bodies.each(function () {
518                        if ($(this).height() > maxHeightBody) {
519                            maxHeightBody = $(this).height();
520                        }
521                    });
522                    headers.height(maxHeightHeader);
523                    bodies.height(maxHeightBody);
524                    elem.data('heightsynced', true);
525                }
526            }
527
528        },
529
530        mobileSelectClick: function (elem) {
531            // check if an item is being added to the cart (rather than removed)
532            if (elem.parent().data('selected') == 0) {
533                document.body.scrollTop = document.documentElement.scrollTop = 0;
534                // open the shopping cart if it isn't opened
535                if ($('.cart').is(':visible') == false) {
536                    $('.cart').slideDown();
537                }
538            }
539        }
540    };
541
542    var initialize = function () {
543        $(document).ready(function () {
544
545            external.model = productSelectionModel;
546
547            internal.setDeviceWidth();
548            $('.layout-initial-mask').hide();
549            internal.setActiveClass(external.model.category, external.model.subCategory);
550            internal.updateBadge();
551            internal.updateMobileCategoryPath(external.model.category, external.model.subCategory);
552
553            // product selection handlers ------------------------------------------------
554            $('.product .select-wrap').on('click', function (e) {
555                e.stopPropagation();
556            });
557            $('.product .select-wrap-spinner button.minus').on('click', function (e) {
558                var parent = $(this).parent();
559                internal.selectButtonClick(parent, -1);
560                internal.cartShowHide(parent.data("id"), parent.data("category"), parent.data("subcategory"), -1);
561            });
562            $('.product .select-wrap-spinner button.plus').on('click', function (e) {
563                var parent = $(this).parent();
564                internal.selectButtonClick(parent, 1);
565                internal.cartShowHide(parent.data("id"), parent.data("category"), parent.data("subcategory"), 1);
566            });
567            $('.product .select-wrap-button button').on('click', function (e) {
568
569                if ($(this).hasClass("prequalifyproduct")) {
570                    return; //If the prequalify button was clicked, do nothing.
571                }
572
573                var parent = $(this).parent();
574                var val = 1;
575                if (parent.data('selected') === 1) {
576                    val = -1;
577                }
578
579                internal.isAccountProductsReachMaximum(parent.data("id"));
580                if (!internal.isAccountProductsReachMaxiumResult) {
581                    internal.selectButtonClick(parent, val);
582                    internal.cartShowHide(parent.data("id"), parent.data("category"), parent.data("subcategory"), val);
583                }
584                else {
585                    Aksw.Dialog.show({
586                        title: 'Add Account Products:',
587                        text: "This Account Product has reached the maximum number allowed for the application.",
588                        type: 'info',
589                        buttons: ['OK']
590                    });
591                }
592            });
593
594            // ----------------------------------------------------------------
595
596            // general X button for mobile
597            $('.product-selection .close').on('click', function () {
598                $(this).parent().slideUp();
599            });
600
601            
602            $('.cart').on('click', '.remove', function () {
603                // remove it from the model
604                var id = $(this).parent().data('id');
605                var category = $(this).parent().data('category');
606
607                internal.removeProduct(id);
608                // special UI handling for button
609                var select = $('.product .select-wrap div[data-id=' + id + ']');
610                var count = parseInt(select.data('selected'));
611                count -= 1;
612                internal.removeGroupElement(id, category);
613                internal.selectButtonRefresh(id, count);
614            });
615
616            // collapse handling               
617            $('.product .heading').on('click', function (e) {
618                //debugger;
619                var collapse = false;
620
621                if (external.model.collapseOnLarge && !internal.isSmallDevice()) {
622                    collapse = true;
623                }
624                if (external.model.collapseOnSmall && internal.isSmallDevice()) {
625                    collapse = true;
626                }
627                if (collapse) {
628                    var $this = $(this);
629                    var body = $this.parents('.panel').find('.panel-body');
630                    var isHidden = !body.is(':visible');
631                    if (isHidden) {
632                        body.slideDown();
633                        $this.find('i.down').hide();
634                        $this.find('i.up').show();
635                    } else {
636                        body.slideUp();
637                        $this.find('i.down').show();
638                        $this.find('i.up').hide();
639                    }
640                }
641
642            })
643
644            $('.category-tabs').on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
645                var category = $(this).data('category');
646                var subCategory = '';
647                // since we are switching categories, we need to activate a subcategory
648                // the last subcategory used is stored off.  if it is empty, grab the first one
649                var subCategoryTabs = $('.subcategory-tabs[data-category="' + category + '"]');
650                if (subCategoryTabs.data('lastsubcategory')) {
651                    subCategory = subCategoryTabs.data('lastsubcategory');
652                } else {
653                    subCategory = subCategoryTabs.find('> li:first-child > a').data('subcategory');
654                    // store this off
655                    subCategoryTabs.data('lastsubcategory', subCategory);
656                }
657
658                // update model
659                external.model.category = category;
660                external.model.subCategory = subCategory;
661                internal.setActiveClass(category, subCategory);
662
663                // normalize
664                external.syncCardHeight();
665            })
666
667            // Mobile Header handling --------------------------------------------------------------------------------------
668            $('.header-mobile .category').on('click', function () {
669                var categories = $('.header-mobile .categories');
670                var icon = $('.header-mobile .category-icon');
671                if (categories.is(':visible')) {
672                    categories.slideUp();
673                } else {
674                    categories.slideDown();
675                }
676                icon.toggleClass('glyphicon-chevron-down').toggleClass('glyphicon-chevron-up');
677            });
678
679            $('.header-mobile .categories a').on('click', function (e) {
680                e.preventDefault();
681                var a = $(this);
682                var categories = $('.header-mobile .categories');
683                var icon = $('.header-mobile .category-icon');
684                var category = a.data('category');
685                var subCategory = a.data('subcategory');
686                categories.slideUp();
687                icon.toggleClass('glyphicon-chevron-down').toggleClass('glyphicon-chevron-up');
688                // update model
689                external.model.category = category;
690                external.model.subCategory = subCategory;
691                internal.setActiveClass(category, subCategory);
692
693                // normalize
694                external.syncCardHeight();
695            });
696
697            $('.product-selection .header-mobile .cart-mobile').on('click', function () {
698                var products = $('.product-selection .header-mobile .cart');
699                if (products.is(':visible')) {
700                    products.slideUp();
701                } else {
702                    products.slideDown();
703                }
704            });
705            // -------------------------------------------------------------------------------------------------------------
706
707
708            // handle sub category tab select
709            $('.subcategory-tabs').on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
710                var $this = $(this);
711                var category = $this.data('category');
712                var subCategory = $this.data('subcategory');
713                // store off last subcategory for this category on the ul element
714                $this.parent().parent().data('lastsubcategory', subCategory)
715                external.model.category = category;
716                external.model.subCategory = subCategory;
717                internal.setActiveClass(category, subCategory);
718                external.syncCardHeight();
719            })
720
721            $('.product-selection .apply-now').on('click', function () {
722                external.applyNow();
723            });
724
725            $('.product-selection .prequalify').on('click', function () {
726                external.prequalify();
727            });
728
729            // initialize the visible tab
730            // When this file gets cached card heights were incorrect.
731            // We need to wait until all images and such are fully rendered before the
732            // initial card height sync.  
733            $(window).on("load", function () {
734                external.syncCardHeight();
735            });
736
737            // handle the account products select button text if useShoppingCart to false and we are in a application
738            $('.select').each(function (elm) {
739
740                var el = $(this)
741                if (!external.model.useShoppingCart && Aksw.AddProducts !== undefined)
742                    el.html(external.model.addProductsNoCartSelectText)
743
744            });
745
746
747            // initialize select button states...i don't like the following lines.
748            // this is not needed if we only have loans as everything is "Apply Now"
749            if (external.model.hasAccountProducts) {
750                var products = external.model.products;
751                for (var i = 0; i < products.length; i++) {
752                    var p = products[i];
753                    // now count these products
754                    var count = 0;
755                    for (var j = 0; j < products.length; j++) {
756                        if (products[j].id === p.id)
757                            count++;
758                    }
759                    //now refresh the buttons for this product
760                    if (!external.model.useShoppingCart && Aksw.AddProduct !== undefined) {
761                        count = 0;
762                    }
763                    internal.selectButtonRefresh(p.id, count);
764                }
765            }
766
767            // add window resize handlers
768            $(window).on('resize', function () {
769
770                // set width
771                internal.setDeviceWidth();
772
773                // reset all card heights
774                $('.products-wrap').data('heightsynced', false);
775                $('.product .body').css('height', 'auto');
776
777                // show all cards if we are large device and multiple cards...collapse is not allowed
778                if (external.model.cardCountOnLarge > 1 && !internal.isSmallDevice()) {
779                    $('.product .body').removeClass('collapse-on-default').show();
780                    $('.product .heading .up').show();
781                    $('.product .heading .down').hide();
782                }
783
784                // sync visible tab
785                external.syncCardHeight();
786            })
787
788            internal.toggleApplyNow();
789        });
790
791
792    }();
793
794    return external;
795}();
796
797

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.