1

How to add radio button to set default value for product custom options (Customizable Options) in Magento2 Admin grid

enter image description here

asked Aug 30, 2017 at 7:52

2 Answers 2

1

Here is a solution from Github that worked for me on Magento 2.4.2 https://github.com/dmitrykazak/magento2-custom-option-default-value

answered May 26, 2021 at 20:26
0

Here is the cleanest way I found to set a default value for customizable options :

(Based on answers on this similar question)

Note : I will assume you work on an already created module which I'll call Vendor_Module.

1. Add is_default column to catalog_product_option_type_value table

app/code/Vendor/Module/Setup/UpgradeSchema.php

<?php
namespace Vendor\Module\Setup;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
/**
 * @codeCoverageIgnore
 */
class UpgradeSchema implements UpgradeSchemaInterface
{
 /**
 * {@inheritdoc}
 * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
 */
 public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
 {
 if (version_compare($context->getVersion(), '2.0.1') < 0) {
 $setup->getConnection()->addColumn(
 $setup->getTable('catalog_product_option_type_value'),
 'is_default',
 [
 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
 'length' => 1,
 'unsigned' => true,
 'nullable' => false,
 'default' => '0',
 'comment' => 'Defines if Is Default'
 ]
 );
 }
 }
}

Note : Don't forget to change the version compared according to your module

2. Define and create a plugin to add the checkbox element in the back office

app/code/Vendor/Module/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">
 <type name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions">
 <plugin name="vendor_module_custom_options_ui_plugin"
 type="Vendor\Module\Plugin\CustomOptionsUiPlugin" />
 </type>
</config>

app/code/Vendor/Module/Plugin/CustomOptionsUiPlugin.php

<?php
namespace Vendor\Module\Plugin;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions;
use Magento\Ui\Component\Form\Field;
use Magento\Ui\Component\Form\Element\Checkbox;
use Magento\Ui\Component\Form\Element\DataType\Number;
/**
 * Data provider for "Customizable Options" panel
 */
class CustomOptionsUiPlugin
{
 /**
 * Field values
 */
 const FIELD_IS_DEFAULT = 'is_default';
 /**
 * @param \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions $subject
 * @param bool $meta
 * @return bool
 */
 public function afterModifyMeta(CustomOptions $subject, $meta) {
 $result = $meta;
 $result[CustomOptions::GROUP_CUSTOM_OPTIONS_NAME]['children']
 [CustomOptions::GRID_OPTIONS_NAME]['children']['record']['children']
 [CustomOptions::CONTAINER_OPTION]['children']
 [CustomOptions::GRID_TYPE_SELECT_NAME]['children']['record']['children']
 [static::FIELD_IS_DEFAULT] = $this->getIsDefaultFieldConfig(70);
 return $result;
 }
 /**
 * Get config for checkbox field used for default values
 *
 * @param int $sortOrder
 * @return array
 */
 protected function getIsDefaultFieldConfig($sortOrder)
 {
 return [
 'arguments' => [
 'data' => [
 'config' =>[
 'label' => __('Default'),
 'componentType' => Field::NAME,
 'formElement' => Checkbox::NAME,
 'dataScope' => static::FIELD_IS_DEFAULT,
 'dataType' => Number::NAME,
 'additionalClasses' => 'admin__field-small',
 'sortOrder' => $sortOrder,
 'value' => '0',
 'valueMap' => [
 'true' => '1',
 'false' => '0'
 ]
 ],
 ],
 ],
 ];
 }
}

Note : Here we use Magento\Ui\Component\Form\Element\Checkbox instead of Magento\Ui\Component\Form\Element\Radio component as it seems Magento never defines it in its Form Elements.

See vendor\magento\module-ui\view\base\ui_component\etc\definition.xml line 112+

3. Overwrite Magento\Catalog\Block\Product\View\Options\Type\Select to check the element which has been chosen as "Default element".

app/code/Vendor/Module/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">
 <preference for="Magento\Catalog\Block\Product\View\Options\Type\Select"
 type="Vendor\Module\Block\Rewrite\Catalog\Product\View\Options\Type\Select" />
</config>

app/code/Vendor/Module/Block/Rewrite/Catalog/Product/View/Options/Type/Select.php

<?php
namespace Vendor\Module\Block\Rewrite\Catalog\Product\View\Options\Type;
/**
 * Product options text type block
 */
