Magento Onepage Checkout – Add New Step

Banners
In this blog post, we are going to see how to add a new step to magento onepage checkout.

We will see 3 different scenario’s i.e adding a new step which is the first step, adding a new step in middle, adding a dynamic step. This blog is a continuation of previous blog written to add custom fields to magento checkout. This blog is pretty long and complex so i am attaching the source files here.
Module Name: Checkout Add Step Module Source

Adding New Step at First Position

So here we are going to add a new step just after login step or if user is already logged ours will be the first step. The title of step added is “Excellence Blog Review” and id of step would be “excellence”, the step will have a single drop down field. The code for saving this field to database is not explained in this blog, as it was already covered in the previous blog.

Checkout Page With New Step Added

Checkout Page With New Step Added


Now lets see the steps to make this happen Here the module name i am using is Excellence_Custom
Step1: Creating the HTML
The simplest step as always, first we will create our phtml file excellence.phtml at location custom\checkout\onepage\excellence.phtml. This file contains the html code for our new tab and field in the tab.

<form id="co-excellence-form" action="">
<fieldset>
    <ul class="form-list">
    <li id="excellence-form">
        <fieldset>
            <ul>
                <li class="wide">
                    <label for="excellence:like" class="required"><em>*</em><?php echo $this->__('Do you like Excellence Magento Blog?') ?></label>
                    <div class="input-box">
                        <select class="required-entry" name="excellence[like]" id="excellence:like">
                        	<option value=''><?php echo $this->__('Please Choose..');?></option>
                        	<option value='1' <?php if($this->getQuote()->getExcellenceLike() == 1){echo 'selected="selected"';} ?>><?php echo $this->__('Yes');?></option>
                        	<option value='2' <?php if($this->getQuote()->getExcellenceLike() == 2){echo 'selected="selected"';} ?>><?php echo $this->__('No');?></option>
                        </select>
                    </div>
                </li>
            </ul>
        </fieldset>
     </li>
    </ul>
    <div class="buttons-set" id="excellence-buttons-container">
        <p class="required"><?php echo $this->__('* Required Fields') ?></p>
        <button type="button" title="<?php echo $this->__('Continue') ?>" class="button" onclick="excellence.save()"><span><span><?php echo $this->__('Continue') ?></span></span></button>
        <span class="please-wait" id="excellence-please-wait" style="display:none;">
            <img src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif') ?>" alt="<?php echo $this->__('Loading next step...') ?>" title="<?php echo $this->__('Loading next step...') ?>" class="v-middle" /> <?php echo $this->__('Loading next step...') ?>
        </span>
    </div>
</fieldset>
</form>
<script type="text/javascript">
//<![CDATA[
    var excellence = new ExcellenceMethod('co-excellence-form','<?php echo $this->getUrl('custom/onepage/saveExcellence') ?>');
    var excellenceForm = new VarienForm('co-excellence-form');
//]]>
</script>

I have added here a new drop down field. For your tab, just replace the name excellence with your tab name. The field id’s and class names are important for proper working on onestep checkout’s javascript features. Another thing to note here is the “new ExcellenceMethod” javascript class created, which i will show later. Next we need to have our own onepage.phtml file as at location custom/checkout/onepage.phtml. This file will replace the default checkout/onepage.phtml file.

<div class="page-title">
    <h1><?php echo $this->__('Checkout') ?></h1>
</div>
<script type="text/javascript" src="<?php echo $this->getJsUrl('varien/accordion.js') ?>"></script>
<script type="text/javascript" src="<?php echo $this->getSkinUrl('js/opcheckout.js') ?>"></script>
<!-- New Code Added Below  -->
<script type="text/javascript" src="<?php echo $this->getSkinUrl('js/excellencecheckout.js') ?>"></script>
<script type="text/javascript">countryRegions = <?php echo $this->helper('directory')->getRegionJson() ?></script>
<ol class="opc" id="checkoutSteps">
<?php $i=0; foreach($this->getSteps() as $_stepId => $_stepInfo): ?>
<?php if (!$this->getChild($_stepId) || !$this->getChild($_stepId)->isShow()): continue; endif; $i++ ?>
    <li id="opc-<?php echo $_stepId ?>" class="section<?php echo !empty($_stepInfo['allow'])?' allow':'' ?><?php echo !empty($_stepInfo['complete'])?' saved':'' ?>">
        <div class="step-title">
            <span class="number"><?php echo $i ?></span>
            <h2><?php echo $_stepInfo['label'] ?></h2>
            <a href="#"><?php echo $this->__('Edit') ?></a>
        </div>
        <div id="checkout-step-<?php echo $_stepId ?>" class="step a-item" style="display:none;">
            <?php echo $this->getChildHtml($_stepId) ?>
        </div>
    </li>
<?php endforeach ?>
</ol>
<script type="text/javascript">
//<![CDATA[
    var accordion = new Accordion('checkoutSteps', '.step-title', true);
    <?php if($this->getActiveStep()): ?>
    accordion.openSection('opc-<?php echo $this->getActiveStep() ?>');
    <?php endif ?>
    //New Code Added Below
    var checkout = new Excellence(accordion,{
        progress: '<?php echo $this->getUrl('checkout/onepage/progress') ?>',
        review: '<?php echo $this->getUrl('checkout/onepage/review') ?>',
        saveMethod: '<?php echo $this->getUrl('checkout/onepage/saveMethod') ?>',
        failure: '<?php echo $this->getUrl('checkout/cart') ?>'}
    );
//]]>
</script>

So if you look at code and compare it with default onepage.phtml file, i have included a new javascript file called excellencecheckout.js and instead of “new Checkout” i have used “new Excellence”. Next we need to change the html of the progress.phtml file (The progress blocks which show on the right side). For this i have created my own progress.phtml file at location custom/checkout/onepage/progress.phtml. Since i am adding the step at first position, i will add the below code before the billing step

