javascriptpythondjangotinymcedjango-tinymce

Django-TinyMCE with Multiple Forms


I'm trying to create a single HTML page with multiple instances of TinyMCE editors. The number of editors varies by the request; so I can't enumerate them and initialize them individually. Here is my code:

views.py:

from tinymce.widgets import TinyMCE
class ThreadForm(forms.Form):
    subject = forms.CharField(max_length=300, widget=forms.TextInput(attrs={'size':'100'}))
    body = forms.CharField(widget=TinyMCE())
class MessageForm(forms.Form):
    thread_pk = forms.IntegerField()
    body = forms.CharField(widget=TinyMCE())

urls.py:

urlpatterns = patterns('',
    ...
    url(r'^tinymce/', include('tinymce.urls')),
)

settings.py:

INSTALLED_APPS = (
    ...
    'tinymce',
)
...
TINYMCE_DEFAULT_CONFIG = {
    'selector': 'textarea',
    'theme': 'advanced',
    'width': 600,
    'height': 300,
    'theme_advanced_toolbar_location': 'top',
    'theme_advanced_buttons1': 'bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,outdent,indent,hr,|,undo,redo',
    'theme_advanced_buttons2': 'cut,copy,paste,pastetext,pasteword,|,search,replace,|,link,unlink,charmap,|,visualaid,table,|,blockquote,sub,sup,|,preview,code,emotions,image',
    'theme_advanced_buttons3': '',
    'plugins': 'paste,table,spellchecker,searchreplace,emotions',
    'theme_advanced_resizing': True,
}

member_forums.html:

...
{% block headers %}
{{ thread_form.media }}
{% endblock %}
...
<table id="new_thread_table">
    {{ thread_form.as_table }}
</table>
...
{% for message_form in message_forms %}
    <table class="new_message_table">
        {{ message_form.as_table }}
    </table>
    ...
{% endfor %}

There is one ThreadForm in the template and multiple MessageForms.

When I comment out the MessageForms in the HTML, the ThreadForm seems to work, but when I uncomment them, the ThreadForm loads with a TinyMCE skin that doesn't update (adding text doesn't make the undo button appear enabled even though it is), and when I submit the form, the body entry for the form is missing, resulting in form.is_valid failing.

I only have {{ thread_form.media }} in my template header and nothing for the MessageForms. Iterating through:

{% for message_form in message_forms %}
    {{ message_form.media }}
{% endfor %}

didn't do any good, either.

After doing some research, it appears TinyMCE is being initialized too many times when the MessageForms are loaded, causing the data to be lost during form submitting (EDIT in top answer to: TinyMCE with Django: "This field is required")

I'm lost on how to get this to work. Any help or pointers would be appreciated.


Solution

  • TinyMCE uses id to assign which textarea should be TinyMCE, and ids are supposed to be unique in HTML. Since my bodies were both called body, Django's form.as_table was rendering them with the same id. When TinyMCE tried to assign the editor to the id, it failed when it reached the second field with the same id. Similar issue:

    TinyMCE not working when loading two textareas

    I changed the MessageForm.body to MessageForm.body1 and that made the ThreadForm TinyMCE work like a charm. Now I need to iterate through and change the id of each MessageForm. But there should be a better solution. TinyMCE should be able to render all textareas. Maybe removing ids altogether?