Question

I'm having some problems when using a mass action when a filter is applied to a grid block...

After a user has tried the mass action with the filter applied (once or twice) the mass action begins to work?!

When no filter is applied to the grid the mass actions work as expected..

Mage v1.6.2, All Caches off with Dev mode on..

Any help or tips appreciated

Below is my grid block app/code/local/NS/Swatchrequest/Block/Adminhtml/Swatchrequest/Grid.php or Code Gist

further below are the controller actions updateMassAction + deleteMassAction

EDIT: see layout xml right at the bottom

Ben

/**
 * Class Group path for Resource Collection
 */
const RESOURCE_COLLECTION = 'baddass_swatchrequest/swatchrequest_collection';

/**
 * Prepare base grid
 */
protected function _construct()
{
    parent::_construct();

    $this->setId('baddass_swatchrequest_swatchrequest');
    $this->setDefaultSort('created_at');

    /**
     * @TODO: Why??
     */
    $this->setSaveParametersInSession(true);

    $this->setUseAjax(true);
}

/**
 * Grid URL for AJAX request
 *
 * @return string
 */
public function getGridUrl()
{
    return $this->getUrl('*/*/grid', array('_current' => true));
}

/**
 * Assign Swatchrequest collection to grid block
 *
 * @return this
 */
protected function _prepareCollection()
{
    /**
     * @var Baddass_Swatchrequest_Model_Resource_Swatchrequest_Collection
     */
    $collection = Mage::getResourceModel(self::RESOURCE_COLLECTION);
    $this->setCollection($collection);

    return parent::_prepareCollection();
}

/**
 * Required to filter collection
 *
 * @TODO: really?
 * @param $column
 * @return $this
 */
protected function _addColumnFilterToCollection($column)
{
    return parent::_addColumnFilterToCollection($column);
}

/**
 * From Collection define columns and Export types
 *
 * @return $this
 */
protected function _prepareColumns()
{
    $this->addColumn('id', array(
        'header' => $this->__('ID'),
        'index' => 'entity_id',
        'sortable' => true,
        'width' => '60px'
    ));

    $this->addColumn('email', array(
        'header' => $this->__('Customer Email'),
        'index' => 'email',
    ));

    $this->addColumn('created_at', array(
        'header' => $this->__('Created'),
        'type' =>'datetime',
        'index' => 'created_at'
    ));

    $this->addColumn('name', array(
        'header' => $this->__('Customer Name'),
        'index' => 'name',
    ));

    $this->addColumn('product_name', array(
        'header' => $this->__('Product Name'),
        'index' => 'product_name',
    ));

    $this->addColumn('address', array(
        'header' => $this->__('Address Name'),
        'index' => 'address',
    ));

    $this->addColumn('status', array(
        'header' => $this->__('Status'),
        'width' => '120',
        'align' => 'left',
        'index' => 'delivered_status',
        'type' => 'options',
        'options'   => array(
            0 => $this->__('Not Delivered'),
            1 => $this->__('Delivered')
        ),
        'frame_callback' => array(
            $this, 'decorateStatus'
        )
    ));

    $this->addExportType('*/*/exportCsv', $this->__('CSV'));
    $this->addExportType('*/*/exportXml', $this->__('XML'));

    return parent::_prepareColumns();
}

/**
 * @return Mage_Adminhtml_Block_Widget_Grid
 */
protected function _prepareMassaction()
{
    $this->setMassactionIdField('id');
    $this->getMassactionBlock()->setFormFieldName('swatchrequests');

    // delete en mass
    $this->getMassactionBlock()->addItem('delete', array(
        'label' => $this->__('Delete'),
        'url' => $this->getUrl('*/*/deleteMass'),
        'confirm' => $this->__('Are you sure?')
    ));

    // update delivered status en mass
    $this->getMassactionBlock()->addItem('status', array(
        'label' => $this->__('Delivery Status'),
        'url' => $this->getUrl('*/*/updateMass'),
        'additional' => array(
            'visibility' => array(
                'name' => 'delivered_status',
                'type' => 'select',
                'class' => 'required-entry',
                'label' => $this->__('Status'),
                'values' => array(
                    array(
                        'label' => 'Not Delivered',
                        'value' => 0
                    ),
                    array(
                        'label' => 'Delivered',
                        'value' => 1
                    )
                )
            )
        )
    ));

    return parent::_prepareMassaction();
}