<dl>
        <?php if ($this->getCheckout()->getStepData('excellence', 'is_show')): ?>
        <?php if($this->getCheckout()->getStepData('excellence', 'complete')): ?>
            <dt class="complete">
                <?php echo $this->__('Excellence Review') ?> <span class="separator">|</span> <a href="#excellence" onclick="checkout.accordion.openSection('opc-excellence'); return false;"><?php echo $this->__('Change') ?></a>
            </dt>
            <dd class="complete">
                <div>
                	<?php echo $this->__('Excellence Review Is: ');?>
                	<?php 
                		$like = $this->getQuote()->getExcellenceLike();
                		if($like == 1){
                			echo $this->__('Yes');
                		} else{
                			echo $this->__('No');
                		}
                	?>
                </div>
            </dd>
        <?php else: ?>
            <dt>
                <?php echo $this->__('Excellence Review') ?>
            </dt>
        <?php endif; ?>
        <?php endif; ?>

The full source of this file is there in the module attached.
Next we need to include these files in our layout xml file, so in my module layout file custom.xml file i have added code

<?xml version="1.0"?>
<layout version="0.1.0">
    <sales_order_view> <!-- Code From Previous Module -->
        <reference name="my.account.wrapper">
            <block type="custom/custom_order" name="custom.order" template="custom/order.phtml" after='sales.order.info' />
        </reference>
    </sales_order_view>
    <checkout_onepage_index> <!-- Adding our new step to onepage block  -->
    	<reference name='checkout.onepage'>
    		 <action method='setTemplate'><template>custom/checkout/onepage.phtml</template></action>
    		 <block type="custom/checkout_onepage_excellence" name="checkout.onepage.excellence" as="excellence" template="custom/checkout/onepage/excellence.phtml"/> <!-- Here we change the template of onepage block to our custom template -->
    	</reference>
    	<reference name='checkout.progress'> <!-- Change the template of progress block -->
    	      <action method='setTemplate'><template>custom/checkout/onepage/progress.phtml</template></action>
    	</reference> <!-- Here we change the template of the progress block to our custom template created -->
    </checkout_onepage_index>
    <checkout_onepage_progress>  <!-- Change the template of progress block -->
    	<reference name='root'>
    		<action method='setTemplate'><template>custom/checkout/onepage/progress.phtml</template></action>
    	</reference>
    </checkout_onepage_progress>
</layout> 

Now we have created all the required html files and made the changes in layout files to include them in the checkout page.
Step2: Javascript Classes
In the previous code we have included one new javascipt file excellencecheckout.js and created two new javascript classes Excellence and ExcellenceMethod. So first i will create the javascript file excellencecheckout.js in my skin folder at location skin\frontend\default\default\js\excellencecheckout.js and put the code shown below.
First lets look at the class Excellence, which we used in the new onepage.phtml file. The class Excellence actually replaces the default magento Checkout class. If you look at onepage.phtml this is the code i had written is

var checkout = new Excellence(accordion,{
        progress: '<?php echo $this->getUrl('checkout/onepage/progress') ?>',
        review: '<?php echo $this->getUrl('checkout/onepage/review') ?>',
        saveMethod: '<?php echo $this->getUrl('checkout/onepage/saveMethod') ?>',
        failure: '<?php echo $this->getUrl('checkout/cart') ?>'}
    );

and the default onepage.phtml file has

var checkout = new Checkout(accordion,{
        progress: '<?php echo $this->getUrl('checkout/onepage/progress') ?>',
        review: '<?php echo $this->getUrl('checkout/onepage/review') ?>',
        saveMethod: '<?php echo $this->getUrl('checkout/onepage/saveMethod') ?>',
        failure: '<?php echo $this->getUrl('checkout/cart') ?>'}
    );

So basically, this Excellence class replaces the Checkout class. So using prototype.js object inheritance i have created the new Excellence class and changed only what is required.

var Excellence = Class.create(Checkout, {
	initialize: function($super,accordion, urls){
		$super(accordion, urls);
		//New Code Addded
		this.steps = ['login', 'excellence' ,'billing', 'shipping', 'shipping_method', 'payment', 'review'];
	},
	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('excellence'); //New Code Here
	    }
	    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('excellence'); //New Code Here
	    }
	    else{
	        alert(Translator.translate('Please choose to register or to checkout as a guest'));
	        return false;
	    }
	}
});

So as you can see, i have added my new step “excellence” in the javascript file and also changed the code so that, in the login step when the user clicks on continue button, it goes to the “excellence” step.
Next we will look at ExcellenceMethod class, which was used in the excellence.phtml (new step phtml file). The ExellenceMethod class is used for the ajax operations, to save the drop down value of our new step. The code we have used in excellence.phtml file is

<script type="text/javascript">
//<![CDATA[
    var excellence = new ExcellenceMethod('co-excellence-form','<?php echo $this->getUrl('custom/onepage/saveExcellence') ?>');
    var excellenceForm = new VarienForm('co-excellence-form');
//]]>
</script>

As you can see here, we are using URL custom/onepage/saveExcellence in the ajax. the code ExcellenceMethod class is

var ExcellenceMethod = Class.create();
ExcellenceMethod.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() {
        if(!this.validator.validate()) {
            return false;
        }
        return true;
    },

    save: function(){

        if (checkout.loadWaiting!=false) return;
        if (this.validate()) {
            checkout.setLoadWaiting('excellence');
            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) {
            alert(response.message);
            return false;
        }

        if (response.update_section) {
            $('checkout-'+response.update_section.name+'-load').update(response.update_section.html);
        }


        if (response.goto_section) {
            checkout.gotoSection(response.goto_section);
            checkout.reloadProgressBlock();
            return;
        }

        checkout.setBilling();
    }
}

Both these classes code is written in the excellencecheckout.js file.
Step3: Checkout and Step Block
Next we need to create blocks for our phtml file. The 2 blocks to create are Excellence_Custom_Block_Checkout_Onepage
Excellence_Custom_Block_Checkout_Onepage_Excellence
The block Excellence_Custom_Block_Checkout_Onepage will override the default Onepage.php block of magento.
So to override open your config.xml file and add

<blocks>
        	<checkout>
        		<rewrite>
        			<onepage>Excellence_Custom_Block_Checkout_Onepage</onepage>
        		</rewrite>
        	</checkout>
        </blocks>

and the code in class Onepage.php would be

<?php
class Excellence_Custom_Block_Checkout_Onepage extends Mage_Checkout_Block_Onepage{

