0

How to add new dropdown field, next to the position field of bundle item like shown in the below screenshot.

enter image description here

1

In order to create new dropdown field next to position, we will create new module for it or add code in any of your custom module. Do whatever is easy for you. Here our field name is "is fixed bundle" with "Yes/No" option.

We will do following things in that module-

  1. Will create a custom table for new dropdown field and values will be stored in that table when product get saved using observer.

  2. We rewrite block/template file that is responsible to render new field, can use that value on frontend by loading it from custom table.

Lets create module step by step -

STEP 1 : Create app/code/local/Yourpackage/Yourmodule/etc/config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Yourpackage_Yourmodule>
            <version>0.1.0</version>
        </Yourpackage_Yourmodule>
    </modules>
    <global>
        <blocks>
            <bundle>
                <rewrite>
                    <adminhtml_catalog_product_edit_tab_bundle_option>Yourpackage_Yourmodule_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option</adminhtml_catalog_product_edit_tab_bundle_option>
                </rewrite>
            </bundle>
        </blocks>
        <models>
            <yourmodule>
                <class>Yourpackage_Yourmodule_Model</class>
                <resourceModel>yourmodule_mysql4</resourceModel>
            </yourmodule>
            <yourmodule_mysql4>
                <class>Yourpackage_Yourmodule_Model_Mysql4</class>
                <entities>
                    <fixedbundle>
                        <table>catalog_product_bundle_option_fixedbundle</table>
                    </fixedbundle>
                </entities>
            </yourmodule_mysql4>
        </models>
        <resources>
            <yourmodule_setup>
                <setup>
                    <module>Yourpackage_Yourmodule</module>
                    <class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
                </setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </yourmodule_setup>
            <yourmodule_write>
                <connection>
                    <use>core_write</use>
                </connection>
            </yourmodule_write>
            <yourmodule_read>
                <connection>
                    <use>core_read</use>
                </connection>
            </yourmodule_read>
        </resources>
    </global>
    <adminhtml>
        <events>
            <catalog_product_save_commit_after>
                <observers>
                    <custom_field_observer>
                        <type>singleton</type>
                        <class>Yourpackage_Yourmodule_Model_Observer</class>
                        <method>SaveDropdownAfterProductSave</method>
                    </custom_field_observer>
                </observers>
            </catalog_product_save_commit_after>
        </events> 
    </adminhtml>
</config>

In this file we added an event and rewrite magento block. This configuration file also contains details of custom table catalog_product_bundle_option_fixedbundle .

STEP 2 : Now create sql script to create table in path - app/code/local/Yourpackage/Yourmodule/sql/yourmodule_setup/mysql4-install-0.1.0.php

<?php
$installer=$this;
$installer->startSetup();

