php 将自定义表单元素添加到 Adminhtml 表单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1993597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:34:33  来源:igfitidea点击:

Adding a Custom Form Element to an Adminhtml Form

phpformsmagentoautoload

提问by Alan Storm

Is there a way to add a custom form element to a Magento Adminhtml form without placing the custom element in the lib/Varianfolder?

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

I've tracked down the code that's essentially a Varian_Data_Form_Element_factory

我已经找到了本质上是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;
}

So, if I'm reading this correctly, I ensure that an EAV attribute's frontend returns a specific fieldType, (such as supertextfield) and the system will instantiate/render a Varien_Data_Form_Element_Supertextfieldwhen displaying this attribute's editing form.

因此,如果我正确阅读本文,我会确保 EAV 属性的前端返回特定的 fieldType(例如supertextfield),并且系统将Varien_Data_Form_Element_Supertextfield在显示此属性的编辑表单时实例化/呈现 a 。

This is well and good, but it means I need to include my custom form element in the lib/Varianfolder hierarchy. Given how module oriented Magento is, it seems like this is doing it wrong.

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

I realize I could jank around with a custo autoloader or symlinks in the lib, but I'm primarily interested in learning if there's

我意识到我可以在库中使用 custo 自动加载器或符号链接,但我主要想了解是否有

  1. A canonical way to add custom form elements for attributes

  2. A canonical way to customize the Magento autoloader.

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

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

采纳答案by Alan Storm

Self help desk strikes again. It looks like Magento sets up include paths in such a way that you can drop class files from lib (not just from the Mage_ namespace) in your local code branch

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

app/code/local/Varien/etc

When the autoloader tries to load a lib/Varien class, it will check your directory first. This still puts you at risk if Varien ever creates a data element with the same name as yours, but as risks go it's relatively low.

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

回答by liquidity

This is an old post but it still can be usefull for someone :

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

yes you can.

是的你可以。

The code below is located in : app/code/local/MyCompany/MyModule/Block/MyForm.php

下面的代码位于: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;',
        ));
    }
}

Here is the code of your custom element, which is located in app/code/local/MyCompany/MyModule/Lib/Varien/Data/Form/Element/ExtendedLabel.php:

这是您的自定义元素的代码,它位于 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;
    }
}

回答by Uwe Mesecke

The class Varien_Data_Form_Abstracthas a method addType()where you can add new element types and their respective class names. To exploit this functionality you can copy the block Mage_Adminhtml_Block_Widget_Formto the local code pool and extend the method _getAdditionalElementTypes():

该类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;
}

As the class Mage_Adminhtml_Block_Widget_Formis a base class for all the other form classes, unfortunately just rewriting the block in the config will not work.

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

EDIT: If you need the custom element types in just one form you could override the specific class and add the type there by overriding the method _getAdditionelElementTypes(). This would be a cleaner solution than copying an importend magento class to the local code pool.

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

EDIT2: Looking at Mage_Adminhtml_Block_Widget_Form::_setFieldset()there is another possibility: If the attribute has a value in frontend_input_renderer(e.g. mymodule/element_mytype) then a block with that name is loaded. See also Mage/Eav/Model/Entity/Attribute/Frontend/Abstract.php line 160. This should work without overriding any Magento classes.

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