In Magento 2 I am trying to remove first option "--Please Select--". Here is my code. After the rewrite, I am not able to see custom option dropdown itself but the page is loading. Please let me know if I am doing anything wrong.
di.xml
<?xml version="1.0" encoding="UTF-8"?> <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="Sigma\Override\Block\Magento\Catalog\Product\View\Options\Type\Select" /> </config>
Rewrite code of Block
<?php /** * Product options text type block * * @author Company */ namespace Namespace\Module\Block\Magento\Catalog\Product\View\Options\Type; 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\Model\Product\Option::OPTION_TYPE_DROP_DOWN || $_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_MULTIPLE ) { $require = $_option->getIsRequire() ? ' required' : ''; $extraParams = ''; $select = $this->getLayout()->createBlock( 'Magento\Framework\View\Element\Html\Select' )->setData( [ 'id' => 'select_' . $_option->getId(), 'class' => $require . ' product-custom-option admin__control-select' ] ); if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_DROP_DOWN) { $select->setName('options[' . $_option->getid() . ']'); } 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 ); $select->addOption( $_value->getOptionTypeId(), $_value->getTitle() . ' ' . strip_tags($priceStr) . '', ['price' => $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)] ); } if ($_option->getType() == \Magento\Catalog\Model\Product\Option::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\Model\Product\Option::OPTION_TYPE_RADIO || $_option->getType() == \Magento\Catalog\Model\Product\Option::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\Model\Product\Option::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\Model\Product\Option::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; } } }
Solved! Go to Solution.
Use Plugins to override the above block.
di.xml
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Catalog\Block\Product\View\Options\Type\Select"> <plugin name="Sigma_CategoryCustomAttribute_select" sortOrder="10" type="Sigma\Override\Block\Magento\Catalog\Product\View\Options\Type\Select"/> </type> </config>
Block Code will be
<?php namespace Sigma\Override\Block\Magento\Catalog\Product\View\Options\Type; class Select extends \Magento\Catalog\Block\Product\View\Options\AbstractOptions { /** * Return html for control element * * @return string * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function afterGetValuesHtml(\Magento\Catalog\Block\Product\View\Options\Type\Select $subject) { $_option = $subject->getOption(); $configValue = $subject->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId()); $store = $subject->getProduct()->getStore(); $subject->setSkipJsReloadPrice(1); // Remove inline prototype onclick and onchange events if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_DROP_DOWN || $_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_MULTIPLE ) { $require = $_option->getIsRequire() ? ' required' : ''; $extraParams = ''; $select = $subject->getLayout()->createBlock( 'Magento\Framework\View\Element\Html\Select' )->setData( [ 'id' => 'select_' . $_option->getId(), 'class' => $require . ' product-custom-option admin__control-select' ] ); if ($_option->getType() == \Magento\Catalog\Model\Product\Option::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 = $subject->_formatPrice( [ 'is_percent' => $_value->getPriceType() == 'percent', 'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'), ], false ); $select->addOption( $_value->getOptionTypeId(), $_value->getTitle() . ' ' . strip_tags($priceStr) . '', ['price' => $subject->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)] ); } if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_MULTIPLE) { $extraParams = ' multiple="multiple"'; } if (!$subject->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\Model\Product\Option::OPTION_TYPE_RADIO || $_option->getType() == \Magento\Catalog\Model\Product\Option::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\Model\Product\Option::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() . ']"' . ($subject->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\Model\Product\Option::OPTION_TYPE_CHECKBOX: $type = 'checkbox'; $class = 'checkbox admin__control-checkbox'; $arraySign = '[]'; break; } $count = 1; foreach ($_option->getValues() as $_value) { $count++; $priceStr = $subject->_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"' . ($subject->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') . ' name="options[' . $_option->getId() . ']' . $arraySign . '" id="options_' . $_option->getId() . '_' . $count . '" value="' . $htmlValue . '" ' . $checked . ' data-selector="' . $dataSelector . '"' . ' price="' . $subject->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; } } }
In Above block (Select.php)
i) Replace public function getValuesHtml() to public function afterGetValuesHtml(\Magento\Catalog\Block\Product\View\Options\Type\Select $subject)
ii) Replace $this to $subject.
As Done In above code.
Use Plugins to override the above block.
di.xml
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Catalog\Block\Product\View\Options\Type\Select"> <plugin name="Sigma_CategoryCustomAttribute_select" sortOrder="10" type="Sigma\Override\Block\Magento\Catalog\Product\View\Options\Type\Select"/> </type> </config>
Block Code will be
<?php namespace Sigma\Override\Block\Magento\Catalog\Product\View\Options\Type; class Select extends \Magento\Catalog\Block\Product\View\Options\AbstractOptions { /** * Return html for control element * * @return string * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function afterGetValuesHtml(\Magento\Catalog\Block\Product\View\Options\Type\Select $subject) { $_option = $subject->getOption(); $configValue = $subject->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId()); $store = $subject->getProduct()->getStore(); $subject->setSkipJsReloadPrice(1); // Remove inline prototype onclick and onchange events if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_DROP_DOWN || $_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_MULTIPLE ) { $require = $_option->getIsRequire() ? ' required' : ''; $extraParams = ''; $select = $subject->getLayout()->createBlock( 'Magento\Framework\View\Element\Html\Select' )->setData( [ 'id' => 'select_' . $_option->getId(), 'class' => $require . ' product-custom-option admin__control-select' ] ); if ($_option->getType() == \Magento\Catalog\Model\Product\Option::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 = $subject->_formatPrice( [ 'is_percent' => $_value->getPriceType() == 'percent', 'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'), ], false ); $select->addOption( $_value->getOptionTypeId(), $_value->getTitle() . ' ' . strip_tags($priceStr) . '', ['price' => $subject->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)] ); } if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_MULTIPLE) { $extraParams = ' multiple="multiple"'; } if (!$subject->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\Model\Product\Option::OPTION_TYPE_RADIO || $_option->getType() == \Magento\Catalog\Model\Product\Option::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\Model\Product\Option::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() . ']"' . ($subject->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\Model\Product\Option::OPTION_TYPE_CHECKBOX: $type = 'checkbox'; $class = 'checkbox admin__control-checkbox'; $arraySign = '[]'; break; } $count = 1; foreach ($_option->getValues() as $_value) { $count++; $priceStr = $subject->_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"' . ($subject->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') . ' name="options[' . $_option->getId() . ']' . $arraySign . '" id="options_' . $_option->getId() . '_' . $count . '" value="' . $htmlValue . '" ' . $checked . ' data-selector="' . $dataSelector . '"' . ' price="' . $subject->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; } } }
In Above block (Select.php)
i) Replace public function getValuesHtml() to public function afterGetValuesHtml(\Magento\Catalog\Block\Product\View\Options\Type\Select $subject)
ii) Replace $this to $subject.
As Done In above code.
Hi @umar,
Thanks for the solution.
I am not sure whether using the plugin is right or wrong in this situation. Please educate me if you have a proper reason for using plugin over preference.
--------
Give Kudos if it helped or Accept it as solution
From Magento 2.4.X the class function was changed. can you share the responsible file for this?
I would also like to get an updated answer for this.
I have created the `di.xml` file under `/app/design/frontend/<Vendor>/<theme-name>/etc`, and I am not quite sure where to put the `Select.php` file. I tried under `/app/design/frontend/<Vendor>/<theme_name>/Block/Magento/Catalog/Product/View/Options/Type`, but that did not work. Hoping to get a clear answer on this, as the "-- Please Select --" is quite an annoying thing to have displayed.