วิธีเพิ่มฟิลด์ที่กำหนดเองสำหรับค่าตัวเลือกในตัวเลือกผลิตภัณฑ์ขั้นสูง
เผยแพร่แล้ว: 2020-11-20จากบทความที่แล้ว คุณได้เรียนรู้วิธีสร้างฟิลด์ตัวเลือกแบบกำหนดเองของ Magento นอกจากนี้เรายังพบวิธีแสดงข้อมูลภาคสนามทั้งในส่วนหน้าของผลิตภัณฑ์และหน้าคำสั่งซื้อในแผงการดูแลระบบ
อะไรตอนนี้?
มาเรียนรู้วิธีเพิ่มฟิลด์ GTIN แบบกำหนดเองเดียวกันสำหรับค่าตัวเลือกและแสดงบนส่วนหน้าของหน้าผลิตภัณฑ์
สารบัญ
- ขั้นตอนที่ 1. การสร้างโมดูลใหม่
- 1. composer.json
- 2. etc/module.xml
- 3. register.php
- ขั้นตอนที่ 2. การเพิ่มฟิลด์ใหม่ให้กับฐานข้อมูล
- ขั้นตอนที่ #3 การเพิ่มตรรกะในการทำงานกับแบ็กเอนด์
- ขั้นตอนที่ #4 การเพิ่มการตั้งค่าเพื่อปิดใช้งานการแสดงฟิลด์ GTIN สำหรับการกำหนดค่าตัวเลือกผลิตภัณฑ์ขั้นสูง
- ขั้นตอนที่ #5 การแสดงฟิลด์ใหม่บนหน้าผลิตภัณฑ์ Front-End
ขั้นตอนที่ 1. การสร้างโมดูลใหม่
มาเริ่มกันที่การสร้างโมดูลใหม่ ซึ่งมีรายละเอียดเกี่ยวกับกระบวนการนี้ในโพสต์บล็อกของ Mageworx
ดังนั้น โดยไม่ต้องกังวลใจอีกต่อไป นี่คือรหัสที่เราต้องการ:
1. composer.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. register.php
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'VendorName_OptionValueGtin', __DIR__ );
ขั้นตอนที่ 2. การเพิ่มฟิลด์ใหม่ให้กับฐานข้อมูล
ได้เวลาสร้างฟิลด์ GTIN และเพิ่มลงในตารางที่เกี่ยวข้องในฐานข้อมูล
ขณะที่เรากำลังเพิ่มฟิลด์สำหรับค่าตัวเลือก จะต้องมีตาราง `catalog_product_option_type_value`
มาสร้างไฟล์ต่อไปนี้กัน:
`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(); } }
ขั้นตอนที่ #3 การเพิ่มตรรกะในการทำงานกับแบ็กเอนด์
ใช้กลไกการ ปรับพูล เพื่อเพิ่มฟิลด์ Magento ให้กับตัวเลือกที่กำหนดเอง
มาสร้างไฟล์ต่อไปนี้กัน:
`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>
ที่นี่:
เราเพิ่มตัวแก้ไขของเราในกลุ่มทั่วไปของส่วนขยาย Advanced Product Options สำหรับ Magento 2―
`MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\Pool`
`VendorName\OptionValueGtin\Ui\DataProvider\Product\Form\Modifier\OptionValueGtin` คือคลาสตัวแก้ไข
ด้านล่าง:
ดูโค้ดที่อนุญาตให้เพิ่มฟิลด์ของเราลงในฟอร์ม `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; } }
ตอนนี้ ติดตั้งส่วนขยายและตรวจสอบว่าทั้งหมดทำถูกต้อง กล่าวคือ
- โมดูล php bin/magento: เปิดใช้งาน VendorName_OptionValueGtin
- php bin/การติดตั้งวีโอไอพี:อัพเกรด
- php bin/magento cache:flush
อย่างที่คุณเห็น ฟิลด์ที่เพิ่มใหม่จะแสดงขึ้นในขณะนี้:
ขั้นตอนที่ #4 การเพิ่มการตั้งค่าเพื่อปิดใช้งานการแสดงฟิลด์ GTIN สำหรับการกำหนดค่าตัวเลือกผลิตภัณฑ์ขั้นสูง
แล้วบทความของเราที่ปะปนกันเล็กน้อยล่ะ?
ฉันเสนอให้เพิ่มฟังก์ชันการทำงานใหม่—ความสามารถในการเปิด/ปิดการแสดงช่อง GTIN สำหรับค่าตัวเลือกที่ส่วนหน้าของหน้าผลิตภัณฑ์
คุณจะต้องสร้างไฟล์:
`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>
เพื่อความเรียบง่าย:
เราจะเพิ่มแท็บ ตัวเลือกมูลค่า GTIN ใหม่ให้กับการกำหนดค่าของส่วนขยายตัวเลือกผลิตภัณฑ์ขั้นสูงของเรา คุณควรจะสามารถสร้างแท็บในโมดูลของคุณได้เช่นกัน
ควรสร้าง Helper Class ใหม่ ที่นั่น เราจะรับข้อมูลเกี่ยวกับการตั้งค่า
มาสร้างและกรอกข้อมูลในคลาสต่อไปนี้:
`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 ); } }
อย่าลืมบันทึกการเปลี่ยนแปลงและล้างแคช
การตั้งค่าควรแสดงในแผงการดูแลระบบ
ขั้นตอนที่ #5 การแสดงฟิลด์ใหม่บนหน้าผลิตภัณฑ์ Front-End
จำสิ่งที่เราพูดถึงในบทความที่แล้วได้ไหม?
เรากล่าวว่าโมดูล MageWorx_OptionBase ของเรามีวิธี `getExtendedOptionsConfig()` ที่รวบรวมและแสดงแอตทริบิวต์ที่กำหนดเองทั้งหมดของเราในส่วนหน้าผ่านบล็อก
หากต้องการดูวิธีการดำเนินการ ให้เปิดคลาสต่อไปนี้:
`app/code/MageWorx/OptionBase/Block/Product/View/Options.php`
ตอนนี้:
สร้างแบบจำลองด้วยแอตทริบิวต์ของเรา:
`แอป/รหัส/ชื่อผู้ขาย/OptionValueGtin/รุ่น/แอตทริบิวต์/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'; } }
ผ่าน การแทรกการพึ่งพา เพิ่มแอตทริบิวต์ไปยังบล็อกแอตทริบิวต์ทั่วไปของส่วนขยาย Advanced Product Options และสร้างไฟล์ต่อไปนี้:
`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>
ตอนนี้:
สร้างบล็อกใหม่และเทมเพลตของเรา:
`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); } }
ที่นี่ เราได้รับข้อมูลเกี่ยวกับการตั้งค่าจาก Helper Class
ต่อไป:
ใช้เมธอด `getJsonData()` มาแสดงผลข้อมูลไปยังส่วนหน้าโดยใช้เทมเพลตที่เรากำลังจะสร้าง:
`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>
เราใช้กลไก มิกซ์อิน JavaScript เพื่อแสดงค่าสำหรับช่อง GTIN
อะไรต่อไป?
ลองใช้แนวทางที่แตกต่างออกไปและสร้างวิดเจ็ต js ซึ่งจะใช้เพื่อแสดงข้อมูลใหม่บนหน้าผลิตภัณฑ์
กำหนด js ใหม่:
`app/code/VendorName/OptionValueGtin/view/frontend/requirejs-config.js`
var config = { map: { '*': { optionValueGtin: 'VendorName_OptionValueGtin/js/option-value-gtin' } } };
ถึงเวลาสร้างวิดเจ็ตเองแล้ว มันจะประกอบด้วยตรรกะทั้งหมดในการทำงานกับแอตทริบิวต์ใหม่ในส่วนหน้า
ในไฟล์ตัวอย่าง เรามาปรับใช้ตรรกะการแสดงผลของ GTIN สำหรับตัวเลือกที่เลือก และสำหรับตัวเลือกวิทยุและตัวเลือกช่องทำเครื่องหมายแยกกัน
สิ่งเหล่านี้จะเป็นตรรกะที่แตกต่างกันสองแบบ เนื่องจากตรรกะในการทำงานและมาร์กอัปของตัวเลือกดังกล่าวแตกต่างกัน:
`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; });
จะเพิ่มสไตล์อะไรอีกบ้าง?
`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; }
เหลือเพียงการเชื่อมต่อบล็อกและสไตล์ของเรา
สำหรับสิ่งนั้น ให้สร้างไฟล์ต่อไปนี้:
`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>
เราเกือบจะเสร็จแล้ว
ก่อนที่เราจะเรียกใช้การตรวจสอบขั้นสุดท้าย อย่าลืมล้างแคชและปรับใช้เนื้อหาแบบคงที่อีกครั้ง:
- php bin/magento cache:flush
- php bin/magento static-content:deploy
และในที่สุดก็:
ลงชื่อเข้าใช้แผงผู้ดูแลระบบ
สร้างผลิตภัณฑ์ด้วยตัวเลือกที่กำหนดเองในผลิตภัณฑ์ Magento
ในตัวอย่างของเรา ฉันได้เพิ่มดรอปดาวน์ สวอตช์ วิทยุ และกล่องกาเครื่องหมาย
อย่าลืมกรอกข้อมูลในฟิลด์ GTIN ใหม่ของเราสำหรับค่าตัวเลือกที่เกี่ยวข้อง
เก็บสินค้า.
ถึงเวลาดูว่าทุกอย่างจะเป็นอย่างไรในฟรอนต์เอนด์:
คุณคิดอย่างไรเกี่ยวกับผลลัพธ์?
โปรดแบ่งปันความคิดเห็นของคุณเกี่ยวกับบทความในช่องความคิดเห็นด้านล่าง การเพิ่มฟิลด์ Magento ให้กับตัวเลือกที่กำหนดเองนั้นง่ายเพียงใด?