Grid Loader doesn't hide after request finished

I had today the problem, that the loader doesn't hide after a a ajax response is loaded:

My problem is the following error:

"TypeError: Cannot read property 'down' of null
    at Object.bindFieldsChange (http://demo.dev/js/mage/adminhtml/grid.js:280:63)
    at Object.initGrid (http://demo.dev/js/mage/adminhtml/grid.js:80:14)
    at Object.initGridAjax (http://demo.dev/js/mage/adminhtml/grid.js:93:14)
    at http://demo.dev/js/prototype/prototype.js:391:23
    at klass.respondToReadyState (http://demo.dev/js/mage/adminhtml/loader.js:95:68)
    at klass.onStateChange (http://demo.dev/js/prototype/prototype.js:1545:12)
    at XMLHttpRequest.<anonymous> (http://demo.dev/js/prototype/prototype.js:391:23)"

We can't see the error, because magento is catching it and doesn't show it to us.

For debugging purposes we can change the js/mage/adminhtml/grid.js to add this:

    // line 174
    onException: function (response, exception) {
        console.log(response);
        console.log(exception);
    },

so it looks afterwards like this:

reload : function(url){
    if (!this.reloadParams) {
        this.reloadParams = {form_key: FORM_KEY};
    }
    else {
        this.reloadParams.form_key = FORM_KEY;
    }
    url = url || this.url;
    if(this.useAjax){
        new Ajax.Request(url + (url.match(new RegExp('\\?')) ? '&ajax=true' : '?ajax=true' ), {
            loaderArea: this.containerId,
            parameters: this.reloadParams || {},
            evalScripts: true,
            onException: function (a,b,c,d,e) {
                console.log(e);
            },

Solution

In my case the problem is a missing ID on the grid

class My_Module_Block_Adminhtml_Tab_Grid  
    extends Mage_Adminhtml_Block_Widget_Grid
    implements Mage_Adminhtml_Block_Widget_Tab_Interface
{
    public function __construct()
    {
        parent::__construct();
        $this->setId('transactionMailFilesGrid'); // <-- this was missing

Tab is rendered in left block instead of content

I want to add tabs to a custom form in the backend.

There are a couple of great tutorials how to add tabs, like from Inchoo or Erfan Imani.

But I wanted this:

And got this:

The problem is simple - if you know it (costs me an hour and a few hairs):

The tabs are rendered with JS. So they live originally in left, but they are shown in content, to be more specific in the node, defined by:

class My_Module_Block_Adminhtml_Project_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs {

    public function __construct()
    { 
        // ...
        $this->setDestElementId('project_form');
    }
}

And this id needs to be the same as in

class My_Module_Block_Adminhtml_Project_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
{
    protected function _prepareForm()
    {
        $form = new Varien_Data_Form(
            [
                'id'     => 'project_form',
            ]);
    }
}

Hope this helps anyone.

Parameters of Varien_Data_Form?

Why do I write this? Because I had the problem a few hours ago that no form was rendered in my backend formular. And as a few of you may know, the FireGento GermanSetup Team met today. Noone of us knew instantly why. So here are a few tipps.

HTML Attributes

You can set the html attributes id, name, method, action, enctype, class and onsubmit. Especially method and enctype is needed for file uploads. With onsubmit you can implement more checks in javascript. And with action the target of the form is defined, as you should know.

Container yes or no?

As you can see in the code there is another parameter: use_container. With use_container you decied wether to wrap a <form> around your form elements and add a form_key.