如何将Serializable属性添加到类别?
-
13-12-2019 - |
题
我试过这个
$installer->addAttribute(
'catalog_category',
'ser_attr',
array(
'input_renderer' => 'namespace_module/block',
'backend' => 'adminhtml/system_config_backend_serialized_array',
)
);
.
和
class namespace_module/block
extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
{
protected function _prepareToRender()
{
$this->addColumn('price', array(
'label' => 'price'
));
$this->_addAfter = false;
return $this;
}
}
.
但是当我访问admin中的编辑类别页面时,没有可用的html / css / js,只有一个带有price
行的表。
解决方案
不幸的是,这并不像你想象的那么简单(我希望我希望)。这不起作用的第一个原因是因为您正在扩展属于管理员的系统配置部分的类,而不是admin的目录部分。
这不是简单的第二个原因是因为没有内置支持序列化阵列作为类别的属性。巧妙地,这是产品的情况(特别是群体和层价格属性)。
我遵循了这些产品属性的逻辑,并将某种东西放在一起工作。最终,它看起来像这样;
首先,我们需要将属性添加到属于类别的magento。我会假设你知道如何以概念的追求方式编辑地做到这一点,我会把查询放在这里。我假设你的扩展名为your_module。
INSERT INTO eav_attribute SET entity_type_id = 3, attribute_code = 'serialize_array', backend_model = 'your_module/category_attribute_backend_serializearray', backend_type = 'text', frontend_input = 'text', frontend_label = 'Serialize Array';
.
然后然后找到此属性的属性ID并运行此查询;
INSERT INTO eav_entity_attribute SET entity_type_id = 3, attribute_set_id = 3, attribute_group_id = 4, attribute_id = ATTRIBUTE_ID_HERE, sort_order = 100;
.
现在我们将在类别页面上具有一个很好的属性。但它并不像你想要的配置,它仍然是一个正常的文本字段。
我们现在将创建显示,存储和检索序列化阵列所需的逻辑。
首先,我们需要创建后端模型。我们需要这是因为我们需要在通过使用beforeSave()函数保存时序列化数组。
<?php
class Your_Module_Model_Category_Attribute_Backend_Serializearray
extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
{
public function beforeSave($object)
{
$object->setData('serialize_array', serialize($object->getData('serialize_array')));
}
}
.
接下来,我们需要创建表单渲染器以显示将构成选择元素和表格的HTML。
<?php
class Your_Module_Block_Catalog_Form_Renderer_Attribute_SerializeArray
extends Mage_Adminhtml_Block_Catalog_Form_Renderer_Fieldset_Element
{
public function __construct()
{
$this->setTemplate('your/module/serialize_array.phtml');
}
public function getOptions() {
return array(
array('name' => 'Option 1'),
array('name' => 'Option 2')
);
}
public function getOtherOptions() {
return array('Other Option 1', 'Other Option 2');
}
public function getValues() {
$_category = Mage::registry('current_category');
$array = $_category->getSerializeArray();
if($array) {
return unserialize($array);
}
return array();
}
public function getElementHtml()
{
$element = $this->getElement();
if(!$element->getValue()) {
return parent::getElementHtml();
}
$element->setOnkeyup("onUrlkeyChanged('" . $element->getHtmlId() . "')");
$element->setOnchange("onUrlkeyChanged('" . $element->getHtmlId() . "')");
$data = array(
'name' => $element->getData('name') . '_create_redirect',
'disabled' => true,
);
$hidden = new Varien_Data_Form_Element_Hidden($data);
$hidden->setForm($element->getForm());
$storeId = $element->getForm()->getDataObject()->getStoreId();
$data['html_id'] = $element->getHtmlId() . '_create_redirect';
$data['label'] = Mage::helper('catalog')->__('Create Permanent Redirect for old URL');
$data['value'] = $element->getValue();
$data['checked'] = Mage::helper('catalog')->shouldSaveUrlRewritesHistory($storeId);
$checkbox = new Varien_Data_Form_Element_Checkbox($data);
$checkbox->setForm($element->getForm());
return parent::getElementHtml() . '<br/>' . $hidden->getElementHtml() . $checkbox->getElementHtml() . $checkbox->getLabelHtml();
}
protected function _prepareLayout()
{
$button = $this->getLayout()->createBlock('adminhtml/widget_button')
->setData(array(
'label' => Mage::helper('catalog')->__('Add Option'),
'onclick' => 'return serializeArrayControl.addItem()',
'class' => 'add'
));
$button->setName('add_serialize_array_item_button');
$this->setChild('add_button', $button);
return parent::_prepareLayout();
}
public function getAddButtonHtml()
{
return $this->getChildHtml('add_button');
}
}
.
我们还需要实际的HTML。创建模板文件
app / design / adminhtml / base / base / defaute / template /您的/ module / serialize_array.phtml
使用此HTML;
<?php
/** @var $this Your_Module_Block_Catalog_Form_Renderer_Attribute_SerializeArray */
$_htmlId = $this->getElement()->getHtmlId();
$_htmlClass = $this->getElement()->getClass();
$_htmlName = $this->getElement()->getName();
$_readonly = $this->getElement()->getReadonly();
$_showFirstColumn = true;
?>
<tr>
<td class="label"><?php echo $this->getElement()->getLabel(); ?></td>
<td colspan="10" class="grid tier">
<table cellspacing="0" class="data border" id="serialize_array_table">
<?php if ($_showFirstColumn) : ?>
<col width="135" />
<?php endif; ?>
<col width="120" />
<col />
<col width="1" />
<thead>
<tr class="headings">
<th <?php if (!$_showFirstColumn): ?>style="display: none;"<?php endif; ?>><?php echo Mage::helper('catalog')->__('First Option'); ?></th>
<th><?php echo Mage::helper('catalog')->__('Second Option'); ?></th>
<th><?php echo Mage::helper('catalog')->__('Free field'); ?></th>
<th class="last"><?php echo Mage::helper('catalog')->__('Action'); ?></th>
</tr>
</thead>
<tbody id="<?php echo $_htmlId; ?>_container"></tbody>
<tfoot>
<tr>
<td <?php if (!$_showFirstColumn): ?>style="display: none;"<?php endif; ?>></td>
<td colspan="4" class="a-right"><?php echo $this->getAddButtonHtml(); ?></td>
</tr>
</tfoot>
</table>
<script type="text/javascript">
//<![CDATA[
var serializeArrayRowTemplate = '<tr>'
+ '<td<?php if (!$_showFirstColumn): ?> style="display:none"<?php endif; ?>>'
+ '<select class="<?php echo $_htmlClass; ?> required-entry" name="<?php echo $_htmlName; ?>[{{index}}][first_option]" id="serialize_array_row_{{index}}_first_option">'
<?php foreach ($this->getOptions() as $_websiteId => $_info) : ?>
+ '<option value="<?php echo $_websiteId; ?>"><?php echo $this->jsQuoteEscape($this->escapeHtml($_info['name'])); ?><?php if (!empty($_info['currency'])) : ?> [<?php echo $this->escapeHtml($_info['currency']); ?>]<?php endif; ?></option>'
<?php endforeach; ?>
+ '</select></td>'
+ '<td><select class="<?php echo $_htmlClass; ?> custgroup required-entry" name="<?php echo $_htmlName; ?>[{{index}}][second_option]" id="serialize_array_row_{{index}}_second_option">'
<?php foreach ($this->getOtherOptions() as $_groupId => $_groupName): ?>
+ '<option value="<?php echo $_groupId; ?>"><?php echo $this->jsQuoteEscape($this->escapeHtml($_groupName)); ?></option>'
<?php endforeach; ?>
+ '</select></td>'
+ '<td><input class="<?php echo $_htmlClass; ?> required-entry" type="text" name="<?php echo $_htmlName; ?>[{{index}}][freefield]" value="{{freefield}}" id="serialize_array_row_{{index}}_freefield" /></td>'
+ '<td class="last"><input type="hidden" name="<?php echo $_htmlName; ?>[{{index}}][delete]" class="delete" value="" id="serialize_array_row_{{index}}_delete" />'
+ '<button title="<?php echo $this->jsQuoteEscape(Mage::helper('catalog')->__('Delete')); ?>" type="button" class="scalable delete icon-btn delete-product-option" id="serialize_array_row_{{index}}_delete_button" onclick="return serializeArrayControl.deleteItem(event);">'
+ '<span><?php echo $this->jsQuoteEscape(Mage::helper('catalog')->__('Delete')); ?></span></button></td>'
+ '</tr>';
var serializeArrayControl = {
template: new Template(serializeArrayRowTemplate, new RegExp('(^|.|\\r|\\n)({{\\s*(\\w+)\\s*}})', '')),
itemsCount: 0,
addItem : function () {
<?php if ($_readonly): ?>
if (arguments.length < 3) {
return;
}
<?php endif; ?>
var data = {
first_option: '', // default value
second_option: '', // default value
freefield: '', // default value
readOnly: false,
index: this.itemsCount++
};
if(arguments.length >= 3) {
data.first_option = arguments[0];
data.second_option = arguments[1];
data.freefield = arguments[2];
}
if (arguments.length == 4) {
data.readOnly = arguments[3];
}
Element.insert($('<?php echo $_htmlId; ?>_container'), {
bottom : this.template.evaluate(data)
});
$('serialize_array_row_' + data.index + '_first_option').setValue(data.first_option);
$('serialize_array_row_' + data.index + '_second_option').setValue(data.second_option);
$('serialize_array_row_' + data.index + '_freefield').setValue(data.freefield);
if (data.readOnly == '1') {
['first_option', 'second_option', 'freefield', 'delete'].each(function(element_suffix) {
$('serialize_array_row_' + data.index + '_' + element_suffix).disabled = true;
});
$('serialize_array_row_' + data.index + '_delete_button').hide();
}
<?php if ($_readonly): ?>
$('<?php echo $_htmlId; ?>_container').select('input', 'select').each(this.disableElement);
$('<?php echo $_htmlId; ?>_container').up('table').select('button').each(this.disableElement);
<?php else: ?>
$('<?php echo $_htmlId; ?>_container').select('input', 'select').each(function(element) {
Event.observe(element, 'change', element.setHasChanges.bind(element));
});
<?php endif; ?>
},
disableElement: function(element) {
element.disabled = true;
element.addClassName('disabled');
},
deleteItem: function(event) {
var tr = Event.findElement(event, 'tr');
if (tr) {
Element.select(tr, '.delete').each(function(element) {
element.value='1';
});
Element.select(tr, ['input', 'select']).each(function(element) {
element.hide();
});
Element.hide(tr);
Element.addClassName(tr, 'no-display template');
}
return false;
}
};
<?php foreach ($this->getValues() as $_item) : ?>
serializeArrayControl.addItem('<?php echo $_item['first_option']; ?>', '<?php echo $_item['second_option']; ?>', '<?php echo $_item['freefield']; ?>');
<?php endforeach; ?>
<?php if ($_readonly) : ?>
$('<?php echo $_htmlId; ?>_container').up('table').select('button')
.each(serializeArrayControl.disableElement);
<?php endif; ?>
//]]>
</script>
</td></tr>
.
在此HTML中可能存在一些无用/荒谬的cruft,因为我从
复制它应用/设计/ adminhtml /默认/默认/模板/目录/产品/编辑/价格/ group.phtml
并将其调整一下。
清除您的缓存,reindex(如果您使用的目录扁平表),您应该好好走!