2011-11-17 12 views
9

Tengo un diálogo modal básico, que contiene una instancia de TinyMCE. Este modal se crea dinámicamente cada vez que se abre, y el diálogo (y el elemento) se destruyen y eliminan en el cuadro de diálogo Cerrar.¿Por qué no puedo escribir TinyMCE en mi cuadro de diálogo modal jQueryUI?

La primera vez que abro el diálogo, todo está bien. Las cargas de formulario (llamada ajax), uniforme se aplica a la forma y TinyMCE se aplica al área de texto. Puedo realizar todas las acciones bien. Todas las veces posteriores que abro la forma en que el proceso se repite, con la diferencia de que, aunque TinyMCE se aplica al área de texto, ya no puedo escribir en él.

Esto es en un método que se activa en el enlace clic:

$('<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'); 
     }} 
    ] 
}); 

Cuando se carga la plantilla, las líneas finales se aplican TinyMCE para el área de texto en la forma cargado:

$('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 
}); 

Este utiliza el El plugin de JQuery para TinyMCE para cargar el editor en todas las áreas de texto con una clase de tinyMCE, que funciona según lo previsto.

He leído varias preguntas diferentes sobre StackOverflow en problemas similares, pero ninguna ha proporcionado una respuesta a este problema. ¿Alguien tiene ideas?

Algunos seguimiento: Hice una comparación de salida entre el diálogo inicial abierto, y las aperturas posteriores, y noté algo. En la carga inicial, y TinyMCE se aplica al área de texto, veo que la aplicación ha creado un iframe, ha cargado una tabla con una fila para el menú y una fila con un iframe adicional. el contenido de dicho marco flotante (en la primera carga) se ve así:

<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> 

Pero, en las cargas posteriores consigo el menú, pero eso iframe interna se ve así:

<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> 

Lo que podría hacer que?

Actualización 2: Por sugerencias de Patricia, he cambiado evento de cierre de mi diálogo con el siguiente:

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); 
}, 

Con un poco de depuración paso a paso, y FireBug, he confirmado que el editor se destruye, y luego el textarea completamente eliminado, antes de destruir el diálogo y eliminar el div. Dicho esto, al reiniciar el diálogo todavía no puedo escribir en la nueva instancia de TinyMCE, con el código subyacente como mi última actualización. No parece estar relacionado con la destrucción inadecuada del elemento anterior.

Actualización: última sugerencia de Patricia era mover la llamada ajax, que carga el formulario en el cuadro de diálogo, en un método .load(), y luego crear el diálogo. Intenté esto, y las cosas se fueron al sur rápidamente. El contenido remoto contiene script que debe ejecutarse, de ahí el script dataType en el método .ajax(). El método .load() no tiene esta opción, y realmente no le gustó. Entonces ahora no estoy seguro de qué probar.

+0

¿Tiene ajaxSetup en juego aquí? –

+0

Yo no. Aquí está sucediendo mucho ajax, con muchos requisitos diferentes, por lo que no estoy aplicando ninguna configuración global, ya que cada implementación es diferente. –

+0

solo una cosa menor: datos: {id: id,}, deben ser datos: {id: id}, –

Respuesta

1

me he encontrado con un problema similar cuando uso un botón para actualizar una sección.

tiene que destruir por completo los controles tinyMCE antes de volver a crear instancias.

i utilizar esta lógica en mi actualización de controlador de botón:

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

}); 

para los diálogos, tengo el "cierre" manejador establecido así:

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



     } 

uno de estos debe fijar el ¡problema para usted!

EDIT:

tengo ni idea de si este es el propblem o no, pero:

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

haciendo .html ('') no hace las cosas limpias muy bien. deberías usar .empty() en su lugar. quizás hay algunos manejadores perdidos o algo que no está completamente limpio.

es posible que también desee intentar agregar $ (this) .remove(); a su controlador cercano.

+0

He intentado ambas soluciones, y ninguna de las dos soluciona mi problema. –

+0

hmm, vale, mira mi edición. – Patricia

+0

Gracias por el encabezado de .html (""). No estaba enterado de eso. Mi eliminación está allí, pero está en ese setTimeout(). Tuve un problema al tratar de 'eliminar' el el cuando el diálogo 'cerrar' todavía se estaba ejecutando, así que configúrelo para que ocurra un poco después (que funciona, según Firebug). Lamentablemente, el cambio de .html ("") a .empty() tampoco solucionó el problema. –

0

esto funcionó para mí.

$('.jq_tinymce').each(function(idx, el) 
    { 
     toggle_editor('textarea[name="'+ $(this).attr('name') +'"]', $(this).data('tinymce_theme')); 
    }); 

Todo lo que necesita hacer es ejecutar este código solo después de haber abierto el diálogo. Estoy usando jq_tinymce para que sepa qué áreas de texto iniciar. El uso de un atributo data-tinymce_theme en la etiqueta html le permitirá especificar un tema de tinymce.

toggle_editor es

function toggle_editor(selector, theme) 
{ 
if (theme == undefined) 
{ 
    theme = 'simple'; 
} 

if($(selector+':first').css('display') == 'none') 
{ 
    $(selector).each(function(){ 
     $(this).tinymce().hide(); 
    }) 
} 
else 
{ 
    $(selector).tinymce({ 
     script_url : Vega.base_url+'ext/tinymce_3.5_jquery/tiny_mce.js', 
     // General options 
     theme : theme, 
     width: '100%', 
     language: Vega.tinyMceLocale, 
     plugins : "autolink,lists,pagebreak,style,layer,table,save,advimage,advlink,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,advlist", 
     file_browser_callback : "tinymce_uploader", 

     // Theme options 
     theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect,styleprops", 
     theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor", 
     theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,|,print,|,fullscreen,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak", 
     theme_advanced_toolbar_location : "top", 
     theme_advanced_toolbar_align : "left", 
     theme_advanced_statusbar_location : "bottom", 
     theme_advanced_resizing : true 
    }); 
} 

}

0

que tenía que asegurarse de que mi tinymce init se ejecuta después de la configuración de diálogo. Eso solucionó el problema para mí.

$("#editDialog").dialog({ 
       ...   
      }); 
      tinymce.init({ 
       selector: '#txtCourseDesc' 
      }); 
      $('#editDialog').show(); 
Cuestiones relacionadas