5

I tried to create an admin grid on magento.Get the error while click on the admin menu setSaveParametersInSession() on a non-object.

My Config.xml : path(\app\code\local\ORD\UpdatePro\etc)

<admin>
 <routers>
     <updatepro>
        <use>admin</use>
        <args>
           <module>ORD_UpdatePro</module>
           <frontName>admintest</frontName>
        </args>
     </updatepro>
  </routers>
</admin>
<adminhtml>
   <layout>
      <updates>
          <updatepro>
              <file>updatepro.xml</file>
           </updatepro>
      </updates>
   </layout>
   <menu>
      <updatepro translate="title" module="adminhtml">
         <title>updatepro</title>
         <sort_order>100</sort_order>
         <children>
             <set_time>
                   <title>Report</title>
                   <sort_order>0</sort_order>
                   <action>admintest/adminhtml_index</action>
              </set_time>

          </children>
       </updatepro>
   </menu>
</adminhtml>

My IndexController.php : Path(\app\code\local\ORD\UpdatePro\controllers\Adminhtml)

class ORD_UpdatePro_Adminhtml_IndexController extends Mage_Adminhtml_Controller_Action
{
protected function _initAction()
{
    $this->loadLayout()->_setActiveMenu('updatepro/set_time')
            ->_addBreadcrumb('updatepro Manager','updatepro Manager');
   return $this;
 }
//END of initaction
public function indexAction()
  {
     $this->_initAction();
     $this->renderLayout();
  }
}

My Block Class Grid.php : Path(\app\code\local\ORD\UpdatePro\Block\Adminhtml)

class ORD_UpdatePro_Block_Adminhtml_Grid extends Mage_Adminhtml_Block_Widget_Grid_Container
{ 
  public function __construct(){
     $this->_controller = 'adminhtml_grid';
     $this->_blockGroup = 'updatepro';
     $this->_headerText = 'Adressbook management';
     $this->_addButtonLabel = 'Add a contact';
     parent::__construct();
 }
}

My Layout file updatepro.xml : Path(\app\design\adminhtml\default\default\layout)

<?xml version="1.0" ?>
   <layout version="0.1.0">
   <updatepro_adminhtml_index_index>
     <reference name="content">
      <block type="updatepro/adminhtml_grid"  name="updatepro" template="updatepro/afficher.phtml" />
    </reference>
   </updatepro_adminhtml_index_index>
</layout>

while click on the admin panel menu link i got the below error message

Fatal error: Call to a member function setSaveParametersInSession() on a non-object in C:\xampp\htdocs\staging_furryfriends\app\code\core\Mage\Adminhtml\Block\Widget\Grid\Container.php on line 69

it was a common error and found in many threads, Followed every steps carefully, unfortunately i am unable to figure out the problem and what was the error. Expecting your kind explanation if any one can help me on this topic.

2
  • add $this->_addButtonLabel using helper: blog.chapagain.com.np/… Nov 10, 2014 at 11:33
  • Thank you, $this->_controller = 'adminhtml_mynewgrid'; your changes are on this line.i used this $this->_controller = 'adminhtml_grid';according to me its right
    – Mujahidh
    Nov 10, 2014 at 11:37

2 Answers 2

9

Take a look at [How to create a custom grid from scratch][1] and custom module with custom database table

Grid.php : Incorrect and missing

class <Namespace>_<Module>_Block_Adminhtml_<Module> extends Mage_Adminhtml_Block_Widget_Grid_Container
{
    public function __construct()
    {
        $this->_controller = 'adminhtml_<module>';
        $this->_blockGroup = '<module>';
        $this->_headerText = Mage::helper('<module>')->__('Item Manager');
        $this->_addButtonLabel = Mage::helper('<module>')->__('Add Item');
        parent::__construct();
    }
}


