Magento Custom Attribute Rendering Through Observer In Admin Customer Account Section By Custom Script

This magento tutorial explains about creating an attribute which is responsible to render the dynamic input grid in admin.

You can see this grid in tier price attribute in admin product edit page where you can add multiple tier prices for multiple customer groups.
Step 1 - We will create first a module registration file named as Namespace_Customer.xml
Location: app/etc/modules/Mynamespace_Customer.xml

<?xml version="1.0"?>
<config>
<modules>
<Mynamespace_Customer>
<active>true</active>
<codePool>local</codePool>
</Mynamespace_Customer>
</modules>
</config>

Step 2 - We will create our module configuration file to add a model observer file and sql setup script to create our custom attribute.
Location: app/code/local/Mynamespace/Customer/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Mynamespace_Customer>
<version>0.0.1</version>
</Mynamespace_Customer>
</modules>
<global>
<blocks>
<mynamespace_customer>
<class>Mynamespace_Customer_Block</class>
</mynamespace_customer>
</blocks>
<resources>
<mynamespace_customer_setup>
<setup>
<module>Mynamespace_Customer</module>
<class>Mynamespace_Customer_Model_Resource_Setup</class>
</setup>
</mynamespace_customer_setup>
</resources>
</global>
<adminhtml>
<events>
<adminhtml_block_html_before>
<observers>
<custom_attr_append>
<type>model</type>
<class>Mynamespace_Customer_Model_Observer</class>
<method>appendCustomAttribute</method>
</custom_attr_append>
</observers>
</adminhtml_block_html_before>
</events>
</adminhtml>
</config>

Step 3 - Now we will create our sql setup scipt to create our custom attribute with following code.
Location: app/code/local/Mynamespace/Customer/sql/mynamespace_customer_setup/mysql4-install-0.0.1.php

<?php
//app/code/local/NameSpace/ModuleName/sql/namespace_modulename_setup/install-0.0.1.php
/* @var $installer NameSpace_ModuleName_Model_Resource_Setup */
$installer = $this;

$installer->startSetup();

$customerEntityTypeId = $installer->getEntityTypeId('customer');
$atttributeCode = 'attribute_code';

$installer->removeAttribute($customerEntityTypeId, $atttributeCode );
$installer->addAttribute('customer', $atttributeCode, array(
'type' => 'varchar',
'input' => 'text',
'label' => 'Attribute Name',
'input_renderer' => 'mynamespace_customer/customer_edit_renderer_attribute_test',
'global' => true,
'visible' => true,
'required' => false,
'user_defined' => true,
'visible_on_front' => true
));

//the values can be taken from customer_form_attribute table
$usedInCustomerAddressForms = array(
'adminhtml_customer',
'customer_account_create',
'checkout_register',
'customer_account_edit',
'adminhtml_checkout'
);

$attribute = Mage::getSingleton('eav/config')->getAttribute('customer', $attributeCode);
$attribute->setData('used_in_forms', $usedInCustomerAddressForms)
->setData("is_used_for_customer_segment", true)
->setData("is_system", 0)
->setData("is_user_defined", 1)
->setData("is_visible", 1)
->setData("sort_order", 100);
$attribute->save();

$this->endSetup();
?>

Step 4 - Create a model class file to run our custom module sql setup script properly
Location: app/code/local/Mynamespace/Customer/Model/Resource/Setup.php

<?php
class Mynamespace_Customer_Model_Resource_Setup
extends Mage_Customer_Model_Resource_Setup
{
//add code here if you want to extend default resource setup
}
?>

Step 5 - Create a renderer block class file to render our custom template for dynamic attribute display and functioning.
Location: app/code/local/Mynamespace/Customer/Block/Customer/Edit/Renderer/Attribute/Test.php

<?php
class Mynamespace_Customer_Block_Customer_Edit_Renderer_Attribute_Test
extends Mage_Adminhtml_Block_Widget_Form_Renderer_Fieldset_Element
{
/**
* Override parent constructor just for setting custom template
*/
protected function _construct()
{
parent::_construct();
$this->setTemplate('mynamespace_customer/edit/tab/account/form/renderer/test.phtml');
}

}
?>

Step 6 - Create a custom template file to display our custom dynamic grid with following code.
Location: app/design/adminhtml/default/default/template/mynamespace_customer/edit/tab/account/form/renderer/test.phtml

