Массовое действие в виджетах
Некоторое время назад я нашел вопрос в stackoverflow о разрешении нескольких продуктов через виджет. Я подумал про себя, что это был бы отличный вариант и, конечно, не могло быть так сложно. К сожалению, я ошибся: (Мне удалось настроить флажки и кнопки массового действия для отображения на виджете, но JavaScript, который идет с ним, либо не включен, либо не работает.
Отображается сетка, включающая параметры массового действия, но когда я пытаюсь использовать эти элементы, я получите следующую ошибку JavaScript.
Неперехваченная ошибка ссылки: options_fieldset1adc562cf047406a634a7c10ae4f7db2_product_idsa765921c1aaf6166ee36c2e83468e0bf_massactionJsObject не определен
Итак, вот что я сделал до сих пор.
Создал 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>
Создал 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>
Создал 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>
Наконец-то я создал свой блок 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();
}
';
}
}
Оригинальный вопрос о стековом потоке
Репозиторий на GitHub
3 answers
Во-первых, вот почему вы получаете эту ошибку.
Кнопка блокировки массовых действий содержит это событие onclick.
$this->getJsObjectName() . ".apply()"
Углубляясь в методы, приведенный выше код преобразуется в
{parent_block_id}_massactionJsObject.apply();
(Для выбора виджета идентификатор родительского блока - это какой-то случайный хэш, но это не важно). Идея состоит в том, что объект выше не существует.
Теперь (возможное) решение. Измените блок массовых действий только для вашего виджета. Для этого создайте новый класс:
<?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.
}
}
Теперь расскажи ваша сетка для использования этого нового блока массовых действий. Для этого добавьте в класс Manners_Widgets_Block_Catalog_Product_Widget_Chooser
этот метод:
protected function _construct(){
parent::_construct();
$this->setMassactionBlockName('manners_widgets/catalog_product_massaction');
}
Теперь, когда вы нажмете на кнопку "отправить", вы получите предупреждение и никаких ошибок.
Измените предупреждение в приведенном выше коде своими действиями.
Это проблема масштаба. Объект Massactionjsobject объявляется с помощью "var" в файле Mage_Adminhtml_Block_Widget_Grid_Massaction_Abstract
public function getJavaScript()
{
return " var {$this->getJsObjectName()} = new varienGridMassaction('{$this->getHtmlId()}', "
. "{$this->getGridJsObjectName()}, '{$this->getSelectedJson()}'"
. ", '{$this->getFormFieldNameInternal()}', '{$this->getFormFieldName()}');"
. "{$this->getJsObjectName()}.setItems({$this->getItemsJson()}); "
. "{$this->getJsObjectName()}.setGridIds('{$this->getGridIdsJson()}');"
. ($this->getUseAjax() ? "{$this->getJsObjectName()}.setUseAjax(true);" : '')
. ($this->getUseSelectAll() ? "{$this->getJsObjectName()}.setUseSelectAll(true);" : '')
. "{$this->getJsObjectName()}.errorText = '{$this->getErrorText()}';";
}
Если вы переопределите этот метод и удалите ключевое слово "var" из объявления, область действия будет глобальной, а объект будет доступен из всплывающего окна виджета.
Итак, в основном:
- Переопределите действие Mage_Adminhtml_Block_Widget_Grid_Massaction своим блоком
- переопределите метод getJavascript, удалив "вар"
-
В своем блоке Widget_Product_Chooser установите защищенное имя $_massactionblock с помощью блока massaction
$_massactionblockname= 'мой модуль/widget_product_massaction';
Я боролся с этим 2 дня :/ Надеюсь, это поможет
Новая функция в Magento 1.4.1. заключается в том, что любая фильтрация, выполняемая на странице Продажи > Заказы, теперь обновляется с помощью вызова AJAX при нажатии кнопки отправить. К сожалению, это имеет неиндентированный побочный эффект: после любых обновлений ajax массовые действия (Отмена, Удержание, Печать счетов-фактур, Печать упаковочных листов и т.д.) не будут работать. Вместо этого вы будете возвращены на панель мониторинга (или на любую другую стартовую страницу ваших текущих пользователей в области администрирования).
После обновления ajax Magento не загружает полный макет страницы. Однако в макете он сохраняет ключ формы для аутентификации отправки запроса. Поскольку теперь это отсутствует, он "отклонит" запрос от массового действия, и вы будете отброшены обратно на панель мониторинга.
Чтобы устранить эту проблему, вы можете отредактировать app/design/adminhtml/default/default/template/widget/grid/massactions.phtml
и изменить
<?php echo $this->getBlockHtml('formkey')?>
До
<div><input name="form_key" type="hidden" value="<?php echo Mage::getSingleton('core/session')->getFormKey() ?>" /></div>
В примечании: после того, как вы вернетесь на панель управления и во второй раз посетите Продажи > Заказы, он запомнит ваш предыдущий выбор. И так как теперь это сделало полная загрузка страницы массовое действие завершится успешно.