Un modo semplice per aggiungere un set di campi con campi al modulo dell'interfaccia utente
Pubblicato: 2016-08-23In questo articolo creeremo un semplice modulo che aggiungerà un fieldset con campi nel modulo dell'interfaccia utente di modifica del prodotto. Inoltre, creeremo un osservatore per intercettare questi dati durante il salvataggio del prodotto.
Innanzitutto, dobbiamo creare un modulo Vendor_Product:
1. Crea una directory app/codice/Vendor/Prodotto
2. Crea un file di registrazione app/code/Vendor/Product/registration.php con il seguente contenuto:
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Vendor_Prodotto', __DIR__ ); ?>
Crea un file compositore (se prevedi di trasferire il modulo) app/code/Vendor/Module/composer.json :
{ "nome": "fornitore/prodotto-modulo", "descrizione": "N/A", "tipo": "modulo magento2", "versione": "1.0.0", "licenza": [ "OSL-3.0", "AFL-3.0" ], "caricamento automatico": { "File": [ "registrazione.php" ], "psr-4": { "Venditore\\Prodotto\\": "" } } }
Ora, crea il file XML principale app/code/Vendor/Product/etc/module.xml del modulo con la dipendenza dal modulo Magento_Catalog perché la nostra finestra modale verrà aggiunta al suo modulo:
<?versione xml="1.0"?> <config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Vendor_Product" setup_version="1.0.0"> <sequenza> <module name="Magento_Catalog"/> </sequenza> </modulo> </config>
Abilita il modulo inserendo quanto segue: bin/magento module:enable Vendor_Product e bin/magento setup:upgrade nella directory principale di Magento.
Quindi, aggiungi il contenuto del modulo: i metadati del modulo UI e il tipo virtuale per la sua aggiunta.
Crea un file app/codice/Vendor/Product/etc/adminhtml/di.xml. Inseriamo un modificatore all'interno:
<?versione xml="1.0"?> <config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool"> <argomenti> <nome argomento="modificatori" xsi:type="array"> <item name="custom-fieldset" xsi:type="array"> <item name="class" xsi:type="string">Vendor\Product\Ui\DataProvider\Product\Form\Modifier\CustomFieldset</item> <item name="sortOrder" xsi:type="number">10</item> </item> </argomento> </argomenti> </tipo virtuale> </config>
Il modificatore è responsabile dell'aggiunta di dati e di alcune manipolazioni con elementi e componenti del modulo dell'interfaccia utente. Ci sono 2 metodi principali che provengono dall'interfaccia del modificatore (dovrebbero sempre essere presenti):
<?php /** * Copyright 2016 Magento. Tutti i diritti riservati. * Vedere COPYING.txt per i dettagli sulla licenza. */ spazio dei nomi Magento\Ui\DataProvider\Modifier; /** * Class ModifierInterface */ interfaccia ModifierInterface { /** * @param array $dati * @return array */ funzione pubblica editData(array $dati); /** * @param array $meta * @return array */ funzione pubblica modifyMeta(array $meta); } ?>
In questo esempio utilizzeremo il metodo modifyMeta. Il metodo modifyData verrà spiegato nel prossimo articolo.
Ora crea il file modificatore (app/code/Vendor/Product/Ui/DataProvider/Product/Form/Modifier/CustomFieldset.php) con un fieldset personalizzato per la pagina di modifica del prodotto e compilalo con i campi:
<?php spazio dei nomi Vendor\Product\Ui\DataProvider\Product\Form\Modifier; usa Magento\Catalog\Model\Locator\LocatorInterface; usa Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; usa Magento\Framework\Stdlib\ArrayManager; usa Magento\Framework\UrlInterface; usa Magento\Ui\Component\Contenitore; usa Magento\Ui\Component\Form\Fieldset; usa Magento\Ui\Component\Form\Element\DataType\Number; usa Magento\Ui\Component\Form\Element\DataType\Text; usa Magento\Ui\Component\Form\Element\Input; usa Magento\Ui\Component\Form\Element\Select; usa Magento\Ui\Component\Form\Element\MultiSelect; usa Magento\Ui\Component\Form\Field; la classe CustomFieldset estende AbstractModifier { // Indici dei componenti const CUSTOM_FIELDSET_INDEX = 'custom_fieldset'; const CUSTOM_FIELDSET_CONTENT = 'custom_fieldset_content'; const CONTAINER_HEADER_NAME = 'custom_fieldset_content_header'; // Nomi dei campi const FIELD_NAME_TEXT = 'example_text_field'; const FIELD_NAME_SELECT = 'example_select_field'; const FIELD_NAME_MULTISELECT = 'example_multiselect_field'; /** * @var \Magento\Catalog\Model\Locator\LocatorInterface */ localizzatore $ protetto; /** * @var ArrayManager */ protetto $arrayManager; /** * @var UrlInterface */ protetto $urlBuilder; /** * @var array */ protetto $ meta = []; /** * @param LocatorInterface $ localizzatore * @param ArrayManager $arrayManager * @param UrlInterface $urlBuilder */ funzione pubblica __construct( LocatorInterface $ localizzatore, ArrayManager $arrayManager, UrlInterface $urlBuilder ) { $questo->localizzatore = $localizzatore; $questo->arrayManager = $arrayManager; $questo->urlBuilder = $urlBuilder; } /** * Modificatore di dati, non fa nulla nel nostro esempio. * * @param array $dati * @return array */ funzione pubblica editData(array $dati) { restituire $dati; } /** * Modificatore di metadati: aggiunge il nostro fieldset * * @param array $meta * @return array */ funzione pubblica editMeta(array $meta) { $questo->meta = $meta; $questo->aggiungiCustomFieldset(); restituisce $questo->meta; } /** * Unisci i metadati esistenti con i nostri metadati (non sovrascriverli!) * * @ritorno vuoto */ funzione protetta addCustomFieldset() { $questo->meta = array_merge_recursive( $questo->meta, [ static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(), ] ); } /** * Dichiara la nostra configurazione fieldset * * @return array */ funzione protetta getFieldsetConfig() { Restituzione [ 'argomenti' => [ 'dati' => [ 'config' => [ 'label' => __('Titolo campo'), 'componentType' => Set di campi::NAME, 'dataScope' => static::DATA_SCOPE_PRODUCT, // salva i dati nei dati del prodotto 'provider' => statico::DATA_SCOPE_PRODUCT . '_fonte di dati', 'ns' => statico::FORM_NAME, 'comprimibile' => vero, 'sortOrder' => 10, 'aperto' => vero, ], ], ], 'bambini' => [ static::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10), static::FIELD_NAME_TEXT => $this->getTextFieldConfig(20), static::FIELD_NAME_SELECT => $this->getSelectFieldConfig(30), static::FIELD_NAME_MULTISELECT => $this->getMultiSelectFieldConfig(40), ], ]; } /** * Ottieni la configurazione per il contenitore di intestazione * * @param int $sortOrdine * @return array */ funzione protetta getHeaderContainerConfig($sortOrder) { Restituzione [ 'argomenti' => [ 'dati' => [ 'config' => [ 'etichetta' => nullo, 'formElement' => Contenitore::NAME, 'componentType' => Contenitore::NAME, 'template' => 'ui/form/components/compless', 'sortOrder' => $sortOrdine, 'content' => __('Puoi scrivere qualsiasi testo qui'), ], ], ], 'bambini' => [], ]; } /** * Esempio di configurazione del campo di testo * * @param $sortOrdine * @return array */ funzione protetta getTextFieldConfig($sortOrder) { Restituzione [ 'argomenti' => [ 'dati' => [ 'config' => [ 'label' => __('Campo di testo di esempio'), 'formElement' => Campo::NAME, 'componentType' => Input::NAME, 'dataScope' => statico::FIELD_NAME_TEXT, 'dataType' => Numero::NAME, 'sortOrder' => $sortOrdine, ], ], ], ]; } /** * Esempio di configurazione del campo di selezione * * @param $sortOrdine * @return array */ funzione protetta getSelectFieldConfig($sortOrder) { Restituzione [ 'argomenti' => [ 'dati' => [ 'config' => [ 'label' => __('Opzioni Seleziona'), 'componentType' => Campo::NAME, 'formElement' => Seleziona::NOME, 'dataScope' => statico::FIELD_NAME_SELECT, 'dataType' => Testo::NAME, 'sortOrder' => $sortOrdine, 'opzioni' => $this->_getOptions(), 'visibile' => vero, 'disabilitato' => falso, ], ], ], ]; } /** * Esempio di configurazione del campo a selezione multipla * * @param $sortOrdine * @return array */ funzione protetta getMultiSelectFieldConfig($sortOrder) { Restituzione [ 'argomenti' => [ 'dati' => [ 'config' => [ 'label' => __('Opzioni multiselezione'), 'componentType' => Campo::NAME, 'formElement' => MultiSelect::NAME, 'dataScope' => statico::FIELD_NAME_MULTISELECT, 'dataType' => Testo::NAME, 'sortOrder' => $sortOrdine, 'opzioni' => $this->_getOptions(), 'visibile' => vero, 'disabilitato' => falso, ], ], ], ]; } /** * Ottieni opzioni di esempio come array di opzioni: * [ * etichetta => stringa, * valore => id_opzione * ] * * @return array */ funzione protetta _getOptions() { $opzioni = [ 1 => [ 'etichetta' => __('Opzione 1'), 'valore' => 1 ], 2 => [ 'etichetta' => __('Opzione 2'), 'valore' => 2 ], 3 => [ 'etichetta' => __('Opzione 3'), 'valore' => 3 ], ]; ritorno $opzioni; } } ?>
In questo esempio dobbiamo prendere i metadati esistenti del modulo UI e unirli (non riscrivere!) Con i nostri nuovi dati:
<?php /** * Unisci i metadati esistenti con i nostri metadati (non sovrascriverli!) * * @ritorno vuoto */ funzione protetta addCustomFieldset() { $questo->meta = array_merge_recursive( $questo->meta, [ static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(), ] ); } ?>
Al termine, aggiungi il nuovo fieldset al metodo getFieldsetConfig:
<?php /** * Dichiara la nostra configurazione fieldset * * @return array */ funzione protetta getFieldsetConfig() { Restituzione [ 'argomenti' => [ 'dati' => [ 'config' => [ 'label' => __('Titolo campo'), 'componentType' => Set di campi::NAME, 'dataScope' => static::DATA_SCOPE_PRODUCT, // salva i dati nei dati del prodotto 'provider' => statico::DATA_SCOPE_PRODUCT . '_fonte di dati', 'ns' => statico::FORM_NAME, 'comprimibile' => vero, 'sortOrder' => 10, 'aperto' => vero, ], ], ], 'bambini' => [ static::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10), static::FIELD_NAME_TEXT => $this->getTextFieldConfig(20), static::FIELD_NAME_SELECT => $this->getSelectFieldConfig(30), static::FIELD_NAME_MULTISELECT => $this->getMultiSelectFieldConfig(40), ], ]; } ?>
Ereditiamo dal modificatore di modulo dell'interfaccia utente del prodotto astratto e utilizziamo il suo spazio dei nomi e i suoi dati come provider: 'provider' => static::DATA_SCOPE_PRODUCT . '_data_source' (dove DATA_SCOPE_PRODUCT è la riga 'data.product').
L'opzione componentType è una delle opzioni principali ed è responsabile del tipo di componente. L'opzione pieghevole è responsabile del collasso e dell'espansione del nostro fieldset. E l'opzione di apertura definisce se il fieldset sarà aperto per impostazione predefinita durante il disegno del modulo.
Quindi, di conseguenza, aggiungiamo un'intestazione al nostro fieldset nel metodo getHeaderContainerConfig e 3 esempi di campi: testo, select e multiselect. Tuttavia, il nostro prodotto e il nostro modulo non riceveranno dati finché non li aggiungiamo al metodo modifyData. Ma abbiamo la possibilità di trasmettere e intercettare i dati durante il salvataggio.
Vediamo come appare il modulo:
Il salvataggio dei dati avviene all'interno del file del controller del prodotto vendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php nel metodo di esecuzione principale. Se tutto è stato fatto nel modo giusto, i nostri dati verranno visualizzati correttamente nei dati di input di questo metodo:
Nota, se il tuo prodotto non ha quegli attributi dall'inizio, dovresti salvarli manualmente. Puoi farlo nell'osservatore.
Innanzitutto, dichiaralo nel file app/code/Vendor/Product/etc/adminhtml/events.xml (stiamo usando l'ambito adminhtml perché il modulo non esiste sul front-end):
<?versione xml="1.0"?> <config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <nome evento="catalog_product_save_after"> <observer name="save_example_data" instance="Vendor\Product\Observer\ProductSaveAfter" /> </evento> </config>
Quindi, crea la classe dell'osservatore che abbiamo indicato nell'attributo dell'istanza: app/code/Vendor/Product/Observer/ProductSaveAfter.php:
<?php spazio dei nomi Fornitore\Prodotto\Osservatore; usa \Magento\Framework\Event\ObserverInterface; usa \Magento\Framework\Event\Observer come EventObserver; usa Vendor\Product\Ui\DataProvider\Product\Form\Modifier\CustomFieldset; classe ProductSaveAfter implementa ObserverInterface { /** * @param EventObserver $osservatore */ funzione pubblica esegui(\Magento\Framework\Event\Observer $observer) { /** @var \Magento\Catalogo\Modello\Prodotto $prodotto */ $prodotto = $osservatore->getEvent()->getProduct(); se (!$prodotto) { Restituzione; } $exampleTextField = $prodotto->getData(CustomFieldset::FIELD_NAME_TEXT); $exampleSelectField = $product->getData(CustomFieldset::FIELD_NAME_SELECT); $exampleMultiSelectField = $product->getData(CustomFieldset::FIELD_NAME_MULTISELECT); // Manipola i dati qui } } ?>
I dati nell'osservatore:
Ora puoi chiamare il tuo modello dall'osservatore e salvarci i dati o modificarlo come desideri.
Stai attento! Se il salvataggio del tuo modello è collegato al salvataggio del prodotto, può portare alla ricorrenza.