Category dropdown element

To get an treelike drop-down option field for all existing categories in the system you have yo add an own source model:

<?php
/**
 *
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * It is  available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 *
 *
 * @category   Sheldon
 * @package    Sheldon_Package
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 * @author     Marcel Lange (info@ask-sheldon.com)
 *
 * Sourcemodel for productcategoryselection in module configuration
 */
class Sheldon_Package_Model_Adminhtml_Source_Product_Category {

    /**
     * Systemconfiguration - Category select
     * @return array
     */
    public function toOptionArray($bAddEmpty = true)
    {

        $oCategoryCollection = Mage::getResourceModel('catalog/category_collection');

        $oCategoryCollection->addAttributeToSelect('name')
            ->addAttributeToSelect('is_active')
            ->addAttributeToSelect('parent_id')
            ->setStoreId($iStoreId)
            ->addFieldToFilter('parent_id', array('gt' => 0))
            ->addFieldToFilter('is_active', 1)
            ->addFieldToFilter('level', array('gteq' => 1)) //Don't display root categories
            ->addAttributeToSelect('position', 'ASC');

        $aOptions = array();

        if ($bAddEmpty) {
            $aOptions[] = array(
                'label' => Mage::helper('adminhtml')->__('-- Please Select a Category --'),
                'value' => ''
            );
        }
        foreach ($oCategoryCollection as $oCategory) {
            $sLabel = " {$oCategory->getName()} (ID: {$oCategory->getId()})";

            /*
                Let's draw som '-' before the name depending on the
                category depth (two '-' for each level)

                Result in a select option:
                Category
                -- CategoryA
                ---- CategoryB
                ------ CategoryC
                -- CategoryD
                ---- CategoryE
            */

            $iPadWidth = ($oCategory->getLevel() - 1) * 2 + strlen($sLabel);
            $sLabel = str_pad($sLabel, $iPadWidth, '-', STR_PAD_LEFT); //pad the '-' to the left side

            $aOptions[] = array(
                'label' => $sLabel,
                'value' => $oCategory->getId()
            );
        }

        return $aOptions;
    }
}

Now you can just use this source model in your modules system configuration file to generate a category selection:

<fields>
    <categories>
        <label>Sale Categories</label>
        <frontend_type>multiselect</frontend_type>
        <source_model>sheldon_package/adminhtml_source_product_category</source_model>
        <sort_order>10</sort_order>
        <comment><![CDATA[Select categories]]></comment>
        <show_in_default>1</show_in_default>
        <validate>validate-one-required</validate>
    </categories>
</fields>

For more information about system.xml field definitions have a look at the blogpost System configuration fields.

Leave a Reply

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

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.