Cara Menambahkan Bidang Kustom untuk Nilai Opsi di Opsi Produk Tingkat Lanjut
Diterbitkan: 2020-11-20Dari artikel sebelumnya, Anda telah mempelajari cara membuat bidang opsi kustom Magento. Kami juga telah menemukan cara menampilkan data lapangan pada front-end halaman produk dan halaman pemesanan di panel admin.
Sekarang apa?
Mari pelajari cara menambahkan bidang GTIN khusus yang sama untuk nilai opsi dan menampilkannya di bagian depan halaman produk.
Daftar isi
- Langkah 1. Pembuatan Modul Baru
- 1. komposer.json
- 2. etc/module.xml
- 3. registrasi.php
- Langkah 2. Menambahkan Bidang Baru ke Basis Data
- Langkah #3. Menambahkan Logika untuk Bekerja dengan Backend
- Langkah #4. Menambahkan Pengaturan ke Nonaktifkan Tampilan Bidang GTIN untuk Konfigurasi Opsi Produk Tingkat Lanjut
- Langkah #5. Menampilkan Bidang Baru di Front-End Halaman Produk
Langkah 1. Pembuatan Modul Baru
Mari kita mulai dengan pembuatan modul baru, yang prosesnya dibahas secara rinci dalam posting blog Mageworx ini.
Jadi, tanpa basa-basi lagi, berikut adalah kode yang kita perlukan:
1. komposer.json
{ "name": "mageworx/module-optionvaluegtin", "description": "N/A", "require": { "magento/framework" : ">=100.1.0 <101", "magento/module-catalog": ">=101.0.0 <104" }, "type": "magento2-module", "version": "1.0.0", "license": [ "OSL-3.0", "AFL-3.0" ], "autoload": { "files": [ "registration.php" ], "psr-4": { "VendorName\\OptionValueGtin\\": "" } } }
2. etc/module.xml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="VendorName_OptionValueGtin" setup_version="1.0.0"> <sequence> <module name="Magento_Catalog"/> <module name="MageWorx_OptionBase"/> </sequence> </module> </config>
3. registrasi.php
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'VendorName_OptionValueGtin', __DIR__ );
Langkah 2. Menambahkan Bidang Baru ke Basis Data
Saatnya membuat bidang GTIN dan menambahkannya ke tabel yang sesuai di database.
Saat kami menambahkan bidang untuk nilai opsi, tabel `catalog_product_option_type_value` akan diperlukan.
Mari kita buat file berikut:
`app/code/VendorName/OptionValueGtin/Setup/InstallSchema.php`
<?php namespace VendorName\OptionValueGtin\Setup; use Magento\Framework\Setup\InstallSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; use Magento\Framework\DB\Ddl\Table; class InstallSchema implements InstallSchemaInterface { public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $setup->startSetup(); $setup->getConnection()->addColumn( $setup->getTable('catalog_product_option_type_value'), 'gtin', [ 'type' => Table::TYPE_TEXT, 'nullable' => true, 'default' => null, 'comment' => 'Gtin (added by MageWorx Option Value Gtin)', ] ); $setup->endSetup(); } }
Langkah #3. Menambahkan Logika untuk Bekerja dengan Backend
Gunakan mekanisme pengubah kumpulan untuk Magento menambahkan bidang ke opsi khusus.
Mari kita buat file berikut:
`app/code/VendorName/OptionValueGtin/etc/adminhtml/di.xml`
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <virtualType name="MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="mageworx-option-value-gtin" xsi:type="array"> <item name="class" xsi:type="string">MageWorx\OptionValueGtin\Ui\DataProvider\Product\Form\Modifier\OptionValueGtin</item> <item name="sortOrder" xsi:type="number">72</item> </item> </argument> </arguments> </virtualType> </config>
Di Sini:
Kami menambahkan pengubah kami ke kumpulan umum ekstensi Opsi Produk Lanjutan untuk Magento 2
`MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\Pool`.
`VendorName\OptionValueGtin\Ui\DataProvider\Product\Form\Modifier\OptionValueGtin` adalah kelas pengubah.
Di bawah:
Lihat kode yang memungkinkan penambahan bidang kita ke formulir `app/code/VendorName/OptionValueGtin/Ui/DataProvider/Product/Form/Modifier/OptionValueGtin.php`:
<?php namespace VendorName\OptionValueGtin\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions; use Magento\Ui\Component\Form\Element\Input; use Magento\Ui\Component\Form\Element\DataType\Number; use Magento\Ui\Component\Form\Field; use MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\ModifierInterface; class OptionValueGtin extends AbstractModifier implements ModifierInterface { /** * @var array */ protected $meta = []; /** * {@inheritdoc} */ public function modifyData(array $data) { return $data; } /** * {@inheritdoc} */ public function modifyMeta(array $meta) { $this->meta = $meta; $this->addFields(); return $this->meta; } /** * Adds fields to the meta-data */ protected function addFields() { $groupCustomOptionsName = CustomOptions::GROUP_CUSTOM_OPTIONS_NAME; $optionContainerName = CustomOptions::CONTAINER_OPTION; // Add fields to the values $valueFeaturesFields = $this->getValueFieldsConfig(); $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children']['values']['children']['record']['children'] = array_replace_recursive( $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children']['values']['children']['record']['children'], $valueFeaturesFields ); } /** * The custom option fields config * * @return array */ protected function getValueFieldsConfig() { $fields['gtin'] = $this->getGtinFieldConfig(); return $fields; } /** * Get gtin field config * * @return array */ protected function getGtinFieldConfig() { return [ 'arguments' => [ 'data' => [ 'config' => [ 'label' => __('GTIN'), 'componentType' => Field::NAME, 'formElement' => Input::NAME, 'dataType' => Number::NAME, 'dataScope' => 'gtin', 'sortOrder' => 92 ], ], ], ]; } /** * Check is current modifier for the product only * * @return bool */ public function isProductScopeOnly() { return false; } /** * Get sort order of modifier to load modifiers in the right order * * @return int */ public function getSortOrder() { return 32; } }
Sekarang, instal ekstensi dan periksa apakah semuanya dilakukan dengan benar, yaitu,
- php bin/magento modul: aktifkan VendorName_OptionValueGtin
- pengaturan bin/magento php: tingkatkan
- php bin/cache magento: flush
Seperti yang Anda lihat, bidang yang baru ditambahkan akan ditampilkan sekarang:
Langkah #4. Menambahkan Pengaturan ke Nonaktifkan Tampilan Bidang GTIN untuk Konfigurasi Opsi Produk Tingkat Lanjut
Bagaimana dengan mencampur artikel kami sedikit?
Saya menawarkan untuk menambahkan beberapa fungsi baru―kemampuan untuk mengaktifkan/menonaktifkan tampilan bidang GTIN untuk nilai opsi pada halaman produk front-end.
Anda perlu membuat file:
`app/code/VendorName/OptionValueGtin/etc/adminhtml/system.xml`
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> <system> <tab sortOrder="2001"> <label>MageWorx</label> </tab> <section translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label><![CDATA[Advanced Product Options]]></label> <tab>mageworx</tab> <resource>VendorName_OptionValueGtin::config_optionvaluegtin</resource> <group translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1"> <label><![CDATA[Option Value GTIN]]></label> <field translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1"> <label><![CDATA[Enable Option's Value 'GTIN']]></label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> </group> </section> </system> </config>
Untuk kesederhanaan:
Kami akan menambahkan tab Opsi Nilai GTIN baru ke konfigurasi ekstensi Opsi Produk Lanjutan kami. Anda juga harus dapat membuat tab di modul Anda.
Kelas Pembantu baru harus dibuat. Di sana, kita akan mendapatkan data tentang pengaturan.
Jadi, mari kita buat dan isi kelas berikut:
`app/code/VendorName/OptionValueGtin/Helper/Data.php`
<?php namespace VendorName\OptionValueGtin\Helper; use Magento\Framework\App\Helper\AbstractHelper; use Magento\Store\Model\ScopeInterface; use Magento\Framework\App\Helper\Context; class Data extends AbstractHelper { const XML_PATH_DEFAULT_OPTION_VALUE_GTIN = 'mageworx_apo/optionvaluegtin/use_optionvaluegtin'; /** * Additional product attributes for product_attributes table * * @var array */ protected $additionalProductAttributes; /** * @param Context $context */ public function __construct( Context $context ) { parent::__construct($context); } /** * Check if option value GTIN enabled * * @param int|null $storeId * @return string */ public function isOptionValueGtinEnabled($storeId = null) { return $this->scopeConfig->getValue( self::XML_PATH_DEFAULT_OPTION_VALUE_GTIN, ScopeInterface::SCOPE_STORE, $storeId ); } }
Jangan lupa untuk menyimpan perubahan dan menghapus cache.
Pengaturan harus ditampilkan di panel admin.
Langkah #5. Menampilkan Bidang Baru di Front-End Halaman Produk
Ingat apa yang kita bicarakan di artikel sebelumnya?
Kami menyebutkan bahwa modul MageWorx_OptionBase kami sudah memiliki metode `getExtendedOptionsConfig()` yang mengumpulkan dan menampilkan semua atribut khusus kami di front-end melalui blok.
Untuk melihat bagaimana penerapannya, buka kelas berikut:
`app/code/MageWorx/OptionBase/Block/Product/View/Options.php`
Sekarang:
Buat model dengan atribut kami:
`app/code/VendorName/OptionValueGtin/Model/Attribute/OptionValue/Gtin.php`
<?php namespace VendorName\OptionValueGtin\Model\Attribute\OptionValue; use MageWorx\OptionBase\Model\Product\Option\AbstractAttribute; class Gtin extends AbstractAttribute { /** * @return string */ public function getName() { return 'gtin'; } }
Melalui injeksi ketergantungan , tambahkan atribut ke blok atribut umum dari ekstensi Opsi Produk Lanjutan dan buat file berikut:
`app/code/VendorName/OptionValueGtin/etc/di.xml`
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <!-- Data --> <type name="MageWorx\OptionBase\Model\Product\Option\Value\Attributes"> <arguments> <argument name="data" xsi:type="array"> <item name="gtin" xsi:type="object">VendorName\OptionValueGtin\Model\Attribute\OptionValue\Gtin</item> </argument> </arguments> </type> </config>
Sekarang:
Buat blok baru kami dan template untuk itu:
`app/code/VendorName/OptionValueGtin/Block/ValueGtin.php`
<?php namespace MageWorx\OptionValueGtin\Block; use Magento\Framework\Json\EncoderInterface; use Magento\Framework\View\Element\Template; use Magento\Framework\View\Element\Template\Context; use MageWorx\OptionValueGtin\Helper\Data as Helper; class ValueGtin extends Template { /** * @var EncoderInterface */ protected $jsonEncoder; /** * @var Helper */ protected $helper; /** * @param Context $context * @param EncoderInterface $jsonEncoder * @param Helper $helper * @param array $data */ public function __construct( Context $context, EncoderInterface $jsonEncoder, Helper $helper, array $data = [] ) { parent::__construct( $context, $data ); $this->jsonEncoder = $jsonEncoder; $this->helper = $helper; } /** * @return string */ public function getJsonData() { $data = [ 'isOptionValueGtinEnabled' => $this->helper->isOptionValueGtinEnabled($this->_storeManager->getStore()) ]; return $this->jsonEncoder->encode($data); } }
Di sini, kami telah memperoleh data tentang pengaturan dari Kelas Helper.
Lanjut:
Dengan menggunakan metode `getJsonData()`, mari kita render data ke front-end menggunakan template yang akan kita buat:
`app/code/VendorName/OptionValueGtin/view/frontend/templates/config.phtml`
<?php /** @var \VendorName\OptionValueGtin\Block\ValueGtin $block */ ?> <script> require([ 'jquery', 'optionValueGtin', 'uiRegistry' ], function ($, optionValueGtin, registry) { var optionBase = registry.get('mageworxOptionBase'); if (optionBase) { optionBase.addUpdater(7, optionValueGtin(<?= /* @noEscape */ $block->getJsonData() ?>)); } else { var updaters = registry.get('mageworxOptionUpdaters'); if (!updaters) { updaters = {}; } updaters[7] = optionValueGtin(<?= /* @noEscape */ $block->getJsonData() ?>); registry.set('mageworxOptionUpdaters', updaters); } }); </script>
Kami menggunakan mekanisme mixin JavaScript untuk menampilkan nilai bidang GTIN .
Apa berikutnya?
Mari kita ambil pendekatan berbeda dan buat widget js, yang akan digunakan untuk menampilkan data baru di halaman produk.
Tentukan js baru:
`app/code/VendorName/OptionValueGtin/view/frontend/requirejs-config.js`
var config = { map: { '*': { optionValueGtin: 'VendorName_OptionValueGtin/js/option-value-gtin' } } };
Saatnya membuat widget itu sendiri. Ini akan berisi semua logika dalam pekerjaan dengan atribut baru di front-end.
Dalam file contoh, mari terapkan logika tampilan GTIN untuk opsi pilih, dan untuk opsi radio dan kotak centang secara terpisah.
Ini akan menjadi dua logika yang berbeda karena logika dalam pekerjaan dan markup opsi tersebut berbeda satu sama lain:
`app/code/VendorName/OptionValueGtin/view/frontend/web/js/option-value-gtin.js`
define([ 'jquery', 'Magento_Catalog/js/price-utils', 'underscore', 'jquery/ui' ], function ($, utils, _) { 'use strict'; $.widget('mageworx.optionValueGtin', { options: { optionConfig: {} }, /** * * @param optionConfig * @param productConfig * @param base * @param self */ firstRun: function firstRun(optionConfig, productConfig, base, self) { if (parseFloat(this.options.isOptionValueGtinEnabled)) { var extendedOptionsConfig = typeof base.options.extendedOptionsConfig != 'undefined' ? base.options.extendedOptionsConfig : {}; for (var option_id in optionConfig) { if (!optionConfig.hasOwnProperty(option_id)) { continue; } var $option = base.getOptionHtmlById(option_id); this._addValueGtin($option, optionConfig, extendedOptionsConfig); } } }, /** * Add description to the values * @param $option * @param optionConfig * @param extendedOptionsConfig * @private */ _addValueGtin: function _addValueGtin($option, optionConfig, extendedOptionsConfig) { var self = this, $options = $option.find('.product-custom-option'); //selectable options $options.filter('select').each(function (index, element) { var $element = $(element), optionId = utils.findOptionId($element), value = extendedOptionsConfig[optionId]['values']; if ($element.attr('multiple') && !$element.hasClass('mageworx-swatch')) { return; } if (typeof value == 'undefined' || _.isEmpty(value)) { return; } var gtinTitle = 'GTIN: '; var $gtin = $('<div class="option-value-gtin"></div>', { style: 'display: none' }); var $label = $option.find('.control'); $element.parent().prepend($gtin); $element.on('change', function (e) { var valueId = $element.val(); if (!_.isUndefined(value[valueId]) && !_.isEmpty(value[valueId]['gtin']) ) { if ($label.length > 0) { $label .first() .after($gtin.text(gtinTitle + value[valueId]['gtin'])); } $gtin.show(); } else { $gtin.hide(); } }); if ($element.val()) { $element.trigger('change'); } }); $options.filter('input[type="radio"], input[type="checkbox"]').each(function (index, element) { var $element = $(element), optionId = utils.findOptionId($element), value = extendedOptionsConfig[optionId]['values']; if ($element.attr('multiple') && !$element.hasClass('mageworx-swatch')) { return; } if (typeof value == 'undefined' || _.isEmpty(value)) { return; } var gtinTitle = 'GTIN: '; var $gtin = $('<div class="option-value-gtin-redio-check"></div>'); var $label = $option.find('.control'); $element.parent().append($gtin); var valueId = $element.val(); if (!_.isUndefined(value[valueId]) && !_.isEmpty(value[valueId]['gtin'])) { $gtin.text(gtinTitle + value[valueId]['gtin']); } if ($element.val()) { $element.trigger('change'); } }); }, }); return $.mageworx.optionValueGtin; });
Bagaimana kalau menambahkan beberapa gaya?
`app/code/VendorName/OptionValueGtin/view/frontend/web/css/valueGtin.css`
.option-value-gtin, .option-value-gtin-redio-check { color: #1da0e0; font-weight: 700; margin-top: 5px; } .option-value-gtin-redio-check { display: contents; }
Tinggal menghubungkan blok kita dan gaya.
Untuk itu, buat file berikut:
`app/code/VendorName/OptionValueGtin/view/frontend/layout/catalog_product_view.xml`
<?xml version="1.0"?> <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <head> <css src="VendorName_OptionValueGtin::css/valueGtin.css"/> </head> <body> <referenceBlock name="product.info.options.wrapper"> <container name="vendorname.option.value.gtin.container" after="product.info.options"> <block class="VendorName\OptionValueGtin\Block\ValueGtin" name="vendorname.option.value.gtin" template="VendorName_OptionValueGtin::config.phtml"/> </container> </referenceBlock> </body> </page>
Kami hampir selesai.
Sebelum kita menjalankan pemeriksaan terakhir, jangan lupa untuk mengosongkan cache dan menyebarkan konten statis lagi:
- php bin/cache magento: flush
- php bin/magento static-content:deploy
Dan akhirnya:
Masuk ke panel admin.
Buat produk dengan opsi khusus di produk Magento.
Dalam contoh kami, saya menambahkan dropdown, swatch, radio, dan kotak centang.
Jangan lupa untuk mengisi bidang GTIN baru kami untuk nilai opsi yang sesuai.
Simpan produk.
Saatnya untuk melihat bagaimana semuanya terlihat di front-end:
Apa pendapat Anda tentang hasilnya?
Silakan bagikan tanggapan Anda tentang artikel di kolom komentar di bawah. Seberapa mudahkah Magento menambahkan bidang ke opsi khusus?