$installer->run("
-- DROP TABLE IF EXISTS {$this->getTable('yourmodule/fixedbundle')};
CREATE TABLE {$this->getTable('yourmodule/fixedbundle')} (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `store_id` int(11) NOT NULL default '0',
  `option_id` int(11) NOT NULL,
  `is_fixed_bundle` int(11) NOT NULL default '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    ");
$installer->endSetup();
?>

STEP 3 : Lets create model/collection for this table -

File1 : app/code/local/Yourpackage/Yourmodule/Model/Fixedbundle.php

<?php
class Yourpackage_Yourmodule_Model_Fixedbundle extends Mage_Core_Model_Abstract {

    public function _construct()
    {
        $this->_init('yourmodule/fixedbundle');
    }

}

File2: app/code/local/Yourpackage/Yourmodule/Model/Mysql4/Fixedbundle.php

<?php
class Yourpackage_Yourmodule_Model_Mysql4_Fixedbundle extends Mage_Core_Model_Mysql4_Abstract
{
    public function _construct()
    {
        $this->_init('yourmodule/fixedbundle', 'id');
    }
}

File3 : app/code/local/Yourpackage/Yourmodule/Model/Mysql4/Fixedbundle/Collection.php

<?php
class Yourpackage_Yourmodule_Model_Mysql4_Fixedbundle_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
    protected function _construct(){
        $this->_init('yourmodule/fixedbundle');
    }
}

STEP 4 : Now we need to rewrite block, that render the bundle options. The block is app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php

Create File - app/code/local/Yourpackage/Yourmodule/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php

<?php
class Yourpackage_Yourmodule_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option extends Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option
{
    public function getOptions()
    {
        if (!$this->_options) {
            $this->getProduct()->getTypeInstance(true)->setStoreFilter($this->getProduct()->getStoreId(),
                $this->getProduct());

            $optionCollection = $this->getProduct()->getTypeInstance(true)->getOptionsCollection($this->getProduct());

            $selectionCollection = $this->getProduct()->getTypeInstance(true)->getSelectionsCollection(
                $this->getProduct()->getTypeInstance(true)->getOptionsIds($this->getProduct()),
                $this->getProduct()
            );

            $this->_options = $optionCollection->appendSelections($selectionCollection);
            $storeId = $this->getProduct()->getData('store_id');
            foreach ($this->_options as $option) {
                //gets each option's id
                $option_id = $option->getData('option_id');
                $optionFixed = Mage::getModel('yourmodule/fixedbundle')->load($option_id, "option_id");
                if ($optionFixed->getId() != "") {
                    $id = (int)$optionFixed->getId();
                    $isFixedBundle = $optionFixed->getIsFixedBundle();
                    //adds our new datas to option
                    $option->addData(array('fixedbundle_id'=> $id, 'is_fixed_bundle' => $isFixedBundle, 'is_new'=> 'no'));
                } else {              
                    $option->addData(array('fixedbundle_id'=> '', 'is_fixed_bundle' => '', 'is_new'=> 'yes'));
                }
            }

            if ($this->getCanReadPrice() === false) {
                foreach ($this->_options as $option) {
                    if ($option->getSelections()) {
                        foreach ($option->getSelections() as $selection) {
                            $selection->setCanReadPrice($this->getCanReadPrice());
                            $selection->setCanEditPrice($this->getCanEditPrice());
                        }
                    }
                }
            }    
        }
        return $this->_options;
    }

    public function getIsFixedSelectHtml()
    {
        $options = array(
            array('value' => 0, 'label'=>Mage::helper('adminhtml')->__('No')),
            array('value' => 1, 'label'=>Mage::helper('adminhtml')->__('Yes')),
        );
        $select = $this->getLayout()->createBlock('adminhtml/html_select')
            ->setData(array(
                'id' => $this->getFieldId().'_{{index}}_is_fixed_bundle',
                'class' => 'select is-fixed-bundle-assigned-select'
            ))
            ->setName($this->getFieldName().'[{{index}}][is_fixed_bundle]')
            ->setOptions($options);
        return $select->getHtml();
    }

}

This getOption() method is use to include our module's data to the existing options of bundle items.

STEP 5 : Now modify a temple file that is used to display options-

app/design/adminhtml//bundle/product/edit/bundle/option.phtml

Here only modified part of template file is given.

<script type="text/javascript">
optionTemplate = '<div id="<?php echo $this->getFieldId() ?>_{{index}}"  class="option-box"> ' +
'<input id="fixedbundle_id" type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][fixedbundle_id]" value="{{fixedbundle_id}}" />'+
'<input id="is_new" type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][is_new]" value="{{is_new}}" />'+
'<div class="option-title"> ' +
    '<label for="<?php echo $this->getFieldName() ?>[{{index}}][title]"><?php echo $this->jsQuoteEscape(Mage::helper('bundle')->__('Default Title')) ?> <span class="required">*</span></label>' +
    <?php if ($this->isDefaultStore()): ?>
    '<input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_title" value="{{title}}">' +
    <?php else: ?>
    '<input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][default_title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_default_title" value="{{default_title}}">' +
    <?php endif; ?>
'<?php echo $this->jsQuoteEscape($this->getOptionDeleteButtonHtml()) ?>' +
'</div>' +
    '<table class="option-header" cellpadding="0" cellspacing="0">' +
        '<thead>' +
            '<tr>' +
                <?php if (!$this->isDefaultStore()): ?>
                '<th class="opt-title"><?php echo $this->jsQuoteEscape(Mage::helper('bundle')->__('Store View Title')) ?>  <span class="required">*</span></th>' +
                <?php endif; ?>
                '<th class="opt-type"><?php echo $this->jsQuoteEscape(Mage::helper('bundle')->__('Input Type')) ?></th>' +
                '<th class="opt-req"><?php echo $this->jsQuoteEscape(Mage::helper('bundle')->__('Is Required')) ?></th>' +
                '<th class="opt-order"><?php echo $this->jsQuoteEscape(Mage::helper('bundle')->__('Position')) ?></th>' +
                '<th class="opt-order is-fixed-bundle-assigned"><?php echo Mage::helper('bundle')->__('Is Fixed Bundle') ?></th>' +
                '<th>&nbsp;</th>' +
            '</tr>' +
        '</thead>' +
        '<tbody>' +
            '<tr>' +
                '<input type="hidden" id="<?php echo $this->getFieldId() ?>_id_{{index}}" name="<?php echo $this->getFieldName() ?>[{{index}}][option_id]" value="{{option_id}}">' +
                '<input type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][delete]" value="" class="delete">' +
                <?php if (!$this->isDefaultStore()): ?>
                '<td><input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_title_store" value="{{title}}"></td>' +
                <?php endif; ?>
                '<td><?php echo $this->getTypeSelectHtml() ?></td>' +
                '<td><?php echo $this->getRequireSelectHtml() ?></td>' +
                '<td><input class="input-text validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][position]" value="{{position}}"></td>' +
                '<td class="is-fixed-bundle-assigned"><?php echo $this->getIsFixedSelectHtml() ?></td>' +
                '<td>&nbsp;<?php echo $this->jsQuoteEscape($this->getAddSelectionButtonHtml()) ?></td>' +
            '</tr>' +
        '</tbody>' +
    '</table>' +
    '<div id="<?php echo $this->getFieldId() ?>_search_{{index}}">' +
    '</div>' +
'</div>';
</script>

In this template file we added a new field in table below the position field. Also added two hidden fields for internal use.

STEP 6 : Now create an observer that will save custom field value in table-

app/code/local/Yourpackage/Yourmodule/Model/Observer.php

<?php

class Yourpackage_Yourmodule_Model_Observer extends Mage_Core_Model_Abstract
{
    public function SaveDropdownAfterProductSave($observer)
    {   
        $product = Mage::registry('product');
        if (Mage::registry('catalog_product_save_commit_after' . $product->getId())) {
            return;
        }
        Mage::register('catalog_product_save_commit_after' . $product->getId(), true);
        $model = Mage::getModel('yourmodule/fixedbundle');
        $optionCollection =  $product->getTypeInstance(TRUE)->getOptionsCollection($product);        
        $bundleOptions = $product->getBundleOptionsData();   
        if (!empty($bundleOptions)) {
            $storeId = (int)$product->getData('store_id');
            foreach ($bundleOptions as $option) {
                $optionId = (int)$option['option_id'];
                $id = (int)$option['fixedbundle_id'];
                $isDeleted =  (int)$option['delete'];
                //use to set option_id for new options in our module
                if ($optionId <= 0 || $optionId == "" || is_null($optionId)) {
                    foreach ($optionCollection as $new) {
                        if($new['type'] == $option['type'] && ( $new['title'] == $option['title'] || $new['default_title'] == $option['title'] )){
                            $optionId = $new['option_id'];
                        }
                    }
                }
                $data = array(
                    'option_id' => $optionId,
                    'store_id' => $storeId,
                    'is_fixed_bundle' => $option['is_fixed_bundle']
                );
                $optionFixed = Mage::getModel('yourmodule/fixedbundle')->load($optionId, "option_id");
                // id exist means already there is an entry in custom table
                try {
                    if ($isDeleted == 1) {
                        $model->setId($id)->delete();
                    } else {
                        if ($optionFixed->getId() != ""){
                            $model->load($id);
                            $model->addData($data);
                            $model->setId($id)->save();
                        } else {
                            $model->setData($data);
                            $insertId =  $model->save()->getId();
                        }
                    }
                } catch (Exception $e) {
                    Mage::logException($e);
                }
            }
        }  
        return $this;
    }
}

That is it, our module is ready now. Clear your magento cache and open your bundle product in admin. You can see a dropdown field "is fixed bundle" next to the position field of bundle options.

Please note that this is a basic magento module, so don't forget to add any other required file of module like app/etc/Yourpackage_Yourmodule.xml, Helper if needed.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.