class Select extends \Magento\Catalog\Block\Product\View\Options\Type\Select
{
 /**
 * Return html for control element
 *
 * @return string
 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
 * @SuppressWarnings(PHPMD.NPathComplexity)
 * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
 */
 public function getValuesHtml()
 {
 $_option = $this->getOption();
 $configValue = $this->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId());
 $store = $this->getProduct()->getStore();
 $this->setSkipJsReloadPrice(1);
 // Remove inline prototype onclick and onchange events
 if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN ||
 $_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE
 ) {
 $require = $_option->getIsRequire() ? ' required' : '';
 $extraParams = '';
 $select = $this->getLayout()->createBlock(
 \Magento\Framework\View\Element\Html\Select::class
 )->setData(
 [
 'id' => 'select_' . $_option->getId(),
 'class' => $require . ' product-custom-option admin__control-select'
 ]
 );
 if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN) {
 $select->setName('options[' . $_option->getId() . ']')->addOption('', __('-- Please Select --'));
 } else {
 $select->setName('options[' . $_option->getId() . '][]');
 $select->setClass('multiselect admin__control-multiselect' . $require . ' product-custom-option');
 }
 foreach ($_option->getValues() as $_value) {
 $priceStr = $this->_formatPrice(
 [
 'is_percent' => $_value->getPriceType() == 'percent',
 'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
 ],
 false
 );
 if($_value->getData('is_default') == true && !$configValue) {
 $configValue = $_value->getOptionTypeId();
 }
 $select->addOption(
 $_value->getOptionTypeId(),
 $_value->getTitle() . ' ' . strip_tags($priceStr) . '',
 ['price' => $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)]
 );
 }
 if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE) {
 $extraParams = ' multiple="multiple"';
 }
 if (!$this->getSkipJsReloadPrice()) {
 $extraParams .= ' onchange="opConfig.reloadPrice()"';
 }
 $extraParams .= ' data-selector="' . $select->getName() . '"';
 $select->setExtraParams($extraParams);
 if ($configValue) {
 $select->setValue($configValue);
 }
 return $select->getHtml();
 }
 if ($_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_RADIO ||
 $_option->getType() == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_CHECKBOX
 ) {
 $selectHtml = '<div class="options-list nested" id="options-' . $_option->getId() . '-list">';
 $require = $_option->getIsRequire() ? ' required' : '';
 $arraySign = '';
 switch ($_option->getType()) {
 case \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_RADIO:
 $type = 'radio';
 $class = 'radio admin__control-radio';
 if (!$_option->getIsRequire()) {
 $selectHtml .= '<div class="field choice admin__field admin__field-option">' .
 '<input type="radio" id="options_' .
 $_option->getId() .
 '" class="' .
 $class .
 ' product-custom-option" name="options[' .
 $_option->getId() .
 ']"' .
 ' data-selector="options[' . $_option->getId() . ']"' .
 ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
 ' value="" checked="checked" /><label class="label admin__field-label" for="options_' .
 $_option->getId() .
 '"><span>' .
 __('None') . '</span></label></div>';
 }
 break;
 case \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_CHECKBOX:
 $type = 'checkbox';
 $class = 'checkbox admin__control-checkbox';
 $arraySign = '[]';
 break;
 }
 $count = 1;
 foreach ($_option->getValues() as $_value) {
 $count++;
 $priceStr = $this->_formatPrice(
 [
 'is_percent' => $_value->getPriceType() == 'percent',
 'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
 ]
 );
 $htmlValue = $_value->getOptionTypeId();
 if ($arraySign) {
 $checked = is_array($configValue) && in_array($htmlValue, $configValue) ? 'checked' : '';
 } else {
 $checked = $configValue == $htmlValue ? 'checked' : '';
 }
 $dataSelector = 'options[' . $_option->getId() . ']';
 if ($arraySign) {
 $dataSelector .= '[' . $htmlValue . ']';
 }
 $selectHtml .= '<div class="field choice admin__field admin__field-option' .
 $require .
 '">' .
 '<input type="' .
 $type .
 '" class="' .
 $class .
 ' ' .
 $require .
 ' product-custom-option"' .
 ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
 ' name="options[' .
 $_option->getId() .
 ']' .
 $arraySign .
 '" id="options_' .
 $_option->getId() .
 '_' .
 $count .
 '" value="' .
 $htmlValue .
 '" ' .
 $checked .
 ' data-selector="' . $dataSelector . '"' .
 ' price="' .
 $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false) .
 '" />' .
 '<label class="label admin__field-label" for="options_' .
 $_option->getId() .
 '_' .
 $count .
 '"><span>' .
 $_value->getTitle() .
 '</span> ' .
 $priceStr .
 '</label>';
 $selectHtml .= '</div>';
 }
 $selectHtml .= '</div>';
 return $selectHtml;
 }
 }
}

4. Upgrade your module version and update the database

Upgrade your setup_version in app/code/Vendor/Module/etc/module.xml

Update your version in app/code/Vendor/Module/composer.json

Run following commands :

php bin/magento cache:clean
php bin/magento setup:upgrade
answered Jan 22, 2019 at 15:46

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.