Magento Tips & Tricks

Magento category attributes dependency

There is no default way to create dependent category attributes in magento admin. Dependency can be easily added to system configuration inputs or custom magento forms, but not for category attributes.

We are going to create simple attribute dependency by adding new input renderer for attribute. It will work this way:
You have several attributes:
– my_attribute
– my_attribute_text
– my_attribute_select

Note that they all start from my_attribute.
First attribute has boolean type. When it is set to true – other attributes that start from my_attribute is visible.

Source can be found on Github

1. How to add category attribute ?

Adding new category attribute is pretty easy task, but it require several steps.

First you need to tell magento that your extension will use install script. Add this code in extension config app/code/community/Company/Extension/etc/config.xml

<config>
	...
	<global>
		...
		<resources>
			<company_extension_setup>
				<setup>
					<module>Company_Extension</module>
					<class>Mage_Catalog_Model_Resource_Setup</class>
				</setup>
				<connection>
					<use>core_setup</use>
				</connection>
			</company_extension_setup>
		</resources>
	</global>
	...
</config>

Second you need to create install script and add following code
app/code/community/Company/Extension/sql/company_extension_setup\mysql4-install-1.0.0.php

<?php
$this->startSetup();
...
$this->addAttribute('catalog_category', 'feature', array(

	'group' => 'My group',
	'position' => 300,

	'type' => 'int',
	'input' => 'select',
	'source'   => 'eav/entity_attribute_source_boolean',
	
	'label' => 'Feature status',
	'note' => "Attribute comment here",

	'backend' => '',
	'visible' => 1,
	'required' => 0,
	'visible_on_front' => 1,
	'wysiwyg_enabled' => 1,
	'is_html_allowed_on_front'	=> 1,
	'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,

));

$this->addAttribute('catalog_category', 'feature_text', array(

	'group' => 'My group',
	'position' => 300,

	'type' => 'text',
	'input' => 'textarea',
	
	'label' => 'Feature text',
	'note' => "Attribute comment here",

	'backend' => '',
	'visible' => 1,
	'required' => 0,
	'visible_on_front' => 1,
	'wysiwyg_enabled' => 1,
	'is_html_allowed_on_front'	=> 1,
	'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,

));
...
$this->endSetup();

More information about creating category attributes can be found here:
http://www.atwix.com/magento/add-category-attribute/
http://inchoo.net/magento/how-to-add-new-custom-category-attribute-in-magento/

2. Add our input renderer

Now we will create new input renderer class to inject our javascript.
app/code/community/Company/Extension/Block/Adminhtml/Catalog/Category/Dependency.php

<?php

class Company_Extension_Block_Adminhtml_Catalog_Category_Dependency extends Varien_Data_Form_Element_Select
{
	/**
	 * Retrieve Element HTML fragment
	 *
	 * @return string
	 */
	public function getElementHtml()
	{
		$this->setData('after_element_html', sprintf('<script>new categoryAttributeDependency("%s");</script>', $this->getHtmlId()));
		return parent::getElementHtml();
	}
}

3. Create dependency javascript class and add it to admin layout.

Create new file called js/company/category_attribute_dependency.js
It will create new class that will track for attribute state and show / hide other attributes based on main attribute value.

categoryAttributeDependency = Class.create();

categoryAttributeDependency.prototype = {

	initialize: function (htmlId) {
		this.element = $(htmlId);
		this.dependentElements = $$("[id^="+htmlId+"]");
		this.refreshView();
		this.bindEvents();
	},

	bindEvents: function () {
		Event.observe(this.element, "change", this.refreshView.bind(this));
		Event.observe(this.element, "keyup", this.refreshView.bind(this));
		Event.observe(this.element, "keydown", this.refreshView.bind(this));
	},

	refreshView: function () {
		var that = this;
		this.dependentElements.each(function(el){
			if (that.element.id != el.id) {
				if (that.element.value == '1') {
					el.up(1).show();
				} else {
					el.up(1).hide();
				}
			}
		});
	}
};

4. Add javascript to admin layout

– declare our layout xml updates in extension config

	<adminhtml>
		<layout>
			<updates>
				<extension>
					<file>company/extension.xml</file>
				</extension>
			</updates>
		</layout>
	</adminhtml>

