Magento – Mass Action in Widgets

adminhtmljavascriptmassactionwidgets

A while back I found a question on stackoverflow about allowing multiple products via a widget. I thought to myself that it would be a great option and surely could not be that difficult. Sadly I was wrong 🙁 I have managed to get the mass action checkboxes and buttons to display on a widget but the JavaScript that goes with it is either not included or not working.

The grid is displayed include mass action options but when I try to use these items I get the following JavaScript error.

Uncaught ReferenceError: options_fieldset1adc562cf047406a634a7c10ae4f7db2_product_idsa765921c1aaf6166ee36c2e83468e0bf_massactionJsObject is not defined

So here is what I have done so far.

Created a app\etc\modules\Manners_Widgets.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Manners_Widgets>
            <active>true</active>
            <codePool>community</codePool>
            <depends>
                <Mage_Adminhtml />
                <Mage_Widget />
            </depends>
        </Manners_Widgets>
    </modules>
</config>

Created a app\code\community\Manners\Widgets\etc\config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Manners_Widgets>
            <version>1.0.0</version>
        </Manners_Widgets>
    </modules>

    <global>
        <blocks>
            <manners_widgets>
                <class>Manners_Widgets_Block</class>
            </manners_widgets>
            <adminhtml>
                <rewrite>
                    <catalog_product_widget_chooser>Manners_Widgets_Block_Catalog_Product_Widget_Chooser</catalog_product_widget_chooser>
                </rewrite>
            </adminhtml>
        </blocks>

        <helpers>
            <manners_widgets>
                <class>Manners_Widgets_Helper</class>
            </manners_widgets>
        </helpers>
    </global>
</config>

Created a app\code\community\Manners\Widgets\etc\widget.xml

<?xml version="1.0"?>
<widgets>
    <manners_widgets_products type="manners_widgets/products" translate="name description" module="manners_widgets">
        <name>Multiple Products Widget</name>
        <description>Widget to display multiple products on one page</description>
        <parameters>
            <product_ids translate="label">
                <visible>1</visible>
                <required>1</required>
                <label>Product</label>
                <type>label</type>
                <helper_block>
                    <type>manners_widgets/catalog_product_widget_chooser</type>
                    <data>
                        <button translate="open remove">
                            <open>Select Products...</open>
                        </button>
                    </data>
                </helper_block>
            </product_ids>
        </parameters>
    </manners_widgets_products>
</widgets>

Finally I created my block Manners_Widgets_Block_Catalog_Product_Widget_Chooser

<?php
class Manners_Widgets_Block_Catalog_Product_Widget_Chooser extends Mage_Adminhtml_Block_Catalog_Product_Widget_Chooser {
    /**
     *
     * @return Mage_Adminhtml_Block_Widget_Grid|void
     */
    protected function _prepareColumns() {
        $this->addColumn('entity_id', array(
            'header'    => Mage::helper('catalog')->__('ID'),
            'sortable'  => true,
            'width'     => '60px',
            'index'     => 'entity_id'
        ));
        $this->addColumn('chooser_sku', array(
            'header'    => Mage::helper('catalog')->__('SKU'),
            'name'      => 'chooser_sku',
            'width'     => '80px',
            'index'     => 'sku'
        ));
        $this->addColumn('chooser_name', array(
            'header'    => Mage::helper('catalog')->__('Product Name'),
            'name'      => 'chooser_name',
            'index'     => 'name'
        ));
    }

    /**
     * Prepare the massaction
     *  - Block,
     *  - Item
     *
     * @return $this|Mage_Adminhtml_Block_Widget_Grid
     */
    protected function _prepareMassaction() {
        $this->setMassactionIdField('entity_id');
        $this->setMassactionIdFilter('entity_id');
        $this->getMassactionBlock()->setFormFieldName('product');

        $this->getMassactionBlock()->addItem('delete', array(
            'label'=> Mage::helper('catalog')->__('Add Products'),
            'url'  => $this->getUrl('*/*/addProducts')
        ));

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

    /**
     * Checkbox Check JS Callback
     *
     * @return string
     */
    public function getCheckboxCheckCallback()
    {
        return "function (grid, element) {
            $(grid.containerId).fire('product:changed', {element: element});
        }";
    }

    /**
     * Grid Row JS Callback
     *
     * @return string
     */
    public function getRowClickCallback()
    {
        $chooserJsObject = $this->getId();
            return '
                function (grid, event) {
                    var trElement = Event.findElement(event, "tr");
                    var productId = trElement.down("td").innerHTML;
                    var productName = trElement.down("td").next().next().innerHTML;
                    var optionLabel = productName;
                    var optionValue = "product/" + productId.replace(/^\s+|\s+$/g,"");
                    if (grid.categoryId) {
                        optionValue += "/" + grid.categoryId;
                    }
                    if (grid.categoryName) {
                        optionLabel = grid.categoryName + " / " + optionLabel;
                    }
                    '.$chooserJsObject.'.setElementValue(optionValue);
                    '.$chooserJsObject.'.setElementLabel(optionLabel);
                    '.$chooserJsObject.'.close();
                }
            ';
    }
}

Original stackoverflow question

https://stackoverflow.com/questions/13493630/how-to-allow-multiple-product-selection-in-magento-widget-configuration

GitHub Repo

https://github.com/dmanners/Manners_Widgets

Best Answer

First, here is why you get that error.
The mass action block button has this onclick event.

$this->getJsObjectName() . ".apply()"

Digging deeper in the methods the code above translates into

{parent_block_id}_massactionJsObject.apply();

(For a widget chooser the parent block id is some random hash but that's not important). The idea is that the object above does not exist.
Now the (possible) solution. Change the mass action block only for your widget chooser. For this create a new class:

<?php 
class Manners_Widgets_Block_Catalog_Product_Massaction extends Mage_Adminhtml_Block_Widget_Grid_Massaction{
    public function getApplyButtonHtml()
    {
        return $this->getButtonHtml($this->__('Submit'), "alert('Doh!')");//add this your js function that should do the magic.
    }
}

Now tell your grid to use this new mass action block. For this add int the class Manners_Widgets_Block_Catalog_Product_Widget_Chooser this method:

protected function _construct(){
    parent::_construct();
    $this->setMassactionBlockName('manners_widgets/catalog_product_massaction');
}

Now when you click on the "submit" button you will get an alert and no errors.
Change the alert in the code above with your actions.

Related Topic