Условие фильтра сетки Magento по умолчанию исключает определенное значение поля


У меня есть пользовательская сетка администратора, в которой отображаются данные таблицы из пользовательской таблицы. Одним из полей в этой пользовательской таблице является "статус", который добавляется в сетку со следующими значениями и функциями.

$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')
));

Если для строки установлено значение "Черновик", "Ожидает утверждения" или "В режиме реального времени", она должна отображаться и быть фильтруемой/доступной для поиска в обычном режиме. Однако, если для строки установлено значение "Заархивировано", я не хочу, чтобы она отображалась, если только пользователь не отфильтровал явность для "Заархивированных" строк.

Мой первый попытка сделать это состояла в том, чтобы отфильтровать коллекцию в функции _prepareCollection следующим образом.

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

Это скрывает их правильно, но не позволяет пользователю видеть их, если они ищут заархивированные строки.

Затем я попытался добавить фильтр по умолчанию в _prepareCollection

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

Вместе с пользовательским фильтром_condition_callback для столбца

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);
  }
}

Первоначально это работало, показывая только неархивированные столбцы, но позволяя вам фильтровать, чтобы показать любой конкретный статус. Однако всякий раз, когда при поиске по другому полю или сбросе фильтров стрелка фильтра по умолчанию теряется, и архивированные результаты отображаются снова.

Я попытался настроить функцию filter_condition_callback, чтобы противостоять этому, но, похоже, она не вызывается, когда вы сбрасываете фильтры или оставляете статус пустым.

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);
  }
}
Author: Typhado, 2014-08-07

3 answers

Попробуйте это.
Потеряйте filter_condition_callback в столбце. Вам нужно сосредоточиться на методе _prepareCollection.

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();
}

Приведенный выше код не тестировался, но он выглядит так, как нужно.

 8
Author: Marius, 2014-08-07 08:10:35

Просто вариант. Что делать, если вы переместите архивированные элементы в отдельную сетку на новой странице? Возможно, для клиента архива также потребуется другой набор полей, например "дата архива" или "перемещено в архив пользователем"

 1
Author: Amasty, 2014-08-07 08:31:35

Да. Если кто-то хочет присоединить таблицу eav_attribute_option_value к значению параметра фильтрации, можно использовать приведенный ниже код.

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

Ниже добавьте функцию обратного вызова условия фильтра, включая соединения, такие как

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;
}
 0
Author: Kazim Noorani, 2018-06-13 07:02:13