Are you a Magento 2 store owner looking to offer more customization options to your customers? The ability to add custom input types in custom options can significantly enhance the shopping experience and cater to diverse needs. In this guide, we’ll explore how you can effortlessly integrate custom input types into your Magento 2 store’s custom options, empowering both you and your customers with more flexibility and choice.
Custom options in Magento 2 allow you to offer personalized variations of your products. These options can include dropdown menus, text fields, checkboxes, and more. While Magento 2 provides several default input types, such as text, file, and dropdown, sometimes you may need to go beyond these options to fulfill specific requirements.
Steps to Add Custom Input Types in Custom Options in Magento 2:
Step 1: Create “product_options.xml” file, inside the etc folder.
app\code\Vendor\Extension\etc\
Then add the code as follows
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/product_options.xsd"> <option name="text" label="Text" renderer="Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\Type\Text"> <inputType name="field" label="Field"/> <inputType name="area" label="Area"/> </option> <option name="file" label="File" renderer="Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\Type\File"> <inputType name="file" label="File"/> </option> <option name="select" label="Select" renderer="Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\Type\Select"> <inputType name="drop_down" label="Drop-down"/> <inputType name="radio" label="Radio Buttons"/> <inputType name="checkbox" label="Checkbox"/> <inputType name="multiple" label="Multiple Select"/> <inputType name="new_option_type" label="New Option Type"/> </option> <option name="date" label="Date" renderer="Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\Type\Date"> <inputType name="date" label="Date"/> <inputType name="date_time" label="Date & Time"/> <inputType name="time" label="Time"/> </option> </config>
Step 2: Then create “di.xml” file inside etc folder.
app\code\Vendor\Extension\etc\
And add the code as given below
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Catalog\Block\Product\View\Options\Type\Select" type="Vendor\Extension\Block\Product\View\Options\Type\Select" /> <preference for="Magento\Catalog\Model\Product\Option" type="Vendor\Extension\Model\Product\Option" /> </config>
Step 3: Then create “Select.php” file inside Type folder.
app\code\Vendor\Extension\Block\Product\View\Options\Type\
And include the below-mentioned code
<?php namespace Vendor\Extension\Block\Product\View\Options\Type; use Magento\Catalog\Block\Product\View\Options\Type\Select\CheckableFactory; use Magento\Catalog\Block\Product\View\Options\Type\Select\MultipleFactory; use Magento\Catalog\Helper\Data as CatalogHelper; use Magento\Catalog\Model\Product\Option; use Magento\Framework\App\ObjectManager; use Magento\Framework\Pricing\Helper\Data; use Magento\Framework\View\Element\Template\Context; use Vendor\Extension\Model\Product\Option as ProductModel; class Select extends \Magento\Catalog\Block\Product\View\Options\AbstractOptions { private $checkableFactory; private $multipleFactory; public function __construct( Context $context, Data $pricingHelper, CatalogHelper $catalogData, array $data = [], CheckableFactory $checkableFactory = null, MultipleFactory $multipleFactory = null ) { parent::__construct($context, $pricingHelper, $catalogData, $data); $this->checkableFactory = $checkableFactory ?: ObjectManager::getInstance()->get(CheckableFactory::class); $this->multipleFactory = $multipleFactory ?: ObjectManager::getInstance()->get(MultipleFactory::class); } public function getValuesHtml(): string { $option = $this->getOption(); $optionType = $option->getType(); if ($optionType === Option::OPTION_TYPE_DROP_DOWN || $optionType === Option::OPTION_TYPE_MULTIPLE || $optionType === ProductModel::OPTION_TYPE_NEW_OPTION_TYPE ) { $optionBlock = $this->multipleFactory->create(); } if ($optionType === Option::OPTION_TYPE_RADIO || $optionType === Option::OPTION_TYPE_CHECKBOX ) { $optionBlock = $this->checkableFactory->create(); } return $optionBlock ->setOption($option) ->setProduct($this->getProduct()) ->setSkipJsReloadPrice(1) ->_toHtml(); } }
Step 4: Then create “Option.php” file inside Product folder.
app\code\Vendor\Extension\Model\Product\
And add the below code-snippet
<?php namespace Vendor\Extension\Model\Product; use Magento\Catalog\Model\Product; class Option extends \Magento\Catalog\Model\Product\Option { const OPTION_TYPE_NEW_OPTION_TYPE = 'new_option_type'; private $optionTypesToGroups; public function getGroupByType($type = null) { if ($type === null) { $type = $this->getType(); } $optionTypesToGroups = [ self::OPTION_TYPE_FIELD => self::OPTION_GROUP_TEXT, self::OPTION_TYPE_AREA => self::OPTION_GROUP_TEXT, self::OPTION_TYPE_FILE => self::OPTION_GROUP_FILE, self::OPTION_TYPE_DROP_DOWN => self::OPTION_GROUP_SELECT, self::OPTION_TYPE_RADIO => self::OPTION_GROUP_SELECT, self::OPTION_TYPE_CHECKBOX => self::OPTION_GROUP_SELECT, self::OPTION_TYPE_MULTIPLE => self::OPTION_GROUP_SELECT, self::OPTION_TYPE_NEW_OPTION_TYPE => self::OPTION_GROUP_SELECT, self::OPTION_TYPE_DATE => self::OPTION_GROUP_DATE, self::OPTION_TYPE_DATE_TIME => self::OPTION_GROUP_DATE, self::OPTION_TYPE_TIME => self::OPTION_GROUP_DATE, ]; return isset($optionTypesToGroups[$type]) ? $optionTypesToGroups[$type] : ''; } }
Step 5: Then create “di.xml” file inside adminhtml folder.
app\code\Vendor\Extension\adminhtml
And add the following code
<?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="Magento\CatalogStaging\Ui\DataProvider\Product\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="new-modifier-all" xsi:type="array"> <item name="class" xsi:type="string">Vendor\Extension\Ui\DataProvider\Product\Form\Modifier\All</item> <item name="sortOrder" xsi:type="number">71</item> </item> </argument> </arguments> </virtualType> <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="new-modifier-all" xsi:type="array"> <item name="class" xsi:type="string">Vendor\Extension\Ui\DataProvider\Product\Form\Modifier\All</item> <item name="sortOrder" xsi:type="number">71</item> </item> </argument> </arguments> </virtualType> <virtualType name="Vendor\Extension\Ui\DataProvider\Product\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> </argument> </arguments> </virtualType> <type name="Vendor\Extension\Ui\DataProvider\Product\Form\Modifier\All"> <arguments> <argument name="pool" xsi:type="object">Vendor\Extension\Ui\DataProvider\Product\Form\Modifier\Pool</argument> </arguments> </type> <virtualType name="Vendor\Extension\Ui\DataProvider\Product\Form\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="new-custom-option" xsi:type="array"> <item name="class" xsi:type="string">Vendor\Extension\Ui\DataProvider\Product\Form\Modifier\CustomOptions</item> <item name="sortOrder" xsi:type="number">72</item> </item> </argument> </arguments> </virtualType> </config>
Step 6: Then create “All.php” file inside Modifier folder.
app\code\Vendor\Extension\Ui\DataProvider\Product\Form\Modifier\
Now add the below-mentioned piece of code
<?php namespace Vendor\Extension\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Ui\DataProvider\Modifier\ModifierInterface; use Magento\Ui\DataProvider\Modifier\PoolInterface; class All extends AbstractModifier implements ModifierInterface { protected $pool; protected $meta = []; public function __construct( PoolInterface $pool ) { $this->pool = $pool; } public function modifyData(array $data) { foreach ($this->pool->getModifiersInstances() as $modifier) { $data = $modifier->modifyData($data); } return $data; } public function modifyMeta(array $meta) { $this->meta = $meta; foreach ($this->pool->getModifiersInstances() as $modifier) { $this->meta = $modifier->modifyMeta($this->meta); } return $this->meta; } }
Step 7: Then create “CustomOptions.php” file inside Modifier folder.
app\code\Vendor\Extension\Ui\DataProvider\Product\Form\Modifier\
And add the code as follows
<?php namespace Vendor\Extension\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Model\Locator\LocatorInterface; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions as CustomOptionsModifier; use Magento\Framework\UrlInterface; use Magento\Store\Model\StoreManagerInterface; class CustomOptions extends AbstractModifier { protected $meta = []; protected $urlBuilder; protected $locator; protected $storeManager; public function __construct( UrlInterface $urlBuilder, LocatorInterface $locator, StoreManagerInterface $storeManager ) { $this->urlBuilder = $urlBuilder; $this->locator = $locator; $this->storeManager = $storeManager; } public function modifyData(array $data) { return $data; } public function modifyMeta(array $meta) { $this->meta = $meta; $this->addCustomOptionsFields(); return $this->meta; } protected function addCustomOptionsFields() { $groupCustomOptionsName = CustomOptionsModifier::GROUP_CUSTOM_OPTIONS_NAME; $optionContainerName = CustomOptionsModifier::CONTAINER_OPTION; $commonOptionContainerName = CustomOptionsModifier::CONTAINER_COMMON_NAME; $fieldTypeName = CustomOptionsModifier::FIELD_TYPE_NAME; $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children'] [$commonOptionContainerName]['children'] [$fieldTypeName]['arguments']['data']['config']['groupsConfig']['select'] = $this->getSelect(); } private function getSelect() { return [ 'values' => [ 'drop_down', 'radio', 'checkbox', 'multiple', 'new_option_type', ], 'indexes' => [ CustomOptionsModifier::GRID_TYPE_SELECT_NAME, ], ]; } }
Output:
Conclusion:
Custom input types in custom options empower Magento 2 store owners to offer unparalleled flexibility and personalization to their customers. By understanding your requirements, developing custom input type modules, and seamlessly integrating them with Magento 2’s custom options feature, you can elevate the shopping experience and drive sales growth.
Whether you’re selling customizable apparel, personalized gifts, or bespoke products, incorporating custom input types can set your store apart and delight your customers with tailored offerings. Embrace the power of customization and unlock new opportunities for your Magento 2 store today!
Happy Coding!