/** * Magento * * NOTICE OF LICENSE * * This source file is subject to the Academic Free License (AFL 3.0) * that is bundled with this package in the file LICENSE_AFL.txt. * It is also available through the world-wide-web at this URL: * http://opensource.org/licenses/afl-3.0.php * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@magentocommerce.com so we can send you a copy immediately. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade Magento to newer * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * * @category design * @package base_default * @copyright Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ var Checkout = Class.create(); Checkout.prototype = { initialize: function(accordion, urls){ this.accordion = accordion; this.progressUrl = urls.progress; this.reviewUrl = urls.review; this.saveMethodUrl = urls.saveMethod; this.failureUrl = urls.failure; this.billingForm = false; this.shippingForm= false; this.syncBillingShipping = false; this.method = ''; this.payment = ''; this.loadWaiting = false; this.steps = ['login', 'billing', 'shipping', 'shipping_method', 'payment', 'review']; //We use billing as beginning step since progress bar tracks from billing this.currentStep = 'billing'; this.accordion.sections.each(function(section) { Event.observe($(section).down('.step-title'), 'click', this._onSectionClick.bindAsEventListener(this)); }.bind(this)); this.accordion.disallowAccessToNextSections = true; }, /** * Section header click handler * * @param event */ _onSectionClick: function(event) { var section = $(Event.element(event).up().up()); if (section.hasClassName('allow')) { Event.stop(event); this.gotoSection(section.readAttribute('id').replace('opc-', ''), false); return false; } }, ajaxFailure: function(){ location.href = this.failureUrl; }, reloadProgressBlock: function(toStep) { this.reloadStep(toStep); if (this.syncBillingShipping) { this.syncBillingShipping = false; this.reloadStep('shipping'); } }, reloadStep: function(prevStep) { var updater = new Ajax.Updater(prevStep + '-progress-opcheckout', this.progressUrl, { method:'get', onFailure:this.ajaxFailure.bind(this), onComplete: function(){ this.checkout.resetPreviousSteps(); }, parameters:prevStep ? { prevStep:prevStep } : null }); }, reloadReviewBlock: function(){ var updater = new Ajax.Updater('checkout-review-load', this.reviewUrl, {method: 'get', onFailure: this.ajaxFailure.bind(this)}); }, _disableEnableAll: function(element, isDisabled) { var descendants = element.descendants(); for (var k in descendants) { descendants[k].disabled = isDisabled; } element.disabled = isDisabled; }, setLoadWaiting: function(step, keepDisabled) { if (step) { if (this.loadWaiting) { this.setLoadWaiting(false); } var container = $(step+'-buttons-container'); container.addClassName('disabled'); container.setStyle({opacity:.5}); this._disableEnableAll(container, true); Element.show(step+'-please-wait'); } else { if (this.loadWaiting) { var container = $(this.loadWaiting+'-buttons-container'); var isDisabled = (keepDisabled ? true : false); if (!isDisabled) { container.removeClassName('disabled'); container.setStyle({opacity:1}); } this._disableEnableAll(container, isDisabled); Element.hide(this.loadWaiting+'-please-wait'); } } this.loadWaiting = step; }, gotoSection: function (section, reloadProgressBlock) { if (reloadProgressBlock) { this.reloadProgressBlock(this.currentStep); } this.currentStep = section; var sectionElement = $('opc-' + section); sectionElement.addClassName('allow'); this.accordion.openSection('opc-' + section); if(!reloadProgressBlock) { this.resetPreviousSteps(); } }, resetPreviousSteps: function () { var stepIndex = this.steps.indexOf(this.currentStep); //Clear other steps if already populated through javascript for (var i = stepIndex; i < this.steps.length; i++) { var nextStep = this.steps[i]; var progressDiv = nextStep + '-progress-opcheckout'; if ($(progressDiv)) { //Remove the link $(progressDiv).select('.changelink').each(function (item) { item.remove(); }); $(progressDiv).select('dt').each(function (item) { item.removeClassName('complete'); }); //Remove the content $(progressDiv).select('dd.complete').each(function (item) { item.remove(); }); } } }, changeSection: function (section) { var changeStep = section.replace('opc-', ''); this.gotoSection(changeStep, false); }, setMethod: function(){ if ($('login:guest') && $('login:guest').checked) { this.method = 'guest'; var request = new Ajax.Request( this.saveMethodUrl, {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'guest'}} ); Element.hide('register-customer-password'); this.gotoSection('billing', true); } else if($('login:register') && ($('login:register').checked || $('login:register').type == 'hidden')) { this.method = 'register'; var request = new Ajax.Request( this.saveMethodUrl, {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'register'}} ); Element.show('register-customer-password'); this.gotoSection('billing', true); } else{ alert(Translator.translate('Please choose to register or to checkout as a guest').stripTags()); return false; } document.body.fire('login:setMethod', {method : this.method}); }, setBilling: function() { if (($('billing:use_for_shipping_yes')) && ($('billing:use_for_shipping_yes').checked)) { shipping.syncWithBilling(); $('opc-shipping').addClassName('allow'); this.gotoSection('shipping_method', true); } else if (($('billing:use_for_shipping_no')) && ($('billing:use_for_shipping_no').checked)) { $('shipping:same_as_billing').checked = false; this.gotoSection('shipping', true); } else { $('shipping:same_as_billing').checked = true; this.gotoSection('shipping', true); } // this refreshes the checkout progress column // if ($('billing:use_for_shipping') && $('billing:use_for_shipping').checked){ // shipping.syncWithBilling(); // //this.setShipping(); // //shipping.save(); // $('opc-shipping').addClassName('allow'); // this.gotoSection('shipping_method'); // } else { // $('shipping:same_as_billing').checked = false; // this.gotoSection('shipping'); // } // this.reloadProgressBlock(); // //this.accordion.openNextSection(true); }, setShipping: function() { //this.nextStep(); this.gotoSection('shipping_method', true); //this.accordion.openNextSection(true); }, setShippingMethod: function() { //this.nextStep(); this.gotoSection('payment', true); //this.accordion.openNextSection(true); }, setPayment: function() { //this.nextStep(); this.gotoSection('review', true); //this.accordion.openNextSection(true); }, setReview: function() { this.reloadProgressBlock(); //this.nextStep(); //this.accordion.openNextSection(true); }, back: function(){ if (this.loadWaiting) return; //Navigate back to the previous available step var stepIndex = this.steps.indexOf(this.currentStep); var section = this.steps[--stepIndex]; var sectionElement = $('opc-' + section); //Traverse back to find the available section. Ex Virtual product does not have shipping section while (sectionElement === null && stepIndex > 0) { --stepIndex; section = this.steps[stepIndex]; sectionElement = $('opc-' + section); } this.changeSection('opc-' + section); }, setStepResponse: function(response){ if (response.update_section) { $('checkout-'+response.update_section.name+'-load').update(response.update_section.html); } if (response.allow_sections) { response.allow_sections.each(function(e){ $('opc-'+e).addClassName('allow'); }); } if(response.duplicateBillingInfo) { this.syncBillingShipping = true; shipping.setSameAsBilling(true); } if (response.goto_section) { this.gotoSection(response.goto_section, true); return true; } if (response.redirect) { location.href = response.redirect; return true; } return false; } } // billing var Billing = Class.create(); Billing.prototype = { initialize: function(form, addressUrl, saveUrl){ this.form = form; if ($(this.form)) { $(this.form).observe('submit', function(event){this.save();Event.stop(event);}.bind(this)); } this.addressUrl = addressUrl; this.saveUrl = saveUrl; this.onAddressLoad = this.fillForm.bindAsEventListener(this); this.onSave = this.nextStep.bindAsEventListener(this); this.onComplete = this.resetLoadWaiting.bindAsEventListener(this); }, setAddress: function(addressId){ if (addressId) { request = new Ajax.Request( this.addressUrl+addressId, {method:'get', onSuccess: this.onAddressLoad, onFailure: checkout.ajaxFailure.bind(checkout)} ); } else { this.fillForm(false); } }, newAddress: function(isNew){ if (isNew) { this.resetSelectedAddress(); Element.show('billing-new-address-form'); } else { Element.hide('billing-new-address-form'); } }, resetSelectedAddress: function(){ var selectElement = $('billing-address-select') if (selectElement) { selectElement.value=''; } }, fillForm: function(transport){ var elementValues = {}; if (transport && transport.responseText){ try{ elementValues = eval('(' + transport.responseText + ')'); } catch (e) { elementValues = {}; } } else{ this.resetSelectedAddress(); } arrElements = Form.getElements(this.form); for (var elemIndex in arrElements) { if (arrElements[elemIndex].id) { var fieldName = arrElements[elemIndex].id.replace(/^billing:/, ''); arrElements[elemIndex].value = elementValues[fieldName] ? elementValues[fieldName] : ''; if (fieldName == 'country_id' && billingForm){ billingForm.elementChildLoad(arrElements[elemIndex]); } } } }, setUseForShipping: function(flag) { $('shipping:same_as_billing').checked = flag; }, save: function(){ if (checkout.loadWaiting!=false) return; var validator = new Validation(this.form); if (validator.validate()) { checkout.setLoadWaiting('billing'); // if ($('billing:use_for_shipping') && $('billing:use_for_shipping').checked) { // $('billing:use_for_shipping').value=1; // } var request = new Ajax.Request( this.saveUrl, { method: 'post', onComplete: this.onComplete, onSuccess: this.onSave, onFailure: checkout.ajaxFailure.bind(checkout), parameters: Form.serialize(this.form) } ); } }, resetLoadWaiting: function(transport){ checkout.setLoadWaiting(false); document.body.fire('billing-request:completed', {transport: transport}); }, /** This method recieves the AJAX response on success. There are 3 options: error, redirect or html with shipping options. */ nextStep: function(transport){ if (transport && transport.responseText){ try{ response = eval('(' + transport.responseText + ')'); } catch (e) { response = {}; } } if (response.error){ if ((typeof response.message) == 'string') { alert(response.message); } else { if (window.billingRegionUpdater) { billingRegionUpdater.update(); } alert(response.message.join("\n")); } return false; } checkout.setStepResponse(response); payment.initWhatIsCvvListeners(); // DELETE //alert('error: ' + response.error + ' / redirect: ' + response.redirect + ' / shipping_methods_html: ' + response.shipping_methods_html); // This moves the accordion panels of one page checkout and updates the checkout progress //checkout.setBilling(); } } // shipping var Shipping = Class.create(); Shipping.prototype = { initialize: function(form, addressUrl, saveUrl, methodsUrl){ this.form = form; if ($(this.form)) { $(this.form).observe('submit', function(event){this.save();Event.stop(event);}.bind(this)); } this.addressUrl = addressUrl; this.saveUrl = saveUrl; this.methodsUrl = methodsUrl; this.onAddressLoad = this.fillForm.bindAsEventListener(this); this.onSave = this.nextStep.bindAsEventListener(this); this.onComplete = this.resetLoadWaiting.bindAsEventListener(this); }, setAddress: function(addressId){ if (addressId) { request = new Ajax.Request( this.addressUrl+addressId, {method:'get', onSuccess: this.onAddressLoad, onFailure: checkout.ajaxFailure.bind(checkout)} ); } else { this.fillForm(false); } }, newAddress: function(isNew){ if (isNew) { this.resetSelectedAddress(); Element.show('shipping-new-address-form'); } else { Element.hide('shipping-new-address-form'); } shipping.setSameAsBilling(false); }, resetSelectedAddress: function(){ var selectElement = $('shipping-address-select') if (selectElement) { selectElement.value=''; } }, fillForm: function(transport){ var elementValues = {}; if (transport && transport.responseText){ try{ elementValues = eval('(' + transport.responseText + ')'); } catch (e) { elementValues = {}; } } else{ this.resetSelectedAddress(); } arrElements = Form.getElements(this.form); for (var elemIndex in arrElements) { if (arrElements[elemIndex].id) { var fieldName = arrElements[elemIndex].id.replace(/^shipping:/, ''); arrElements[elemIndex].value = elementValues[fieldName] ? elementValues[fieldName] : ''; if (fieldName == 'country_id' && shippingForm){ shippingForm.elementChildLoad(arrElements[elemIndex]); } } } }, setSameAsBilling: function(flag) { $('shipping:same_as_billing').checked = flag; // #5599. Also it hangs up, if the flag is not false // $('billing:use_for_shipping_yes').checked = flag; if (flag) { this.syncWithBilling(); } }, syncWithBilling: function () { $('billing-address-select') && this.newAddress(!$('billing-address-select').value); $('shipping:same_as_billing').checked = true; if (!$('billing-address-select') || !$('billing-address-select').value) { arrElements = Form.getElements(this.form); for (var elemIndex in arrElements) { if (arrElements[elemIndex].id) { var sourceField = $(arrElements[elemIndex].id.replace(/^shipping:/, 'billing:')); if (sourceField){ arrElements[elemIndex].value = sourceField.value; } } } //$('shipping:country_id').value = $('billing:country_id').value; shippingRegionUpdater.update(); $('shipping:region_id').value = $('billing:region_id').value; $('shipping:region').value = $('billing:region').value; //shippingForm.elementChildLoad($('shipping:country_id'), this.setRegionValue.bind(this)); } else { $('shipping-address-select').value = $('billing-address-select').value; } }, setRegionValue: function(){ $('shipping:region').value = $('billing:region').value; }, save: function(){ if (checkout.loadWaiting!=false) return; var validator = new Validation(this.form); if (validator.validate()) { checkout.setLoadWaiting('shipping'); var request = new Ajax.Request( this.saveUrl, { method:'post', onComplete: this.onComplete, onSuccess: this.onSave, onFailure: checkout.ajaxFailure.bind(checkout), parameters: Form.serialize(this.form) } ); } }, resetLoadWaiting: function(transport){ checkout.setLoadWaiting(false); }, nextStep: function(transport){ if (transport && transport.responseText){ try{ response = eval('(' + transport.responseText + ')'); } catch (e) { response = {}; } } if (response.error){ if ((typeof response.message) == 'string') { alert(response.message); } else { if (window.shippingRegionUpdater) { shippingRegionUpdater.update(); } alert(response.message.join("\n")); } return false; } checkout.setStepResponse(response); /* var updater = new Ajax.Updater( 'checkout-shipping-method-load', this.methodsUrl, {method:'get', onSuccess: checkout.setShipping.bind(checkout)} ); */ //checkout.setShipping(); } } // shipping method var ShippingMethod = Class.create(); ShippingMethod.prototype = { initialize: function(form, saveUrl){ this.form = form; if ($(this.form)) { $(this.form).observe('submit', function(event){this.save();Event.stop(event);}.bind(this)); } this.saveUrl = saveUrl; this.validator = new Validation(this.form); this.onSave = this.nextStep.bindAsEventListener(this); this.onComplete = this.resetLoadWaiting.bindAsEventListener(this); }, validate: function() { var methods = document.getElementsByName('shipping_method'); if (methods.length==0) { alert(Translator.translate('Your order cannot be completed at this time as there is no shipping methods available for it. Please make necessary changes in your shipping address.').stripTags()); return false; } if(!this.validator.validate()) { return false; } for (var i=0; i