10

I want to set default option to the custom options value in the product level.

How to do that in Magento 2 ? enter image description here

Please help me to resolve on this.

5
  • Please explain your question with more details. Commented Mar 23, 2017 at 10:39
  • It seems that you are asking to place some default text in your input field. Commented Mar 23, 2017 at 10:43
  • in my question I have 2 options m I want to set one option to be the default selected on the frontend.
    – rajat kara
    Commented Mar 23, 2017 at 10:54
  • How to implement this ? i want to add default value ?
    – Mahi M
    Commented Dec 20, 2018 at 12:39
  • Here is a solution from Github that worked for me on Magento 2.4.2 github.com/dmitrykazak/magento2-custom-option-default-value
    – Josiah
    Commented May 26, 2021 at 20:31

5 Answers 5

2

I'm not sure you can do this via admin. I just did a work around where I made sure all my "default options" are the first option within admin then added the below to js for my store.

<script>
require(['jquery', 'jquery/ui'], function($){ 
  $('.product-add-form .field select').each(function(i, obj) {
    $(obj).find('option:eq(1)').prop('selected', true);
  });
});
</script>

This works for custom options as they are all rendered on page load. The code just loops through all custom options and sets the 2nd option as the first was "please select".

I had a bit more difficulty however with configurable products as the options were all loaded after page load but to do that too you can see my question here: Magento 2: How to set default option in configurable options?

1
1

I think what you want to achieve is something like this?

enter image description here

I implemented that for the dropdown fields, should be the same with radiobuttons.

  1. Add a column for the default option (is_default or whatever) into the table catalog_product_option_type_value.
  2. Add a plugin which intercepts the modifyMeta method of Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions.

Example:

vendor/module/etc/adminhtml/di.xml

<?xml version="1.0"?>
<config>
  <type name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions">
    <plugin name="CustomOptionsUiPlugin" type="Vendor\Module\Plugin\CustomOptionsUiPlugin" sortOrder="1"/>
  </type>
</config>

Vendor\Module\Plugin\CustomOptionsUiPlugin.php

namespace Vendor\Module\Plugin;

class CustomOptionsUiPlugin
{

...

    public function afterModifyMeta(\Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions $subject,$meta)
    {

        $result = $meta;

        $result['custom_options']['children']['options']['children']['record']['children']["container_option"]['children']['values']['children']['record']['children']['is_default'] = [
            'arguments' => [
                'data' => [
                    'config' => [
                        'label' => __('Default'),
                        'componentType' => 'field',
                        'formElement' => 'checkbox',
                        'dataScope' => 'is_default',
                        'dataType' => 'number',
                        'additionalClasses' => 'admin__field-small',
                        'sortOrder' => 55,
                        'value' => '0',
                        'valueMap' => [
                            'true' => '1',
                            'false' => '0'
                        ]
                    ]
                ]
            ]
        ];

        return $result;

    }

}
  1. And lastly you need to overwrite the file Magento\Catalog\Block\Product\View\Options\Type\Select.php with something like this

    $defaultAttribute = array();
    
    if($_value->getData('is_default') == true){
        $defaultAttribute = ['selected' => 'selected','default' => 'default'];
    }
    
    $select->addOption(
        $_value->getOptionTypeId(),
        $_value->getTitle() . ' ' . strip_tags($priceStr) . '',
        ['price' => $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false),$defaultAttribute]
    );
    

    Hope that helps!

2
  • Thanks For your solution. I have tried with your code and I'm able to display "Default" option but custom values are not displaying. Please help me to fix the Issue. Commented Jul 26, 2018 at 7:58
  • @TrytoFly adding $defaultAttribute as extra attributes for the option will conflict with preconfigured values (buy_request, ...). For example, when editing a cart item, the value selected by the customer and the "is_default" value will both be marked as selected="selected" in the code.
    – Cladiuss
    Commented Jan 30, 2019 at 10:49
0

@TrytoFly This is what worked for me.

<?php
namespace Sigma\DefaultCustomOptions\Plugin;

class CustomOptionsUiPlugin
{
       public function afterModifyMeta(
    \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions $subject,
    $result
) {

    $subject;
    $result['custom_options']['children']['options']['children']['record']['children']["container_option"]
    ['children']['values']['children']['record']['children'] =array_replace_recursive(
        $result['custom_options']['children']['options']['children']['record']['children']
        ["container_option"]['children']['values']['children']['record']['children'],
        [
            'is_default' => [
                'arguments' => [
                    'data' => [
                        'config' => [
                            'label' => __('Default'),
                            'componentType' => 'field',
                            'formElement' => 'checkbox',
                            'dataScope' => 'is_default',
                            'dataType' => 'number',
                            'sortOrder' => 70,
                            'value' => '0',
                            'valueMap' => [
                                'true' => '1',
                                'false' => '0'
                            ]
                        ]
                    ]
                ]
            ]
        ]
    );
    return $result;
    }
}
1
  • 1
    Can you please write full code here? By this I'm able to display checkbox with custom option in admin but when I'm going to save product default selected option is not saving. And how to display default selected on front-side?
    – Magecode
    Commented Aug 20, 2018 at 9:18
0

You can override Select.php file like folowing code function :

class AroundOptionValuesHtml extends \Magento\Catalog\Block\Product\View\Options\Type\Select
{

    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
                );

                // custom code   
                $defaultAttribute = array();
                if($_value->getData('is_default') == true){
                    $defaultAttribute = ['selected' => 'selected'];
                }

                // custom code

                $select->addOption(
                    $_value->getOptionTypeId(),
                    $_value->getTitle() . ' ' . strip_tags($priceStr) . '',
                    ['price' => $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false),$defaultAttribute]
                );
            }

            // custom code added 

            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();

        }


    }

}
0

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

(Based on @TrytoFly answer)

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

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.