2

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>
  • Would you mind posting the controller actions for deleteMass and updateMass – philwinkle May 30 '13 at 16:19
  • updated the post. cheers. – bennoislost May 30 '13 at 16:32
  • "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.." - What exactly is your problem? – Fabian Blechschmidt May 30 '13 at 20:25
  • First try this one: remove $this->setSaveParametersInSession(true); from your grid constructor. If you don't use the grid somewhere else this is not really useful. If that doesn't work please post the layout section for the grid action. I mean the xml layout for <adminhtml_..._swatchrequest_grid> or however you defined it. – Marius May 31 '13 at 7:00
  • Hi Marius, I removed $this->setSaveParamatersInSession(true) from my grid _construct() method with the following results... the delete and update mass actions worked without a filter applied. when a filter was applied (to any column) none of the mass actions worked an re-directed to the adminhtml dashboard, where as before if a filter was applied on the second++ attempt a mass action would work.. seems like the form data was being stored in the session?! – bennoislost May 31 '13 at 7:42
1

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.)

  • hi marius, that had no effect on the outcome :( I had to change my _construct method to __construct but when a filter is applied it redirects to the dashboard on the first attempt still. thanks for your help. – bennoislost Jun 3 '13 at 8:29
  • did you try also to revmove $this->setUseAjax(true); or to set this to $this->setUseAjax(false);. Also make sure you clear the cache after changing the layout file. – Marius Jun 3 '13 at 8:35
  • that seemed to do the trick! i removed the getGridUrl() method from Grid.php along with your recommendations. thank you for your help! Do you know why setUseAjax(true) is an issue? It seems to work fine in /app/code/core/Mage/Adminhtml/Block/Catalog/Product/Grid.php? – bennoislost Jun 3 '13 at 10:27
  • Actually setUseAjax is not an issue. For some reason it does not work for you. Magento uses a form_key parameter for all POST requests to avoid CSRF. In your case, after the first ajax filter this form key was lost. That's why you get redirected to the dashboard and that's why I recommended changing the layout...so Magento will be able to insert the form_key block in the ajax response. But for some reason it didn't work for you. I don't know why. – Marius Jun 3 '13 at 10:31
  • thanks again. have you got any resources you could share to get filtering with setUseAjax? – bennoislost Jun 3 '13 at 10:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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