	public function getSteps()
	{
		$steps = array();

		if (!$this->isCustomerLoggedIn()) {
			$steps['login'] = $this->getCheckout()->getStepData('login');
		}

		//New Code Adding step excellence here
		$stepCodes = array('excellence','billing', 'shipping', 'shipping_method', 'payment', 'review');

		foreach ($stepCodes as $step) {
			$steps[$step] = $this->getCheckout()->getStepData($step);
		}
		return $steps;
	}

	public function getActiveStep()
	{
		//New Code, make step excellence active when user is already logged in
		return $this->isCustomerLoggedIn() ? 'excellence' : 'login';
	}

}

Next the code in our step block Excellence_Custom_Block_Checkout_Onepage_Excellence would be

<?php
class Excellence_Custom_Block_Checkout_Onepage_Excellence extends Mage_Checkout_Block_Onepage_Abstract{
	protected function _construct()
	{
		$this->getCheckout()->setStepData('excellence', array(
            'label'     => Mage::helper('checkout')->__('Excelence Blog Review'),
            'is_show'   => $this->isShow()
		));
		if ($this->isCustomerLoggedIn()) {
			$this->getCheckout()->setStepData('excellence', 'allow', true);
			$this->getCheckout()->setStepData('billing', 'allow', false);
		}

		parent::_construct();
	}
}

Step4: Creating the Controller
Now we need to create the controller for our ajax url. The ajax url which is being called is custom/onepage/saveExcellence. So the controller file for this is created at location app\code\local\Excellence\Custom\controllers\OnepageController.php

<?php
require_once 'Mage/Checkout/controllers/OnepageController.php';
class Excellence_Custom_OnepageController extends  Mage_Checkout_OnepageController{
	public function saveExcellenceAction(){
		if ($this->_expireAjax()) {
			return;
		}
		if ($this->getRequest()->isPost()) {
			$data = $this->getRequest()->getPost('excellence', array());

			$result = $this->getOnepage()->saveExcellence($data);

			if (!isset($result['error'])) {
				$result['goto_section'] = 'billing';
			}

			$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
		}
	}
}

The code is very simple and the main part to focus on is $this->getOnepage()->saveExcellence($data) and also $result['goto_section'] = ‘billing’;
The goto_section specified which section to show after the data for current section is successfully saved.
Step4: Model
Now need to create the saveExcellence() function in the Onepage Model. So we will override the Onepage.php model class, for this in the modules config.xml put in this code

<models>
        	<checkout>
	            <rewrite>
             <type_onepage>Excellence_Custom_Model_Checkout_Type_Onepage</type_onepage>
	            </rewrite>
	        </checkout>
</models>

and code in our new Onepage.php file is

<?php
class Excellence_Custom_Model_Checkout_Type_Onepage extends Mage_Checkout_Model_Type_Onepage{
	public function saveExcellence($data){
		if (empty($data)) {
			return array('error' => -1, 'message' => $this->_helper->__('Invalid data.'));
		}
		$this->getQuote()->setExcellenceLike($data['like']);
		$this->getQuote()->collectTotals();
		$this->getQuote()->save();

		$this->getCheckout()
		->setStepData('excellence', 'allow', true)
		->setStepData('excellence', 'complete', true)
		->setStepData('billing', 'allow', true);

		return array();
	}
}

Here we are putting doing setExcellenceLike on the quote object, and as in my previous blog using Observer we will save this value to database. The detail code for this is found the module attached.
After this the new step would be fully functional.

Adding Step In Between

Now we will see how to add a step in between Shipping Step and Shipping Method Step. The title of the new step will be “Excelence2 Post Review” and its id will be “excellence2″.

Magento Checkout - New Step Added Between Shipping and Shipping Method

Magento Checkout - New Step Added Between Shipping and Shipping Method


Step1: Adding HTML
Now again we need to create the phtml file for our step. The name of file will be excellence2.phtml and location would be app\design\frontend\default\default\template\custom\checkout\onepage\excellence2.phtml

<form id="co-excellence2-form" action="">
<fieldset>
    <ul class="form-list">
    <li id="excellence2-form">
        <fieldset>
            <ul>
                <li class="wide">
                    <label for="excellence2:like" class="required"><em>*</em><?php echo $this->__('Do you like this post?') ?></label>
                    <div class="input-box">
                        <input type='text' name='excellence2[like]'  class="required-entry input-text" id="excellence2:like" value='<?php echo $this->getQuote()->getExcellenceLike2()?>'/>
                    </div>
                </li>
            </ul>
        </fieldset>
     </li>
    </ul>
    <div class="buttons-set" id="excellence2-buttons-container">
        <p class="required"><?php echo $this->__('* Required Fields') ?></p>
        <button type="button" title="<?php echo $this->__('Continue') ?>" class="button" onclick="excellence2.save()"><span><span><?php echo $this->__('Continue') ?></span></span></button>
        <span class="please-wait" id="excellence2-please-wait" style="display:none;">
            <img src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif') ?>" alt="<?php echo $this->__('Loading next step...') ?>" title="<?php echo $this->__('Loading next step...') ?>" class="v-middle" /> <?php echo $this->__('Loading next step...') ?>
        </span>
    </div>
</fieldset>
</form>
<script type="text/javascript">
//<![CDATA[
    var excellence2 = new ExcellenceMethod2('co-excellence2-form','<?php echo $this->getUrl('custom/onepage/saveExcellence2') ?>');
    var excellenceForm2 = new VarienForm('co-excellence2-form');
//]]>
</script>

This time we have added a text field instead of drop down and used the javascript class ExcellenceMethod2. Since we have already create progress.phtml and onepage.phtml we don’t need to create it again, but we need to add our new step’s progress html to the progress.phtml. So between the two steps i will put this code

<?php if ($this->getCheckout()->getStepData('excellence2', 'is_show')): ?>
        <?php if($this->getCheckout()->getStepData('excellence2', 'complete')): ?>
            <dt class="complete">
                <?php echo $this->__('Excellence2 Review') ?> <span class="separator">|</span> <a href="#excellence2" onclick="checkout.accordion.openSection('opc-excellence2'); return false;"><?php echo $this->__('Change') ?></a>
            </dt>
            <dd class="complete">
                <div>
                	<?php echo $this->__('Excellence2 Review Is: ');?>
                	<?php 
                		$like = $this->getQuote()->getExcellenceLike2();
                		echo $like;
                	?>
                </div>
            </dd>
        <?php else: ?>
            <dt>
                <?php echo $this->__('Excellence2 Review') ?>
            </dt>
        <?php endif; ?>
        <?php endif; ?>

