0

I've registered a custom select option to my categories using the files below in my module. The select option appears in the backend with my custom options however it doesn't save the selected option when you save the categories?

Could anyone please advise whether I am missing anything to get this to save or advise how I can get the below to work?

app/code/[vendor]/[module]/Setup/UpgradeData.php

<?php
namespace Vendor\Module\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class UpgradeData implements UpgradeDataInterface
{
    private $eavSetupFactory;

    public function __construct(\Magento\Eav\Setup\EavSetupFactory $eavSetupFactory)
    {
            $this->eavSetupFactory = $eavSetupFactory;
    }

    public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
            $setup->startSetup();

            if (version_compare($context->getVersion(), '9.0.1', '<')) {
                $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

                $eavSetup->addAttribute(
                \Magento\Catalog\Model\Category::ENTITY,
                'category_icon_select',
                [
                    'group' => 'General',
                    'type' => 'varchar',
                    'backend' => '',
                    'frontend' => '',
                    'label' => 'Select Category Icon',
                    'input' => 'select',
                    'class' => '',
                    'source' => 'Vendor\Module\Model\Config\Source\Options',
                    'global' => \Magento\Catalog\Model\ResourceModel\Eav\Attribute::SCOPE_GLOBAL,
                    'visible' => true,
                    'required' => true,
                    'user_defined' => false,
                    'default' => '',
                    'searchable' => false,
                    'filterable' => false,
                    'comparable' => false,
                    'visible_on_front' => false,
                    'used_in_product_listing' => true,
                    'unique' => false
                ]);
            }

            $setup->endSetup();
    }

}

app/code/[vendor]/[module]/view/adminhtml/ui_component/category_form.xml

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="category_fields">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">Additional Settings</item>
                <item name="collapsible" xsi:type="boolean">true</item>
                <item name="sortOrder" xsi:type="number">100</item>
            </item>
        </argument>
        <field name="category_icon_select">
            <argument name="data" xsi:type="array">
            <item name="options" xsi:type="object">Vendor\Module\Model\Config\Source\Options</item>
                <item name="config" xsi:type="array">
                    <item name="sortOrder" xsi:type="number">60</item>
                    <item name="dataType" xsi:type="string">string</item>
                    <item name="formElement" xsi:type="string">select</item>
                    <item name="label" xsi:type="string" translate="true">Category Icon</item>
                </item>
            </argument>
        </field>
    </fieldset>
</form>

app/code/[vendor]/[module]/Model/Config/Source/Options.php

<?php
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Vendor\Module\Model\Config\Source;

/**
 * Catalog category landing page attribute source
 *
 * @author      Magento Core Team <[email protected]>
 */
class Options extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
{
    /**
     * {@inheritdoc}
     * @codeCoverageIgnore
     */
    public function getAllOptions()
    {
        if (!$this->_options) {
            $this->_options = [
                ['value' => 'car', 'label' => __('Car')],
                ['value' => 'truck', 'label' => __('Truck')],
                ['value' => 'van', 'label' => __('Van')],
            ];
        }
        return $this->_options;
    }
      /**
     * Get options in "key-value" format
     *
     * @return array
     */
    public function toArray()
    {
        return [
            'car' => __('Car'),
            'truck' => __('Truck'),
            'van' => __('Van'),
            ];
    }

}

1 Answer 1

4

Have you checked if your Custom Category Attribute has actually been added to the database because if it hasn't you should update your version number in the module.xml and run setup:upgrade

Example module files for Custom Category Attribute.

app/code/Vendor/Module/etc/module.xml

<?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Vendor_Module" setup_version="1.0.0"/>
    </config>

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

namespace Vendor\Module\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;

class InstallData implements InstallDataInterface
{

    private $eavSetupFactory;

    /**
     * Constructor
     *
     * @param \Magento\Eav\Setup\EavSetupFactory $eavSetupFactory
     */
    public function __construct(EavSetupFactory $eavSetupFactory)
    {
        $this->eavSetupFactory = $eavSetupFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        $eavSetup->addAttribute(
            \Magento\Catalog\Model\Category::ENTITY,
            'category_icon_select',
            [
                'type' => 'int',
                'label' => 'Select Category Icon',
                'input' => 'select',
                'sort_order' => 333,
                'source' => 'Vendor\Module\Model\Category\Attribute\Source\CategoryIconSelect',
                'global' => 1,
                'visible' => true,
                'required' => true,
                'user_defined' => false,
                'default' => null,
                'group' => 'General Information',
                'backend' => ''
            ]
        );
    }
}

app/code/Vendor/Module/view/adminhtml/ui_component/category_form.xml

<?xml version="1.0" ?>
    <form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
        <fieldset name="general">
            <field name="category_icon_select">
                <argument name="data" xsi:type="array">
                    <item name="options" xsi:type="object">Vendor\Module\Model\Category\Attribute\Source\CategoryIconSelect</item>
                    <item name="config" xsi:type="array">
                        <item name="required" xsi:type="boolean">true</item>
                        <item name="validation" xsi:type="array">
                            <item name="required-entry" xsi:type="boolean">true</item>
                        </item>
                        <item name="sortOrder" xsi:type="number">333</item>
                        <item name="dataType" xsi:type="string">string</item>
                        <item name="formElement" xsi:type="string">select</item>
                        <item name="label" translate="true" xsi:type="string">Select Category Icon</item>
                    </item>
                </argument>
            </field>
        </fieldset>
    </form>

app/code/Vendor/Module/Model/Category/Attribute/Source/CategoryIconSelect.php

<?php


namespace Vendor\Module\Model\Category\Attribute\Source;

class CategoryIconSelect extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
{

    protected $_optionsData;

    /**
     * Constructor
     *
     * @param array $options
     */
    public function __construct(array $options = [])
    {
        $this->_optionsData = $options;
    }

    /**
     * getAllOptions
     *
     * @return array
     */
    public function getAllOptions()
    {
        if (count($this->_optionsData) < 1) {
            $this->_optionsData = [
                ['value' => '1', 'label' => __('car')],
                ['value' => '2', 'label' => __('truck')],
                ['value' => '3', 'label' => __('van')]
            ];
        }
        return $this->_optionsData;
    }
}

If this doesn't work you can take a look at Mage2Gen to create a custom Category Attribute

https://mage2gen.com/

4
  • Thanks for your reply, but unfortunately the above didn't work :( That mage2gen looks cool however I am pretty new to magento 2 so I am really unsure how to use it :( Do you know whether I need to add any additional files to be able to save the attribute? Just struggling to find anything in regards to this?
    – lky
    Jul 3, 2017 at 9:08
  • @heady12 I have updated my answer
    – Mr. Lewis
    Jul 3, 2017 at 9:57
  • Thanks Mr. Lewis, I've got this working by saving the type as 'int' and changing the values in my options to integers :)
    – lky
    Jul 3, 2017 at 10:17
  • I am facing Type Error occurred when creating object Vendor\Module\Model\Category\Attribute\Source\CategoryIconSelect, I also removed the generated folder & recompiled again, still unable to fix the issue
    – senthil
    May 1, 2020 at 8:11

Your Answer

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

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