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