/**
 * Get editable URL
 *
 * @param $row      Row in collection
 * @return string
 */
public function getRowUrl($row)
{
    return $this->getUrl('*/*/edit', array(
        'id' => $row->getId()
    ));
}

/**
 * Decorate Delivery Status column with a Badge
 *
 * @param $value    Value for $row
 * @param $row      Row in collection
 * @param $column
 * @param $isExport
 * @return string
 */
public function decorateStatus($value, $row, $column, $isExport)
{
    $cell = '<span class="grid-severity-critical"><span>' . $value . '</span></span>';

    if($row->getDeliveredStatus() == 1) {
        $cell = '<span class="grid-severity-notice"><span>' . $value . '</span></span>';
    }

    return $cell;
}

controller actions...

public function deleteMassAction()
{
    if($data = $this->getRequest()->getPost('swatchrequests')) {
        $deleted = array();

        $model = Mage::getModel('baddass_swatchrequest/swatchrequest');

        foreach((array) $data as $id) {
            $model->setId($id)->delete();
            $deleted[] = $id;
        }

        $this
            ->_getSession()
            ->addSuccess($this->__("Deleted Swatch Requests with ID's %s", implode(',', $deleted)));
    }

    $this->_redirect('*/*/');
}

public function updateMassAction()
{
    if($records = $this->getRequest()->getPost('swatchrequests')) {

        $delivered_status = (int) $this->getRequest()->getPost('delivered_status');
        $model = Mage::getModel('baddass_swatchrequest/swatchrequest');

        try {
            foreach((array) $records as $id) {
                $model->load($id);
                $model->setDeliveredStatus($delivered_status);
                $model->save();
            }

            $this
                ->_getSession()
                ->addSuccess($this->__('%s Swatch Requests updated', count($records)));
        }
        catch(Mage_Core_Model_Exception $e) {
            $this->_getSession()->addError($e->getMessage());
        }
        catch(Mage_Core_Exception $e) {
            $this->_getSession()->addError($e->getMessage());
        }
        catch(Exception $e) {
            $this
                ->_getSession()
                ->addException($e, $this->__('An error occurred while updating the product(s) status.'));
        }
    }

    $this->_redirect('*/*/');
}

Layout xml.

<?xml version="1.0" encoding="UTF-8"?>
<layout>
    <adminhtml_swatchrequest_list>
        <reference name="content">
            <block type="baddass_swatchrequest/adminhtml_swatchrequest" name="swatchrequest"/>
        </reference>
    </adminhtml_swatchrequest_list>
    <adminhtml_swatchrequest_grid>
        <block type="baddass_swatchrequest/adminhtml_swatchrequest_grid" name="ajax_grid" output="toHtml"/>
    </adminhtml_swatchrequest_grid>
    <adminhtml_swatchrequest_edit>
        <reference name="content">
            <block type="baddass_swatchrequest/adminhtml_swatchrequest_edit" name="baddass_swatchrequest_edit" />
        </reference>
    </adminhtml_swatchrequest_edit>
</layout>
Was it helpful?

Solution

I think the problem comes from the layout file (at least it was for me some time ago, that's why I asked for the layout code). Mainly this:

<adminhtml_swatchrequest_grid>
    <block type="baddass_swatchrequest/adminhtml_swatchrequest_grid" name="ajax_grid" output="toHtml"/>
</adminhtml_swatchrequest_grid>

The block should have a wrapper around it.

<adminhtml_swatchrequest_grid>
    <block type="core/text_list" name="root" output="toHtml">
        <block type="baddass_swatchrequest/adminhtml_swatchrequest_grid" name="ajax_grid"/>
    </block>
  </adminhtml_swatchrequest_grid>

This allows Magento to add the block that contains the form_key to the response of the ajax request. The form_key is required for all POST requests. That's why the mass action didn't work after filtering, because you didn't have anymore the form_key.
You can also put back $this->setSaveParamatersInSession(true) (I realized is not relevant. I wanted to refer to $this->setUseAjax(true);. Stupid mistake. Sorry.)

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top