<?php
/** @var $this Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Price_Group */
$_htmlId = $this->getElement()->getHtmlId();
$_htmlClass = $this->getElement()->getClass();
$_htmlName = $this->getElement()->getName();
$_readonly = $this->getElement()->getReadonly();
?>
<tr>
<td class="label"><?php echo $this->getElement()->getLabel(); ?></td>
<td colspan="10" class="grid tier">
<table cellspacing="0" class="data border" id="group_prices_table">
<col width="120" />
<col />
<col width="1" />
<thead>
<tr class="headings">
<th><?php echo Mage::helper('catalog')->__('test1'); ?></th>
<th><?php echo Mage::helper('catalog')->__('test2'); ?></th>
<th class="last"><?php echo Mage::helper('catalog')->__('test3'); ?></th>
</tr>
</thead>
<tbody id="<?php echo $_htmlId; ?>_container"></tbody>
<tfoot>
<tr>
<td colspan="4" class="a-right"><?php echo $this->getLayout()->createBlock('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Price_Group')->getAddButtonHtml(); ?></td>
</tr>
</tfoot>
</table>

<script type="text/javascript">
//<![CDATA[
var groupPriceRowTemplate = '<tr>'
+ '<td><input class="<?php echo $_htmlClass; ?> required-entry" type="text" name="<?php echo $_htmlName; ?>[{{index}}][test1]" value="{{test1}}" id="attibute_code_{{index}}_test1" /></td>'
+ '<td><input class="<?php echo $_htmlClass; ?> required-entry" type="text" name="<?php echo $_htmlName; ?>[{{index}}][test2]" value="{{test2}}" id="attibute_code_{{index}}_test2" /></td>'
+ '<td><input class="<?php echo $_htmlClass; ?> required-entry" type="text" name="<?php echo $_htmlName; ?>[{{index}}][test3]" value="{{test3}}" id="attibute_code_{{index}}_test3" /></td>'
+ '<td class="last"><input type="hidden" name="<?php echo $_htmlName; ?>[{{index}}][delete]" class="delete" value="" id="group_price_row_{{index}}_delete" />'
+ '<button title="<?php echo $this->jsQuoteEscape(Mage::helper('catalog')->__('Delete Attibute')); ?>" type="button" class="scalable delete icon-btn delete-product-option" id="attibute_code_{{index}}_delete_button" onclick="return groupPriceControl.deleteItem(event);">'
+ '<span><?php echo $this->jsQuoteEscape(Mage::helper('catalog')->__('Delete')); ?></span></button></td>'
+ '</tr>';

var groupPriceControl = {
template: new Template(groupPriceRowTemplate, new RegExp('(^|.|\r|\n)({{\s*(\w+)\s*}})', '')),
itemsCount: 0,
addItem : function () {
<?php if ($_readonly): ?>
if (arguments.length < 3) {
return;
}
<?php endif; ?>
var data = {
readOnly: false,
index: this.itemsCount++
};

if (arguments.length == 4) {
data.readOnly = arguments[3];
}

Element.insert($('<?php echo $_htmlId; ?>_container'), {
bottom : this.template.evaluate(data)
});

<?php if ($_readonly): ?>
$('<?php echo $_htmlId; ?>_container').select('input', 'select').each(this.disableElement);
$('<?php echo $_htmlId; ?>_container').up('table').select('button').each(this.disableElement);
<?php else: ?>
$('<?php echo $_htmlId; ?>_container').select('input', 'select').each(function(element) {
Event.observe(element, 'change', element.setHasChanges.bind(element));
});
<?php endif; ?>
},
disableElement: function(element) {
element.disabled = true;
element.addClassName('disabled');
},
deleteItem: function(event) {
var tr = Event.findElement(event, 'tr');
if (tr) {
Element.select(tr, '.delete').each(function(element) {
element.value='1';
});
Element.select(tr, ['input', 'select']).each(function(element) {
element.hide();
});
Element.hide(tr);
Element.addClassName(tr, 'no-display template');
}
return false;
}
};
<?php foreach ($this->getValues() as $_item) : ?>
groupPriceControl.addItem('<?php echo $_item['website_id']; ?>', '<?php echo $_item['cust_group']; ?>', '<?php echo sprintf('%.2f', $_item['price']); ?>', <?php echo (int)!empty($_item['readonly']); ?>);
<?php endforeach; ?>
<?php if ($_readonly) : ?>
$('<?php echo $_htmlId; ?>_container').up('table').select('button')
.each(groupPriceControl.disableElement);
<?php endif; ?>
//]]>
</script>
</td></tr>


Step 7 - Lastly Create a magento model observer to add our attribute to form on Customer Account section with following code.
Location: app/code/local/Mynamespace/Customer/Model/Observer.php

<?php

class Mynamespace_Customer_Model_Observer
{
/**
*
* @param Varien_Event_Observer $observer
* @return Mynamespace_Customer_Model_Observer
*/
public function appendCustomAttribute(Varien_Event_Observer $observer)
{
$block = $observer->getBlock();
if (!isset($block)) {
return $this;
}

if ($block->getType() == 'adminhtml/customer_edit_tab_account') {
$form = $block->getForm();
$form->getElement('attribute_code')->setRenderer($block->getLayout()
->createBlock('mynamespace_customer/customer_edit_renderer_attribute_test'));
}
}
}
?>
That's it! you have created your custom module with custom attribute rendering with observer on adminhtml event.
 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s