在这一章节里,我们将学习如何将 Grid 表正确的添加至后台表单选项卡所对应的 content 区块里
这一章节只针对于对 Magento 有深刻了解的开发者,并已成功在后台选项卡所对应的 Content 区块里添加过 Grid 表,及有能力解决所碰到的问题
下载: Grid Serializer Module Source (17.19KB)
为了更好的讲解,我们来拿一个客户的需求当作实例,需求方案如下,建立一个实体叫’Customer Manager’, 随之分配一批客户给这个’Customer Manager’来管理,在后台页面,我们需要能够从整个客户表里选择客户,然后保存或者关系到某一个指定的 Customer Manager。所以在’Customer Manager’编辑页面中要显示出一个完整的客户 Grid 表, 这个表里会有 checkbox 列可以多选客户,这个类似于在后台编辑商品页面里的 Related Products 和 Cross-sell Products
默认或者简单的操作方法是: 在 Tabs.php 文件里创建一个后台视窗,这里有个 addTab() 方法来定义我们想要添加的视窗路径(指: block 文件路径),代码如下:
$this->addTab('form_section', array(
'label' => Mage::helper('test')->__('Sample Grid'),
'title' => Mage::helper('test')->__('Sample Grid'),
'content' => $this->getLayout()
->createBlock('fav/adminhtml_fav_edit_tab_grid')
->toHtml(),
));
这样一个 Grid 表会显示在新增选项卡(Tab)所对应的 Content 区块里, 但是在运行的时候会有许多问题产生。比如在搜索或分页的时候,和添加/删除条目有关操作的时候
正确的操作方法
在 Tabs.php 中的 addTab() 方法应该如下:
$this->addTab('form_section1',array(
'label' =>Mage::helper('test')->__('Customers'),
'title' =>Mage::helper('test')->__('Customers'),
'url' =>$this->getUrl('*/*/customer',array('_current'=>true)),
'class' =>'ajax',
));
这样做的话,当你点击 Customers Tab, 它就会以 ajax 方式调用 url 加载,然后显示出 Grid 表
在我们的 controller 文件中, 添加 custoemrAction() 方法,代码如下:
public function customerAction()
{
$this->loadLayout();
$this->getLayout()->getBlock('customer.grid')
->setCustomers(
$this->getRequest()->getPost('customers', null)
);
$this->renderLayout();
}
这个操作十分简单, 只是简单的加载和输出 Layout, 所以还有段重要的代码应该写在该模块的 XML 文件里(在 Layout 文件夹下), 如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<test_adminhtml_test_customer>
<blocktype="core/text_list"name="root"output="toHtml">
<blocktype="test/adminhtml_test_edit_tab_grid"name="customer.grid"></block>
<blocktype="adminhtml/widget_grid_serializer"name="grid_serializer">
<referencename="grid_serializer">
<actionmethod="initSerializerBlock">
<grid_block_name>customer.grid</grid_block_name>
<data_callback>getSelectedCustomers</data_callback>
<hidden_input_name>links[customers]</hidden_input_name>
<reload_param_name>customers</reload_param_name>
</action>
<actionmethod="addColumnInputName">
<input_name>position</input_name>
</action>
</reference>
</block>
</block>
</test_adminhtml_test_customer>
第一个 block 只是简单的定义了我们 Grid 表的 block 文件,第二个 block 非常重要,它增加了一个 grid serializer, 其作用是建立一个 hidden input 框来保存多选框中 check/uncheck 的值
现在来解析下 XMl 中第二个 block:
<action method="initSerializerBlock">
<grid_block_name>customer.grid</grid_block_name>
<data_callback>getSelectedCustomers</data_callback>
<hidden_input_name>links[customers]</hidden_input_name>
<reload_param_name>customers</reload_param_name>
</action>
grid_block_name //包含了 Grid 表的名字
data_callback //这个方法定义在 Grid 里, 将 return 出所选中项目的值
hidden_input_name //包含了 hidden input 框的名字
reload_param_name //很遗憾,这个我都不知道… 囧
<action method="addColumnInputName">
<input_name>position</input_name>
</action>
postion 是在 Grid 表中一个列的名字(需要是一个 text 文本框), 很显然,在使用 grid serializer 的时候,在 Grid 表中需要一个带有 text 文本框的列(作为搜索的选择之一)
现在,让我们来看一下 Grid.php 文件,里面的内容和通常的 Grid.php 一样,在这里,我只指出不同和新增的地方,代码如下:
publicfunction__construct()
{
parent::__construct();
$this->setId('customerGrid');
// 选择是否使用 ajax 十分重要
$this->setUseAjax(true);
$this->setDefaultSort('entity_id');
// 默认我们已经为行添加了一个过滤器, in_products 的值设置为 1
$this->setDefaultFilter(array('in_products'=>1));
// 不要把参数保存在 Session 里面,这样会产生问题
$this->setSaveParametersInSession(false);
}
接下来,我们为显示的 checkboxes 添加一个自定义的过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
protected function _addColumnFilterToCollection($column)
{
// Set custom filter for in product flag
if ($column->getId() == 'in_products') {
$productIds = $this->_getSelectedCustomers();
if (empty($productIds)) {
$productIds = 0;
}
if ($column->getFilter()->getValue()) {
$this->getCollection()->addFieldToFilter('entity_id',
array('in' => $productIds)
);
} else {
if($productIds) {
$this->getCollection()->addFieldToFilter('entity_id',
array('nin'=>$productIds)
);
}
}
} else {
parent::_addColumnFilterToCollection($column);
}
return $this;
}
从上述代码中可以看出,这个方法已经十分明显, 并且会在下面定义
接下来,我们添加一个 checkbox 列
$this->addColumn('in_products',array(
'header_css_class' => 'a-center',
'type' => 'checkbox',
'name' => 'customer',
'values' => $this->_getSelectedCustomers(),
'align' => 'center',
'index' => 'entity_id'
));
这个 $this->_getSelectedCustomers() 方法会 return 出在数据库中存在的并且被选择的所有 id 号,这里所选择的是指已经指定给一个 customer manager 的客户
再额外增加一列 “position” :
$this->addColumn('position', array(
'header' => Mage::helper('catalog')->__('ID'),
'name' => 'position',
'width' => 60,
'type' => 'number',
'validate_class' => 'validate-number',
'index' => 'position',
'editable' => true,
'edit_only' => true
));
这一列的增加只是为了保证 serializer 正常工作, 这个列名已在该模块的 XML 文件里声明过了。该列有一个 text input 框,这也是 serializer 正常工作的必须条件
现在我们来增加两个方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protectedfunction_getSelectedCustomers()
{
$customers=array_keys($this->getSelectedCustomers());
return$customers;
}
publicfunctiongetSelectedCustomers()
{
// Customer Data
$tm_id=$this->getRequest()->getParam('id');
if(!isset($tm_id)){
$tm_id=0;
}
$customers=array(1,2);// 这里是写死的,通常应该从数据库中获得
$custIds=array();
foreach($customersas$customer){
foreach($customeras$cust){
$custIds[$cust]=array('position'=>$cust);
}
}
return$custIds;
}
这个方法已在 XML 中声明过是一个 callback 方法, 同样你可以看出 array 的格式 return 出来的时候带有 postion
另外还有一个 getGridUrl() 需要添加
<p style="color:#FF6600;">
另外还有一个 getGridUrl() 需要添加
</p>
这个方法基于 ajax 并且用在所有的 Grid 表中, 在搜索和分页的时候会用到, 为此还要在我们的 controller 文件中添加对应的 Action 方法:
publicfunctioncustomergridAction()
{
$this->loadLayout();
$this->getLayout()->getBlock('customer.grid')
->setCustomers($this->getRequest()->getPost('customers',null));
$this->renderLayout();
}
同样在 XML 中添加:
<test_adminhtml_test_customergrid>
<block type="core/text_list" name="root" output="toHtml">
<block type="test/adminhtml_test_edit_tab_grid" name="customer.grid" ></block>
</block>
</test_adminhtml_test_customergrid>
为了让 Grid 表正常工作,这些步骤是不可缺少的,现在,Grid 表应该可以正常工作了, 你也可以用 firebug 查看下你的 HTML 代码, 在 Grid <div> 标签后面, 你应该可以查看到这个 hidden input :
当你选中或者取消选中 checkbox 时, 里面的值应该随之变化。下一步,就是要保存我们的表单,我们需要获得我们所选客户的值,以便保存到数据库, 为了达到,添加如下代码至 saveAction 里面:
if(isset($data['links'])){
$customers=Mage::helper('adminhtml/js')
->decodeGridSerializedInput($data['links']['customers']);
//保存数组到数据库
}
你可以使用 customers array 来保存到数据库
source: http://www.sunzhenghua.com/magento-admin-module-development-part6-internal-grid-forms-advanced
0 0