1

I added custom tab in customer dashboard, using customer_account.xml and i need to create form to this custom tab, if I click this custom tab, form will open in content area based on customer dashboard. So, which xml file I need to use to write a content.

5

I have done it like this , hope it will help you , i have extracted the script from my full module just to explain the flow of adding form and saving form data to database.

It is bit lengthy , but tried to explain in detail

For adding custom tab to customer dashboard

created a file view/frontend/layout/customer_account.xml with script

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" label="Customer My Account (All Pages)" design_abstraction="custom">
    <body>        
        <referenceBlock name="customer_account_navigation">
            <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-customtab-link">
                <arguments>
                    <argument name="label" xsi:type="string" translate="true">Profile</argument>
                    <argument name="path" xsi:type="string">customtab/profile</argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>

Then created the controller Controller/Profile/Index.php that will work for path customtab/profile with script

namespace Sample\Customtab\Controller\Profile;

class Index extends \Sample\Customtab\Controller\Profile
{
    /**
     * Managing newsletter subscription page
     *
     * @return void
     */
    public function execute()
    {
        $this->_view->loadLayout();

        /*if ($block = $this->_view->getLayout()->getBlock('customer_newsletter')) {
            $block->setRefererUrl($this->_redirect->getRefererUrl());
        }*/
        $this->_view->getPage()->getConfig()->getTitle()->set(__('Custom Profile'));
        $this->_view->renderLayout();
    }
}

Now created the layout file at view/frontend/layout/customtab_profile_index.xml with script

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <body>
        <referenceContainer name="content">
            <block class="Sample\Customtab\Block\Store\Profile" name="customtab.store.profile" template="Sample_Customtab::store/profile.phtml"  />
        </referenceContainer>
    </body>
</page>

Now i have to create the block Block/Store/Profile.php

namespace Sample\Customtab\Block\Store;

/**
 * Sales order history block
 */
class Profile extends \Magento\Framework\View\Element\Template
{
    /**
     * @var string
     */
    //protected $_template = 'order/history.phtml';

    /**
     * @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory
     */
    protected $collectionFactory;

    /**
     * @var \Magento\Customer\Model\Session
     */
    protected $_customerSession;

    /**
     * @var \Magento\Sales\Model\Order\Config
     */
    protected $_orderConfig;

    /** @var \Magento\Sales\Model\ResourceModel\Order\Collection */
    protected $orders;

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory
     * @param \Magento\Customer\Model\Session $customerSession
     * @param \Magento\Sales\Model\Order\Config $orderConfig
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Sample\Customtab\Model\ResourceModel\Stores\CollectionFactory $collectionFactory,
        \Magento\Customer\Model\Session $customerSession,
        array $data = []
    ) {
        $this->collectionFactory = $collectionFactory;
        $this->_customerSession = $customerSession;
        parent::__construct($context, $data);
    }

    /**
     * @return void
     */
    protected function _construct()
    {
        parent::_construct();
        $this->pageConfig->getTitle()->set(__('Store Profile'));

        $customerId     = $this->_customerSession->getCustomerId();   

        if($customerId)
        {
           $profiledata = $this->collectionFactory->create()->addFieldToSelect('*')
            ->addFieldToFilter('customer_id',$customerId);

           foreach($profiledata as $profile)
           {        
                $this->setProfileData($profile);
           }
        }
    }
}

And now the called phtml file view/frontend/templates/store/profile.phtml

$storeProfile = $block->getProfileData();

And in the form you have to put form action like

action="<?php echo $this->getUrl('customtab/profile/save'); ?>"

I have just place the code to fetch the data , in this phtml file you can put your html code with your required fields.

Now for \Sample\Customtab\Model\ResourceModel\Stores\CollectionFactory used in block we have to create collection for it

Create a model Model/Stores.php with

namespace Sample\Customtab\Model;

/**
 * Megamenutab megamenu model
 */
class Stores extends \Magento\Framework\Model\AbstractModel
{

    /**
     * @param \Magento\Framework\Model\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
    }

    /**
     * @return void
     */
    public function _construct()
    {
        $this->_init('Sample\Customtab\Model\ResourceModel\Stores');
    }   
}

The ResourceModel Model/ResourceModel/Stores.php with

namespace Sample\Customtab\Model\ResourceModel;

class Stores extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{

    public function _construct()
    {
        $this->_init('yourtablename', 'id');   // with id primery key 
    }  
}

Then Collection Model Model/ResourceModel/Stores/Collection.php with

namespace Sample\Customtab\Model\ResourceModel\Stores;

class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    public function _construct()
    {
        $this->_init('Sample\Customtab\Model\Stores', 'Sample\Customtab\Model\ResourceModel\Stores');
    }
}

Now have to create abstract class for save profile controller Controller/Profile.php

namespace Sample\Customtab\Controller;

use Magento\Framework\App\RequestInterface;

abstract class Profile extends \Magento\Framework\App\Action\Action
{   
    protected $_customerSession;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Customer\Model\Session $customerSession
    ) {
        parent::__construct($context);
        $this->_customerSession = $customerSession;
    }

    public function dispatch(RequestInterface $request)
    {
        if (!$this->_customerSession->authenticate()) {
            $this->_actionFlag->set('', 'no-dispatch', true);
        }
        return parent::dispatch($request);
    }
}

Now have to create profile save controller that will work on profile save form action Controller/Profile/Save.php

namespace Sample\Customtab\Controller\Profile;

use Magento\Customer\Api\CustomerRepositoryInterface as CustomerRepository;

class Save extends \Sample\Customtab\Controller\Profile
{
    protected $formKeyValidator;

    protected $storeManager;

    protected $customerRepository;

    protected $subscriberFactory;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Customer\Model\Session $customerSession,
        \Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        CustomerRepository $customerRepository,
        \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory
    ) {
        $this->storeManager = $storeManager;
        $this->formKeyValidator = $formKeyValidator;
        $this->customerRepository = $customerRepository;
        $this->subscriberFactory = $subscriberFactory;
        parent::__construct($context, $customerSession);
    }

    /**
     * Save newsletter subscription preference action
     *
     * @return void|null
     */
    public function execute()
    {
        if (!$this->formKeyValidator->validate($this->getRequest())) {
            return $this->_redirect('customer/account/');
        }

        $customerId = $this->_customerSession->getCustomerId();

        if ($customerId === null) {
            $this->messageManager->addError(__('Something went wrong while saving your subscription.'));
        } else {
            try {                   
                    $data = $this->getRequest()->getParams();

                    $model = $this->_objectManager->create('Sample\Customtab\Model\Stores');

                    $data['customer_id'] = $customerId; // customer_id is one of the field from custom database table

                    $id = $this->getRequest()->getParam('id');

                    if ($id) {
                    $model->load($id);
                    }

                    $model->setData($data);

                    $model->save();

                    $this->messageManager->addSuccess(__('Profile has beem saved successfully.'));

                    $this->_redirect('*/*/');

                    return;

                } catch (\Exception $e) {
                    $this->messageManager->addError(__('Something went wrong while saving your profile.'));
                }
        }
        $this->_redirect('customer/account/');
    }
}

Hope i have included all the things. And it will work for you.

  • I want to create the custom tab in customer are for only shows the logged in customer complete details. How I can achieve this using custom controller and Block? – mageDev0688 May 8 '17 at 9:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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