Adminhtml - Hinzufügen einer benutzerdefinierten Vorlage für ein benutzerdefiniertes Produktattribut

7

Ich habe bereits eine benutzerdefinierte Registerkarte und ein benutzerdefiniertes Attribut wie dieses hinzugefügt.

Benutzerdefinierte Vorlage für Produktattribute

Ich habe auch eine benutzerdefinierte Spalte in der Datenbank für Attribute mit dem Namen erstellt custom_values.

Jetzt möchte ich eine benutzerdefinierte Vorlage für dieses Attribut hinzufügen (im Bild ist das Attribut Aktiv).

In meiner benutzerdefinierten Vorlage enthält es ein Formular (möglicherweise harter Code). Beim Speichern des Produkts möchte ich Formulardaten serialisieren und dann dem custom_valuesAttribut Active zuweisen

Fragen sind:

  1. Hinzufügen einer benutzerdefinierten Vorlage für ein bestimmtes Produktattribut in adminhtml

  2. So beobachten Sie das Produktspeicherereignis, um Formulardaten zu serialisieren und dann einen Wert zuzuweisen, bevor es tatsächlich gespeichert wird

Tran Dinh Khanh
quelle

Antworten:

15

Zuallererst ... schöne Frage. Hat mich wirklich interessiert.
Hier ist ein Beispiel, wie Sie ein Attribut mit einem benutzerdefinierten Renderer (Vorlage) erstellen und den Wert serialisiert speichern können.
In diesem Beispiel habe ich ein Attribut erstellt, das zwei Texteingaben enthält, aber Sie können dort grundsätzlich alles einfügen.

Ich empfehle, ein benutzerdefiniertes Modul für Ihr Attribut zu erstellen. Nennen wir diese Erweiterung Easylife_Attr.
Sie benötigen die folgenden Dateien.
app/etc/module/Easylife_Attr.xml- die Deklarationsdatei.

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Attr>
            <codePool>local</codePool>
            <active>true</active>
            <depends>
                <Mage_Catalog /><!-- should depend on mage_catalog-->
                <Mage_Adminhtml /><!-- should depend on mage_adminhtml-->
            </depends>
        </Easylife_Attr>
    </modules>
</config>

app/code/local/Easylife/Attr/etc/config.xml - die Konfigurationsdatei

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Attr>
            <version>0.0.1</version>
        </Easylife_Attr>
    </modules>
    <global>
        <resources>
            <easylife_attr_setup>
                <setup>
                    <module>Easylife_Attr</module>
                    <class>Mage_Catalog_Model_Resource_Setup</class><!-- use the catalog setup so you can add your attribute -->
                </setup>
            </easylife_attr_setup>
        </resources>
        <models>
            <easylife_attr>
                <class>Easylife_Attr_Model</class>
            </easylife_attr>
        </models>
        <blocks>
            <easylife_attr>
                <class>Easylife_Attr_Block</class>
            </easylife_attr>
        </blocks>
    </global>
    <adminhtml>
        <events>
            <adminhtml_catalog_product_edit_prepare_form><!-- event needed to add a template to a certain attribute -->
                <observers>
                    <easylife>
                        <class>Easylife_Attr_Model_Observer</class>
                        <method>convertCustomValues</method>
                    </easylife>
                </observers>
            </adminhtml_catalog_product_edit_prepare_form>
        </events>
    </adminhtml>
</config>

app/code/local/Easylife/Attr/sql/easylife_attr_setup/install-0.0.1.php- das Installationsskript. Es wird Ihr Attribut hinzufügen

<?php
$this->addAttribute('catalog_product', 'custom_values', array(
    'group'         => 'Custom values', //the tab name where the attribute will be placed
    'input'         => 'textarea', //this is not really important
    'type'          => 'text', //attribute type should be text to support long values
    'label'         => 'Custom values', //the attribute label
    'backend'       => 'easylife_attr/custom',  //a custom backend model that will handle serialization and deserialization
    'visible'       => true,
    'required'      => false,
    'visible_on_front' => true,
    'global'        => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL, //scope can be anything but if it's not global you will need some changes to support store view values
));

Nun der lustige Teil.

app/code/local/Easylife/Attr/Model/Observer.php - die Beobachtung, die die Attributvorlage ändert

<?php
class Easylife_Attr_Model_Observer {
    public function convertCustomValues($observer) {
        $form = $observer->getEvent()->getForm();
        $customValues = $form->getElement('custom_values');
        if ($customValues) {
            $customValues->setRenderer(
                Mage::app()->getLayout()->createBlock('easylife_attr/adminhtml_product_custom')
            ); //set a custom renderer to your attribute
        }
    }
}

