2011-04-21 60 views
12

我正在为我的项目使用django Grappelli皮肤。Django Grappelli Tabular Inline添加新行TinyMCE textfield not editable

我有一个带有表格内联函数的ModelAdmin。

我使用extra = 0来防止页面加载时自动插入空行。它工作正常。

现在,当我单击+符号插入新行时,行被加载,但tinymce文本字段不可编辑。

任何人都知道是什么原因以及如何解决这个问题?

阅读文档后:

http://django-grappelli.readthedocs.org/en/latest/customization.html#using-tinymce

我注意到:

使用TinyMCE的与内联是因为隐藏的空形式的比较麻烦一些。您需要编写自定义模板,并使用内联回调函数

onInit:从空格中删除TinyMCE实例。

onAfterAdded:从窗体初始化TinyMCE实例。

onBeforeRemoved:从窗体中删除TinyMCE实例。

TinyMCE with Inlines默认不支持。

这样的任何样本?我注意到这是一个我需要改变的TinyMCE函数。

+0

有没有人知道如何解决这个问题? – kelvinfix 2011-05-03 12:41:16

+0

我遇到了同样的问题。任何更新? – 2011-09-07 20:38:54

回答

4

我没有时间去考虑这个更彻底,所以我敢肯定有一个更好的解决方案,但是这似乎为我(与Django的格拉佩利2.3.5Django的测试工作-tinymce 1.5.1a2

我假设你正在使用堆叠内联。

您必须覆盖从格拉佩利模板,templates/admin/edit_inline/stacked.html。 在for循环迭代过inline_admin_formset|formsetsort:sortable_field_name吧船尾呃嵌套的for循环迭代过inline_admin_form,添加这段代码:

{% if forloop.last %} 
    <script type="text/javascript"> 
    if (tinyMCE != undefined) { 
     django.jQuery('textarea', '.empty-form').each(function() { 
     tinyMCE.execCommand('mceRemoveControl', false, django.jQuery(this).attr('id')); 
     }); 
    } 
    </script> 
{% endif %} 

应该禁用在隐藏的“空形式”的textarea元素,通过内联初始化的JavaScript渲染为TinyMCE的插件TinyMCE的控制(S )。

在原始grappelli模板133行周围的某处,您会看到grp_inline()的调用。添加/修改参数:

$("#{{ inline_admin_formset.formset.prefix }}-group").grp_inline({ 
    prefix: "{{ inline_admin_formset.formset.prefix }}", 
    onBeforeRemoved: function(f) { 
    if (tinyMCE != undefined) { 
     // make sure tinyMCE instances in empty-form are inactive 
     django.jQuery('textarea', '.empty-form').each(function() { 
     tinyMCE.execCommand('mceRemoveControl', false, django.jQuery(this).attr('id')); 
     }); 
    } 
    }, 
    [...] 
    onAfterAdded: function(form) { 
    if (tinyMCE != undefined) { 
     // re-initialise tinyMCE instances 
     $('textarea', form).each(function(k,v) { 
     var tid = $(this).attr('id'); 
     tinyMCE.execCommand('mceRemoveControl', false, tid); 
     tinyMCE.execCommand('mceAddControl', false, tid); 
     }); 
     // make sure tinyMCE instances in empty-form are inactive 
     django.jQuery('textarea', '.empty-form').each(function() { 
     tinyMCE.execCommand('mceRemoveControl', false, django.jQuery(this).attr('id')); 
     }); 
    } 
    [...] 
    } 
    [...] 

如果使用sortables,你想也想在内嵌的文本域禁用TinyMCE的控制被拖动。外观为sortable()初始化,并修改了“开始”回调:

start: function(evt, ui) { 
    ui.placeholder.height(ui.item.height() + 12); 
    if (tinyMCE != undefined) { 
    // make sure tinyMCE instances in empty-form are inactive 
    $('textarea', ui.item).each(function(k,v) { 
     var tid = $(this).attr('id'); 
     tinyMCE.execCommand('mceRemoveControl', false, tid); 
    }); 
    } 
}, 
[...] 

这应该给了粗略的想法如何解决这个问题,讨厌...

+0

这似乎不适用于以下版本:Django == 1.4,django-tinymce == 1.5.1b2,django-grappelli == 2.4.0 – 2012-09-07 15:47:23

13

它看起来像一些CSS类和自从Almflm的解决方案撰写以来,Grappelli使用的HTML结构发生了变化。但是,我能够修改hir解决方案以使用Grappelli v2.4.7,并简化了过程中的实现。

设置

  1. 覆盖复制/PATH/TO/grappelli/templates/admin/edit_inline/stacked.html/PATH/TO/YOURMOD/templates/admin/edit_inline/
  2. 在相关模板网站的settings.py,确保YOURMOD是INSTALLED_APPS以上格拉佩利。否则,Django将继续使用Grappelli版本的模板。

代码

现在你只需要进行两次更改您的stacked.html副本。查找的javascript的开头块:

$("#{{ inline_admin_formset.formset.prefix }}-group").grp_inline({ 

...并作出块内的以下变化:

  1. 添加onBeforeAdded功能像这样(或者如果存在修改现有的功能,但我没有一个):

    onBeforeAdded:function(form) { 
         // New inlines start as a hidden template with class grp-empty-form. 
         // This contains a textarea, which TinyMCE converts correctly, but 
         // something about the transformation from template to visible 
         // form breaks TinyMCE, so we need to remove it from the template and 
         // then re-add it after the transformation. 
         // c.f. http://stackoverflow.com/questions/5738173/ 
         if (tinyMCE != undefined) { 
          django.jQuery('.grp-empty-form').find('textarea').each(function() { 
           var tid = django.jQuery(this).attr("id"); 
           tinyMCE.execCommand("mceRemoveControl",false,tid); 
          }); 
         } 
        }, 
    
  2. 添加以下到onAfterAdded功能(你应该已经有一个,所以一定要修改现有的而不是定义一个新的):

     if (tinyMCE != undefined) { 
          // re-initialise tinyMCE instances 
          deselector = tinyMCE.settings.editor_deselector; 
          django.jQuery(form).find('textarea:not(.'+deselector+')').each(function(k,v) { 
          var tid = django.jQuery(this).attr('id'); 
          tinyMCE.execCommand('mceAddControl', false, tid); 
          }); 
         } 
         // This line is optional. It just ensures that the new inline appears 
         // un-collapsed, even if inlines are collapsed by default 
         django.jQuery(form).removeClass("grp-closed").addClass("grp-open"); 
    

这就是它!

编辑 添加了deselector到onAfterLoad - 确保你仍然可以定义TinyMCE的配置文件中的deselector类和内联将符合这一点。

+0

为Django 1.5.2和Grappelli工作2.4.5 – 2014-02-11 17:58:55

+0

谢谢。这也适用于Django 1.6.7和Grappelli 2.5.4 – edgar 2014-10-04 05:28:17

+1

对于tinymce 4.x,分别使用mceAddEditor和mceRemoveEditor作为mceAddControl和mceRemoveControl的命令名分别为 – 2014-10-09 03:57:24