Hello,
I am working on a module to add a product custom option input type (Derivated from file type).
In the backend under catalog / product / custom options, my new option is present in the "input type" list but when I select it, the associated fields are not displayed (Price, price type, sky, compatible file extension, etc).
I do not manage to find what is going on...
Tank your for your help,
Alexandre
My files :
app/code/A/Custoptiontype/etc/module.xml
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="A_Custoptiontype" setup_version="1.0.0"> <sequence> <module name="Magento_Catalog"/> </sequence> </module> </config>
app/code/A/Custoptiontype/etc/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\Adminhtml\Product\Edit\Tab\Options\Option" type="A\Custoptiontype\Block\Adminhtml\Product\Edit\Tab\Options\Option"/> <preference for="Magento\Catalog\Model\Product\Option" type="A\Custoptiontype\Model\Catalog\Product\Option"/> </config>
app/code/A/Custoptiontype/etc/product_options.xml
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/product_options.xsd"> <option name="xfile" label="X File" renderer="A\Custoptiontype\Block\Adminhtml\Product\Edit\Tab\Options\Type\Xfile"> <inputType name="xfile" label="X File" /> </option> </config>
app/code/A/Custoptiontype/Block/Adminhtml/Product/Edit/Tab/Options/Option.php
<?php namespace A\Custoptiontype\Block\Adminhtml\Product\Edit\Tab\Options; class Option extends \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\Option { protected $_template = 'A_Custoptiontype::catalog/product/edit/options/option.phtml'; /** * Class constructor */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Config\Model\Config\Source\Yesno $configYesNo, \Magento\Catalog\Model\Config\Source\Product\Options\Type $optionType, \Magento\Catalog\Model\Product $product, \Magento\Framework\Registry $registry, \Magento\Catalog\Model\ProductOptions\ConfigInterface $productOptionConfig, array $data = [] ) { parent::__construct( $context, $configYesNo, $optionType, $product, $registry, $productOptionConfig, $data ); } /** * Retrieve html templates for different types of product custom options * * @return string */ public function getTemplatesHtml() { $canEditPrice = $this->getCanEditPrice(); $canReadPrice = $this->getCanReadPrice(); $this->getChildBlock('xfile_option_type') ->setCanReadPrice($canReadPrice) ->setCanEditPrice($canEditPrice); $templates = parent::getTemplatesHtml() . "\n" . $this->getChildHtml('xfile_option_type'); return $templates; } }
app/code/A/Custoptiontype/Block/Adminhtml/Product/Edit/Tab/Options/Type/Xfile.php
<?php namespace A\Custoptiontype\Block\Adminhtml\Product\Edit\Tab\Options\Type; class Xfile extends \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\Type\AbstractType { /** * @var string */ protected $_template = 'A_Custoptiontype::catalog/product/edit/options/type/xfile.phtml'; public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Catalog\Model\Config\Source\Product\Options\Price $optionPrice, array $data = [] ) { $this->_optionPrice = $optionPrice; parent::__construct($context, $optionPrice, $data); } }
app/code/A/Custoptiontype/view/adminhtml/templates/catalog/product/edit/options/option.phtml
<?php /** * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ // @codingStandardsIgnoreFile ?> <?php /** @var $block \A\Custoptiontype\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\Option */ ?> <?php echo $block->getTemplatesHtml() ?> <script id="custom-option-base-template" type="text/x-magento-template"> <div class="fieldset-wrapper admin__collapsible-block-wrapper opened" id="option_<%- data.id %>"> <div class="fieldset-wrapper-title"> <strong class="admin__collapsible-title" data-toggle="collapse" data-target="#<%- data.id %>-content"> <span id="option_<%- data.id %>_header_title"><%- data.title %></span> </strong> <div class="actions"> <button type="button" title="<?php /* @escapeNotVerified */ echo __('Delete Custom Option'); ?>" class="action-delete" id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_delete"> <span><?php /* @escapeNotVerified */ echo __('Delete Custom Option'); ?></span> </button> </div> <div id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_move" data-role="draggable-handle" class="draggable-handle" title="<?php /* @escapeNotVerified */ echo __('Sort Custom Options'); ?>"></div> </div> <div class="fieldset-wrapper-content in collapse" id="<%- data.id %>-content"> <fieldset class="fieldset"> <fieldset class="fieldset-alt" id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>"> <input id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_is_delete" name="<?php /* @escapeNotVerified */ echo $block->getFieldName() ?>[<%- data.id %>][is_delete]" type="hidden" value=""/> <input id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_previous_type" name="<?php /* @escapeNotVerified */ echo $block->getFieldName() ?>[<%- data.id %>][previous_type]" type="hidden" value="<%- data.type %>"/> <input id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_previous_group" name="<?php /* @escapeNotVerified */ echo $block->getFieldName() ?>[<%- data.id %>][previous_group]" type="hidden" value=""/> <input id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_id" name="<?php /* @escapeNotVerified */ echo $block->getFieldName() ?>[<%- data.id %>][id]" type="hidden" value="<%- data.id %>"/> <input id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_option_id" name="<?php /* @escapeNotVerified */ echo $block->getFieldName() ?>[<%- data.id %>][option_id]" type="hidden" value="<%- data.option_id %>"/> <input name="<?php /* @escapeNotVerified */ echo $block->getFieldName() ?>[<%- data.id %>][sort_order]" type="hidden" value="<%- data.sort_order %>"/> <div class="field field-option-title required"> <label class="label" for="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_title"> <?php /* @escapeNotVerified */ echo __('Option Title') ?> </label> <div class="control"> <input id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_title" name="<?php /* @escapeNotVerified */ echo $block->getFieldName() ?>[<%- data.id %>][title]" class="required-entry input-text" type="text" value="<%- data.title %>" data-store-label="<%- data.title %>" <% if (typeof data.scopeTitleDisabled != 'undefined' && data.scopeTitleDisabled != null) { %> disabled="disabled" <% } %> > <%- data.checkboxScopeTitle %> </div> </div> <div class="field field-option-input-type required"> <label class="label" for="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_title"> <?php /* @escapeNotVerified */ echo __('Input Type') ?> </label> <div class="control opt-type"> <?php echo $block->getTypeSelectHtml() ?> </div> </div> <div class="field field-option-req"> <div class="control"> <input id="<?php /* @escapeNotVerified */ echo $block->getFieldId() ?>_<%- data.id %>_required" class="is-required" type="checkbox" checked="checked"/> <label for="field-option-req"> <?php /* @escapeNotVerified */ echo __('Required')?> </label> <span style="display:none"><?php echo $block->getRequireSelectHtml() ?></span> </div> </div> </fieldset> </fieldset> </div> </div> </script> <div id="import-container" style="display: none;"></div> <?php if (!$block->isReadonly()): ?> <div><input type="hidden" name="affect_product_custom_options" value="1"/></div> <?php endif; ?> <script> require([ "jquery", "Magento_Catalog/js/custom-options" ], function(jQuery){ jQuery(function ($) { var fieldSet = $('[data-block=product-custom-options]'); fieldSet.customOptions(<?php /* @escapeNotVerified */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode( [ 'fieldId' => $block->getFieldId(), 'productGridUrl' => $block->getProductGridUrl(), 'formKey' => $block->getFormKey(), 'customOptionsUrl' => $block->getCustomOptionsUrl(), 'isReadonly' => $block->isReadonly(), 'itemCount' => $block->getItemCount(), 'currentProductId' => $block->getCurrentProductId(), ] )?>); //adding data to templates <?php /** @var $_value \Magento\Framework\DataObject */ ?> <?php foreach ($block->getOptionValues() as $_value): ?> fieldSet.customOptions('addOption', <?php /* @escapeNotVerified */ echo $_value->toJson() ?>); <?php endforeach; ?> }); }); </script>
app/code/A/Custoptiontype/view/adminhtml/templates/catalog/product/edit/options/type/xfile.phtml
<?php /** * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ // @codingStandardsIgnoreFile ?> <?php /** @var $block \A\Custoptiontype\Block\Adminhtml\Product\Edit\Tab\Options\Type\Xfile */ ?> <h1>TOTOTOTOTO</h1> <script id="custom-option-xfile-type-template" type="text/x-magento-template"> <div id="product_option_<%- data.option_id %>_type_<%- data.group %>" class="fieldset"> <table class="data-table"> <thead> <tr> <?php if ($block->getCanReadPrice() !== false) : ?> <th><?php /* @escapeNotVerified */ echo __('Price'); ?></th> <th><?php /* @escapeNotVerified */ echo __('Price Type'); ?></th> <?php endif; ?> <th><?php /* @escapeNotVerified */ echo __('SKU'); ?></th> <th><?php /* @escapeNotVerified */ echo __('Compatible File Extensions'); ?></th> <th><?php /* @escapeNotVerified */ echo __('Maximum Image Size'); ?></th> </tr> </thead> <tr> <?php if ($block->getCanReadPrice() !== false) : ?> <td class="opt-price"> <input name="product[options][<%- data.option_id %>][price]" data-store-label="<%- data.price %>" class="input-text validate-zero-or-greater" type="text" value="<%- data.price %>" <?php if ($block->getCanEditPrice() === false) : ?> disabled="disabled" <?php endif; ?>> </td> <td class="opt-price-type"><?php echo $block->getPriceTypeSelectHtml('data-attr="price-type"') ?><%- data.checkboxScopePrice %></td> <?php else : ?> <input name="product[options][<%- data.option_id %>][price]" type="hidden"> <input id="product_option_<%- data.option_id %>_price_type" name="product[options][<%- data.option_id %>][price_type]" type="hidden"> <?php endif; ?> <td> <input name="product[options][<%- data.option_id %>][sku]" class="input-text" type="text" value="<%- data.sku %>"> </td> <td> <input name="product[options][<%- data.option_id %>][file_extension]" class="input-text" type="text" value="<%- data.file_extension %>"> </td> <td class="col-file"><?php /* @escapeNotVerified */ echo __('%1 <span>x</span> %2 <span>px.</span>', '<input class="input-text" type="text" name="product[options][<%- data.option_id %>][image_size_x]" value="<%- data.image_size_x %>">', '<input class="input-text" type="text" name="product[options][<%- data.option_id %>][image_size_y]" value="<%- data.image_size_y %>">') ?> <div class="note"><?php /* @escapeNotVerified */ echo __('Please leave blank if it is not an image.') ?></div> </td> </tr> </table> </div> </script>
HI Alex,
Would you mind your experience and answer here with updated code, so it can help to all members here as I am too looking for same solution.
--Yogi
Hey Alex,
I go through your steps , but my custom option fields is not displaying . Can u upload your answer. So I will be great thankful to you
Divya
Here is a quick solution for it (100% success):
[Solved] Magento Error: Custom Option Type Fields Are Not Displayed
Follow the instruction, if it still doesn't work, I will help!