Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I type in TinyMCE in my jQueryUI modal dialog?

I have a basic modal dialog, containing an instance of TinyMCE. This modal is dynamically created each time it is opened, and the dialog (and element) are destroyed and removed on dialog close.

The first time I open the dialog, all is well. The form loads (ajax call), uniform is applied to the form, and TinyMCE is applied to the textarea. I can perform all actions fine. All of the subsequent times I open the form the process repeats itself, with the difference being that, though TinyMCE is applied to the textarea I can no longer type in it.

This is in a method that fires on link click:

$('<div id="perspDlg">').dialog({
    title:'My Dialog',
    width:900,
    height:575,
    modal:true,
    create: function(){
        $('span.ui-icon-closethick').html("");
    },
    close:function(){
        $('form#myForm').unbind('submit');
        $('textarea[name="discussion"]').tinymce().destroy();
        $(this).html('').dialog('destroy');
        setTimeout("$('#perspDlg').remove();",100);
    },
    open:function(){
        var dlg = $(this);
        $.ajax({
            url:_cfcPath+'/lessons/myTemplate.cfm',
            dataType:'script',
            data:{id:id},
            success:function(d,r,o){
                dlg.html(d);
                $('form#myForm').bind('submit',formHandler);
            }
        });
    },
    buttons:[
        {text:'Save Form',
        click:function(){
            $('form#myForm').submit();
            //$(this).dialog('close');
        }},
        {text:'Cancel',
        click:function(){
            $(this).dialog('close');
        }}
    ]
});

When the template loads, the final lines apply TinyMCE to the textarea in the loaded form:

$('textarea.tinyMCE').tinymce({
    script_url : '/assets/scripts/_lib/tiny_mce/tiny_mce.js',
    mode : "textareas",
    editor_deselector : "mceNoEditor",
    theme : "advanced",
    plugins : pluginVal,
    //Paste options
    extended_valid_elements : "a[name|href|target|rel|title|style|class],div[align|class|style|height|width],form[accept|accept-charset|action|class|dir<ltr?rtl|enctype|id|lang|method<get?post|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onreset|onsubmit|style|title|target],hr[class],span[align|class|style],img[class|src|style|alt|title|name],input[accept|accesskey|align<bottom?left?middle?right?top|alt|checked<checked|class|dir<ltr?rtl|disabled<disabled|id|ismap<ismap|lang|maxlength|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onselect|readonly<readonly|size|src|style|tabindex|title|type<button?checkbox?file?hidden?image?password?radio?reset?submit?text|usemap|value],table[border|class|style|cellpadding|cellspacing|background|height|width],td[background|style|class|valign|align|height|width],p",
    invalid_elements: "font,align,script,applet,iframe",
    paste_auto_cleanup_on_paste : true,
    paste_remove_styles: true,
    paste_remove_styles_if_webkit: true,
    paste_strip_class_attributes: true,
    paste_retain_style_properties: "none",
    paste_block_drop: true,
    remove_linebreaks : false,
    paste_create_paragraphs : false,
    paste_create_linebreaks : false,
    relative_urls : false,
    remove_script_host : false,
    document_base_url : baseURL,
    theme_advanced_buttons1 : btn1Val,
    theme_advanced_buttons2 : btn2Val,
    theme_advanced_buttons3 : btn3Val,
    theme_advanced_buttons4 : btn4Val,
    theme_advanced_toolbar_location : "top",
    theme_advanced_toolbar_align : "left",
    theme_advanced_resizing : true
});

This uses the JQuery plugin for TinyMCE to load the editor in to all textareas with a class of tinyMCE, which works as intended.

I have read several different Questions on StackOverflow on similar issues, but none that have provided an answer to this issue. Anybody have any ideas?

Some follow up: I did some output comparison between the initial dialog open, and subsequent openings, and noticed something. In the initial load, and TinyMCE being applied to the text area, I see that the application has created an iframe, loaded a table with a row for the menu and a row with an additional iframe. That iframe's content (on first load) looks like this:

