Step 1:

Create a template called configurable_category.phtml and put it on the template/catalog/product/view/type folder of your theme (create the folder if it doesn’t exist). Put the following code in that file:

<?php
$_product    = $this->getProduct();
$_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes());
?>
 
<?php if ($_product->isSaleable() && count($_attributes)):?>
<dl>
    <?php foreach($_attributes as $_attribute): ?>
    <dt><label><em>*</em><?php echo $_attribute->getLabel() ?></label></dt>
    <dd<?php if ($_attribute->decoratedIsLast){?><?php }?>>
        <div>
        <select name="super_attribute&#91;<?php echo $_attribute->getAttributeId() ?>]" id="attribute<?php echo $_attribute->getAttributeId() ?>" class="required-entry super-attribute-select_<?php echo $_product->getId()?>">
        <option><?php echo $this->__('Choose an Option...') ?></option>
        </select>
        </div>
    </dd>
    <?php endforeach; ?>
</dl>
 
<script type="text/javascript">
    var spConfig_<?php echo $_product->getId()?> = new Inchoo_Product.Config(<?php echo $this->getJsonConfig() ?>);
</script>
<?php endif;?>

The differences with the original configurable.phtml file and this one are that now we create a different spConfig object for each product. This object contains all the product configurable options. We also add the class super-attribute-select with the product id at the end.
Step 2:
Now create the configurable_list.js file that is going to handle and print the options on the select. Create this file in the js directory (we’ll place it directly in /js):

if(typeof Inchoo_Product =='undefined') {
    var Inchoo_Product  = {};
}
 
