Our Work

Add Custom Attribute to Customer in Magento 2

Updated today

This article will explains, how to create custom attribute to customer. In this article we have added phone number filed to the customer.
To create Phone Number custom attribute to customer we need to do the following activities.

  • Create a module.
  • Create installdata file
  • Add custom attribute to admin customers grid
  • Add custom attribute to customer registration (frontend)

1.Module

1.1 Create module

Please refer this article for Module Creation.
https://ktree.com/create-magento-2-module-custom.html

1.2 Folder Structure

1.3 List of created files other then default files

  • app/code/KTree/CustomerAttribute/Setup/InstallData.php
  • app/code/KTree/CustomerAttribute/view/adminhtml/ui_component/customer_listing.xml
  • app/code/KTree/CustomerAttribute/Ui/Component/Listing/Column/PhoneNumber.php
  • app/code/KTree/CustomerAttribute/view/frontend/layout/customer_account_create.xml
  • app/code/KTree/CustomerAttribute/view/frontend/templates/phone_number.phtml

2. Create installdata file

This step is similar to Magento 1, to add new attribute we need to create script file inside Setup folder

  • This file executes only one time, when install the module and first install method will be called.
  • Customer attributes can be used in different forms, this example will show customer attribute at the admin customer edit , create page and grid.You can also use also other forms.
    For example:
    “used_in_forms”=>                                      ['adminhtml_checkout','adminhtml_customer','adminhtml_customer_address','customer_account_edit','
    customer_address_edit','customer_register_address']

File Location :-  app/code/KTree/CustomerAttribute/Setup/InstallData.php

<?php
namespace KTree\CustomerAttribute\Setup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Customer\Model\Customer;
use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
class InstallData implements InstallDataInterface
{
    /**
     * @var CustomerSetupFactory
     */
    protected $customerSetupFactory;
    /**
     * @var AttributeSetFactory
     */
    private $attributeSetFactory;
    /**
     * @param CustomerSetupFactory $customerSetupFactory
     * @param AttributeSetFactory $attributeSetFactory
     */
    public function __construct(
        CustomerSetupFactory $customerSetupFactory,
        AttributeSetFactory $attributeSetFactory
    ) {
        $this->customerSetupFactory = $customerSetupFactory;
        $this->attributeSetFactory = $attributeSetFactory;
    }
  public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
/*customersetupfactory instead of eavsetupfactory */
$customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
$customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
    $attributeSetId = $customerEntity->getDefaultAttributeSetId();
/** @var $attributeSet AttributeSet */
        $attributeSet = $this->attributeSetFactory->create();
        $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);
/* create customer phone number attribute */
$customerSetup->addAttribute(Customer::ENTITY,'phone_number',	[
'type'         => 'varchar', // attribute with varchar type
'label'        => 'Phone Number',
'input'        => 'text',  // attribute input field is text
'required'     => false,  // field is not required
'visible'      => true,  
'user_defined' => true,
'position'     => 999,
'sort_order'  => 999,
'system'       => 0,
'is_used_in_grid' => 1,   //setting grid options
'is_visible_in_grid' => 1,
'is_filterable_in_grid' => 1,
'is_searchable_in_grid' => 1,
]
);
$sampleAttribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'phone_number')
->addData(
[
            'attribute_set_id' => $attributeSetId,
            'attribute_group_id' => $attributeGroupId,
            'used_in_forms' => ['adminhtml_customer','customer_account_edit','customer_account_create'],
        ]
// more used_in_forms ['adminhtml_checkout','adminhtml_customer','adminhtml_customer_address','customer_account_edit','customer_address_edit','customer_register_address']
);
$sampleAttribute->save();
}
}

