Back to blog home

Magento Chooser Widget in add / edit admin forms

Recently I worked on a Magento task that required to create a product chooser in generic Magento admin edit form. Recently I played with the admin widget type "Catalog Product Link" and I was reminded that we already have a built-in product chooser.

I decided to reuse the logic from the admin widget classes to complete the task. I met some difficulties, because I had to extend Mage_Widget_Block_Adminhtml_Widget_Options, but this creates too many dependencies with the Mage_Widget extension, and I also noticed some visual differences which were not desired. Finally after some reverse engineering and deep look in Mage_Widget_Block_Adminhtml_Widget_Options, Mage_Adminhtml_Block_Catalog_Product_Widget_Chooser and the layout handle "editor" I found a solution that gives me the ability to easily create widget choosers in generic Magento admin forms. I even went further than the initial idea and created a helper class that gives the ability to create the following choosers:

  • Product Chooser
  • Category Chooser
  • CMS Page Chooser
  • Static Block Chooser
  • Custom Chooser

 

The solution is packed in extension Jarlssen_ChooserWidget and you can download it from here: https://github.com/Jarlssen/Jarlssen_ChooserWidget

Basically, when you use this module you will be able to create chooser buttons in the admin forms and after pressing the button you will see a popup similar to:

How to use

First you need to install Jarlssen_ChooserWidget. Also it’s a good idea to create dependency to Jarlssen_ChooserWidget in your custom extension:

<?xml version="1.0"?>
<config>
    <modules>
        <My_CustomExtension>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Jarlssen_ChooserWidget/>
            </depends>
        </My_CustomExtension>
    </modules>
</config>

 

There are 4 important things you need to do to make the chooser work:

  1. It's required to add in the layout update a handle called "editor". This handle includes the JS logic that is needed to render the chooser popups
  2. After that in method _prepareForm() of your admin form you need to have an instance of helper 'jarlssen_chooser_widget/chooser' and pass some parameters to the function creating the chooser.
  3. Use any of the chooser create functions of Jarlssen_ChooserWidget_Helper_Chooser:
    • createProductChooser
    • createCategoryChooser
    • createCmsPageChooser
    • createCmsBlockChooser
    • createChooser
  4. There is a required config value called "input_name" and must be passed to the chooser through a configuration array.

 

The function creating the chooser accepts the following parameters:

  • $model - instance of Mage_Core_Model_Abstract - the current entity
  • $fieldset - instance of Varien_Data_Form_Element_Fieldset - It’s required, because we create the chooser in this fieldset
  • $config - array of the widget configuration, the element “input_name” is required, because this is the name of the field name, that we save after form submit.
  • $blockAlias - this parameter is used only when we invoke Jarlssen_ChooserWidget_Helper_Chooser::createChooser and it’s useful for creating our own custom chooser

 

The array $config also can contain more elements, but they are not mandatory:

  • 'input_label' - The text of the input label
  • 'button_text' - The text of the chooser button
  • 'required' - If it’s true, then we will have frontend validation and to pass it we need to choose something from the chooser

Example of config array:


$categoryConfig = array(
    'input_name'  => 'entity_link',
    'input_label' => $this->__('Product'),
    'button_text' => $this->__('Select Product...'),
    'required'    => true
);

 

Code Examples

Product Chooser:

Code


$chooserHelper = Mage::helper('jarlssen_chooser_widget/chooser');

$productConfig = array(
    'input_name'  => 'entity_link',
    'input_label' => $this->__('Product'),
    'button_text' => $this->__('Select Product...'),
    'required'    => true
);

$chooserHelper->createCategoryChooser($model, $fieldset, $productConfig);

 

Screenshot

Category Chooser:

Code

$chooserHelper = Mage::helper('jarlssen_chooser_widget/chooser');

$categoryConfig = array(
    'input_name'  => 'entity_link',
    'input_label' => $this->__('Category'),
    'button_text' => $this->__('Select Category...'),
    'required'    => true
);

$chooserHelper->createProductChooser($model, $fieldset, $categoryConfig);

Screenshot

Static Block Chooser:

Code


$chooserHelper = Mage::helper('jarlssen_chooser_widget/chooser');

$blockConfig = array(
    'input_name'  => 'entity_link',
    'input_label' => $this->__('Block'),
    'button_text' => $this->__('Select Block...'),
    'required'    => true
);

$chooserHelper->createCmsBlockChooser($model, $fieldset, $blockConfig);

Screenshot

Example for CMS Page Chooser:

Code

$chooserHelper = Mage::helper('jarlssen_chooser_widget/chooser');

$cmsPageConfig = array(
    'input_name'  => 'entity_link',
    'input_label' => $this->__('CMS Page'),
    'button_text' => $this->__('Select CMS Page…'),
    'required'    => true
);

$chooserHelper->createCmsPageChooser($model, $fieldset, $cmsPageConfig);

Screenshot

Example for Custom Chooser:

Code

$chooserHelper = Mage::helper('jarlssen_chooser_widget/chooser');

$customChooserConfig = array(
    'input_name'  => 'entity_link',
    'input_label' => $this->__('Custom entity'),
    'button_text' => $this->__('Select entity…'),
    'required'    => true
);

$chooserBlock = 'custom_module/chooser';

$chooserHelper->createChooser($model, $fieldset, $customChooserConfig, chooserBlock);

Screenshot

 

Data representation

The table below represents the values we store in a hidden input, after we choose an entity from the chooser popup.

We also need to save these values in the DB in the same format which the chooser generates, because later the chooser will need these values, e.g. to render the product name.

 

We also need to save these values in the DB in the same format which the chooser generates, because later the chooser will need these values, e.g. to render the product name.

Facts

  • If the layout handle "editor" is not included in the layout update, the module will throw exception
  • If "input_name" is not set in $config array, then the module will throw exception
  • All $config elements, that are not mandatory have placeholders that are defined in config.xml of the chooser module
<config>
    ...........
    ...........
    ...........
    <default>
        <jarlssen_chooser_widget>
            <chooser_defaults>
                <catalog_product_widget_chooser>
                    <input_label>Product</input_label>
                    <button_text>Select Product...</button_text>
                </catalog_product_widget_chooser>
                <catalog_category_widget_chooser>
                    <input_label>Category</input_label>
                    <button_text>Select Category...</button_text>
                </catalog_category_widget_chooser>
                <cms_block_widget_chooser>
                    <input_label>Block</input_label>
                    <button_text>Select Block...</button_text>
                </cms_block_widget_chooser>
                <cms_page_widget_chooser>
                    <input_label>CMS Page</input_label>
                    <button_text>Select CMS Page…</button_text>
                </cms_page_widget_chooser>
                <default>
                    <input_label>Element</input_label>
                    <button_text>Select...</button_text>
                </default>
            </chooser_defaults>
        </jarlssen_chooser_widget>
    </default>

</config>

 

Proof reading by Oliver Baumann. Thanks!