Magento – Adding tabs to custom view in Magento’s admin section

admintabs

I have tried to follow a couple of tutorials and when that failed tried to copy an example in the magento core to add tabs to a custom admin module, but with no success. Looking at the tutorials and the code the magento I feel I am close but can't work out what I am missing to achieve my desired results.

What I have is a displays for users that fall into set groups. I would like to add a couple of tabs to the left of that grid to allow the end user more options.

So far I have got this:

layout/prefs.xml

<layout version="0.1.0">
<prefs_adminhtml_adminprefs_index>
    <reference name="content">
        <block type="prefs/adminhtml_edit_tabs" name="admin.tabs" >
            <block type="prefs/adminhtml_prefs" name="adminprefs" />
        </block>
    </reference>
</prefs_adminhtml_adminprefs_index>
</layout>

.

class Ps_Prefs_Block_Adminhtml_Prefs
extends Mage_Adminhtml_Block_Widget_Grid_Container
{
public function _construct()
{
    $this->_controller = 'adminhtml_prefs';
    $this->_blockGroup = 'prefs';
    $this->_headerText = $this->__('Preference centre users');//title
    $this->_addButtonLabel = $this->__('Add Item');
    parent::_construct();
}

protected function _prepareLayout()
{
    $this->setChild( 'grid',
            $this->getLayout()->createBlock( $this->_blockGroup . '/' . $this->_controller . '_grid',
            $this->_controller . '.grid')->setSaveParametersInSession(TRUE) );
    return parent::_prepareLayout();
}
}

.

class Ps_Prefs_Block_Adminhtml_Prefs_Grid
extends Mage_Adminhtml_Block_Widget_Grid
{
public function _construct()
{
    parent::_construct();
    $this->setId('prefs_adminprefs_index');
    $this->setDefaultSort('email');
    $this->setDefaultDir('ASC');
    $this->setSaveParametersInSession(TRUE);
    $this->setUseAjax(TRUE);
}

protected function _prepareCollection()
{
    $collection = Mage::getModel('prefs/prefs')->getCollection();
    $this->setCollection($collection);
    return parent::_prepareCollection();
}

protected function _prepareColumns()
{
    $this->addColumn('prefcentre_id', array(
        'header'    =>  $this->__('ID'),
        'align'     => 'left',
        'width'     => '50px',
        'index'     => 'prefcentre_id',
    ));

    ......MORE COLUMNS......

    $this->addColumn('subscribed', array(
        'header'    =>  $this->__('Subscribed'),
        'align'     => 'left',
        'width'     => '80px',
        'index'     => 'Subscribed',
        'type'      => 'options',
        'options'   => array(
            0 => 'Subscribed',
            1 => 'Not Subscribed',
        ),
    ));

    return parent::_prepareColumns();
}

public function getRowUrl($row)
{
    return $this->getUrl('*/*/edit', array('id' => $row->getId()));
}

public function getGridUrl()
{
    return $this->getUrl('*/*/grid', array('_current'=>true));
}
}

.

class Ps_Prefs_Block_Adminhtml_Prefs_Edit_Tabs
extends Mage_Adminhtml_Block_Widget_Tabs
{
public function __construct()
{
    parent::__construct();
    $this->setId('prefs_tabs');
    $this->setDestElementId('prefs_edit_form');
    $this->setTitle($this->__('News Information'));
}

public function _prepareLayout()
{
    parent::_prepareLayout();

    $this->addTab('Signed up', array(
        'label'     => $this->__('User Information'),
        'title'     => $this->__('A User'),
        'content'   => $this->getLayout()->createBlock('prefs/adminhtml_prefs_edit_tab_form')->toHtml()
    ));

    $this->addTab('Newsletter options', array(
        'label'     => $this->__('Newsletter options'), 
        'title'     => $this->__('Checkboxes'), 
        'content'   => $this->__('some text to show its working')
    ));
}
}

The way I understood the tutorials was that this last file would get called and because of my layout file the grid would be rendered within those tabs. Why is this not working?

Best Answer

Magento core has all the example you need. Look at how the salesrules adminhtml is built. It is a good example of how tabs can be built using layout.xml

You just need to systematically duplicate the structure into your own module, and you will have tabs, handled by layout.xml. It is then easy to add tabs as needed.

Here is a rundown:

Have a look at promo.xml in app/design/adminhtml/default/default/layout/promo.xml, specifically at the handle <adminhtml_promo_quote_edit>

Here you will find the layout that defines the tabs used in the promo rule section:

<reference name="left">
    <block type="adminhtml/promo_quote_edit_tabs" name="promo_quote_edit_tabs">
        <block type="adminhtml/promo_quote_edit_tab_main" name="promo_quote_edit_tab_main" />
        <block type="adminhtml/promo_quote_edit_tab_conditions" name="promo_quote_edit_tab_conditions"/>
        <block type="adminhtml/promo_quote_edit_tab_actions" name="promo_quote_edit_tab_actions"/>
        <block type="adminhtml/promo_quote_edit_tab_labels" name="promo_quote_edit_tab_labels"/>
        <block type="adminhtml/promo_quote_edit_tab_coupons" name="promo_quote_edit_tab_coupons">
            <block type="adminhtml/promo_quote_edit_tab_coupons_form" name="promo_quote_edit_tab_coupons_form"/>
            <block type="adminhtml/promo_quote_edit_tab_coupons_grid" name="promo_quote_edit_tab_coupons_grid"/>
        </block>
        <action method="addTab"><name>main_section</name><block>promo_quote_edit_tab_main</block></action>
        <action method="addTab"><name>conditions_section</name><block>promo_quote_edit_tab_conditions</block></action>
        <action method="addTab"><name>actions_section</name><block>promo_quote_edit_tab_actions</block></action>
        <action method="addTab"><name>labels_section</name><block>promo_quote_edit_tab_labels</block></action>
        <action method="addTab"><name>coupons_section</name><block>promo_quote_edit_tab_coupons</block></action>
    </block>
    <block type="adminhtml/template" template="promo/salesrulejs.phtml" name="promo_quote_edit_jsinit"/>
</reference>

So, from the above you will find that you first define the main tabs container block:

<block type="adminhtml/promo_quote_edit_tabs" name="promo_quote_edit_tabs">

The block class definition is as such:

class Mage_Adminhtml_Block_Promo_Quote_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs

which gives you the 'addTabs' functionality, as used in the layouts.

This is thus your starting point.

Next you define a block that will become a tab within this container.

In the example, the first block is <block type="adminhtml/promo_quote_edit_tab_main" name="promo_quote_edit_tab_main" />

and the class is defined as:

class Mage_Adminhtml_Block_Promo_Quote_Edit_Tab_Main
    extends Mage_Adminhtml_Block_Widget_Form
    implements Mage_Adminhtml_Block_Widget_Tab_Interface

You then attach this block to the container using the addTab action

<action method="addTab"><name>main_section</name><block>promo_quote_edit_tab_main</block></action>

and repeat the process for each tab you add.

The coupons tab gives you a good example of how to place a grid within a tab.

I hope this pointer gets you in the right direction.

Ask for any further clarification.