フィールドを含むフィールドセットを 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);
// ここでデータを操作します
}
}
?>オブザーバーのデータ:

これで、オブザーバーから独自のモデルを呼び出して、データを保存したり、必要に応じて変更したりできます。
気をつけて! モデルの保存が製品の保存に関連している場合、再帰につながる可能性があります。
