フィールドを含むフィールドセットを UI フォームに追加する簡単な方法
公開: 2016-08-23この記事では、製品編集 UI フォームにフィールドを含むフィールドセットを追加する単純なモジュールを作成します。 また、製品の保存中にこのデータを傍受するためのオブザーバーを作成します。
まず、Vendor_Product モジュールを作成する必要があります。
1. ディレクトリ app/code/Vendor/Product を作成します
2. 次の内容の登録ファイル app/code/Vendor/Product/registration.php を作成します。
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Vendor_Product', __DIR__ ); ?>
composer ファイルを作成します (モジュールを転送する場合) app/code/Vendor/Module/composer.json :
{ "name": "vendor/module-product", "説明": "該当なし", "type": "magento2-module", "バージョン": "1.0.0", "ライセンス": [ "OSL-3.0", 「AFL-3.0」 ]、 "オートロード": { "ファイル": [ 「登録.php」 ]、 "psr-4": { "ベンダー\\製品\\": "" } } }
次に、モーダル ウィンドウがそのフォームに追加されるため、Magento_Catalog モジュールからの依存関係を使用して、モジュールのメイン XML ファイル app/code/Vendor/Product/etc/module.xml を作成します。
<?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"> <シーケンス> <モジュール名="Magento_Catalog"/> </シーケンス> </モジュール> </config>
次のように入力してモジュールを有効にします: bin/magento module:enable Vendor_Product および bin/magento setup:upgrade をルート Magento ディレクトリに入力します。
次に、モジュールの内容を追加します: UI 形式のメタデータとその追加用の仮想型。
ファイル app/code/Vendor/Product/etc/adminhtml/di.xml を作成します。 内部に修飾子を配置します。
<?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"> <引数> <argument name="modifiers" 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> </アイテム> </引数> </引数> </virtualType> </config>
修飾子は、データの追加と、要素および UI フォーム コンポーネントを使用した一部の操作を担当します。 モディファイアのインターフェイスから派生した 2 つの主要なメソッドがあります (常に存在する必要があります)。
<?php /** * 著作権 2016 マジェント。 全著作権所有。 * ライセンスの詳細については、COPYING.txt を参照してください。 */ 名前空間 Magento\Ui\DataProvider\Modifier; /** * クラス ModifierInterface */ インターフェイス ModifierInterface { /** * @param 配列 $data * @return 配列 */ public function modifyData(array $data); /** * @param 配列 $meta * @return 配列 */ public function modifyMeta(array $meta); } ?>
この例では、modifyMeta メソッドを使用します。 modifyData メソッドについては、次の記事で説明します。
ここで、製品編集ページ用のカスタム フィールドセットを含む修飾子ファイル (app/code/Vendor/Product/Ui/DataProvider/Product/Form/Modifier/CustomFieldset.php) を作成し、フィールドを入力します。
<?php namespace Vendor\Product\Ui\DataProvider\Product\Form\Modifier; Magento\Catalog\Model\Locator\LocatorInterface を使用します。 Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier を使用します。 Magento\Framework\Stdlib\ArrayManager を使用します。 Magento\Framework\UrlInterface を使用します。 Magento\Ui\Component\Container を使用します。 Magento\Ui\Component\Form\Fieldset を使用します。 Magento\Ui\Component\Form\Element\DataType\Number を使用します。 Magento\Ui\Component\Form\Element\DataType\Text を使用します。 Magento\Ui\Component\Form\Element\Input を使用します。 Magento\Ui\Component\Form\Element\Select を使用します。 Magento\Ui\Component\Form\Element\MultiSelect を使用します。 Magento\Ui\Component\Form\Field を使用します。 クラス CustomFieldset は AbstractModifier を拡張します { // コンポーネントのインデックス const CUSTOM_FIELDSET_INDEX = 'custom_fieldset'; const CUSTOM_FIELDSET_CONTENT = 'custom_fieldset_content'; const CONTAINER_HEADER_NAME = 'custom_fieldset_content_header'; // フィールド名 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 */ 保護された $locator; /** * @var ArrayManager */ 保護された $arrayManager; /** * @var URLInterface */ 保護された $urlBuilder; /** * @var 配列 */ 保護された $meta = []; /** * @param LocatorInterface $locator * @param ArrayManager $arrayManager * @param UrlInterface $urlBuilder */ パブリック関数 __construct( LocatorInterface $ロケータ、 ArrayManager $arrayManager, URL インターフェース $urlBuilder ) { $this->locator = $locator; $this->arrayManager = $arrayManager; $this->urlBuilder = $urlBuilder; } /** * データ修飾子は、この例では何もしません。 * * @param 配列 $data * @return 配列 */ public function modifyData(配列 $data) { $データを返します。 } /** * メタデータ修飾子: 私たちのフィールドセットを追加します * * @param 配列 $meta * @return 配列 */ public function modifyMeta(配列 $meta) { $this->meta = $meta; $this->addCustomFieldset(); $this->meta を返します。 } /** * 既存のメタデータを私たちのメタデータとマージします (上書きしないでください!) * * @return void */ 保護された関数 addCustomFieldset() { $this->meta = array_merge_recursive( $this->メタ、 [ static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(), ] ); } /** * 私たちのフィールドセット構成を宣言します * * @return 配列 */ 保護された関数 getFieldsetConfig() { 戻る [ '引数' => [ 'データ' => [ '設定' => [ 'ラベル' => __('フィールドセットのタイトル'), 'componentType' => フィールドセット::名前, 'dataScope' => static::DATA_SCOPE_PRODUCT, // 商品データにデータを保存 'プロバイダー' => static::DATA_SCOPE_PRODUCT . '_情報源'、 'ns' => static::FORM_NAME, '折りたたみ可能' => true, 'sortOrder' => 10, 「開かれた」=>真、 ]、 ]、 ]、 '子供' => [ 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), ]、 ]; } /** * ヘッダー コンテナーの構成を取得する * * @param int $sortOrder * @return 配列 */ 保護された関数 getHeaderContainerConfig($sortOrder) { 戻る [ '引数' => [ 'データ' => [ '設定' => [ 'ラベル' => null, 'formElement' => コンテナ::名前, 'componentType' => コンテナ::名前, 'テンプレート' => 'UI/フォーム/コンポーネント/複合', 'sortOrder' => $sortOrder, 'content' => __('ここに任意のテキストを記述できます'), ]、 ]、 ]、 '子供' => [], ]; } /** * テキストフィールドの設定例 * * @param $sortOrder * @return 配列 */ 保護された関数 getTextFieldConfig($sortOrder) { 戻る [ '引数' => [ 'データ' => [ '設定' => [ 'label' => __('サンプル テキスト フィールド'), 'formElement' => フィールド::名前, 'componentType' => 入力::名前, 'dataScope' => static::FIELD_NAME_TEXT, 'dataType' => 番号::名前、 'sortOrder' => $sortOrder, ]、 ]、 ]、 ]; } /** * 選択フィールドの設定例 * * @param $sortOrder * @return 配列 */ 保護された関数 getSelectFieldConfig($sortOrder) { 戻る [ '引数' => [ 'データ' => [ '設定' => [ 'ラベル' => __('オプション選択'), 'componentType' => フィールド::名前, 'formElement' => Select::NAME, 'dataScope' => static::FIELD_NAME_SELECT, 'dataType' => テキスト::名前、 'sortOrder' => $sortOrder, 'オプション' => $this->_getOptions(), 「目に見える」=>真、 「無効」 => false、 ]、 ]、 ]、 ]; } /** * 複数選択フィールド構成の例 * * @param $sortOrder * @return 配列 */ 保護された関数 getMultiSelectFieldConfig($sortOrder) { 戻る [ '引数' => [ 'データ' => [ '設定' => [ 'label' => __('Options Multiselect'), 'componentType' => フィールド::名前, 'formElement' => MultiSelect::NAME, 'dataScope' => static::FIELD_NAME_MULTISELECT, 'dataType' => テキスト::名前、 'sortOrder' => $sortOrder, 'オプション' => $this->_getOptions(), 「目に見える」=>真、 「無効」 => false、 ]、 ]、 ]、 ]; } /** * オプション配列としてサンプル オプションを取得します。 * [ * ラベル => 文字列、 * 値 => option_id * ] * * @return 配列 */ 保護された関数 _getOptions() { $options = [ 1 => [ 'ラベル' => __('オプション 1'), '値' => 1 ]、 2 => [ 'ラベル' => __('オプション 2'), '値' => 2 ]、 3 => [ 'ラベル' => __('オプション 3'), '値' => 3 ]、 ]; $オプションを返します。 } } ?>
この例では、既存の UI フォームのメタデータを取得して、新しいデータとマージする必要があります (書き換えではありません!)。
<?php /** * 既存のメタデータを私たちのメタデータとマージします (上書きしないでください!) * * @return void */ 保護された関数 addCustomFieldset() { $this->meta = array_merge_recursive( $this->メタ、 [ static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(), ] ); } ?>
完了したら、新しいフィールドセットを getFieldsetConfig メソッドに追加します。
<?php /** * 私たちのフィールドセット構成を宣言します * * @return 配列 */ 保護された関数 getFieldsetConfig() { 戻る [ '引数' => [ 'データ' => [ '設定' => [ 'ラベル' => __('フィールドセットのタイトル'), 'componentType' => フィールドセット::名前, 'dataScope' => static::DATA_SCOPE_PRODUCT, // 商品データにデータを保存 'プロバイダー' => static::DATA_SCOPE_PRODUCT . '_情報源'、 'ns' => static::FORM_NAME, '折りたたみ可能' => true, 'sortOrder' => 10, 「開かれた」=>真、 ]、 ]、 ]、 '子供' => [ 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), ]、 ]; } ?>
抽象製品の UI フォーム修飾子から継承し、その名前空間とデータをプロバイダーとして使用します: 'provider' => static::DATA_SCOPE_PRODUCT 。 '_data_source' (ここで、DATA_SCOPE_PRODUCT は 'data.product' 行です)。
componentType オプションは主要なオプションの 1 つであり、コンポーネント タイプを担当します。 折りたたみ可能なオプションは、フィールドセットの折りたたみと展開を担当します。 open オプションは、フォームの描画中にデフォルトでフィールドセットを開くかどうかを定義します。
次に、getHeaderContainerConfig メソッドでヘッダーをフィールドセットに追加し、フィールドの 3 つの例: text、select、および multiselect を追加します。 ただし、modifyData メソッドにデータを追加するまで、製品とフォームはデータを受け取りません。 ただし、保存中にデータを送信および傍受する機能があります。
フォームがどのように見えるか見てみましょう:
データの保存は、メインの execute メソッドの製品コントローラー ファイル vendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php 内で行われます。 すべてが正しい方法で行われた場合、データはこのメソッドの入力データに正しく表示されます。
製品に最初からこれらの属性がない場合は、手動で保存する必要があります。 オブザーバーでこれを行うことができます。
まず、app/code/Vendor/Product/etc/adminhtml/events.xml ファイルで宣言します (フォームがフロントエンドに存在しないため、adminhtml スコープを使用しています)。
<?xml バージョン="1.0"?> <config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="catalog_product_save_after"> <observer name="save_example_data" instance="Vendor\Product\Observer\ProductSaveAfter" /> </イベント> </config>
次に、インスタンス属性で指定したオブザーバーのクラスを作成します – app/code/Vendor/Product/Observer/ProductSaveAfter.php:
<?php 名前空間ベンダー\製品\オブザーバー; \Magento\Framework\Event\ObserverInterface を使用します。 \Magento\Framework\Event\Observer を EventObserver として使用します。 Vendor\Product\Ui\DataProvider\Product\Form\Modifier\CustomFieldset を使用します。 クラス ProductSaveAfter は ObserverInterface を実装します { /** * @param EventObserver $observer */ public function execute(\Magento\Framework\Event\Observer $observer) { /** @var \Magento\Catalog\Model\Product $product */ $product = $observer->getEvent()->getProduct(); if (!$製品) { 戻る; } $exampleTextField = $product->getData(CustomFieldset::FIELD_NAME_TEXT); $exampleSelectField = $product->getData(CustomFieldset::FIELD_NAME_SELECT); $exampleMultiSelectField = $product->getData(CustomFieldset::FIELD_NAME_MULTISELECT); // ここでデータを操作します } } ?>
オブザーバーのデータ:
これで、オブザーバーから独自のモデルを呼び出して、データを保存したり、必要に応じて変更したりできます。
気をつけて! モデルの保存が製品の保存に関連している場合、再帰につながる可能性があります。