6

In my Grid.php of custom module, I added the following code (excerpt) to enable mass action.

protected function _prepareMassaction(){
    $this->setMassactionIdField('entity_id');
    $this->getMassactionBlock()->setFormFieldName('some_thing');
    // options code here
    return $this;
}

I want the checkboxes of mass action to be checked by default for some items based on a variable which holds the field entity_id of the items in an array.

I am trying to show the checked items as shown in the below image even after page reload:

enter image description here

How to do this?

  • why the downvote? did I miss anything to explain? – Mr_Green May 2 '14 at 7:41
  • This is actually a good question. Here is an upvote to compensate. – Marius May 2 '14 at 7:44
  • Thanks Marius, and sorry for not using your UMC as we here having merge issues. which we will solve soon. – Mr_Green May 2 '14 at 7:46
  • You don't need to say sorry. I'm not saying that UMC is good for everything. :) I don't think it can help you with this. – Marius May 2 '14 at 7:48
  • @Marius just now realized.. I think you implemented this feature in UMC when the relation is many to many. because Just now I checked on of your UMC created custom module and found that the checkbox is checked for some products. Please check this screenshot. I am trying to figure it out now.. – Mr_Green May 4 '14 at 17:43
6
+50

If I have understood what you want, which I hope I have. You are looking for a filtered list of products where there is a checkbox for associated product that will be checked when associated and will stay checked even on page reload etc.

For this I would suggest looking at how Magento itself does it and the best place to see this is in the Associated products tab on the product edit screen in the admin section.

Firstly how does Magento assign the current selection to the gird. Well we can see this in the construct of Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Group with the following lines.

if ($this->_getProduct()->getId()) {
    $this->setDefaultFilter(array('in_products'=>1));
}

Here Magento checks for a currenlty set product, Mage::registry('current_product');, and if we have one then is sets some default filters to the grid.

Now lets look a bit into these filters. It sets that the filter in_products => 1 but what does that actually mean. Well we can see it being used in the function _addColumnFilterToCollection where here it checks the column for type in_products and when this is set then it will get the selected products and add them as filters. If you follow were this function is called it should be called at some point as part of the _prepareCollection code.

$productIds = $this->_getSelectedProducts();
if (empty($productIds)) {
    $productIds = 0;
}
if ($column->getFilter()->getValue()) {
    $this->getCollection()->addFieldToFilter('entity_id', array('in'=>$productIds));
}
else {
    $this->getCollection()->addFieldToFilter('entity_id', array('nin'=>$productIds));
}

Where Magento gets the selected products looks like the following.

protected function _getSelectedProducts()
{
    $products = $this->getProductsGrouped();
    if (!is_array($products)) {
        $products = array_keys($this->getSelectedGroupedProducts());
    }
    return $products;
}

The column itself is simply added with the rest of the columns in the grid with the following lines.

$this->addColumn('in_products', array(
    'header_css_class' => 'a-center',
    'type'      => 'checkbox',
    'name'      => 'in_products',
    'values'    => $this->_getSelectedProducts(),
    'align'     => 'center',
    'index'     => 'entity_id'
));

So to summarise we need to do the following.

  1. Add the column as if it is a normal column in the grid,
  2. On construct set the default filters,
  3. During the _addColumnFilterToCollection check to see if the column is our in_products column and add our custom filter.
  4. ???
  5. PROFIT!!!

I hope this helps with your development.

  • yup working fine :) Thanks alot.. but I kept only $this->setDefaultFilter(array('in_products'=>1)); with no if condition because I don't have a product in register. will that be a headache in future? – Mr_Green May 7 '14 at 11:14
  • and also as you might have observed, I was calling the save action through _prepareMassAction. As now I removed this how to call the save action? – Mr_Green May 7 '14 at 11:16
  • @Mr_Green as for your first point, I cannot see a problem with this. For the second one do you not have a controller action for the save part of this? – David Manners May 7 '14 at 11:22
  • I have controller action, but how to call it? before I was calling it through _prepareMassAction (which is now deleted) with '*/*/massSave'. please check the complete function code here. – Mr_Green May 7 '14 at 11:27
  • Just found that if we write $this->_addButton('save', array('label'=> 'Save')); in Mage_Adminhtml_Block_Widget_Grid_Container extended class, I am getting a button. which is exactly what I want. but now How should I call my massSaveAction method from controller on this button? Please help in this.. – Mr_Green May 7 '14 at 11:41
2

I found something that might help with keeping your massaction block with selected values :

In Mage_Adminhtml_Block_Widget_Grid the method _prepareMassactionColumn() sets the column for massaction. Note that there is no 'values' field defined for the column.

Then there is this line :

$massactionColumn->setSelected($this->getMassactionBlock()->getSelected())
            ->setGrid($this)
            ->setId($columnId);