Next we need to add the excellence2.phtml to onepage block through the layout file. So we will add this code in the custom.xml layout file

<block type="custom/checkout_onepage_excellence2" name="checkout.onepage.excellence2" as="excellence2" template="custom/checkout/onepage/excellence2.phtml"/>

This block is added inside the “checkout.onepage” block.
Step2: Javascript
Now we will create the javascript code for our new step. We will create the class ExcellenceMethod2 in the previously created javascript file excellencecheckout.js

var ExcellenceMethod2 = Class.create();
ExcellenceMethod2.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() {
        if(!this.validator.validate()) {
            return false;
        }
        return true;
    },

    save: function(){

        if (checkout.loadWaiting!=false) return;
        if (this.validate()) {
            checkout.setLoadWaiting('excellence2');
            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) {
            alert(response.message);
            return false;
        }

        if (response.update_section) {
            $('checkout-'+response.update_section.name+'-load').update(response.update_section.html);
        }


        if (response.goto_section) {
            checkout.gotoSection(response.goto_section);
            checkout.reloadProgressBlock();
            return;
        }

        checkout.setPayment();
    }
}

Rest other javascript changes are same as before.
Step3: Checkout and Step Block
The checkout block we have already created previously, we just need to modify it. We only need to change the $stepCodes array to

$stepCodes = array('excellence','billing', 'shipping', 'excellence2', 'shipping_method', 'payment', 'review');

Next need to create a block for our new step. The block class is Excellence_Custom_Block_Checkout_Onepage_Excellence2

<?php
class Excellence_Custom_Block_Checkout_Onepage_Excellence2 extends Mage_Checkout_Block_Onepage_Abstract{
	protected function _construct()
	{
		$this->getCheckout()->setStepData('excellence2', array(
            'label'     => Mage::helper('checkout')->__('Excelence2 Post Review'),
            'is_show'   => $this->isShow()
		));
		parent::_construct();
	}
}

Here we are setting the title of our step.
Step4: Controller
In the onepage controller created previously, we need to add a new action i.e saveExcellence2Action. This is the action that is called in our phtml file through ajax.

public function saveExcellence2Action(){
		if ($this->_expireAjax()) {
			return;
		}
		if ($this->getRequest()->isPost()) {
			$data = $this->getRequest()->getPost('excellence2', array());

			$result = $this->getOnepage()->saveExcellence2($data);

			if (!isset($result['error'])) {
				$result['goto_section'] = 'shipping_method';
				$result['update_section'] = array(
                    'name' => 'shipping-method',
                    'html' => $this->_getShippingMethodsHtml()
				);
			}

			$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
		}
	}

In this action, we also set what would next step would be and its html.
Now, since this block is being placed in the middle of the site, we need to change the code of other steps as well, so that when other steps are successful our new step shows. Specifically, in our case we need to change the billing and shipping step. So when billing step is competed and user has chosen shipping address same as billing our step should open, and also when shipping step is completed our step should open. So for this we need to change the saveBillingAction and saveShippingAction function. So we will no override the default OnepageController with our OnepageController. To do this in the config.xml file put this code