– create app/design/adminhtml/default/default/layout/company/extension.xml

<?xml version="1.0"?>
<layout version="0.1.1">

	<adminhtml_catalog_category_edit>
		<reference name="head">
			<action method="addJs"><file>company/category_attribute_dependency.js</file></action>
		</reference>
	</adminhtml_catalog_category_edit>

</layout>

5. Update install script to add our input renderer

$this->addAttribute('catalog_category', 'feature', array(

	'group' => 'My group',
	'position' => 300,

	'type' => 'int',
	'input' => 'select',
	'source'   => 'eav/entity_attribute_source_boolean',
	'input_renderer' => 'extension/adminhtml_catalog_category_dependency',
	
	'label' => 'Feature status',
	'note' => "Attribute comment here",

	'backend' => '',
	'visible' => 1,
	'required' => 0,
	'visible_on_front' => 1,
	'wysiwyg_enabled' => 1,
	'is_html_allowed_on_front'	=> 1,
	'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,

));

6. Cache issues

You might now see your new attributes on category edit page. In this case you can manually run reindex ( System > Index Management ). Or you can modify install script to reindex data programmatically

//reindex new attributes
$process = Mage::getModel('index/indexer')->getProcessByCode('catalog_category_flat');
$process->reindexAll();

More info on magento reindex process can be found here
http://www.kennydeckers.com/magento-programatically-reindexing-indexes/
http://www.codetweet.com/magento/reindexing-magento-programmaticaly/

Congratulations

You’re done. Source can be found on Github

Troubleshooting

If you want to reinstall the extension or remove category attributes – you can use following SQL

DELETE from `eav_attribute` where attribute_code like 'feature%';
DELETE from `core_resource` where code = 'company_extension_setup';

License

Our freebies are released under the terms of the MIT license.

The MIT License is simple and easy to understand and it places almost no restrictions on what you can do with our freebie item.

You are allowed to: use any NWDthemes freebie plugin in your project (even commercial projects) as long as the copyright header is left intact.

You MUST NOT:
Provide our freebies on any other site as is.
Sell our freebies.

8 thoughts on “Magento category attributes dependency

  1. Nice tutorial! A couple points:

    For setup class, it’s generally recommended to use your own, rather than rely on another module. In your setup script you then use the class which makes sense, e.g.:

    $installer = Mage::getResourceModel('catalog/setup','catalog_setup');

    This is an academic point though, as the Catalog setup class is unlikely to go away. If you want to couple your module to the Catalog setup class it would make more sense to specify Mage_Catalog_Model_Resource_Setup rather than Mage_Catalog_Model_Resource_Eav_Mysql4_Setup though.

    The other point is regarding the MIT license. AFAIK (might be mistaken) your restrictions (“You MUST NOT…”) are meaningless if your code is MIT licensed. In any event, you need to add the actual MIT license to your repository.

    Thanks for putting this out there, I’m sure that many will find it helpful.

    • Thanks for the comment.

      Update code to use Mage_Catalog_Model_Resource_Setup

      Regarding license – you might be right. I will check it

    • This tutorial is for categories. I would advise you to start debugging from mysql install script

      $this->addAttribute(‘catalog_category’

  2. This is a great Tutorial, however how to call this new attributes in view.phtml or front end?
    How to add image attribute for multiple images for a slider or gallery

    • Code is the same as for other attributes. Say you have attribute called “custom_attr”.

      $categoryObj = Mage::getModel('catalog/category')->load(5);
      $categoryObj ->getCustomAttr();
      $categoryObj ->getData('custom_attr');

      Adding attribute for multiple images is beyong the scope of this tutorial

  3. How to filter “feature” attribute and check if is enable by admin user
    I did something like this but its not working.
    $categoryObj ->addAttributeToFilter(‘feature’, 1)
    Please let me know thanks

    • If you are trying to use code from previous comment – it wont work since it works with single object. You need to use category collection.

      $collection = Mage::getModel("catalog/category")
          ->getCollection()
          ->addAttributeToSelect("*")
          ->addAttributeToFilter("feature", 1);

Leave a Reply

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