Chcę ustawić opcję domyślną na wartość opcji niestandardowych na poziomie produktu.
Pomóż mi rozwiązać ten problem.
Chcę ustawić opcję domyślną na wartość opcji niestandardowych na poziomie produktu.
Pomóż mi rozwiązać ten problem.
Odpowiedzi:
Nie jestem pewien, czy możesz to zrobić przez administratora. Właśnie zrobiłem obejście, w którym upewniłem się, że wszystkie moje „domyślne opcje” są pierwszą opcją w adminie, a następnie dodałem poniższe do js dla mojego sklepu.
<script>
require(['jquery', 'jquery/ui'], function($){
$('.product-add-form .field select').each(function(i, obj) {
$(obj).find('option:eq(1)').prop('selected', true);
});
});
</script>
Działa to w przypadku niestandardowych opcji, ponieważ wszystkie są renderowane podczas ładowania strony. Kod po prostu przechodzi przez wszystkie niestandardowe opcje i ustawia drugą opcję, ponieważ pierwszą było „proszę wybrać”.
Miałem jednak trochę więcej trudności z konfigurowalnymi produktami, ponieważ wszystkie opcje były ładowane po załadowaniu strony, ale aby to zrobić, możesz zobaczyć moje pytanie tutaj: Magento 2: Jak ustawić domyślną opcję w konfigurowalnych opcjach?
Myślę, że to, co chcesz osiągnąć, to coś takiego?
Zaimplementowałem, że dla pól rozwijanych powinno być tak samo z przyciskami radiowymi.
catalog_product_option_type_value
.Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions
.Przykład:
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;
}
}
Na koniec musisz zastąpić plik Magento\Catalog\Block\Product\View\Options\Type\Select.php
czymś takim
$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]
);
Mam nadzieję, że to pomaga!
$defaultAttribute
jako dodatkowych atrybutów opcji spowoduje konflikt ze wstępnie skonfigurowanymi wartościami (buy_request, ...). Na przykład podczas edycji elementu koszyka zarówno wartość wybrana przez klienta, jak i wartość „is_default” zostaną oznaczone jak selected="selected"
w kodzie.
@TrytoFly Dzięki za Twoje rozwiązanie. Próbowałem z twoim kodem i jestem w stanie wyświetlić opcję „Domyślne”, ale wartości niestandardowe nie są wyświetlane. Pomóż mi rozwiązać problem. Proszę znaleźć obrazy
$result = $meta;
na początku metody afterModifyMeta (). W przeciwnym razie po prostu nadpiszesz wartość zwracaną zamiast dodawać do niej opcję domyślną.
@TrytoFly To działało dla mnie.
<?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;
}
}
Możesz zastąpić plik Select.php, np. Funkcję kodu podążającego:
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();
}
}
}
Oto najczystszy sposób, jaki znalazłem, aby ustawić wartość domyślną dla opcji, które można dostosować :
(Na podstawie odpowiedzi @TrytoFly)
Uwaga : Zakładam, że pracujesz na już utworzonym module, który wywołam Vendor_Module
.
is_default
kolumnę do catalog_product_option_type_value
tabeliapp / 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'
]
);
}
}
}
Uwaga : Nie zapomnij zmienić wersji w zależności od modułu
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'
]
],
],
],
];
}
}
Uwaga : Tutaj używamy Magento\Ui\Component\Form\Element\Checkbox
zamiast Magento\Ui\Component\Form\Element\Radio
komponentu, ponieważ wydaje się, że Magento nigdy nie definiuje go w swoich Elementach Formy.
Zobacz vendor\magento\module-ui\view\base\ui_component\etc\definition.xml
linię 112+
Magento\Catalog\Block\Product\View\Options\Type\Select
aby zaznaczyć element wybrany jako „Element domyślny”.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;
}
}
}
Upgrade setup_version
inapp/code/Vendor/Module/etc/module.xml
Zaktualizuj swoje version
w app/code/Vendor/Module/composer.json
Uruchom następujące polecenia:
php bin/magento cache:clean
php bin/magento setup:upgrade