将<optgroup>应用于gride过滤器下拉列表</optgroup>时出现Magento问题

时间:2014-12-24 08:30:56

标签: magento

我在网格过滤器中有一个类别列。我需要添加到该类别列下拉列表中。我也创建了一个类型类,但是当在prepareColumn函数中调用时,那些没有应用。创建列如下所示:

$options = Mage::getModel('productsync/categorymapping_system_config_source_catalog_categorypaths')
                    ->toOptionArray();


    $this->addColumn(
        'category',
        array(
            'header'   => Mage::helper('productsync')->__('Category'),
            'width'    => '1',
            'type'     => 'options',
            'index'    => 'category_id',
            'editable' => true,
            'options'  => $options,
            'renderer' => 'productsync/adminhtml_categorymapping_widget_grid_column_renderer_options',
            'filter_condition_callback'
                            => array($this, '_filterCategoriesCondition'),
        )
    );

任何人都可以告诉我这是什么问题。

谢谢

1 个答案:

答案 0 :(得分:0)

问题出在Magento的 Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Select 类和 Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Options 类中。

回顾一下Filter类的getHtml()方法,看起来他们确实编写了这个方法,期望支持<optgroup>,但是他们失败的地方是该类的_getOptions()方法。在这里我们可以看到,无论选项数据的格式是什么,它们都将它构建成二维数组。在您的情况下,我假设您的选项已经采用包含“标签”,“值”的格式您的$options变量的结构。

另一方面,Magento的Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Options类似乎从未编写过支持使用optgroup的选项。

为了解决这个问题,我们可以用一些额外的逻辑重写这些类,以支持我们正在寻找的东西。

注意:您没有包含有关您指定的渲染器类的任何信息(adminhtml_categorymapping_widget_grid_column_renderer_options),因此我不确定您对该类与其他任何网格分开的操作“选项”类型的列。我的解决方案只允许这种类型的列支持选项组。

第1步:创建我们的扩展定义文件: app/code/etc/modules/StackOverflow_Question27633881.xml

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

第2步:创建扩展程序的配置文件,其中包含重写上述两个Mage类的说明: app/code/local/StackOverflow/Question27633881/etc/config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <StackOverflow_Question27633881>
            <version>1.0.0</version>
        </StackOverflow_Question27633881>
    </modules>
    <global>
        <blocks>
            <!-- Rewrites -->
            <adminhtml>
                <rewrite>
                   <widget_grid_column_filter_select>StackOverflow_Question27633881_Block_Adminhtml_Widget_Grid_Column_Filter_Select</widget_grid_column_filter_select>
                   <widget_grid_column_renderer_options>StackOverflow_Question27633881_Block_Adminhtml_Widget_Grid_Column_Renderer_Options</widget_grid_column_renderer_options>
                </rewrite>
            </adminhtml>
        </blocks>
    </global>
</config>

第3步:使用更新的逻辑创建新的过滤器类 app/code/local/StackOverflow/Question27633881/Block/Adminhtml/Widget/Grid/Column/Filter/Select.php

<?php
class StackOverflow_Question27633881_Block_Adminhtml_Widget_Grid_Column_Filter_Select
    extends Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Select
{
    /**
     * (non-PHPdoc)
     * @see Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Select::_getOptions()
     */
    protected function _getOptions()
    {
        $emptyOption = array('value' => null, 'label' => '');

        $optionGroups = $this->getColumn()->getOptionGroups();
        if ($optionGroups) {
            array_unshift($optionGroups, $emptyOption);
            return $optionGroups;
        }

        $colOptions = $this->getColumn()->getOptions();

        // Options have already been setup in a way that is "label" / "value" format. Don't mess with it any further
        if (isset($colOptions[0]) && isset($colOptions[0]['label'])) {
            return $colOptions;
        }

        if (!empty($colOptions) && is_array($colOptions) ) {
            $options = array($emptyOption);
            foreach ($colOptions as $value => $label) {
                $options[] = array('value' => $value, 'label' => $label);
            }
            return $options;
        }
        return array();
    }
}

第4步:使用更新的逻辑创建新的渲染类: app/code/local/StackOverflow/Question27633881/Block/Adminhtml/Widget/Grid/Column/Renderer/Options.php

<?php
class StackOverflow_Question27633881_Block_Adminhtml_Widget_Grid_Column_Renderer_Options
    extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Options
{
    /**
     * Render a grid cell as options
     *
     * @param Varien_Object $row
     * @return string
     */
    public function render(Varien_Object $row)
    {
        $options = $this->getColumn()->getOptions();
        $showMissingOptionValues = (bool)$this->getColumn()->getShowMissingOptionValues();
        if (!empty($options) && is_array($options)) {

            // Call our new function if necessary.
            if (   isset($options[0]) && isset($options[0]['value'])
                || isset($options[1]) && isset($options[1]['value'])
            ) {
                $options = $this->_getFlatOptions($options);
            }

            $value = $row->getData($this->getColumn()->getIndex());

            if (is_array($value)) {
                $res = array();
                foreach ($value as $item) {
                    if (isset($options[$item])) {
                        $res[] = $this->escapeHtml($options[$item]);
                    }
                    elseif ($showMissingOptionValues) {
                        $res[] = $this->escapeHtml($item);
                    }
                }
                return implode(', ', $res);
            } elseif (isset($options[$value])) {
                return $this->escapeHtml($options[$value]);
            } elseif (in_array($value, $options)) {
                return $this->escapeHtml($value);
            }
        }
    }

    /**
     * Our new function that will turn a set of options with option groups, to a flat array of options.
     *
     * @param array $grouped_options
     */
    protected function _getFlatOptions($grouped_options)
    {
        $options = array();

        foreach ($grouped_options as $option) {
            if ('' == $option['value'] || null === $option['value']) {
                continue;
            }

            if (is_string($option['value'])) {
                $options[$option['value']] = $option['label'];
            } elseif (is_array($option['value'])) {
                foreach ($option['value'] as $opt) {
                    $options[$opt['value']] = $opt['label'];
                }
            }
        }

        return $options;
    }
}

然后,如果启用了Magento的Configuration缓存类型,请将其刷新。