wagtail: TableBlock with custom TabbedInterface

When new TableBlock is used with default TabbedInterface - all works fine:

from wagtail.contrib.table_block.blocks import TableBlock
from wagtail.wagtailadmin.edit_handlers import StreamFieldPanel
from wagtail.wagtailcore.fields import StreamField
from wagtail.wagtailcore.models import Page


class TestPage(Page):

    content = StreamField([
        ('table', TableBlock()),
    ])

    search_fields = Page.search_fields
    content_panels = Page.content_panels + [
        StreamFieldPanel('content')
    ]

I see editor as expected:

2016-06-07 11-03-33 wagtail - test page test page - google chrome

But when I try to create custom TabbedInterface:

from wagtail.contrib.table_block.blocks import TableBlock
from wagtail.wagtailadmin.edit_handlers import StreamFieldPanel, TabbedInterface, ObjectList
from wagtail.wagtailcore.fields import StreamField
from wagtail.wagtailcore.models import Page


class TestPage(Page):

    content = StreamField([
        ('table', TableBlock()),
    ])

    search_fields = Page.search_fields
    editor_content_panels = [
        StreamFieldPanel('content')
    ]

    edit_handler = TabbedInterface([
        ObjectList(Page.content_panels, heading="Default Editor"),
        ObjectList(Page.promote_panels, heading="Promote"),
        ObjectList(Page.settings_panels, heading="Settings", classname='settings'),
        ObjectList(editor_content_panels, heading="Editor"),
    ])

After creating new page with TableBlock and re-opening it for edition - table editor don’t appears:

2016-06-07 11-06-11 wagtail - test page test page - google chrome

But… After opening “Developer Tools” (F12) magic happens:

2016-06-07 11-08-52 wagtail - test page test page - google chrome

I’ve checked this bug with latest Chrome and Firefox. Looks like some JavaScript window refresh is needed on Tab click event.

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 1
  • Comments: 15 (4 by maintainers)

Most upvoted comments

Oh, 2 hours spent and I finally found the solution:

@hooks.register('insert_global_admin_js')
def fix_editors_in_tabs():
    script = """
            <script>
                $(document).ready(function() {
                    $('.tab-nav a').on('shown.bs.tab', function (e) {
                        // Fix for TableBlock editor
                        $(window).trigger('resize');

                        // Fix for SimpleMDE editor
                        if (window.SimpleMDEInstances != null) {
                            $.each(window.SimpleMDEInstances, function(index, inst) {
                                inst.codemirror.refresh();
                            });
                        }
                    });
                });
            </script>
        """
    return script

It works for TableBlock and my MarkdownBlock.

@BertrandBordage 's fix helped, but didn’t work for me when the second tab is the active one when the page loads (on Chrome - Firefox was fine). I got this to work, but it’s very ugly:

@hooks.register('insert_global_admin_js')
def fix_tables_in_tabs():
    return """
        <script>
            (function() {
                function fix_tables(){
                     $('.handsontable').each(function () {
                        var inputId = $(this).siblings('input').attr('id');
                        if (typeof inputId !== 'undefined') {
                            initTable(inputId, %s);
                        }
                    });
                };
                $(document).ready(function() {
                    setTimeout(fix_tables, 1000);
                    $('.tab-nav a').on('shown.bs.tab', fix_tables);
                });
            })();
        </script>
    """ % json.dumps(TableBlock().table_options)

There has to be a better way.

as a very fast and dirty workaround I’ve used

$(document).on('click', '.tab-nav a', function(e) {
    $('.wtHolder', $(this).attr('href')).scrollTop(1);
    $(window).resize(); // trigger resize to force handsontable relayout 
});

@Proper-Job We’re using Bootstrap’s tabs module, so the events should be as described here: http://getbootstrap.com/javascript/#tabs-events