2

I added a date type column in a custom grid.

$this->addColumn('some_date', array(
    'header'=> Mage::helper('helper_alias')->__('Some Date'),
    'index' => 'some_date',
    'type'=> 'date',
));

Now, when I try to filter my grid by that value and click on the calendar icon I get a js error.

TypeError: $(...) is null

The line that is causing this is

var index = $("widget-chooser").getStyle("zIndex");

because $("widget-chooser") is null.

If I change the column type to datetime the error does not appear. (but I don't want datetime I want date).

The problem reproduces in the core grids (Shopping cart promo rules for example).

Is there anyway to avoid this?

4
  • In you case "widget-chooser" is class or id of an DOM element? Commented Apr 15, 2014 at 18:37
  • @Tim. In my case I have no idea what"widget-chooser" is. I have no code related to anything names "widget" or "chooser". I'm starting to think this is a bug. I'm digging deeper.
    – Marius
    Commented Apr 15, 2014 at 19:57
  • Checked. It's a valid ID. Do you have js/mage/adminhtml/wysiwyg/widget.js loaded? Commented Apr 15, 2014 at 20:01
  • I didn't tell Magento to load widget.js. And I don't need it.
    – Marius
    Commented Apr 15, 2014 at 20:10

2 Answers 2

2

I can replicate this on a vanilla 1.7 install. I wonder how this got unnoticed.

Anyway, the problem is in Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Date::getHtml(). At the end of the JS string, additional callbacks are bound to the click event. Removing those (via anything-except-directly-from-core; you know the drill) fixes your problem. I'm talking about these lines >>here<<.

Two reasons why I think that's erroneous legacy code:

  • the "widget-chooser" ID is dinamically created with WysiwygWidget.chooser.openDialogWindow in js/mage/adminhtml/wysiwyg/widget.js (code here), and this openDialogWindow is used in other places than the date picker (I don't know exactly which are those, but it's related to Mage_Widget_Block_Adminhtml_Widget_Chooser)
  • Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Datetime doesn't have those extra callbacks, and this class is the direct child of Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Date.

Of course, I may be wrong.

2
  • I was looking in the same place. I seams thay you don't even need to remove those lines, If I replace var index = $("widget-chooser").getStyle("zIndex"); with var index = ($("widget-chooser")) ? $("widget-chooser").getStyle("zIndex") : 0; seams to solve it but I don't want to edit the core (duh!). I think someone assumes that there is always going to be an element with id widget-chooser in the DOM. Definatelly a bug by my book.
    – Marius
    Commented Apr 15, 2014 at 20:17
  • Still, I wonder why they bound other click events, when Calendar.setup already does that. They seem to tackle multiple calendar overlapping? Moving the dialog into the browser viewport? And, yes, I think they assume widget-chooser's existence. Maybe they used WysiwygWidget.chooser.openDialogWindow for the calendar in 0.0.1.
    – nevvermind
    Commented Apr 15, 2014 at 20:21
2

After a deep investigation, the results are in.
This is definitely a bug.
The code in question

var index = $("widget-chooser").getStyle("zIndex");

Was added in 1.4, to fix a bug. Apparently, when you had a date element in a widget configuration screen, the calendar was appearing below the element with the widget configuration and you couldn't select a date.

The code is there in order to set a z-index to the calendar element bigger than the z-index of the widget element.

I tried to avoid class rewrites, so here is my stupid fix to the issue:
I created a custom layout handle in one of the admin layout files.

<fix_calendar_js_issue>
    <reference name="content">
        <block type="core/text" name="dummy-widget-chooser" as="dummy-widget-chooser">
            <action method="setText">
                <text><![CDATA[<script type="text/javascript">
                    Event.observe(window, 'load', function() {
                        if (!$('widget-chooser')) {
                            $$('body')[0].insert('<div id="widget-chooser"></div>');
                        }
                });
                </script>]]></text>
            </action>
        </block>
    </reference>
</fix_calendar_js_issue>

This just ads a div with id widget-chooser if one does not exist in the DOM.

Now all I have to do is to include this handle in the pages that show this error. For example the shopping cart price rules.

<adminhtml_promo_quote_index>
    <update handle="fix_calendar_js_issue" />
</adminhtml_promo_quote_index>

All of these can be done from a single custom layout file.

2
  • I like your stupid fix. Non-intrusive all the way.
    – nevvermind
    Commented Apr 16, 2014 at 7:42
  • it is non-intrusive but I'm not 100% sure that there are no side effects to it.
    – Marius
    Commented Apr 16, 2014 at 7:58

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.