Magento – Magento2: Category Select Attribute Not Saving

category-attributecustom-attributesmagento-2.1multiselect-attributesave

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 <core@magentocommerce.com>
 */
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'),
            ];
    }

}

Best Answer

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/