After completing above step:

  • Run command to create attribute   “php bin/magento setup:upgrade” and “php bin/mgento setup:static-content:deploy” (If you are on Magento 2.2.x than you need to add -f at end of command)
  • After running the above script,new entries will create in the following tables.
    • eav_attribute
    • customer_eav_attribute
    • Customer_form_attribute.
  • Check in current module version in setup_module table, which is equivalent of core_resource in Magento 1
  • If we create an account along with the phone number, it gets stored into the database in customer_entity_varchar table.
  • After the values get stored in database, login to admin and Navigate to Customers→All Customers→ New Customer here you can see the phone number field in new customer form.

3.Add custom attribute to admin customers grid

Magento does not provide us with the ability to choose which attributes are included as columns in the customers grid but it’s fairly simple to make the necessary code changes.

  • Extend the customer_listing.xml to inject your column into the grid.
  • Create PhoneNumber class in app/code/KTree/CustomerAttribute/Ui/Component/Listing/Column/ and extends class from Column Class.

 File:-app/code/KTree/CustomerAttribute/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"/>
    <columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
        <column name="phone_number" class="KTree\CustomerAttribute\Ui\Component\Listing\Column\PhoneNumber">
            <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">Phone Number</item>
                    <item name="sortOrder" xsi:type="number">40</item>
                    </item>
            </argument>
        </column>
    </columns>
</listing>
  • Here, name attribute value should be same as existing grid name(customer_columns). name  attribute value  in column tag should be same as custom attribute name.
  • class attribute is used to define values to custom attribute(phone number) column. For column we are passing array type argument items.
  • filter and editor  argument items  used to define type of the input field to filter(here textbox) .
  • label is used to display name of the column. Sortorder is used to define order number of the custom column in grid.

File:app/code/KTree/CustomerAttribute/Ui/Component/Listing/Column/PhoneNumber.php

<?php
namespace KTree\CustomerAttribute\Ui\Component\Listing\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
class PhoneNumber extends Column
{
    /**
     *
     * @param ContextInterface   $context
     * @param UiComponentFactory $uiComponentFactory
     * @param array              $components
     * @param array              $data
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        array $components = [],
        array $data = []
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
    }
    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     * @return array
     */
    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item)
            {
                $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
                $customer =    $objectManager->create('Magento\Customer\Model\Customer')->load($item['entity_id']);
                $item[$this->getData('name')] = $customer->getPhoneNumber();
            }
        }
        return $dataSource;
    }
}
?>
  • We are extending our PhoneNumber  class from Magento\Ui\Component\Listing\Columns\Column component. Column component extends from AbstractComponent and implements ColumnInterface.
  • Column Component is  responsible to set data to grid and able to sort the grid items.
  • Here, $this->getData(‘name’) return phone_number and we are using datasource to set data to custom attribute.
  • After completion of above step run “bin/magento indexer:reindex” and flush the cache command. Phone number will added to customer grid.

4. Add custom attribute to registration form (frontend)

Instead overriding entire registration.phtml file we used container name form.additional.info as reference and adding a new block to it.

File:  app/code/KTree/CustomerAttribute/view/frontend/layout/customer_account_create.xml

<page
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="form.additional.info">
            <block class="Magento\Framework\View\Element\Template" name="phone_number" template="KTree_CustomerAttribute::phone_number.phtml"/>
        </referenceContainer>
    </body>
</page>

In phone_number.phtml file we will write the code to show the textbox

<div class="field phone_number">
   <label class="label" for="phone_number"><span><?php /* @escapeNotVerified */ echo __('Phone Number') ?></span></label>
    <div class="control">
        <input type="text" id="phone_number" name="phone_number"  title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" class="input-text" autocomplete="off">
    </div>
</div>
  • The full source code can be downloaded from this Github link Customer Custom attribute
  • Now clear the cache using php bin/magento cache:clean command and then the attribute will be shown on the customer registration page

Looking for Magento Developer?

Please Contact us if you have any Magento Implementation requirements. Hire dedicated Magento developers or Magento Development services from KTree. KTree is Best offshore Magento E-commerce development company with extensive experience in E-commerce development and Magento Plugins.

Request For Quote