app/code/local/Easylife/Attr/Block/Adminhtml/Product/Custom.php - der benutzerdefinierte Rendererblock

<?php
class Easylife_Attr_Block_Adminhtml_Product_Custom
    extends Mage_Adminhtml_Block_Widget
    implements Varien_Data_Form_Element_Renderer_Interface {
    public function __construct()
    {
        $this->setTemplate('easylife_attr/product/custom.phtml'); //set a template
    }
    public function render(Varien_Data_Form_Element_Abstract $element) {
        $this->setElement($element);
        return $this->toHtml();
    }
}

app/design/adminhtml/default/default/template/easylife_attr/product/custom.phtml - die Vorlage für das Attribut.

<?php
$_htmlId = $this->getElement()->getHtmlId();
$_htmlClass = $this->getElement()->getClass();
$_htmlName = $this->getElement()->getName();
$_readonly = $this->getElement()->getReadonly();
$value = $this->getElement()->getValue();
//get the values for the 2 text elements
$someField = (isset($value['some_field']) ? $value['some_field'] : '');
$otherField = (isset($value['other_field']) ? $value['other_field'] : '');

?>
<tr> <!-- should be wrapped in a tr element to fit in the admin template -->
    <td class="label"><?php echo $this->getElement()->getLabel(); ?></td>
    <td colspan="10" class="grid">
        <table cellspacing="0" class="data border">
            <col width="120" />
            <col />
            <thead>
            <tr class="headings">
                <th><?php echo $this->__('Some field')?></th>
                <th><?php echo $this->__('Other Field')?></th>
            </tr>
            </thead>
            <tbody id="<?php echo $_htmlId; ?>_container"></tbody>
            <tfoot>
            <tr>
                <td><input type="text" name="<?php echo $_htmlName; ?>[some_field]" value="<?php echo $someField?>"<?php echo ($_readonly) ? ' readonly="readonly"' : ''?>> </td>
                <td><input type="text" name="<?php echo $_htmlName; ?>[other_field]" value="<?php echo $otherField?>"<?php echo ($_readonly) ? ' readonly="readonly"' : ''?>></td>
            </tr>
            </tfoot>
        </table>
    </td>
</tr>

app/code/local/Easylife/Attr/Model/Custom.php - das Modell, das die Serialisierung und Deserialisierung übernimmt.

<?php
class Easylife_Attr_Model_Custom extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract{
    public function beforeSave($object) 
    {
        //before sabing the product check if the attribute `custom_values` is array.
        //if it is, serialize it for saving in the db
        $attributeCode = $this->getAttribute()->getAttributeCode();
        $data = $object->getData($attributeCode);
        if (is_array($data)) {
            $data = array_filter($data);
            $object->setData($attributeCode, serialize($data));
        }
        return parent::beforeSave($object);
    }
    public function afterLoad($object) {
        //after loading the product, check if the value for custom_values is not an array. If it's not try to unserialize the value.
        $attributeCode = $this->getAttribute()->getAttributeCode();
        $data = $object->getData($attributeCode);
        if (!is_array($data)) {
            $object->setData($attributeCode, @unserialize($data));
        }
        return parent::afterLoad($object);
    }
}

Das ist es. So würde das Attribut im Backend aussehen:

Benutzerdefiniertes Vorlagenattribut

Marius
quelle
Du bist der Mann! Machen Sie die Leute immer glücklich mit Ihrer Antwort. Ich versuche es jetzt und markiere dann deine Antwort als akzeptiert. Danke Danke.
Tran Dinh Khanh
aber wie man Bilder hinzufügt, Editor für Textbereich, Kalender für Datumsfeld.
Pradeep Singh
@ PradeepSingh. Wie in der Antwort erläutert, wird das, was Sie auf der Registerkarte "Benutzerdefiniert" sehen, von einer HTML-Datei gerendert app/design/adminhtml/default/default/template/easylife_attr/product/custom.phtml. Grundsätzlich können Sie dieser HTML-Datei alles hinzufügen, was Sie wollen. Alle Arten von Feldern oder Javascripts, die Sie benötigen.
Marius
@Marius. Ich möchte mehrere Textfelder hinzufügen und Editor bedeutet, dass ein Block ein Textfeld und einen Editor sowie zwei Datumsfelder und ein Auswahlfeld hat und mehrere Bilder hochlädt. Nachdem diese Schaltfläche "Weitere hinzufügen" vorhanden ist, klicken Sie auf die Schaltfläche "Hinzufügen". Mit Ajax können Sie einen weiteren Block hinzufügen. Dies bedeutet, dass Sie Block1, Block2 hinzufügen können.
Pradeep Singh
1
@Marius Gibt es einen solchen Trick in Magento2? Weil magento2 UI-Komponente verwendet.
Keyur Shah