<global>
    	<rewrite>
	        <test_cart> <!--This can be any unique id -->
	            <from><![CDATA[#^/checkout/onepage/#]]></from>  <!-- the URL which u want to override-->
	            <to>/custom/onepage/</to>  <!-- destination url -->
	        </test_cart>
	    </rewrite>
</global>

and in our OnepageController we will add these two actions

public function saveBillingAction()
	{
		if ($this->_expireAjax()) {
			return;
		}
		if ($this->getRequest()->isPost()) {
			//            $postData = $this->getRequest()->getPost('billing', array());
			//            $data = $this->_filterPostData($postData);
			$data = $this->getRequest()->getPost('billing', array());
			$customerAddressId = $this->getRequest()->getPost('billing_address_id', false);

			if (isset($data['email'])) {
				$data['email'] = trim($data['email']);
			}
			$result = $this->getOnepage()->saveBilling($data, $customerAddressId);

			if (!isset($result['error'])) {
				/* check quote for virtual */
				if ($this->getOnepage()->getQuote()->isVirtual()) {
					$result['goto_section'] = 'payment';
					$result['update_section'] = array(
                        'name' => 'payment-method',
                        'html' => $this->_getPaymentMethodsHtml()
					);
				} elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
					$result['goto_section'] = 'excellence2';  //Goes to our step
					$result['allow_sections'] = array('shipping');
					$result['duplicateBillingInfo'] = 'true';
				} else {
					$result['goto_section'] = 'shipping';
				}
			}

			$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
		}
	}
	public function saveShippingAction()
	{
		if ($this->_expireAjax()) {
			return;
		}
		if ($this->getRequest()->isPost()) {
			$data = $this->getRequest()->getPost('shipping', array());
			$customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
			$result = $this->getOnepage()->saveShipping($data, $customerAddressId);

			if (!isset($result['error'])) {
				$result['goto_section'] = 'excellence2'; //Go to our step
			}
			$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
		}
	}

Step5: Model
Now like before, we need to create the saveExcellence2 function in Onepage model. This would be same as before, in our Onepage.php file add

public function saveExcellence2($data){
		if (empty($data)) {
			return array('error' => -1, 'message' => $this->_helper->__('Invalid data.'));
		}
		$this->getQuote()->setExcellenceLike2($data['like']);
		$this->getQuote()->collectTotals();
		$this->getQuote()->save();

		$this->getCheckout()
		->setStepData('excellence2', 'allow', true)
		->setStepData('excellence2', 'complete', true)
		->setStepData('billing', 'allow', true);

		return array();
	}

Now, this step is fully working.

Adding A Dynamic Step

Here we will add a new step after the Payment Step. This step will be dynamic, meaning the content would depend on our previous steps data. So in our step, i will show two different texts based on the shipping method. So if shipping method is Flate Rate then text shown will be ‘We are shipping your products though Express Delivery, the product will reach you in 3days’, or else text shown will be ‘We are shipping your products though Normal Delivery, the product will reach you in 1weeks time’.

Magento Onestep Checkout - Dynamic Step

Magento Onestep Checkout - Dynamic Step


Step1: Adding HTML
So again we need to create the phtml for our step, but this our step html is divided into two parts: 1. Static Part (buttons, divs) 2. Dynamic Part (The text message). Accordingly, we need to divide our html. We will create a phtml file called excellence3.phtml at location app\design\frontend\default\default\template\custom\checkout\onepage\excellence3.phtml

<form id="co-excellence3-form" action="">
<fieldset>
    <ul class="form-list">
    <li id="checkout-excellence3-load">  <!-- This id format is very important -->
    	<?php echo $this->getChildHtml('info');?>
     </li>
    </ul>
    <div class="buttons-set" id="excellence3-buttons-container">
        <p class="required"><?php echo $this->__('* Required Fields') ?></p>
        <button type="button" title="<?php echo $this->__('Continue') ?>" class="button" onclick="excellence3.save()"><span><span><?php echo $this->__('Continue') ?></span></span></button>
        <span class="please-wait" id="excellence3-please-wait" style="display:none;">
            <img src="<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif') ?>" alt="<?php echo $this->__('Loading next step...') ?>" title="<?php echo $this->__('Loading next step...') ?>" class="v-middle" /> <?php echo $this->__('Loading next step...') ?>
        </span>
    </div>
</fieldset>
</form>
<script type="text/javascript">
//<![CDATA[
    var excellence3 = new ExcellenceMethod3('<?php echo $this->getUrl('custom/onepage/saveExcellence3') ?>');
//]]>
</script>

The main difference here is

<li id="checkout-excellence3-load">  <!-- This id format is very important -->
    	<?php echo $this->getChildHtml('info');?>
     </li>

We have added the dynamic part as a child block and the id of the element which has the child block is “checkout-stepid-load”This id format is important or else the checkout won’t work.
Next we will define our child block, filename info.phtml at location app\design\frontend\default\default\template\custom\checkout\onepage\excellence3\info.phtml

<fieldset>
        <?php
        $shippingMethod = $this->getQuote()->getShippingAddress()->getShippingMethod();
        if($shippingMethod == 'flatrate_flatrate'){
        echo 'We are shipping your products though Express Delivery, the product will reach you in 3days';
        }else{
        echo 'We are shipping your products though Normal Delivery, the product will reach you in 1weeks time';
        }
        ?>
            
</fieldset>

Now, we will add these phtml files to out layout. The below code is inside the checkout.onepage block as usual

<block type="custom/checkout_onepage_excellence3" name="checkout.onepage.excellence3" as="excellence3" template="custom/checkout/onepage/excellence3.phtml">
    		 		<block type="custom/checkout_onepage_excellence3" name="checkout.onepage.excellence3.info" as="excellence3.info" template="custom/checkout/onepage/excellence3/info.phtml" />
    		 </block>

the new code for our dynamic block is

<checkout_onepage_excellence3>
        <!-- Mage_Checkout -->
        <remove name="right"/>
        <remove name="left"/>

        <block type="custom/checkout_onepage_excellence3" name="root" output="toHtml" template="custom/checkout/onepage/excellence3/info.phtml"/>
    </checkout_onepage_excellence3>

Step2: Javascript
The javascript here is very simple, since we don’t have any form so we don’t save any data. So our ajax will simple get the html for the next review step and display it. The code written in our step phtml file, excellence.phtml is

var excellence3 = new ExcellenceMethod3('<?php echo $this->getUrl('custom/onepage/saveExcellence3') ?>');

and the ExcellenceMethod3 is

var ExcellenceMethod3 = Class.create();
ExcellenceMethod3.prototype = {
    initialize: function(saveUrl){
        this.saveUrl = saveUrl;
        this.onSave = this.nextStep.bindAsEventListener(this);
        this.onComplete = this.resetLoadWaiting.bindAsEventListener(this);
    },
    save: function(){

        if (checkout.loadWaiting!=false) return;
            checkout.setLoadWaiting('excellence3');
            var request = new Ajax.Request(
                this.saveUrl,
                {
                    method:'post',
                    onComplete: this.onComplete,
                    onSuccess: this.onSave,
                    onFailure: checkout.ajaxFailure.bind(checkout)
                }
            );
    },

    resetLoadWaiting: function(transport){
        checkout.setLoadWaiting(false);
    },

    nextStep: function(transport){
        if (transport && transport.responseText){
            try{
                response = eval('(' + transport.responseText + ')');
            }
            catch (e) {
                response = {};
            }
        }

        if (response.error) {
            alert(response.message);
            return false;
        }

        if (response.update_section) {
            $('checkout-'+response.update_section.name+'-load').update(response.update_section.html);
        }


        if (response.goto_section) {
            checkout.gotoSection(response.goto_section);
            checkout.reloadProgressBlock();
            return;
        }

        checkout.setReview();
    }
}

Step3: Controller
Now in our OnepageController, first we need to change the implementation of savePaymentAction(), so that it shows our new tab instead of review tab.

public function savePaymentAction()
	{
		if ($this->_expireAjax()) {
			return;
		}
		try {
			if (!$this->getRequest()->isPost()) {
				$this->_ajaxRedirectResponse();
				return;
			}

			// set payment to quote
			$result = array();
			$data = $this->getRequest()->getPost('payment', array());
			$result = $this->getOnepage()->savePayment($data);

			if (empty($result['error'])) {
				$result['goto_section'] = 'excellence3';
				$result['update_section'] = array(
                    'name' => 'excellence3',
                    'html' => $this->_getExcellence3Html()
				);
			}

		} catch (Mage_Payment_Exception $e) {
			if ($e->getFields()) {
				$result['fields'] = $e->getFields();
			}
			$result['error'] = $e->getMessage();
		} catch (Mage_Core_Exception $e) {
			$result['error'] = $e->getMessage();
		} catch (Exception $e) {
			Mage::logException($e);
			$result['error'] = $this->__('Unable to set Payment Method.');
		}
		$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
	}
protected function _getExcellence3Html()
	{
		$layout = $this->getLayout();
		$update = $layout->getUpdate();
		$update->load('checkout_onepage_excellence3');
		$layout->generateXml();
		$layout->generateBlocks();
		$output = $layout->getOutput();
		return $output;
	}

As you can see in the code, dynamic html is called here using the _getExcellence3Html() function. Next we need to add the function for saveExcellence3Action as well, this will simple get the review step html and show it.

public function saveExcellence3Action(){
		if ($this->_expireAjax()) {
			return;
		}

		// get section and redirect data
		$redirectUrl = $this->getOnepage()->getQuote()->getPayment()->getCheckoutRedirectUrl();

		if (!isset($result['error'])) {
			$this->loadLayout('checkout_onepage_review');
			$result['goto_section'] = 'review';
			$result['update_section'] = array(
                    'name' => 'review',
                    'html' => $this->_getReviewHtml()
			);
		}
		if ($redirectUrl) {
			$result['redirect'] = $redirectUrl;
		}

		$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
	}

Step4: Block
Next we need to create the Excellence3.php block as before.

<?php
class Excellence_Custom_Block_Checkout_Onepage_Excellence3 extends Mage_Checkout_Block_Onepage_Abstract{
	protected function _construct()
	{
		$this->getCheckout()->setStepData('excellence3', array(
            'label'     => Mage::helper('checkout')->__('Excellence  Review'),
            'is_show'   => $this->isShow()
		));
		parent::_construct();
	}
}

This is all is required to make this step functional.

In this blog, we have seen in very detail how to add steps to existing magento onepage checkout. We have seen 3 different examples, hopefully all code was covered in the blog. This module has been tested in magento version 1.6, but i see now reason why it shouldn’t work in other magento version. No core files have been changed, not even javascript files. Please comment on the blog if anything is missing or not working.
  • http://twitter.com/webarton AKI

    Hello Manish, many thanks for this article. It helps me a lot! My goal is to show/edit customer’s attribute in a new step, so your articles take me to the goal.

    • Manish Prakash

      Thanks :)

  • Muhammadtalha89

    Hello Manish,

    I installed the above extension but when I go to checkout and select YES or NO from the drop down menu and then select Next. It hangs over there. It doesn’t go to billing information.

    My magento version in 1.6.0. Can you tell me whats the error?

    • Manish Prakash

      Please add firebug in firefox and look at the ajax request which gets fired when you press the continue button. You will see some error in the ajax request, if you can paste the error i can let u know what is the problem

  • Pingback: OnePageCheckout | Magento Media

  • Juma

    Manish is there anyway to add the shipping information into this module so I can rename it processing fee and still have a shipping step?

  • Mau

    What if I want  to only show this step in one theme of a couple of layered shops? If I read this it would add the extra layers on all the shops right?

  • Reva

    Hello, need help please.
    I don’t know why, but magento is redirecting me to cart page after I click ‘continue’ button on my new step.

  • StefanMaier

    Hi Mansih,
    thanks for this great post i have one big issue tough;
    the module doesn’t seem to work on Magento 1.7 – or i did something wrong maybe?
    Problem is there are several js – errors. I want to add another step in the middle of the checkout-process and was able to do the needed adaptions until now.
    On loading the “onepage” i get the following js – error:

    TypeError: $(this.form).observe is not a function

    it occurs in your Excellence2 js-definition. I dried uninstalling jQuery (Which we are using, too) but this didnt do the trick.
    Any Ideas?
    Kind Regards

  • Surbhi

    Hi, I have followed all steps but didn’t get positive output.Please help me

  • Luke Branch

    another great tutorial, one quick question though, I would like to add multiple checkboxes, radio button arrays, text and number input fields and date fields, all with magento form validation into the first custom step and the second custom step. I would also like to eliminate the third custom step in the process. If you could please elaborate on how I might accomplish this using this technique it would be much appreciated.

    Also I would like to know how to implement this in Magento CE 1.7 +. It seems to work well on 1.6+ but it seems to break the checkout process and bounce back to the shopping cart in 1.7+.

    I have a very basic understanding of PHP so please excuse my ignorance.

    • Kristina Sanchez

      hi! I’ve been having the same problem. have you gotten any resolution for this?

  • Kedar

    Hi,

    This module is working fine on my local system. But when I upload this on live site it stops working. Please suggest something about this.

    Thanks

    Kedar

    • Manish Prakash

      Hi, Kedar
      You might be missing some files or might be any js conflict errors. Please look into the firebug console for any errrors.
      Hope it will work..

  • Neeraj Pathak

    Hi Manish,

    Nice script. I downloaded and its working fine. But there is need to remove two steps i.e excellence2 and excellence3. I tried several times but did not get positive result. I need you to help me to state in simple way that can me to remove both steps.

    Thanks in advance.

    • Manish Prakash

      Hi, Neeraj
      For removing the steps you need to alter few files like onepage.php block file, onepagecontroller.php and also excellenceecheckout.js file. You need to modify these files according to your need..

  • Pinkal Vansia

    excellent. Worked like a charm. Added two extra dynamic steps depending upon the products in cart. Showing up perfectly in view order page in admin panel. Now how about writing yet another excellent blog on editing this custom data in order page same as address. And how about adding this form to manually creating order from admin panel.

  • Kelvin

    Woah!!! That incredible tutorial. It’s also work on ver-1.7.0.2. Cool man. I really appreciate that!

    • Kristina Sanchez

      Hi! can I ask how you had it installed in 1.7.0.2? The additional step or field is not being shown on my end during checkout :(

  • http://www.facebook.com/abhishek.sparx Abhishek Sparx

    Continue Button of shipping method is not working , Please post solution as soon as possible.

    • gammacode

      is there any solution available ?

  • Kristina Sanchez

    Does this work in the current version of 1.7.0.2? I tried installing these and even had the files replaced one by one but it doesn’t seem to work. I hope to get some help. Please and Thank you.

    • Manish Prakash

      Hi Kristina,
      Yes it works in all versions from 1.4x onwards. Just you need to do that download the module, unzip it and merge the folders in the magento structure. The files will be automatically reach the required places and then clear the cache and reindex data.

      After this it should work.
      Thanks.

      • Kristina Sanchez

        thanks for your response :)
        unfortunately it doesn’t really work. I think it might have something to do with the path that the folders are in. (php newbie here)
        i’m doing my best right now to have all of it located just so i can get started.
        but you have an awesome blog btw :) gets me started on the things I want to do

  • Manish Prakash

    Thanks Hugo..

  • Manish Prakash

    Hi Jignesh,
    Yes it works in all versions from 1.4x onwards.

  • Manish Prakash

    Hi Jemsenator,
    For installing this module, Just you need to do that download the
    module, unzip it and merge the folders in the magento structure. The
    files will be automatically reach the required places and then clear the
    cache and reindex data.

    After this it should work.
    Thanks.

  • Manish Prakash

    Hi, Arun

    For removing the steps you need to alter few files like onepage.php
    block file, onepagecontroller.php and also excellenceecheckout.js file.
    You need to modify these files according to your need..
    Thanks.

  • jose angel bonfil

    Hi excellent tutorial, i want to know how can i get the order id from the class Excellence_Custom_Model_Sales_Order on the model this class is the one that sends data to the email template, please help thanks

  • Manoj

    Hi Manish,

    I have installed the module in magento 1.7.0.2. Its showing me all the steps that are in the module. But the functionality of “Continue” button is not working. Also one thing is that, how do I add a simple text field as a step in checkout after Payment Information Step?

    • gammacode

      is there any solution available ?

  • Jagesh

    Is it possible to show extra tab attribute value in sales order mail like shipping method and payment method?

    Is it possible to show extra tab value in sales order mail?

  • gammacode

    Hi Manish,

    thank you to spend time to create this ultimativ guide.

    but the continue button has no funtionality.

    shipping method is not defined when i installed the package ..

    var
    shippingMethod = new ShippingMethod(‘co-shipping-method-form’,
    “http://../checkout/onepage/saveShippingMethod/”);

    when shipping method step available so is the shippingMethod undefined on shippingMethod.save()

    what is wrong ?

    i cant isolate this failure. i havent a idea :(

    thx gamma

  • soumyadip nag

    Hey Manish,

    First of all thanks for your smart module, i have installed it properly and its working fine. But the thing is i have lit bit different requirement, i ll be grateful if u help me out by modifying this module as per my requirement.
    Now coming back to my requirement, Well, my requirement is, i want to use 5 to six dropdown(select box) in the first tab , i.e called Excellence Blog Review. (whole day will be saved and viewable from admin site)
    Thanks in advance..

  • jj

    Hi Manish,

    Thank you for writing such an informative article. This has really saved me many hours of investigation and frustration. However, I have made some alterations to the above code that you defined (while Excellence is a wonderful name, it was unsuitable for my client’s needs! Oh picky clients. :) ), and I am seeing an error in the progress column when I enter the new step in the main order step sequence. The error begins:

    Notice: Undefined index: in /app/code/core/Mage/Checkout/Block/Onepage/Progress.php on line 89

    There is much more being spewed out on screen, but I just wanted to ask if this is something that you may have some familiarity with as I have been altering files with little in the way of success for a couple of days now! :(

    The progress.php data displays as expected for the other steps.

    Any advice that can be offered is greatly appreciated.

    Kind regards,
    jj

    • jj

      Hi, I realised the issue that I was having. I needed to add an override of _getStepCodes in my Progress.php file to include the additional step!

      protected function _getStepCodes() {
      return array(‘login’, ‘billing’, ‘shipping’, ‘additionalstep’, ‘shipping_method’, ‘payment’, ‘review’);
      }

      Yay!! That seems to be working fine now. Thanks again for the instructional tutorial.

  • shahid

    hi manish .
    your module working gud.
    i want to add radio button instead of dropout in first step of module .excellence 1
    can u please help me.

  • webattpc

    How do I add these checkout steps to the email template?

  • myrunningattitude

    Hey Manish, thanks for this astonishing guide. I confirm it works as well on Magento 1.8

  • Francesco Schettini

    Hey Manish, thanks for this astonishing guide! Superb! I confirm it works as well on Magento 1.8. all the best!

  • Bhadresh

    Excellent Work,very Helpful

  • deepa

    Hi need to save multiple custom attributes (it is different for different products) based on product . Whether is this possible ?

  • boby

    i got Question when you save the value of the new field “$this->getQuote()->setExcellenceLike($data['like']);” this code save the value in a new Table or no?

  • http://andreacanton.com Andrea Canton

    *****A solution for all who have problems with Continue button****

    First look at the console (with Firebug, Safari or Chrome). My error said the HTML entity doesn’t have the method ‘save’.

    How I found the solution:
    Short story:
    check if your “ExellenceMethod” object has the same name of the input. if so, rename one of those.

    Long Story:
    In my case the object “ExcellenceMethod” object was called “projects” and was the same as the name of the select. In console if I gave the command projects.save() didn’t return the same error.

    So I changed the onClick parameter of the button like this: onclick=”console.log(projects)”. When I click that button in my console the select HTML element was dump.
    So I renamed the object in “projects_method” and everything works.

    I hope that’s useful for somebody.
    Greetings!

  • http://andreacanton.com Andrea Canton

    I’ve installed the 1.8.1.0CE there is an update regardless the progress sidebar. I’m trying to update your code.

    It load the single blocks of the progress sidebar (shipping, billings, etc.)

    more info: http://www.magentocommerce.com/knowledge-base/entry/ce-18-later-release-notes

  • Andre Nickatina

    Hey Manish,
    Could you make your site narrower? I can almost see all the code… I like when the code is hidden behind a frame with no scrollbars and I can only see half or less…
    Also, could you make it so that every time I copy some code and paste it, some additional bullshit gets copied as well, guaranteeing that I will have to manually delete it or my site will be broken? That would be perfect!
    One more request: when you make an example, it would be really helpful if you use the same term for everything; it makes the example easier to understand:
    class Fee_Fee_Model_Fee extends Varien_Abstract {
    $fee = Mage::getModel(‘fee/fee’)->getFee();
    }

    Fee_Fee_Helper

    Fee_Fee_Model

    Fee_Fee_Model_Fee

    Fee_Fee
    Fee_Fee_Model_Resource_Fee

    Fee_Fee_Block

    fee_fee/fee
    fee

    It worked pretty well for the smurfs, right?
    I wish I could fucking smurf you in the smurf right now for being such a smurfing smurfhole.

    Thanks again!

  • Graffix

    Hello, very nice script. I also need to add multiple dropdowns and save the selection to the database, I need these at the excellence2 step. I have added the dropdowns, but I cannot get all the values to save to the database, it will only save the last value selected, any suggestions?

    • Graffix

      Here is my code:

      *__(‘Please confirm your vehicle’s Year/Make/Model/Bed Length’) ?>

      __(‘Year’);?>
      <option value='2015' getQuote()->getexcellence2Like() == 1){echo ‘selected=”selected”‘;} ?>>__(’2015′);?>
      <option value='2014' getQuote()->getexcellence2Like() == 2){echo ‘selected=”selected”‘;} ?>>__(’2014′);?>
      <option value='2013' getQuote()->getexcellence2Like() == 3){echo ‘selected=”selected”‘;} ?>>__(’2013′);?>
      <option value='2012' getQuote()->getexcellence2Like() == 4){echo ‘selected=”selected”‘;} ?>>__(’2012′);?>
      <option value='2011' getQuote()->getexcellence2Like() == 5){echo ‘selected=”selected”‘;} ?>>__(’2011′);?>
      <option value='2010' getQuote()->getexcellence2Like() == 6){echo ‘selected=”selected”‘;} ?>>__(’2010′);?>
      <option value='2009' getQuote()->getexcellence2Like() == 7){echo ‘selected=”selected”‘;} ?>>__(’2009′);?>
      <option value='2008' getQuote()->getexcellence2Like() == 8){echo ‘selected=”selected”‘;} ?>>__(’2008′);?>
      <option value='2007' getQuote()->getexcellence2Like() == 9){echo ‘selected=”selected”‘;} ?>>__(’2007′);?>
      <option value='2006' getQuote()->getexcellence2Like() == 10){echo ‘selected=”selected”‘;} ?>>__(’2006′);?>
      <option value='2005' getQuote()->getexcellence2Like() == 11){echo ‘selected=”selected”‘;} ?>>__(’2005′);?>
      <option value='2004' getQuote()->getexcellence2Like() == 12){echo ‘selected=”selected”‘;} ?>>__(’2004′);?>
      <option value='2003' getQuote()->getexcellence2Like() == 13){echo ‘selected=”selected”‘;} ?>>__(’2003′);?>
      <option value='2002' getQuote()->getexcellence2Like() == 14){echo ‘selected=”selected”‘;} ?>>__(’2002′);?>
      <option value='2001' getQuote()->getexcellence2Like() == 15){echo ‘selected=”selected”‘;} ?>>__(’2001′);?>
      <option value='2000' getQuote()->getexcellence2Like() == 16){echo ‘selected=”selected”‘;} ?>>__(’2000′);?>
      <option value='1999' getQuote()->getexcellence2Like() == 17){echo ‘selected=”selected”‘;} ?>>__(’1999′);?>

      __(‘Make’);?>
      <option value='Ford' getQuote()->getexcellence2Like() == 1){echo ‘selected=”selected”‘;} ?>>__(‘Ford’);?>
      <option value='Chevy' getQuote()->getexcellence2Like() == 2){echo ‘selected=”selected”‘;} ?>>__(‘Chevy’);?>
      <option value='GMC' getQuote()->getexcellence2Like() == 3){echo ‘selected=”selected”‘;} ?>>__(‘GMC’);?>
      <option value='Dodge' getQuote()->getexcellence2Like() == 4){echo ‘selected=”selected”‘;} ?>>__(‘Dodge’);?>
      <option value='Toyota' getQuote()->getexcellence2Like() == 5){echo ‘selected=”selected”‘;} ?>>__(‘Toyota’);?>
      <option value='Lincoln' getQuote()->getexcellence2Like() == 6){echo ‘selected=”selected”‘;} ?>>__(‘Lincoln’);?>
      <option value='International' getQuote()->getexcellence2Like() == 7){echo ‘selected=”selected”‘;} ?>>__(‘International’);?>

      __(‘Model’);?>
      <option value='F-150' getQuote()->getexcellence2Like() == 1){echo ‘selected=”selected”‘;} ?>>__(‘F-150′);?>
      <option value='F-250' getQuote()->getexcellence2Like() == 2){echo ‘selected=”selected”‘;} ?>>__(‘F-250′);?>
      <option value='Silverado' getQuote()->getexcellence2Like() == 3){echo ‘selected=”selected”‘;} ?>>__(‘Silverado’);?>
      <option value='Sierra' getQuote()->getexcellence2Like() == 4){echo ‘selected=”selected”‘;} ?>>__(‘Sierra’);?>
      <option value='Ram' getQuote()->getexcellence2Like() == 5){echo ‘selected=”selected”‘;} ?>>__(‘Ram’);?>
      <option value='Tundra' getQuote()->getexcellence2Like() == 6){echo ‘selected=”selected”‘;} ?>>__(‘Tundra’);?>
      <option value='CXT' getQuote()->getexcellence2Like() == 7){echo ‘selected=”selected”‘;} ?>>__(‘CXT’);?>

      __(‘Bed Length’);?>
      <option value='Short' getQuote()->getexcellence2Like() == 1){echo ‘selected=”selected”‘;} ?>>__(‘Short’);?>
      <option value='Regular' getQuote()->getexcellence2Like() == 2){echo ‘selected=”selected”‘;} ?>>__(‘Regular’);?>
      <option value='Long' getQuote()->getexcellence2Like() == 3){echo ‘selected=”selected”‘;} ?>>__(‘Long’);?>

      __(‘* Required Fields’) ?>
      <button type="button" title="__(‘Continue’) ?>” class=”button” onclick=”excellence2.save()”>__(‘Continue’) ?>

      <img src="getSkinUrl(‘images/opc-ajax-loader.gif’,array(‘_secure’=>true)) ?>” alt=”__(‘Loading next step…’) ?>” title=”__(‘Loading next step…’) ?>” class=”v-middle” /> __(‘Loading next step…’) ?>

      //<![CDATA[
      var excellence2 = new ExcellenceMethod2('co-excellence2-form','getUrl('custom/onepage/saveExcellence2',array('_secure'=>true)) ?>');
      var excellenceForm2 = new VarienForm('co-excellence2-form');
      //]]>

  • http://nilus.in Amit Tripathi

    Hi Manish, Its nice guide and is like bible for me. I have used this module. Its working on default theme, but not showing any result on progress bar. I tried to change it a bit and got attached solution. But still I can’t make excellence steps to shown any resonse.

  • Asif

    checkout progress bar is not working. magento version 1.9