PageSourceSearch

https://helpthehelpless.org/Contributions/js/frontend/CartSummary.js?1789539201

js helpthehelpless.org collected 2026-10-04 20:23:39 UTC 25,134 bytes, 673 lines download raw bytes

1/**
2 * @author Softped Development Team <[email protected]>
3 */
4jQuery.namespace('SS.com.Contributions.frontend');
5SS.com.Contributions.frontend.CartSummary = {
6    
7    cartSummaryContainer: null,
8    shoppingCartModule: null,
9    shoppingCartSummaryContainer: null,
10    transferFeeWrapper: null,
11    currentPopUp: null,
12    
13    init: function(){
14        this.ajaxInProgress = 0;
15        this.cartSummaryContainer = $('#cart-summary-container');
16        this.shoppingCartModule = $('.contributions-modules-shopping-cart');
17        this.shoppingCartSummaryContainer = $('.contributions-modules-shopping-cart .cart-summary');
18        this.transferFeeWrapper = $('.contributions .contributions-transfer-fee-form');
19        this.fixedAmountsEvents();
20        this.showPopupOnPageLoad();
21    },
22
23    showPopupOnPageLoad: function () {
24        var secondsToShow = parseInt(this.shoppingCartModule.data('seconds-to-show'));
25
26        if(secondsToShow && secondsToShow > 0) {
27            this.shoppingCartModule.addClass('popup-opened').delay(secondsToShow * 1000).queue(function(next){
28                $(this).removeClass("popup-opened");
29                next();
30            });
31        }
32    },
33
34    fixedAmountsEvents: function () {
35        $('#custom-amount-other').on('click', function (event) {
36            $('#custom-amount-other-input').focus();
37            event.stopPropagation();
38            event.preventDefault();
39            return false;
40        });
41        $('#custom-amount-other-input').on('keyup', function (keyEvent) {
42            if(keyEvent.keyCode == 13){
43                $(this).trigger('blur');
44            }
45        });
46    },
47
48    update: function( checked )
49    {
50        var me = this;
51        this.showLoading();
52        $.ajax({
53            url: SS.route('Contributions','Contributions','addTransferFeeToCart',null,'json'),
54            cache: false,
55            type: 'POST',
56            data: {checked:checked},
57            success: function(responseData, status, xhr){
58                me.updateContent();
59            },
60            failure: function(){
61                var alertConfig = {
62                    title: 'Contributions Error',
63                    msg: 'Something went wrong. Try again.',
64                    closeButton: false,
65                    buttons: {
66                        ok: {
67                            btnText: 'OK',
68                            btnCls: false,
69                            overCls: false
70                        },
71                        cancel: false
72                    }
73                };
74                new SS.customAlert(alertConfig);
75            },
76            complete: function(){ 
77                me.hideLoading() 
78            }
79        });
80    },
81
82    addRecurringToCart: function(recurring, type)
83    {
84        if (!type) {
85            type = null;
86        }
87
88        var me = this;
89        this.showLoading();
90
91        var recurringFlag = null;
92
93        if (recurring === true) {
94            recurringFlag = 1;
95        }
96
97        if (recurring === false) {
98            recurringFlag = 0;
99        }
100
101        var data = {
102            recurring_type: type
103        }
104
105        if (recurringFlag !== null) {
106            data.recurring = recurringFlag;
107        }
108
109        $.ajax({
110            url: SS.route('Contributions','Contributions','addRecurringToCart',null,'json'),
111            cache: false,
112            type: 'POST',
113            data: data,
114            success: function(responseData, status, xhr){
115                me.updateContent();
116            },
117            failure: function(){
118                var alertConfig = {
119                    title: 'Contributions Error',
120                    msg: 'Something went wrong. Try again.',
121                    closeButton: false,
122                    buttons: {
123                        ok: {
124                            btnText: 'OK',
125                            btnCls: false,
126                            overCls: false
127                        },
128                        cancel: false
129                    }
130                };
131                new SS.customAlert(alertConfig);
132            },
133            complete: function(){ 
134                me.hideLoading() 
135            }
136        });
137    },
138
139    updateContent: function()
140    {
141        var me = this;
142        this.showLoading();
143        if( me.cartSummaryContainer.is(':visible') ){
144            $.ajax({
145                url: SS.route('Contributions','Contributions','cartSummary',null,null),
146                cache: false,
147                type: 'POST',
148                success: function(responseData, status, xhr){
149                    var fadeOutSpeed = me.cartSummaryContainer.find('*').css('visibility')=='hidden' ? 0 : 200;
150
151                    me.cartSummaryContainer.fadeOut(fadeOutSpeed,function(){
152                        $(this).html(responseData);
153                        $(this).find('input[type=radio]').each(function(index, element) {
154                            if(element.checked) {
155                                me.cartSummaryContainer.find('input[name="' + $(this).attr('name') + '"]').parent().removeClass('checked');
156                                $(this).parent().addClass('checked');
157                            }
158                        });
159                        $(this).fadeIn(200, function() {
160                            // Re-attach events
161                            me.fixedAmountsEvents();
162                        });
163                    });
164                },
165                failure: function(){},
166                complete: function(){ 
167                    me.hideLoading() 
168                }
169            });
170        }
171        if( me.shoppingCartSummaryContainer.length ){
172            $.ajax({
173                url: SS.route('Contributions','Contributions','shoppingCartSummary',null,null),
174                cache: false,
175                type: 'POST',
176                success: function(responseData, status, xhr){
177	                me.shoppingCartSummaryContainer.each(function(index, shoppingCartInstance){
178	                	var $shoppingCartInstance = $(shoppingCartInstance);
179
180		                $shoppingCartInstance.fadeOut(200,function(){
181			                $(this).html(responseData);
182			                if(!$(this).find('table').length){
183				                $(this).closest('.contributions-modules-shopping-cart').find('.cart-counter').html('0');
184			                }
185			                $(this).fadeIn(200);
186		                });
187	                });
188                },
189                failure: function(){},
190                complete: function(){ me.hideLoading() }
191            });
192        }
193    },
194
195    extraData: function(index, campaignId, userCampaignId, value )
196    {
197        this.addToCart({
198            index:index,
199            campaign_id:campaignId,
200            user_campaign_id:userCampaignId,
201            extra_data:value
202        });
203    },
204
205    anonymous: function(index, campaignId, userCampaignId, check )
206    {
207        this.addToCart({
208            index:index,
209            campaign_id:campaignId,
210            user_campaign_id:userCampaignId,
211            is_anonymous:check
212        });
213    },
214    fixAmount: function (value) {
215        if (typeof value === 'string' || value instanceof String) {
216            value = value.replace(',', '');
217            return parseFloat(value);
218        }
219
220        return value;
221
222    },
223    getSetAmounts: function (index, campaignId, userCampaignId, currentAmount, minAmount, maxAmount) {
224        var me = this;
225        $.ajax({
226            url: SS.route('Contributions', 'Contributions', 'getAvailableSetAmountsBasedOnCurrentCart', null, 'json'),
227            cache: false,
228            data: {
229                campaign_id: campaignId,
230                index: index
231            },
232            type: 'POST',
233            success: function (responseData, status, xhr) {
234
235                var amounts = [];
236
237                responseData.setAmounts.forEach(function (amount) {
238                    var amountValue = amount.amount;
239
240                    var checked = me.fixAmount(amountValue) == me.fixAmount(currentAmount) ? 'checked' : '';
241                    var skip = false;
242                    var cssClass = me.fixAmount(amountValue) == me.fixAmount(currentAmount) ? ' class="checked"' : '';
243
244                    if (minAmount > 0 && me.fixAmount(amountValue) < minAmount) {
245                        skip = true;
246                    }
247
248                    if (maxAmount > 0 && me.fixAmount(amountValue) > maxAmount) {
249                        skip = true;
250                    }
251
252                    if (!skip) {
253                        amounts.push(
254                            '<label' + cssClass + '><input type="radio" name="newSetAmount" value="' + amountValue + '" ' + checked + ' />$' + $.number(amountValue, 2) + '</label>'
255                        )
256                    }
257                })
258                amounts = amounts.join('');
259
260                if (!amounts) {
261                    amounts = '<div>No options available</div>';
262                }
263
264                var alertConfig = {
265                    title: 'Amount',
266                    msg:
267                        '<div class="amounts-title">Change the amount</div>' +
268                        '<div class="amount-options">' +
269                        amounts +
270                        '</div>',
271                    closeButton: true,
272                    targetLocation: me.cartSummaryContainer.find('.bottom-data .buttons .modify'),
273                    cls: 'modify-set-amounts-window',
274                    buttons: {
275                        ok: {
276                            btnText: 'OK',
277                            btnCls: false,
278                            overCls: false,
279                            closePopUp: false
280                        },
281                        cancel: {
282                            btnText: 'Cancel',
283                            btnCls: false,
284                            overCls: false,
285                            closePopUp: true
286                        }
287                    },
288                    callback: function (clickedButton) {
289                        var newAmount = $('.customAlert input[name="newSetAmount"]:checked').val();
290
291                        if (clickedButton == 'ok') {
292                            if (!newAmount) {
293                                $('.customAlert').find('.customAlertError').slideUp(100, function () {
294                                    $(this).html('You must select an amount to donate!');
295                                    $(this).slideDown(100);
296                                });
297                            } else {
298                                me.currentPopUp.destroyAlert();
299                                me.addToCart({
300                                    index: index,
301                                    campaign_id: campaignId,
302                                    campaign_variation_id: null,
303                                    user_campaign_id: userCampaignId,
304                                    amount: newAmount
305                                });
306                            }
307
308                        }
309                    }
310                };
311                me.currentPopUp = new SS.customAlert(alertConfig);
312
313                $('.customAlert:last').on('aftershow',function(){
314                    var customAlert = $(this);
315
316                    // Listener to add or remove "checked" class on all radios in the form
317                    $(this).find('input[type=radio]').on('change', function () {
318                        if (this.checked) {
319                            customAlert.find('.amount-options label').removeClass('checked');
320                            $(this).parent().addClass('checked');
321                        }
322                    });
323                });
324            },
325            failure: function () {
326            },
327            complete: function () {
328                me.hideLoading()
329            }
330        });
331    },
332
333    amount: function(index, campaignId, userCampaignId, currentAmount, minAmount, maxAmount, quantity, campaignVariationId)
334    {
335        var me = this;
336        minAmount = parseFloat(minAmount);
337        maxAmount = parseFloat(maxAmount);
338
339        var alertConfig = {
340            title: parseInt(quantity) ? 'Quantity' : 'Amount',
341            msg:
342                '<img class="required" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" width="8" height="7" /><span>Change the ' + (parseInt(quantity) ? 'quantity' : 'amount') + '</span><br/>' +
343                '<input type="text" name="new_amount" class="last-row" value="' + currentAmount + '" />',
344            closeButton: true,
345            targetLocation: this.cartSummaryContainer.find('.bottom-data .buttons .modify'),
346            buttons: {
347                ok: {
348                    btnText: 'OK',
349                    btnCls: false,
350                    overCls: false,
351                    closePopUp: false
352                },
353                cancel: {
354                    btnText: 'Cancel',
355                    btnCls: false,
356                    overCls: false,
357                    closePopUp: true
358                }
359            },
360            callback: function( clickedButton ){
361                var newAmount = $('.customAlert input[name="new_amount"]').val();
362                var newFormattedAmount = newAmount.replace(/[^0-9\.]/g,'');
363                if ( clickedButton == 'ok' ){
364                    if( parseFloat(newFormattedAmount) > 0 ){
365
366                        if (!parseInt(quantity) && minAmount>0 && parseFloat(newFormattedAmount) < minAmount) {
367                            $('.customAlert').find('.customAlertError').slideUp(100,function(){
368                                $(this).html('The minimum valid amount is $'+ $.number(minAmount, 2));
369                                $(this).slideDown(100);
370                            });
371                        } else if (!parseInt(quantity) && maxAmount>0 && parseFloat(newFormattedAmount) > maxAmount) {
372                            $('.customAlert').find('.customAlertError').slideUp(100,function(){
373                                $(this).html('The maximum valid amount is $'+ $.number(maxAmount, 2));
374                                $(this).slideDown(100);
375                            });
376                        } else {
377                            me.currentPopUp.destroyAlert();
378                            me.addToCart({
379                                index:index,
380                                campaign_id: campaignId,
381                                campaign_variation_id: campaignVariationId ? campaignVariationId : null,
382                                user_campaign_id: userCampaignId,
383                                amount: newFormattedAmount
384                            });
385                        }
386
387
388                    }else{
389                        $('.customAlert').find('.customAlertError').slideUp(100,function(){
390                            $(this).html('You entered an invalid amount. Use only numbers.');
391                            $(this).slideDown(100);
392                        });
393                    }
394                }
395            }
396        };
397        me.currentPopUp = new SS.customAlert( alertConfig );
398    },
399
400    fixedAmount: function (campaignId, userCampaignId, newAmount, minAmount, maxAmount) {
401        var me = this;
402
403        var newFormattedAmount = parseFloat(newAmount.replace(/[^0-9\.]/g, ''));
404        minAmount = parseFloat(minAmount);
405        maxAmount = parseFloat(maxAmount);
406
407        if (!newFormattedAmount || newFormattedAmount <= 0) {
408            return;
409        }
410
411        if (minAmount > 0 && newFormattedAmount < minAmount) {
412            this.showFixedAmountError('The minimum valid amount is $' + $.number(minAmount, 2));
413            return;
414        }
415
416        if (maxAmount > 0 && newFormattedAmount > maxAmount) {
417            this.showFixedAmountError('The maximum valid amount is $' + $.number(maxAmount, 2));
418            return;
419        }
420
421        me.addToCart({
422            campaign_id: campaignId,
423            user_campaign_id: userCampaignId,
424            amount: newFormattedAmount
425        });
426    },
427
428    showFixedAmountError: function (errorText) {
429        $('#custom-amount-other-input').val('').parent('.option').addClass('error');
430        $('#fixed-amount-error').clearQueue().hide().html(errorText).slideDown(100, function () {
431            $(this).delay(5000).slideUp(100);
432        });
433    },
434
435    cancel: function(index, campaignId, userCampaignId )
436    {
437        var me = this;
438        var alertConfig = {
439            title: 'Cancel Gift',
440            msg: 'Are you sure you want to cancel this gift?',
441            closeButton: true,
442            buttons: {
443                ok: {
444                    btnText: 'Yes',
445                    btnCls: false,
446                    overCls: false,
447                    closePopUp: true
448                },
449                cancel: {
450                    btnText: 'No',
451                    btnCls: false,
452                    overCls: false,
453                    closePopUp: true
454                }
455            },
456            callback: function( clickedButton ){
457                if ( clickedButton == 'ok' ){
458                    me.removeFromCart({
459                        index:index,
460                        campaign_id:campaignId,
461                        user_campaign_id:userCampaignId
462                    })
463                }
464            }
465        };
466        me.currentPopUp = new SS.customAlert( alertConfig );
467    },
468
469    notes: function(index, campaignId, userCampaignId, currentNote, noteLinkText )
470    {
471        var me = this;
472        
473        if(typeof noteLinkText == 'undefined' || noteLinkText == ''){
474            noteLinkText = 'Add instructions to the finance office';
475        }
476        
477        var maxLength = SS.com.Contributions.frontend.componentSettings.notes_max_length;
478        
479        var alertConfig = {
480            title: 'Message',
481            msg:
482                    '<img class="required" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" width="8" height="7" /><span>'+noteLinkText+'</span><br/>' +
483                    '<textarea name="message" class="last-row" rows="4" '+(maxLength?'maxlength="'+maxLength+'"':'')+'>' + currentNote + '</textarea>',
484            closeButton: true,
485            targetLocation: this.cartSummaryContainer.find('.bottom-data .notes a.instructions'),
486            buttons: {
487                ok: {
488                    btnText: 'OK',
489                    btnCls: false,
490                    overCls: false,
491                    closePopUp: false
492                },
493                cancel: {
494                    btnText: 'Cancel',
495                    btnCls: false,
496                    overCls: false,
497                    closePopUp: true
498                }
499            },
500            callback: function( clickedButton ){
501                var message = $('.customAlert textarea[name="message"]').val();
502                if ( clickedButton == 'ok' ){
503                    me.currentPopUp.destroyAlert();
504                    me.addToCart({
505                        index:index,
506                        campaign_id: campaignId,
507                        user_campaign_id: userCampaignId,
508                        notes: message
509                    });
510                }
511            }
512        };
513        me.currentPopUp = new SS.customAlert( alertConfig );
514    },
515
516    removeFromCart: function( params ) {
517        var me = this;
518        this.showLoading();
519        $.ajax({
520            url: SS.route('Contributions','Contributions','removeFromCart',null,'json'),
521            cache: false,
522            data: params,
523            type: 'POST',
524            success: function(responseData, status, xhr){
525                $(window).trigger('removeItemFromCart', [params]);
526                if (responseData.requireReload) {
527                    me.requireReload();
528                } else {
529                    var transferVisible = me.transferFeeWrapper.find('.inputs-wrapper').is(':visible');
530                    var transferChecked = parseInt(me.transferFeeWrapper.find('input[name="transfer_fee"]:checked').val());
531
532                    me.update((transferVisible && transferChecked) ? 1 : 0);
533                }
534            },
535            failure: function(){},
536            complete: function(){ 
537                me.hideLoading() 
538            }
539        });
540    },
541    
542    addToCart: function( params )
543    {
544        var me = this;
545        this.showLoading();
546        $.ajax({
547            url: SS.route('Contributions','Contributions','addToCart',null,'json'),
548            cache: false,
549            data: params,
550            type: 'POST',
551            success: function(responseData, status, xhr){
552                // Check for errors
553                if(responseData.data && responseData.data.errors) {
554                    var errors = [];
555                    $.each(responseData.data.errors, function(index, item) {
556                        errors.push(item);
557                    })
558                    if(errors.length) {
559                        new SS.customAlert({
560                            title: 'Error',
561                            msg: errors.join("<br>"),
562                            closeButton: true,
563                            buttons: {
564                                ok: {
565                                    btnText: 'OK',
566                                    btnCls: false,
567                                    overCls: false,
568                                    closePopUp: true
569                                }
570                            }
571                        })    
572                    }
573                } else {
574                    $(window).trigger('addItemToCart', [params]);
575                    var transferVisible = me.transferFeeWrapper.find('.inputs-wrapper').is(':visible');
576                    var transferChecked = parseInt(me.transferFeeWrapper.find('input[name="transfer_fee"]:checked').val());
577
578                    me.update((transferVisible && transferChecked) ? 1 : 0);      
579                }
580            },
581            error: function(jqXHR, textStatus, errorThrown ) {
582                if(jqXHR.responseJSON && jqXHR.responseJSON.message) {
583                    new SS.customAlert({
584                        title: 'Error',
585                        msg: jqXHR.responseJSON.message,
586                        closeButton: true,
587                        buttons: {
588                            ok: {
589                                btnText: 'OK',
590                                btnCls: false,
591                                overCls: false,
592                                closePopUp: true
593                            }
594                        }
595                    })
596                }
597            },
598            complete: function(){ 
599                me.hideLoading() 
600            }
601        });
602    },
603
604    validate: function()
605    {
606        var me = this;
607        var cartSummaryValidationErrors = {};
608        var requiredCartSummaryFields = this.cartSummaryContainer.find('.extra-data *[required="true"]');
609        $.each(requiredCartSummaryFields,function(index, field){
610            $(field).removeClass('has-error');
611            $(field).siblings('.form-input-error').remove();
612
613            if($(field).val().length < 1){
614                $(field).addClass('has-error');
615                var errorEl = $('<div />');
616                errorEl.addClass('form-input-error').html('This field is required');
617                $(field).parent('.extra-data').append(errorEl);
618                cartSummaryValidationErrors[$(field).attr('name')] = 'This field is required';
619            }
620        });
621        return cartSummaryValidationErrors;
622    },
623
624    clearValidationErrors: function(errorObject) {
625        for (var i in errorObject) {
626            if (i.indexOf('extra-data')===0) {
627                delete errorObject[i];
628            }
629        }
630    },
631
632    showLoading: function() {
633        this.ajaxInProgress++;
634        this.cartSummaryContainer.addClass('loading');
635    },
636
637    hideLoading: function() {
638        this.ajaxInProgress--;
639        if(!this.ajaxInProgress)
640            this.cartSummaryContainer.removeClass('loading');
641    },
642    toggleRecurring: function (index) {
643        var me = this;
644        this.showLoading();
645
646        $.ajax({
647            url: SS.route('Contributions', 'Contributions', 'toggleRecurring', null, 'json'),
648            cache: false,
649            data: {
650                index: index
651            },
652            type: 'POST',
653            success: function (responseData, status, xhr) {
654                $(window).trigger('setRecurring', [responseData.recurring]);
655                me.updateContent();
656            },
657            failure: function () {
658            },
659            complete: function () {
660                me.hideLoading()
661            }
662        });
663    },
664    requireReload: function () {
665        $(window).trigger('requireReload');
666        window.location.reload();
667    }
668    
669};
670
671$(document).ready(function() {
672    SS.com.Contributions.frontend.CartSummary.init();
673});

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.