class <Namespace>_<Module>_Block_Adminhtml_<Module>_Grid extends Mage_Adminhtml_Block_Widget_Grid
{
    public function __construct()
    {
        parent::__construct();
        $this->setId('<module>Grid');
        // This is the primary key of the database
        $this->setDefaultSort('<module>_id');
        $this->setDefaultDir('ASC');
        $this->setSaveParametersInSession(true);
        $this->setUseAjax(true);
    }
2
  • Thank you, Clear answer and now its working and got an idea. one more question to my understanding.. the second class which extends the Mage_Adminhtml_Block_Widget_Grid also in the same class?
    – Mujahidh
    Nov 10, 2014 at 11:43
  • can you pls help me in this question. magento.stackexchange.com/questions/51957/…
    – Mujahidh
    Jan 13, 2015 at 6:57
7

Have a look on the error to which Magento refers.

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

Here the function that holds setSaveParametersInSession() is _prepareLayout(). This function is processed during layout preparation time carried out by magento. If you have a closer look on the method, you will understand that, it is triying to set a child block to grid block that you have defined via layout file ($this stands for the grid block).

In case of admin grid block, actually we just defines the outer block of grid in our layout file. Magento then set a child block to this grid block and then use it for its internally in order to generate the entire grid section. So the collection that we set in grid block, will then use by this child block and will process accordingly. Why Magento generates child blocks programmatically ? This is because, almost all time, magento admin grid looks same . Only the collection that loading in that grid changes. So Magento allows us to _prepareCollection() in our custom grid block so that it the entire grid page uses our custom collection. You dont need to do any complex thing in order to generate the complex grid structure.

Now I want your concenration on this code

 createBlock( $this->_blockGroup.'/' . $this->_controller . '_grid', $this->_controller . '.grid')

this is what become an invalid object in your context. As you can see it tries to generate a block. As per the definition inside your grid block (ORD_UpdatePro_Block_Adminhtml_Grid. this is a wrong class actually. I come to this point later), this code can be rewrite like this.

 createBlock('updatepro/adminhtml_grid_grid', 'adminhtml_grid.grid')

The first argument stands for type of the block and second argurment stands for name of the newly generating block. The type of your block means, Magento will look for ORD_UpdatePro_Block_Adminhtml_Grid_Grid block class inside your module. Unfortunately Magento cannot found out that class because, that class really not exist. So magento complaints it.

Actually the block that should generate in this context is ORD_UpdatePro_Block_Adminhtml_Updatepro_Grid (As per the best practices) and I hope you have that file is actually defined inside your module at app/code/local/RD/UpdatePro/Block/Adminhtml/Updatepro/Grid.php.

Now let us look how can we generate this name inside your grid container block. Oh wait. Your grid block seems wrong. It should be ORD_UpdatePro_Block_Adminhtml_UpdatePro instead of ORD_UpdatePro_Block_Adminhtml_Grid. But block that you defined now is recognizing by Magento. That is why the error itself is raised!!! So let us look why it is recognized. In your layout file, you have this.

<reference name="content">
  <block type="updatepro/adminhtml_grid"  name="updatepro" template="updatepro/afficher.phtml" />
</reference>

The block that you including here is ORD_UpdatePro_Block_Adminhtml_Grid. So magento is able to recognize your block, because it is defined backend of your module. However as per the best practice, it is wrong. Your layout should looks like this.

 <reference name="content">
  <block type="updatepro/adminhtml_updatepro"  name="updatepro" template="updatepro/afficher.phtml" />
</reference>

Now your block points to the block ORD_UpdatePro_Block_Adminhtml_UpdatePro and it should defined at app/code/local/ORD/UpdatePro/Block/Adminhtml/UpdatePro.php.

Inside this you need to look on below property values which is actually using to generate child grid block as I explained before.

    $this->_controller = 'adminhtml_updatepro';
    $this->_blockGroup = 'updatepro';

Now as per the definition of this private properties, the function in question will look like this.

createBlock('updatepro/adminhtml_update_grid', 'adminhtml_updatepro.grid')

and this eventually looks for the block ORD_UpdatePro_Block_Adminhtml_Updatepro_Grid. If you have this block is defined at the backside of your module (app/code/local/RD/UpdatePro/Block/Adminhtml/Updatepro/Grid.php), then everything is super cool. No confusion for us and no confusion for magento. Story should have a happy endings then !!!

What is the big point?

Beware this private properties. $this->_blockGroup and $this->_controller.

$this->_blockGroup should be the block alias name that you have specified insid your module's config.xml file. In normal case it will looks like [namespace]_[modulename] $this->_controller should be the trailing block paths that is pointing towards your grid container block. In normal case it would be adminhtml_[modulename]

12

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.