Magento Adminhtml:带有类别选择器的类别属性
Magento Adminhtml: Category Attribute with category chooser
我正在尝试实现一个类别属性,旨在 link 当前类别与项目特定用途的其他类别。
为此,我创建了一个 varchar 属性,用于存储以逗号分隔的类别 ID 列表,但我希望在显示类别选择器的字段旁边有一个小选择器图标,就像促销管理屏幕的条件部分。
我真的不知道我应该实现什么样的渲染器来实现这一点,我希望你们能给我一个提示。
感谢您的帮助。
我成功了 - 终于 - 所以它是这样的:
仅供参考:我的类别属性名为 "category_top_searches",是一个以逗号分隔的类别 ID 列表。选择器旨在帮助贡献此列表。
1 - 使用观察者添加选项卡
一个。观察者声明
<adminhtml_catalog_category_tabs>
<observers>
<add_topsearches_tab>
<class>mymodule/observer</class>
<method>addTopSearchesTab</method>
</add_topsearches_tab>
</observers>
</adminhtml_catalog_category_tabs>
乙。观察者实现
public function addTopSearchesTab(Varien_Event_Observer $observer)
{
$tabs = $observer->getTabs();
$tabs->addTab(
'top_searches_tab', 'mymodule/catalog_category_edit_tab_topsearches'
);
}
2 - 为 Tab
定义块
需要实现tab接口方法和初始化树时获取勾选分类的方法
class MyNamespace_Adminhtml_Block_Catalog_Category_Edit_Tab_Topsearches
extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Categories
implements Mage_Adminhtml_Block_Widget_Tab_Interface
{
/**
* Specify template to use
*/
public function __construct()
{
parent::__construct();
$this->setTemplate('catalog/category/edit/categorypicker.phtml');
}
/**
* Checks when this block is readonly
*
* @return bool
*/
public function isReadonly()
{
return false;
}
/**
* getCategoryIds method
* @return array
*/
protected function getCategoryIds()
{
$category = Mage::registry('current_category');
$ids = explode(',', $category->getCategoryTopSearches());
return $ids;
}
/**
* getIdsString
*
* @return string
*/
public function getIdsString()
{
$category = Mage::registry('current_category');
return $category->getCategoryTopSearches();
}
/**
* Return Tab label
*
* @return string
*/
public function getTabLabel()
{
return $this->__('Top Searches');
}
/**
* Return Tab title
*
* @return string
*/
public function getTabTitle()
{
return $this->__('Top Searches');
}
/**
* Can show tab in tabs
*
* @return boolean
*/
public function canShowTab()
{
return true;
}
/**
* Tab is hidden
*
* @return boolean
*/
public function isHidden()
{
return false;
}
}
3 - 定义树模板
我将产品编辑页面 app/design/adminhtml/default/default/template/catalog/product/edit/categories.phtml 的类别树的核心模板复制粘贴到 app/design/adminhtml/default/mytheme/template/catalog/category/edit/categorypicker.phtml 中并做了一些小改动:
添加了一个文本字段来显示我的 ID:
<div class="entry-edit">
<div class="entry-edit-head">
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Linked Categories') ?></h4>
</div>
<fieldset id="linked_cat">
<input type="text" name="linked_categories_list" id="linked_categories_list" value="<?php echo $this->getIdsString() ?>">
</fieldset>
</div>
并修改了树头以更适合我的上下文
<div class="entry-edit">
<div class="entry-edit-head">
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Category picker') ?></h4>
</div>
<fieldset id="grop_fields">
<input type="hidden" name="linked_categories" id="linked_categories" value="<?php echo $this->getIdsString() ?>">
<div id="product-categories" class="tree"></div>
</fieldset>
</div>
我不得不稍微修改 beforeLoad 函数来设置 id 参数:
categoryLoader.on("beforeload", function(treeLoader, node) {
treeLoader.baseParams.category = node.attributes.id;
treeLoader.baseParams.id = node.attributes.id;
});
我添加了一个函数来实现 array_unique 功能
Array.prototype.unique = function(){
'use strict';
var im = {}, uniq = [];
for (var i=0;i<this.length;i++){
var type = (this[i]).constructor.name,
// ^note: for IE use this[i].constructor!
val = type + (!/num|str|regex|bool/i.test(type)
? JSON.stringify(this[i])
: this[i]);
if (!(val in im)){uniq.push(this[i]);}
im[val] = 1;
}
return uniq;
}
然后修改 categoryAdd 和 categoryRemove 函数以使用新的 checked/unchecked ID
更新我的文本字段
function categoryAdd(id) {
var ids = $('linked_categories').value.split(',');
ids.push(id);
var idList = ids.unique().join(',').replace(/^,/, '');
document.getElementById("linked_categories_list").value = idList;
$('linked_categories').value = ids.join(',');
}
function categoryRemove(id) {
var ids = $('linked_categories').value.split(',');
// bug #7654 fixed
while (-1 != ids.indexOf(id)) {
ids.splice(ids.indexOf(id), 1);
}
var idList = ids.unique().join(',').replace(/^,/, '');
document.getElementById("linked_categories_list").value = idList;
$('linked_categories').value = ids.join(',');
}
4 - 对类别保存事件实施观察者以将新值注入真实属性
一个。宣言
<catalog_category_save_before>
<observers>
<set_top_searches>
<class>mymodule/observer</class>
<method>setTopSearches</method>
</set_top_searches>
</observers>
</catalog_category_save_before>
乙。实施
/**
* takes the fake attribute value and insert it into the real category_top_searches attribute
*
* @param Varien_Event_Observer $observer Observer
*
* @return void
*/
public function setTopSearches(Varien_Event_Observer $observer)
{
/** @var $category Mage_Catalog_Model_Category */
$category = $observer->getEvent()->getCategory();
$params = Mage::app()->getRequest()->getParams();
$ids = $params['linked_categories_list'];
$category->setData('category_top_searches', $ids);
}
5 - 最后我通过在安装脚本中更新它隐藏了我的原始属性:
(我改变了它的组,否则它的专用标签将是空的但仍然显示)
$installer->updateAttribute("catalog_category", "category_top_searches", 'group', "General");
$installer->updateAttribute("catalog_category", "category_top_searches", 'is_visible', false);
不知道是否有人会使用它,因为我在这个线程上很孤独,但我很想在尝试实现此功能时找到这样的 post...:D
如果有人感兴趣,我还在配置字段中实现了这个类别选择器作为一个新的 frontend_type,非常棒!
我正在尝试实现一个类别属性,旨在 link 当前类别与项目特定用途的其他类别。
为此,我创建了一个 varchar 属性,用于存储以逗号分隔的类别 ID 列表,但我希望在显示类别选择器的字段旁边有一个小选择器图标,就像促销管理屏幕的条件部分。
我真的不知道我应该实现什么样的渲染器来实现这一点,我希望你们能给我一个提示。 感谢您的帮助。
我成功了 - 终于 - 所以它是这样的:
仅供参考:我的类别属性名为 "category_top_searches",是一个以逗号分隔的类别 ID 列表。选择器旨在帮助贡献此列表。
1 - 使用观察者添加选项卡
一个。观察者声明
<adminhtml_catalog_category_tabs>
<observers>
<add_topsearches_tab>
<class>mymodule/observer</class>
<method>addTopSearchesTab</method>
</add_topsearches_tab>
</observers>
</adminhtml_catalog_category_tabs>
乙。观察者实现
public function addTopSearchesTab(Varien_Event_Observer $observer)
{
$tabs = $observer->getTabs();
$tabs->addTab(
'top_searches_tab', 'mymodule/catalog_category_edit_tab_topsearches'
);
}
2 - 为 Tab
定义块需要实现tab接口方法和初始化树时获取勾选分类的方法
class MyNamespace_Adminhtml_Block_Catalog_Category_Edit_Tab_Topsearches
extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Categories
implements Mage_Adminhtml_Block_Widget_Tab_Interface
{
/**
* Specify template to use
*/
public function __construct()
{
parent::__construct();
$this->setTemplate('catalog/category/edit/categorypicker.phtml');
}
/**
* Checks when this block is readonly
*
* @return bool
*/
public function isReadonly()
{
return false;
}
/**
* getCategoryIds method
* @return array
*/
protected function getCategoryIds()
{
$category = Mage::registry('current_category');
$ids = explode(',', $category->getCategoryTopSearches());
return $ids;
}
/**
* getIdsString
*
* @return string
*/
public function getIdsString()
{
$category = Mage::registry('current_category');
return $category->getCategoryTopSearches();
}
/**
* Return Tab label
*
* @return string
*/
public function getTabLabel()
{
return $this->__('Top Searches');
}
/**
* Return Tab title
*
* @return string
*/
public function getTabTitle()
{
return $this->__('Top Searches');
}
/**
* Can show tab in tabs
*
* @return boolean
*/
public function canShowTab()
{
return true;
}
/**
* Tab is hidden
*
* @return boolean
*/
public function isHidden()
{
return false;
}
}
3 - 定义树模板
我将产品编辑页面 app/design/adminhtml/default/default/template/catalog/product/edit/categories.phtml 的类别树的核心模板复制粘贴到 app/design/adminhtml/default/mytheme/template/catalog/category/edit/categorypicker.phtml 中并做了一些小改动:
添加了一个文本字段来显示我的 ID:
<div class="entry-edit">
<div class="entry-edit-head">
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Linked Categories') ?></h4>
</div>
<fieldset id="linked_cat">
<input type="text" name="linked_categories_list" id="linked_categories_list" value="<?php echo $this->getIdsString() ?>">
</fieldset>
</div>
并修改了树头以更适合我的上下文
<div class="entry-edit">
<div class="entry-edit-head">
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Category picker') ?></h4>
</div>
<fieldset id="grop_fields">
<input type="hidden" name="linked_categories" id="linked_categories" value="<?php echo $this->getIdsString() ?>">
<div id="product-categories" class="tree"></div>
</fieldset>
</div>
我不得不稍微修改 beforeLoad 函数来设置 id 参数:
categoryLoader.on("beforeload", function(treeLoader, node) {
treeLoader.baseParams.category = node.attributes.id;
treeLoader.baseParams.id = node.attributes.id;
});
我添加了一个函数来实现 array_unique 功能
Array.prototype.unique = function(){
'use strict';
var im = {}, uniq = [];
for (var i=0;i<this.length;i++){
var type = (this[i]).constructor.name,
// ^note: for IE use this[i].constructor!
val = type + (!/num|str|regex|bool/i.test(type)
? JSON.stringify(this[i])
: this[i]);
if (!(val in im)){uniq.push(this[i]);}
im[val] = 1;
}
return uniq;
}
然后修改 categoryAdd 和 categoryRemove 函数以使用新的 checked/unchecked ID
更新我的文本字段function categoryAdd(id) {
var ids = $('linked_categories').value.split(',');
ids.push(id);
var idList = ids.unique().join(',').replace(/^,/, '');
document.getElementById("linked_categories_list").value = idList;
$('linked_categories').value = ids.join(',');
}
function categoryRemove(id) {
var ids = $('linked_categories').value.split(',');
// bug #7654 fixed
while (-1 != ids.indexOf(id)) {
ids.splice(ids.indexOf(id), 1);
}
var idList = ids.unique().join(',').replace(/^,/, '');
document.getElementById("linked_categories_list").value = idList;
$('linked_categories').value = ids.join(',');
}
4 - 对类别保存事件实施观察者以将新值注入真实属性
一个。宣言
<catalog_category_save_before>
<observers>
<set_top_searches>
<class>mymodule/observer</class>
<method>setTopSearches</method>
</set_top_searches>
</observers>
</catalog_category_save_before>
乙。实施
/**
* takes the fake attribute value and insert it into the real category_top_searches attribute
*
* @param Varien_Event_Observer $observer Observer
*
* @return void
*/
public function setTopSearches(Varien_Event_Observer $observer)
{
/** @var $category Mage_Catalog_Model_Category */
$category = $observer->getEvent()->getCategory();
$params = Mage::app()->getRequest()->getParams();
$ids = $params['linked_categories_list'];
$category->setData('category_top_searches', $ids);
}
5 - 最后我通过在安装脚本中更新它隐藏了我的原始属性: (我改变了它的组,否则它的专用标签将是空的但仍然显示)
$installer->updateAttribute("catalog_category", "category_top_searches", 'group', "General");
$installer->updateAttribute("catalog_category", "category_top_searches", 'is_visible', false);
不知道是否有人会使用它,因为我在这个线程上很孤独,但我很想在尝试实现此功能时找到这样的 post...:D
如果有人感兴趣,我还在配置字段中实现了这个类别选择器作为一个新的 frontend_type,非常棒!