So, this is going to be a really convoluted answer. There are a LOT of pieces in play, and it really helps to know whats going on. I am just going to post the code to get a customer attribute into the customer grid.
Also, I want to STRESS that I cobbled this code together from a helper file and an InstallData.php file, taken from a rather expansive module. Theres a 99% chance it won't just work if you copy and paste. Rather, try to understand how it works.
There are a few important things to do:
- Be sure to extend the customer_listing.xml to inject your column into the grid.
- Make sure the attribute is set up properly: is_searchable_in_grid, etc
- DON'T FORGET THE MAGIC SAUCE (see commented code)
- Use a good toolset like PhpStorm + xdebug to see whats really going on.
Files to set up:
/companyname/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">
<columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
<column name="constit_id">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="editor" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Constit ID</item>
<item name="sortOrder" xsi:type="number">10</item>
</item>
</argument>
</column>
</columns>
</listing>
To create the attribute properly, you must create it using the following methods in your InstallData.php script.
use Magento\Customer\Model\Customer;
const FORM_CUSTOMER_ADMIN = array(
'adminhtml_customer',
'customer_account_create',
'customer_account_edit',
);
const INPUT_TEXT = array (
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'input' => 'text'
);
const CONSTIT_ID = 'constit_id';
protected $_userDefinedAttributeCodes = [];
protected $eavSetupFactory;
protected $attribute_info;
protected $customerSetupFactory;
protected $eavConfigFactory;
protected $indexerRegistry;
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Eav\Setup\EavSetupFactory $eavSetupFactory,
\Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory,
\Magento\Eav\Model\ConfigFactory $eavConfigFactory,
\Magento\Eav\Model\AttributeRepository $attributeRepository,
\Magento\Framework\Indexer\IndexerRegistry $indexerRegistry
) {
$this->eavConfigFactory = $eavConfigFactory;
$this->eavSetupFactory = $eavSetupFactory;
$this->customerSetupFactory = $customerSetupFactory;
parent::__construct($context);
}
public function configCustomerAttribute($setup, $attr_name, $pretty_name, $entity_name) {
$attr_setup = $this->customerSetupFactory->create(['setup' => $setup]);
$attributeExists = count($attr_setup->getAttribute($entity_name, $attr_name)) > 0;
if (empty($attributeExists)) {
$attr_setup->addAttribute(
$entity_name,
$attr_name,
array_merge($this->attribute_info, array('label' => $pretty_name))
);
}
// Pull newly created attribute
$attribute = $this->eavConfigFactory->create()->getAttribute($entity_name, $attr_name);
// Get current used in forms vars (if they exist)
$used_in_forms_diff = array_diff($this->attribute_info['used_in_forms'], $attribute->getUsedInForms());
// add the attribute to the customer_form table
if (count($used_in_forms_diff) > 0) {
$data = [];
foreach ($used_in_forms_diff as $formCode) {
$data[] = ['form_code' => $formCode, 'attribute_id' => $attribute->getId()];
}
$eavSetup = $this->eavSetupFactory->create();
$eavSetup->getSetup()->getConnection()
->insertMultiple($eavSetup->getSetup()->getTable('customer_form_attribute'), $data);
}
}
public function setAttributeInfo($where, $inputType, $required = false, $defaultValue = 0, $frontVisible = true, $useGrid = false) {
$this->attribute_info = array_merge(self::FORM_DEFAULTS, $inputType);
$this->attribute_info['required'] = $required;
$this->attribute_info['used_in_forms'] = $where;
$this->attribute_info['default'] = $defaultValue;
$this->attribute_info['visible_on_front'] = $frontVisible;
if ($useGrid){
$this->attribute_info['is_used_in_grid'] = 1;
$this->attribute_info['is_visible_in_grid'] = 1;
$this->attribute_info['is_filterable_in_grid'] = 1;
$this->attribute_info['is_searchable_in_grid'] = 1;
}
}
public function install(
\Magento\Framework\Setup\ModuleDataSetupInterface $setup,
\Magento\Framework\Setup\ModuleContextInterface $context)
{
$setup->startSetup();
$form_set = $this::FORM_CUSTOMER_ADMIN;
$this->setAttributeInfo($form_set, $this::INPUT_TEXT, false, '', false, true);
$this->configCustomerAttribute($setup, self::CONSTIT_ID , 'Constit ID', 'customer');
// MAGIC SAUCE - You HAVE to manually add the dang column to the customer_grid_flat table or your value won't show up.
$definition = ['type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT];
$definition['comment'] = 'STTI Constituent ID';
$setup->getConnection()->addColumn('customer_grid_flat', self::CONSTIT_ID, $definition);
$indexer = $this->indexerRegistry->get(Customer::CUSTOMER_GRID_INDEXER_ID);
$indexer->reindexAll();
$setup->endSetup();