Which sets the selected value based on the return of the getSelected() method of the massaction block. This methods checks params in the request with the key defined in $this->getMassactionBlock()->setFormFieldName('xxxxx');.

If you do not want to override the massaction block class or use the request for your checked values, you can do the following :

protected function _prepareMassactionColumn() {
    parent::_prepareMassactionColumn();
    $this->_columns['massaction']->setValues($arrayofvalues);
    return $this;
}

Override the _prepareMassactionColumn() method from the Grid class and manually set the values for the massaction column. The massaction column is always named 'massaction', it is defined "magically" in the _prepareMassactionColumn() method.

But that is not enough ! Because the javascript of the massaction object takes as a third argument the selected elements in the following format : value1,value2,value3,.... It takes it using the massaction block method getSelectedJson() which, you might guess, takes the values from the query ! A that point if you do not want to override the method in the massaction class and you have an access to the template file including your grid, you can use javascript to set the massaction values :

<?php $grid = $this->getChild('my-grid'); ?>
<?php echo $grid->getMassactionBlock()->getJsObjectName(); ?>.checkedString = '<?php echo join(',', $arrayofvalues); ?>';
<?php echo $grid->getMassactionBlock()->getJsObjectName(); ?>.checkCheckboxes();
  • I think what you see im chrome is the same as in firefox. Chrome tries to remember checked and unchecked checkboxes, if we wrongly reload a page – Fabian Blechschmidt Sep 30 '14 at 9:40
  • 1
    True, i also found out that the tag is set with checked="checked" in Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Checkbox; if you replace it by checked alone it works – Bouni Sep 30 '14 at 9:55
1

This is what @DavidManners suggested me and it is working fine for me.

In Grid.php of your Module

<?php
class Your_Class_Name_Here extends Mage_Adminhtml_Block_Widget_Grid
{
    public function __construct()
    {
        parent::__construct();
        /* other construct calling code here */
        $this->setDefaultFilter(array('in_products'=>1));
    }
    protected function _prepareCollection()
    {
        $collection = null; /* collection code here */
        $this->setCollection($collection);
        parent::_prepareCollection();
        return $this;
    }
    protected function _prepareColumns()
    {
        // Code like assigning variables for helpers and currency here

        $this->addColumn('in_products', array(
            'header_css_class' => 'a-center',
            'type'      => 'checkbox',
            'name'      => 'in_products',
            'values'    => $this->_getSelectedProducts(),
            'align'     => 'center',
            'index'     => 'entity_id'
        ));

        /* Add other columns here */
        return parent::_prepareColumns();
    }

    protected function _addColumnFilterToCollection($column)
    {
        // Set custom filter for in product flag
        if ($column->getId() == 'in_products') {
            $productIds = $this->_getSelectedProducts();
            if (empty($productIds)) {
                $productIds = 0;
            }
            if ($column->getFilter()->getValue()) {
                $this->getCollection()->addFieldToFilter('entity_id', array('in'=>$productIds));
            }
            else {
                $this->getCollection()->addFieldToFilter('entity_id', array('nin'=>$productIds));
            }
        }
        else {
            parent::_addColumnFilterToCollection($column);
        }

        return $this;
    }

    protected function _getSelectedProducts(){
        /* prepare the array values here and return it. */
    }

    /* other functions here */
}
0

For instance this function will work on the products set as enabled, you can update in admin based on any attribute as per your requirement.

In app\code\core\Mage\Adminhtml\Block\Catalog\Product Grid.php file, update function massAction

$this->setMassactionIdField('entity_id'); 
$this->getMassactionBlock()->setFormFieldName('product');

$this->getMassactionBlock()->addItem('delete', array( 
'label'=> Mage::helper('catalog')->__('Delete'), 
'url' => $this->getUrl('*/*/massDelete'), 
'confirm' => Mage::helper('catalog')->__('Are you sure?') 
));

 $statuses = Mage::getSingleton('catalog/product_status')->getOptionArray();

 array_unshift($statuses, array('label'=>'', 'value'=>'')); 
 $this->getMassactionBlock()->addItem('status', array( 
 'label'=> Mage::helper('catalog')->__('Change status'), 
 'url' => $this->getUrl('*/*/massStatus', array('_current'=>true)), 
 'additional' => array( 
 'visibility' => array( 
 'name' => 'status', 
 'type' => 'select', 
 'class' => 'required-entry', 
 'label' => Mage::helper('catalog')->__('Status'), 
 'values' => $statuses  )
         )
    ));


   if (Mage::getSingleton('admin/session')->isAllowed('catalog/update_attributes')){
        $this->getMassactionBlock()->addItem('attributes', array(
            'label' => Mage::helper('catalog')->__('Update Attributes'),
            'url'   => $this->getUrl('*/catalog_product_action_attribute/edit', array('_current'=>true))
        ));
    }

    Mage::dispatchEvent('adminhtml_catalog_product_grid_prepare_massaction', array('block' => $this));
    return $this;

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.