<tr class="mceLast">
    <td class="mceIframeContainer mceFirst mceLast">
        <iframe id="mce_0_ifr" frameborder="0" src="javascript:""" allowtransparency="true" title="Rich Text AreaPress ALT-F10 for toolbar. Press ALT-0 for help" style="width: 100%; height: 204px; display: block;">
            <html>
                <head xmlns="http://www.w3.org/1999/xhtml">
                    <base href="http://dev.nsite.loc">
                    <meta content="IE=7" http-equiv="X-UA-Compatible">
                    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
                    <link href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/themes/advanced/skins/default/content.css" rel="stylesheet" type="text/css">
                    <link rel="stylesheet" data-mce-href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/spellchecker/css/content.css?110120111025" href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/spellchecker/css/content.css?110120111025">
                    <link rel="stylesheet" data-mce-href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/class_U/css/content.css?110120111025" href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/class_U/css/content.css?110120111025">
                    <link rel="stylesheet" data-mce-href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/noneprovided/css/content.css?110120111025" href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/noneprovided/css/content.css?110120111025">
                    <link rel="stylesheet" data-mce-href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/themes/advanced/skins/default/content.css?110120111025" href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/themes/advanced/skins/default/content.css?110120111025">
                </head>
                <body id="tinymce" class="mceContentBody " contenteditable="true" dir="ltr">
                    <br data-mce-bogus="1">
                </body>
            </html>
        </iframe>
    </td>
</tr>

But, on subsequent loads I get the menu, but that internal iframe looks like this:

<tr class="mceLast">
    <td class="mceIframeContainer mceFirst mceLast">
        <iframe id="mce_12_ifr" frameborder="0" src="javascript:""" allowtransparency="true" title="Rich Text AreaPress ALT-F10 for toolbar. Press ALT-0 for help" style="width: 100%; height: 204px; display: block;">
            <html>
                <head>
                </head>
                <body>
                </body>
            </html>
        </iframe>
    </td>
</tr>

What might cause that?

Update 2: Per Patricia's suggestions, I changed my dialog's close event to the following:

close:function(){
    $('form#perspectiveForm').unbind('submit');
    var id = $('textarea:tinymce').attr('id');
    tinyMCE.execCommand('mceRemoveControl', false, id);
    $('textarea#'+id).remove();
    $(this).empty().dialog('destroy');
    setTimeout("$('#perspDlg').remove();",100);
},

With some step debugging, and FireBug, I have confirmed that the editor is destroyed, and then the textarea completely removed, prior to destroying the dialog and removing the div. That said, reinitializing the dialog I am still unable to type in the new TinyMCE instance, with the underlying code showing like my last update. It doesn't appear to be related to improper destruction of the previous element.

Update: Patricia's last suggestion was to move the ajax call, that loads the form into the dialog, into a .load() method, and then create the dialog. I tried this, and things went south quickly. The remote content contains script that must execute, hence the script dataType on the .ajax() method. The .load() method doesn't have this option, and it really didn't like it. So now I'm not sure what to try next.

like image 602
Steve -Cutter- Blades Avatar asked Nov 17 '11 13:11

Steve -Cutter- Blades


1 Answers

i've run into a similar problem when i use a button to refresh a section.

you have to completely destroy the tinyMCE controls before you re-instantiate them.

i use this logic in my refresh button handler:

$('#sectionToRefresh').find('textarea:tinymce').each(function(){
     var id = $(this).attr('id');
     tinyMCE.execCommand('mceRemoveControl', false, id);
     $(this).remove();

});

for dialogs, i have the "close" handler set up like this:

close: function (ev, ui) {
            if (typeof tinyMCE != 'undefined') {
                $(this).find(':tinymce').remove();
            }
            $(this).dialog("destroy");
            $(this).remove();



        }

Either one of these should fix the problem for you!

EDIT:

I have no idea if this is the propblem or not, but :

 $(this).html('').dialog('destroy');

doing .html('') doesn't clean things up nicely. you should use .empty() instead. perhaps there is some stray handlers or something not being completely cleaned up.

you may also want to try adding the $(this).remove(); to your close handler.

like image 189
Patricia Avatar answered Oct 20 '22 01:10

Patricia