0

I've made a patch and this is the code for creating my customer custom attribute:

public function apply()
{
    $this->moduleDataSetup->getConnection()->startSetup();

    /** @var CustomerSetup $customerSetup */
    $customerSetup  = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
    $customerEntity = $customerSetup->getEavConfig()->getEntityType(Customer::ENTITY);
    $attributeSetId = $customerEntity->getDefaultAttributeSetId();

    $attributeSet       = $this->attributeSetFactory->create();
    $attributeGroupId   = $attributeSet->getDefaultGroupId($attributeSetId);

    try {
        $customerSetup->addAttribute(
            Customer::ENTITY,
            self::CUSTOMER_EMAIL_PREFERENCE,
            [
                'label' => 'Email preferences',
                'input' => 'multiselect',
                'type' => 'text',
                'source' => 'MyVendor\Customer\Model\Customer\Attribute\Source\EmailPreference',
                'required' => false,
                'position' => 333,
                'visible' => true,
                'system' => false,
                'is_used_in_grid' => true,
                'is_visible_in_grid' => true,
                'is_filterable_in_grid' => true,
                'is_searchable_in_grid' => true,
                'backend' => ''
            ]
        );
    } catch (Exception $error) {
        echo $error->getMessage(); exit();
    }

    $attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, self::CUSTOMER_EMAIL_PREFERENCE);
    $attribute->addData([
        'used_in_forms' => [
            'adminhtml_customer',
            'adminhtml_checkout',
            'customer_account_create',
            'customer_account_edit'
        ]
    ]);
    $attribute->addData([
        'attribute_set_id'   => $attributeSetId,
        'attribute_group_id' => $attributeGroupId

    ]);
    $attribute->save();

    $this->moduleDataSetup->getConnection()->endSetup();
}

This code creates the customer attribute and all is good, except that it does not appear in the filters! I've added this part:

        'is_used_in_grid' => true,
        'is_visible_in_grid' => true,
        'is_filterable_in_grid' => true,
        'is_searchable_in_grid' => true,

But still doesn't work. Not sure that it is because of the multiselect type. I've made a new customer attribute , the only difference is that the input 's value is set to select . Like: 'input' => 'multiselect',. In this case I can filter it. Weird!

Would you please share your opinion, advice for this ?

Thanks a lot!

2 Answers 2

0

I found this workaround: Create this file, with this path: app/code/MyVendor/ModuleName/view/adminhtml/ui_component/customer_listing.xml:

<?xml version="1.0" encoding="UTF-8"?>

<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <listingToolbar name="listing_top">
        <filters name="listing_filters">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="templates" xsi:type="array">
                        <item name="filters" xsi:type="array">
                            <item name="select" xsi:type="array">
                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
                                <item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </filters>
    </listingToolbar>
    <columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
        <column name="{ YOUR CUSTOM CUSTOMER ATTRIBUTE CODE }">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">\MyVendor\MyModule\Model\Customer\Attribute\Source\CustomCustomerAttribute</item>
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="label" xsi:type="string" translate="true">Email preferences</item>
                    <item name="sortOrder" xsi:type="number">300</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

and in the \MyVendor\MyModule\Model\Customer\Attribute\Source\CustomCustomerAttribute, make sure you have this:

use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;

class CustomCustomerAttribute extends AbstractSource
{
    /**
     * @return array
     */
    public function getAllOptions(): array
    {
        $this->_options = [];
        $this->_options[] = ['label' => 'Label 1', 'value' => 'value1'];
        $this->_options[] = ['label' => 'Label 2', 'value' => 'value2'];
        $this->_options[] = ['label' => 'Label 3', 'value' => 'value3'];

        return $this->_options;
    }
} 

Good luck !

0

I didn't find this solution so this is the way i figured it out. In this example i am adding a customer_status column and filtering to the customers grid :

file: adminhtml/di.xml:

<type name="Magento\Customer\Model\ResourceModel\Grid\Collection">
    <plugin name="Vendor_Module::AddCustomerStatusFilter"
            type="Vendor\Module\Plugin\Ui\Component\CustomersGrid\CustomerGridAddCustomerStatusFilter"/>
</type>
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <plugin name="vendor_customer_grid_add_customer_status"
            type="Vendor\Module\Plugin\Ui\Component\CustomersGrid\CustomerGridAddCustomerStatusField"/>

Add status filter plugin:

declare(strict_types=1);

namespace Vendor\Module\Plugin\Ui\Component\CustomersGrid;

use Magento\Customer\Model\ResourceModel\Grid\Collection;

class CustomerGridAddCustomerStatusFilter
{

    /**
     * @param Collection $subject
     * @param array|string $field
     * @param array|string|null $condition
     * @throws \Zend_Db_Select_Exception
     */
    public function beforeAddFieldToFilter(Collection $subject, array|string $field, array|string $condition = null)
    {
        if ($field === 'customer_status' && array_key_exists('customer_entity', $subject->getSelect()->getPart('from'))) {
            $field = 'customer_entity.is_active';
        }

        return [
            $field,
            $condition,
        ];
    }
}

Add customer status field plugin:

<?php

declare(strict_types=1);

namespace Vendor\Module\Plugin\Ui\Component\CustomersGrid;

use Magento\Framework\Data\Collection;
use Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory;

class CustomerGridAddCustomerStatusField
{
    private const CUSTOMER_GRID_TABLE = 'customer_grid_flat';

    public function afterGetReport(CollectionFactory $subject, Collection $collection, $requestName)
    {
        if ($collection->getMainTable() === $collection->getConnection()->getTableName(self::CUSTOMER_GRID_TABLE)) {
            $collection->getSelect()->joinLeft(
                ['customer_entity' => 'customer_entity'],
                'customer_entity.entity_id = main_table.entity_id',
                ['customer_status' => 'customer_entity.is_active'],
            );
        }

        return $collection;
    }
}

customer_listing.xml :

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
        <column name="customer_status" class="Vendor\Module\Ui\Component\Listing\Column\CustomerStatus"
                component="Vendor_Module/js/grid/columns/select" sortOrder="10">
            <settings>
                <filter>select</filter>
                <options class="Vendor\Module\Ui\Component\Listing\Column\CustomerStatus\Options"/>
                <dataType>select</dataType>
                <label translate="true">Customer Status</label>
                <visible>true</visible>
            </settings>
        </column>
    </columns>
</listing>

Filter Options class code:

<?php
declare(strict_types=1);

namespace Vendor\Module\Ui\Component\Listing\Column\CustomerStatus;

use Magento\Framework\Data\OptionSourceInterface;

/**
 * Class Options for Listing Column Customer Status
 */
class Options implements OptionSourceInterface
{
    /**
     * Get options
     *
     * @return array
     */
    public function toOptionArray()
    {
        return [
            [
                'value' => '1',
                'label' => __('Active'),
            ],
            [
                'value' => '0',
                'label' => __('Inactive'),
            ],
            [
                'value' => 'guest',
                'label' => __('Guest'),
            ],
        ];
    }
}

Good luck!

Your Answer

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

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