5

I have a custom admin grid that shows grid data from a custom table. One of the fields in this custom table is "status" which is added to the grid with the following values and function.

$this->addColumn('status', array(
  'header'    => Mage::helper('ifactory_schoollist')->__('Status'),
  'align'     =>'left',
  'index'     => 'status',
  'type'      => 'options',
  'options'   => array('1' => 'Draft', '2' => 'Awaiting Approval', '3' => 'Live', '4' => 'Archived'),
  'filter_condition_callback' => array($this, '_filterStatusCondition')
));

If the row is set to "Draft", "Awaiting Approval" or "Live" it should show and be filterable/searchable as normal. However if the row is set to "Archived" I do not want it to show up unless the user has explicity filtered for "Archived" rows.

My first attempt at this was to filter the collection in the _prepareCollection function like this.

$collection->addFieldToFilter("status", array("neq" => '4'));

This hides it correctly but does not let the user see them if they search for archived rows.

I then tried adding a default filter in _prepareCollection

$this->setDefaultFilter(array('status' => array("1","2","3")));

Along with a custom filter_condition_callback for the column

protected function _filterStatusCondition($collection, $column)
{
  $value = $column->getFilter()->getValue();
  if(!$value) {
    return;
  }

  if(is_array($value)){
    $this->getCollection()->addFieldToFilter('status', array('in' => $value));
  } else {
    $this->getCollection()->addFieldToFilter('status', $value);
  }
}

This worked initially only showing the non-archived columns but letting you filter to show any specific status. However whenever you search by another field or reset filters you lose the default filter arrow and archived results show up again.

I tried adjusting the filter_condition_callback function to counter this but it doesn't seem to be being called when you reset filters or leave the status blank.

protected function _filterStatusCondition($collection, $column)
{
  echo "test a";
  $value = $column->getFilter()->getValue();
  if(!$value) {
    // return;
    $value = array("1","2","3"); // if no value given filter default values
  }

  if(is_array($value)){
    $this->getCollection()->addFieldToFilter('status', array('in' => $value));
  } else {
    $this->getCollection()->addFieldToFilter('status', $value);
  }
}

3 Answers 3

8

Try this.
Lose the filter_condition_callback on the column. You need to focus on the _prepareCollection method.

protected function _prepareCollection() {
    $collection = ....;
    ....
    $canShowArchive = false;
    //check if there is a filter.
    $filter = $this->getParam($this->getVarNameFilter(), null);
    //if there is a filter, check if the filter contains the status
    if (!is_null($filter))  {
         //decode the filter
         $filter = $this->helper('adminhtml')->prepareFilterString($filter);
         if (isset($filter['status'])) {
              //if there is a filter by status you may need to show the archive items 
              $canShowArchive = true;
         }
    }
    //if $canShowArchive is false, just filter the collection by status not equal to 'archive'
    if (!$canShowArchive) {
        $collection->addFieldToFilter('status', array('neq'=>4));
    }
    $this->setCollection($collection);
    return parent::_prepareCollection();
}

The code above is not tested but it seams like the way to go.

1
  • I use the above and fitering works fine but its not setting collection after filtering the data, event when i print the collection its show filtered data but when setCollection called its not setting the data in collection and grid shows empty. Commented Sep 21, 2015 at 10:26
1

Just an option. What if you move archived items in the separate grid on a new page? Probably for archive customer also need different field set, like "archive date" or "moved to archive by user"

0

Yes. If one wants to join eav_attribute_option_value table to filtering option value, one can use below code.

$this->addColumn(
        'product_manufacturer',
        [
            'header' => __('Manufacturer'),
            'index' => 'manufacturer',
            'filter_condition_callback' => [$this, 'filterCustomManufacturer'],
            'header_css_class' => 'col-manufacturer',
            'column_css_class' => 'col-manufacturer'
        ]
    );

Below add filter condition callback function including joins like,

protected function filterCustomManufacturer($collection, $column)
{
    if (!$value = $column->getFilter()->getValue()) {
        return $this;
    }

    $collection->getSelect()->joinLeft(array('c_p_e_i'=>'catalog_product_entity_int'),
    'e.row_id = c_p_e_i.row_id',array('value'));

    $collection->getSelect()->joinLeft(array('attribute_option'=>'eav_attribute_option_value'),
    'c_p_e_i.value = attribute_option.option_id and attribute_option.store_id = 0',
     array('eaov_val'=>'value' , 'eaov_option'=>'option_id'));

     $collection->getSelect()->where("`attribute_option`.`value` like ?", "%$value%");

    return $this;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.