使用Magento Admin Grid中的MySQL计算值过滤文本类型列

时间:2012-03-02 08:40:32

标签: filter magento

假设网格中的一列已计算出值:

setCollection()

'refunded' => new Zend_Db_Expr("IF(qty_refunded > 0, 'Yes', 'No')"),

_prepareColumns()

$this->addColumnAfter('refunded', array(
    'header' => Mage::helper('helper')->__('Refunded'),
    'index'  => 'refunded',
    'type'   => 'text',
), 'qty');

如果管理员类型为“是”然后过滤,那么为了使列具有“是”值,必须进行哪些更改以及如何进行更改?

2 个答案:

答案 0 :(得分:5)

Adminhtml网格列有一个filter属性,用于指定块类。对于布尔值是/否通常为adminhtml/widget_grid_column_filter_select的字段 如果您的字段类型为“选项”,它将自动使用。

_prepareCollection()中尝试此操作:

'refunded' => new Zend_Db_Expr("IF(qty_refunded > 0, 1, 0)"),

_prepareColumns()中使用:

$this->addColumnAfter('refunded', array(
    'header'  => Mage::helper('helper')->__('Refunded'),
    'index'   => 'refunded',
    'type'    => 'options',
    'options' => array(0 => $this->__('No'), 1 => $this->__('Yes'))
), 'qty');

这仍然应该在列中将您的值呈现为“是”和“否”,并且您将获得具有适当选项的选择作为过滤器下拉列表。

仅凭这一点是不够的,因为具有计算值的列不能由MySQL在WHERE子句中直接引用。 Magento提供了两种解决方案。

列过滤器块有一个方法getCondition(),它返回一个条件,用于过滤集合。有关示例,请参阅Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Abstract::getCondition() 因此,如果您需要自定义用于执行过滤器的SQL,请创建自己的扩展Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Select的列过滤器块并根据需要调整返回的条件,即使用相同的计算值进行匹配。
您可以在addColumn()定义中为列指定自定义过滤器:

    'type'    => 'options',
    'options' => array(0 => $this->__('No'), 1 => $this->__('Yes')),
    'filter'  => 'your_module/adminhtml_widget_grid_column_filter_custom',

如果您喜欢在Magento的ORM过滤器语法限制之外工作,可以使用过滤器回调直接修改集合选择:

    'type'    => 'options',
    'options' => array(0 => $this->__('No'), 1 => $this->__('Yes')),
    'filter_condition_callback' => array($this, '_applyMyFilter'),

回调接收集合和列作为参数。这是该方法的一个简单示例:

protected function _applyMyFilter(Varien_Data_Collection_Db $collection, Mage_Adminhtml_Block_Widget_Grid_Column $column)
{
    $select = $collection->getSelect();
    $field = $column->getIndex();
    $value = $column->getFilter()->getValue();
    $select->having("$field=?, $value);
}

毋庸置疑,两种方法(针对计算值进行过滤)在MySQL中效率非常低。但在这种情况下,也许对你来说没问题。

答案 1 :(得分:0)

我会发布一个有效的例子,但我会选择Vinai的答案,因为它非常详细。

在Grid.php中:

protected function _addColumnFilterToCollection($column) 
{
    if ($column->getId() == 'refunded' && $column->getFilter()->getValue()) {
        $val        = $column->getFilter()->getValue();
        $comparison = ($val === "No") ? 'lteq' : 'gt'; // lteg: <=; gt: >

        $this->getCollection()->addFieldToFilter('ois.qty_refunded', array($comparison => 0));
    } else {
        parent::_addColumnFilterToCollection($column);
    }

    return $this;
}