/**************************** CONFIGURABLE PRODUCT **************************/
Inchoo_Product.Config = Class.create();
Inchoo_Product.Config.prototype = {
    initialize: function(config){
        this.config     = config;
        this.taxConfig  = this.config.taxConfig;
        var settingsClassToSelect = '.super-attribute-select_'+this.config.productId;
        this.settings   = $$(settingsClassToSelect);
        this.state      = new Hash();
        this.priceTemplate = new Template(this.config.template);
        this.prices     = config.prices;
 
        this.settings.each(function(element){
            Event.observe(element, 'change', this.configure.bind(this))
        }.bind(this));
 
        // fill state
        this.settings.each(function(element){
            var attributeId = element.id.replace(/[a-z]*/, '');
            attributeId = attributeId.replace(/_.*/, '');
            if(attributeId && this.config.attributes[attributeId]) {
                element.config = this.config.attributes[attributeId];
                element.attributeId = attributeId;
                this.state[attributeId] = false;
            }
        }.bind(this))
 
        // Init settings dropdown
        var childSettings = [];
        for(var i=this.settings.length-1;i>=0;i--){
            var prevSetting = this.settings[i-1] ? this.settings[i-1] : false;
            var nextSetting = this.settings[i+1] ? this.settings[i+1] : false;
            if(i==0){
                this.fillSelect(this.settings[i])
            }
            else {
                this.settings[i].disabled=true;
            }
            $(this.settings[i]).childSettings = childSettings.clone();
            $(this.settings[i]).prevSetting   = prevSetting;
            $(this.settings[i]).nextSetting   = nextSetting;
            childSettings.push(this.settings[i]);
        }
 
        // Set default values - from config and overwrite them by url values
        if (config.defaultValues) {
            this.values = config.defaultValues;
        }
 
        var separatorIndex = window.location.href.indexOf('#');
        if (separatorIndex != -1) {
            var paramsStr = window.location.href.substr(separatorIndex+1);
            var urlValues = paramsStr.toQueryParams();
            if (!this.values) {
                this.values = {};
            }
            for (var i in urlValues) {
                this.values[i] = urlValues[i];
            }
        }
 
        this.configureForValues();
        document.observe("dom:loaded", this.configureForValues.bind(this));
    },
 
    configureForValues: function () {
        if (this.values) {
            this.settings.each(function(element){
                var attributeId = element.attributeId;
                element.value = (typeof(this.values[attributeId]) == 'undefined')? '' : this.values[attributeId];
                this.configureElement(element);
            }.bind(this));
        }
    },
 
    configure: function(event){
        var element = Event.element(event);
        this.configureElement(element);
    },
 
    configureElement : function(element) {
        this.reloadOptionLabels(element);
        if(element.value){
            this.state[element.config.id] = element.value;
            if(element.nextSetting){
                element.nextSetting.disabled = false;
                this.fillSelect(element.nextSetting);
                this.resetChildren(element.nextSetting);
            }
        }
        else {
            this.resetChildren(element);
        }
        //this.reloadPrice();
//      Calculator.updatePrice();
    },
 
    reloadOptionLabels: function(element){
        var selectedPrice;
        if(element.options[element.selectedIndex].config){
            selectedPrice = parseFloat(element.options[element.selectedIndex].config.price)
        }
        else{
            selectedPrice = 0;
        }
        for(var i=0;i<element.options.length;i++){
            if(element.options&#91;i&#93;.config){
                element.options&#91;i&#93;.text = this.getOptionLabel(element.options&#91;i&#93;.config, element.options&#91;i&#93;.config.price-selectedPrice);
            }
        }
    },
 
    resetChildren : function(element){
        if(element.childSettings) {
            for(var i=0;i<element.childSettings.length;i++){
                element.childSettings&#91;i&#93;.selectedIndex = 0;
                element.childSettings&#91;i&#93;.disabled = true;
                if(element.config){
                    this.state&#91;element.config.id&#93; = false;
                }
            }
        }
    },
 
    fillSelect: function(element){
        var attributeId = element.id.replace(/&#91;a-z&#93;*/, '');
        attributeId = attributeId.replace(/_.*/, '');
        var options = this.getAttributeOptions(attributeId);
        this.clearSelect(element);
        element.options&#91;0&#93; = new Option(this.config.chooseText, '');
 
        var prevConfig = false;
        if(element.prevSetting){
            prevConfig = element.prevSetting.options&#91;element.prevSetting.selectedIndex&#93;;
        }
 
        if(options) {
            var index = 1;
            for(var i=0;i<options.length;i++){
                var allowedProducts = &#91;&#93;;
                if(prevConfig) {
                    for(var j=0;j<options&#91;i&#93;.products.length;j++){
                        if(prevConfig.config.allowedProducts
                            && prevConfig.config.allowedProducts.indexOf(options&#91;i&#93;.products&#91;j&#93;)>-1){
                            allowedProducts.push(options[i].products[j]);
                        }
                    }
                } else {
                    allowedProducts = options[i].products.clone();
                }
 
                if(allowedProducts.size()>0){
                    options[i].allowedProducts = allowedProducts;
                    element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
                    element.options[index].config = options[i];
                    index++;
                }
            }
        }
    },
 
    getOptionLabel: function(option, price){
        var price = parseFloat(price);
        if (this.taxConfig.includeTax) {
            var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
            var excl = price - tax;
            var incl = excl*(1+(this.taxConfig.currentTax/100));
        } else {
            var tax = price * (this.taxConfig.currentTax / 100);
            var excl = price;
            var incl = excl + tax;
        }
 
        if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
            price = incl;
        } else {
            price = excl;
        }
 
        var str = option.label;
        if(price){
            if (this.taxConfig.showBothPrices) {
                str+= ' ' + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')';
            } else {
                str+= ' ' + this.formatPrice(price, true);
            }
        }
        return str;
    },
 
    formatPrice: function(price, showSign){
        var str = '';
        price = parseFloat(price);
        if(showSign){
            if(price<0){
                str+= '-';
                price = -price;
            }
            else{
                str+= '+';
            }
        }
 
        var roundedPrice = (Math.round(price*100)/100).toString();
 
        if (this.prices && this.prices&#91;roundedPrice&#93;) {
            str+= this.prices&#91;roundedPrice&#93;;
        }
        else {
            str+= this.priceTemplate.evaluate({price:price.toFixed(2)});
        }
        return str;
    },
 
    clearSelect: function(element){
        for(var i=element.options.length-1;i>=0;i--){
            element.remove(i);
        }
    },
 
    getAttributeOptions: function(attributeId){
        if(this.config.attributes[attributeId]){
            return this.config.attributes[attributeId].options;
        }
    },
 
    reloadPrice: function(){
        var price    = 0;
        var oldPrice = 0;
        for(var i=this.settings.length-1;i>=0;i--){
            var selected = this.settings[i].options[this.settings[i].selectedIndex];
            if(selected.config){
                price    += parseFloat(selected.config.price);
                oldPrice += parseFloat(selected.config.oldPrice);
            }
        }
 
        optionsPrice.changePrice('config', {'price': price, 'oldPrice': oldPrice});
        optionsPrice.reload();
 
        return price;
 
        if($('product-price-'+this.config.productId)){
            $('product-price-'+this.config.productId).innerHTML = price;
        }
        this.reloadOldPrice();
    },
 
    reloadOldPrice: function(){
        if ($('old-price-'+this.config.productId)) {
 
            var price = parseFloat(this.config.oldPrice);
            for(var i=this.settings.length-1;i>=0;i--){
                var selected = this.settings[i].options[this.settings[i].selectedIndex];
                if(selected.config){
                    price+= parseFloat(selected.config.price);
                }
            }
            if (price < 0)
                price = 0;
            price = this.formatPrice(price);
 
            if($('old-price-'+this.config.productId)){
                $('old-price-'+this.config.productId).innerHTML = price;
            }
 
        }
    }
}
&#91;/code&#93;
Step 3:
In order to load the configurable_list.js file when browsing a category we need to add it into the head block in the catalog.xml file. So now open the catalog.xml of your theme and look for thetag. There we now add the js file. Simply add the following lines inside it:
&#91;code language="xml"&#93;
<reference name="head">
      <action method="addJs"><script>configurable_list.js</script></action>
</reference>

Step 4:
At this point we have prepared our layout to handle the configurable options block. The only thing that lasts is… that configurable block. We cannot add it to the catalog.xml file, because each configurable block will be different than the previous one (and adding it through the xml layout will show always the same block with the same options). To solve this, we need to dynamically create a block in the phtml file. Simply add these lines before the add to cart button in the catalog/product/list of your theme:

<?php Mage::unregister('product') ?>
<?php Mage::register('product', $_product); ?>
<?php if ( $_product->getTypeId() == 'configurable'): ?>
    <?php echo $this->getLayout()->createBlock('catalog/product_view_type_configurable', '', array('template'=> 'catalog/product/view/type/configurable_category.phtml'))->toHtml(); ?>
<?php endif; ?>

Step 5:
At this point, if you load your category product list, you should be the configurable product options and also select them. But the add to cart button won’t use them when adding the product to the cart. By default there is no form tag, but we need to add it to the list.phtml file, inside the foreach loop, concretly inside the div class=”actions”:

<div class="actions">
    <?php if($_product->isSaleable()): ?>
    <form action="<?php echo $this->helper('checkout/cart')->getAddUrl($_product) ?>" method="post" id="product_addtocart_form" <?php if($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>>
    <?php Mage::unregister('product') ?>
    <?php Mage::register('product', $_product); ?>
     <?php if ( $_product->getTypeId() == 'configurable'): ?>
 
            <?php echo $this->getLayout()->createBlock('catalog/product_view_type_configurable', '', array('template'=> 'catalog/product/view/type/configurable_category.phtml'))->toHtml(); ?>
        <?php endif; ?>
        <button type="submit" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
    <?php else: ?>
        <?php if ($_product->getIsSalable()): ?>
            <p class="availability in-stock"><span><?php echo $this->__('In stock') ?></span></p>
        <?php else: ?>
            <p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
        <?php endif; ?>
    <?php endif; ?>
        <ul class="add-to-links">
            <?php if ($this->helper('wishlist')->isAllow()) : ?>
                <li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
            <?php endif; ?>
            <?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
                <li><a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
            <?php endif; ?>
        </ul>
    </form>
</div>


Categories: Magento

1 Comment

smmuntha · August 17, 2017 at 1:13 am

Hi Sushant
where to put the html and JS files for Magento 2 Age verification popup ? please let me know. cheers

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *