【问题标题】:Adding a Custom Form Element to an Adminhtml Form将自定义表单元素添加到 Adminhtml 表单
【发布时间】:2010-01-03 01:29:32
【问题描述】:

有没有一种方法可以将自定义表单元素添加到 Magento Adminhtml 表单而不将自定义元素放在 lib/Varian 文件夹中?

我已经找到了基本上是 Varian_Data_Form_Element_ 工厂的代码

public function addField($elementId, $type, $config, $after=false)
{
    if (isset($this->_types[$type])) {
        $className = $this->_types[$type];
    }
    else {
        $className = 'Varien_Data_Form_Element_'.ucfirst(strtolower($type));
    }
    $element = new $className($config);
    $element->setId($elementId);
    if ($element->getRequired()) {
        $element->addClass('required-entry');
    }
    $this->addElement($element, $after);
    return $element;
}

所以,如果我没看错的话,我会确保 EAV 属性的前端返回特定的字段类型(例如 supertextfield),并且系统会在显示该属性的编辑表单时实例化/呈现 Varien_Data_Form_Element_Supertextfield

这很好,但这意味着我需要在lib/Varian 文件夹层次结构中包含我的自定义表单元素。鉴于 Magento 是如何面向模块的,这似乎是错误的。

我意识到我可以在 lib 中使用自定义自动加载器或符号链接,但我主要感兴趣的是了解是否有

  1. 为属性添加自定义表单元素的规范方法

  2. 自定义 Magento 自动加载器的规范方法。

【问题讨论】:

    标签: php forms magento autoload


    【解决方案1】:

    这是一篇旧帖子,但它仍然对某人有用:

    是的,你可以。

    以下代码位于: app/code/local/MyCompany/MyModule/Block/MyForm.php

    class MyCompany_MyModule_Block_MyForm extends Mage_Adminhtml_Block_Widget_Form 
    {       
        protected function _prepareForm()
        {
            $form = new Varien_Data_Form(array(
                'id'        => 'edit_form',
                'action'    => $this->getUrl('*/*/save'),
                'method'    => 'post'
            ));
    
            $fieldset = $form->addFieldset('my_fieldset', array('legend' => 'Your fieldset title')));
    
            //Here is what is interesting us          
            //We add a new type, our type, to the fieldset
            //We call it extended_label
            $fieldset->addType('extended_label','MyCompany_MyModule_Lib_Varien_Data_Form_Element_ExtendedLabel');
    
            $fieldset->addField('mycustom_element', 'extended_label', array(
                'label'         => 'My Custom Element Label',
                'name'          => 'mycustom_element',
                'required'      => false,
                'value'     => $this->getLastEventLabel($lastEvent),
                'bold'      =>  true,
                'label_style'   =>  'font-weight: bold;color:red;',
            ));
        }
    }
    

    这是您的自定义元素的代码,位于 app/code/local/MyCompany/MyModule/Lib/Varien/Data/Form/Element/ExtendedLabel.php

    class MyCompany_MyModule_Lib_Varien_Data_Form_Element_ExtendedLabel extends Varien_Data_Form_Element_Abstract
    {
        public function __construct($attributes=array())
        {
            parent::__construct($attributes);
            $this->setType('label');
        }
    
        public function getElementHtml()
        {
            $html = $this->getBold() ? '<strong>' : '';
            $html.= $this->getEscapedValue();
            $html.= $this->getBold() ? '</strong>' : '';
            $html.= $this->getAfterElementHtml();
            return $html;
        }
    
        public function getLabelHtml($idSuffix = ''){
            if (!is_null($this->getLabel())) {
                $html = '<label for="'.$this->getHtmlId() . $idSuffix . '" style="'.$this->getLabelStyle().'">'.$this->getLabel()
                    . ( $this->getRequired() ? ' <span class="required">*</span>' : '' ).'</label>'."\n";
            }
            else {
                $html = '';
            }
            return $html;
        }
    }
    

    【讨论】:

    • 快速添加到表单的addType 部分:我强烈建议使用 Magento 类工厂而不是使用真正的类名。这更好地遵循 Magento 编码规则并允许重写。所以,不要做$fieldset-&gt;addType('type_name', 'My_Module_Block_Class_Name'),请做$fieldset-&gt;addType('type_name', Mage::getConfig()-&gt;getBlockClassName('my_module/class_name'))
    【解决方案2】:

    Varien_Data_Form_Abstract 类有一个方法addType(),您可以在其中添加新元素类型及其各自的类名。要利用此功能,您可以将块 Mage_Adminhtml_Block_Widget_Form 复制到本地代码池并扩展方法 _getAdditionalElementTypes()

    protected function _getAdditionalElementTypes()
    {
        $types = array(
            'my_type' => 'Namespace_MyModule_Block_Widget_Form_Element_MyType',
        );
    
        return $types;
    }
    

    由于Mage_Adminhtml_Block_Widget_Form 类是所有其他表单类的基类,不幸的是,仅重写配置中的块是行不通的。

    编辑:如果您只需要一种形式的自定义元素类型,您可以覆盖特定类并通过覆盖方法_getAdditionelElementTypes() 在其中添加类型。与将 importend magento 类复制到本地代码池相比,这将是一种更简洁的解决方案。

    EDIT2:查看Mage_Adminhtml_Block_Widget_Form::_setFieldset() 还有另一种可能性:如果属性在frontend_input_renderer 中有值(例如mymodule/element_mytype),则加载具有该名称的块。另请参阅 Mage/Eav/Model/Entity/Attribute/Frontend/Abstract.php 第 160 行。这应该可以在不覆盖任何 Magento 类的情况下工作。

    【讨论】:

    • 是否足以覆盖 _getAdditionalElementTypes() 还是我还需要调用 addType('my_type', 'Namespace_MyModule_Block_Widget_Form_Element_MyType'); ?我是在表单上还是在其中的字段集上调用 addType ?发送!
    【解决方案3】:

    自助服务台再次罢工。看起来 Magento 设置包含路径的方式是,您可以从本地代码分支的 lib(而不仅仅是 Mage_ 命名空间)中删除类文件

    app/code/local/Varien/etc
    

    当自动加载器尝试加载 lib/Varien 类时,它会首先检查您的目录。如果 Varien 创建了与您同名的数据元素,这仍然会让您面临风险,但随着风险的增加,风险相对较低。

    【讨论】:

    • 对我不起作用我很抱歉。 Varien 的 Autoload.php 仅在包含时查看其自己的文件夹(第 93 行)。是否可以通过编程方式设置自动加载的“_collectClasses”或“_isIncludePathDefined”属性,使其在我指定的文件夹中查找?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多