2010-05-12 47 views
9

Quería utilizar un editor de texto enriquecido para un área de texto dentro de un panel de actualización.TinyMCE con AJAX (Panel de actualización) nunca tiene un valor

me encontré con este post: http://www.queness.com/post/212/10-jquery-and-non-jquery-javascript-rich-text-editors a través de esta pregunta: Need ASP.Net/MVC Rich Text Editor

decidió ir con TinyMCE como lo hacía antes en situaciones no AJAX, y dice que en esa lista es compatible con AJAX. Bien, hago lo bueno ol tinyMCE.init({ //settings here }); Pruébalo y desaparece después de hacer una actualización del panel de actualización. Me imagino a partir de una pregunta aquí que debería estar en la función page_load por lo que se ejecuta incluso en las devoluciones de datos asincrónicas. Bien, hazlo y el panel se queda. Sin embargo, al tratar de enviar el valor de mi área de texto, el texto siempre aparece como vacío porque mi validador de formularios siempre dice "Debes ingresar una descripción" incluso cuando ingreso texto en él. Esto ocurre la primera vez que se carga la página y después de que se hayan realizado las devoluciones de datos asincrónicas en la página.

Muy bien Me parece esto http://www.dallasjclark.com/using-tinymce-with-ajax/ y Can't post twice from the same AJAX TinyMCE textarea. Intento agregar este código en la función de carga de mi página justo después del tinyMCE.init. Al hacer esto, se rompe toda mi invocación de jquery también en la página_carga después de ella, y todavía tiene el mismo problema.

Todavía soy bastante principiante con el scripting del lado del cliente, así que tal vez deba poner el código en un lugar diferente que page_load? No estoy seguro de que las publicaciones que vinculé no sean una pista sobre dónde poner ese código.

Mi Javascript:

<script type="text/javascript"> 

var redirectUrl = '<%= redirectUrl %>'; 

function pageLoad() { 

    tinyMCE.init({ 
     mode: "exact", 
     elements: "ctl00_mainContent_tbDescription", 
     theme: "advanced", 
     plugins: "table,advhr,advimage,iespell,insertdatetime,preview,searchreplace,print,contextmenu,paste,fullscreen", 
     theme_advanced_buttons1_add_before: "preview,separator", 
     theme_advanced_buttons1: "bold,italic,underline,separator,justifyleft,justifycenter,justifyright, justifyfull,bullist,numlist,undo,redo,link,unlink,separator,styleselect,formatselect", 
     theme_advanced_buttons2: "cut,copy,paste,pastetext,pasteword,separator,removeformat,cleanup,charmap,search,replace,separator,iespell,code,fullscreen", 
     theme_advanced_buttons2_add_before: "", 
     theme_advanced_buttons3: "", 
     theme_advanced_toolbar_location: "top", 
     theme_advanced_toolbar_align: "left", 
     extended_valid_elements: "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]", 
     paste_auto_cleanup_on_paste: true, 
     paste_convert_headers_to_strong: true, 
     button_tile_map: true 
    }); 

    tinyMCE.triggerSave(false, true); 
    tiny_mce_editor = tinyMCE.get('ctl00_mainContent_tbDescription'); 
    var newData = tiny_mce_editor.getContent(); 
    tinyMCE.execCommand('mceRemoveControl', false, 'your_textarea_name'); 

    //QJqueryUI dialog stuff 
}</script> 

Ahora mi código actual no tiene la tinyMCE.execCommand("mceAddControl",true,'content'); cual también que se debe añadir una pregunta indicada. Intenté agregarlo pero, una vez más, no estaba seguro de dónde ponerlo y simplemente ponerlo en la carga de la página no pareció tener ningún efecto.

el control de cuadro de texto:

<asp:TextBox ID="tbDescription" runat="server" TextMode="MultiLine" 
       Width="500px" Height="175px"></asp:TextBox><br /> 

¿Cómo puedo obtener estos valores para que el código subyacente puede conseguir realmente lo que se escribe en el área de texto y mi validador no se van a plantear como decir que está vacío? Incluso después de las devoluciones de datos asincrónicas, ya que tengo varios botones en el formulario que lo actualizan antes del envío real.

Gracias!

Editar: Para mayor claridad que tiene la validación de formularios en el back-end, así:

If tbDescription.Text = "" Or tbDescription.Text Is Nothing Then 
     lblDescriptionError.Text = "You must enter a description." 
     isError = True 
    Else 
     lblDescriptionError.Text = "" 
    End If 

Y este error siempre hará que el mensaje de error que se dispalyed.

Editar: horas

bien estoy desesperando aquí, he gastado en esto. Por fin encontré lo que pensaba ser un ganador en el intercambio de expertos, que establece lo siguiente (había una parte acerca de codificar el valor en XML, pero yo saltamos): http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_25059848.html

Para cualquier persona que quiera usar TinyMCE con AJAX.Net:

  1. Anexar comenzar/manipuladores fin a la solicitud objeto AJAX.Estos le quite el control de TinyMCE antes de enviar los datos (Begin), y se recrearán el control TinyMCE (final):

    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(function(sender, args) { 
        var edID = "<%=this.ClientID%>_rte_tmce"; // the id of your textbox/textarea. 
        var ed = tinyMCE.getInstanceById(edID); 
        if (ed) { 
        tinyMCE.execCommand('mceFocus', false, edID); 
        tinyMCE.execCommand('mceRemoveControl', false, edID); 
    } 
        }); 
    
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) { 
        var edID = "<%=this.ClientID%>_rte_tmce"; 
         var ed = tinyMCE.getInstanceById(edID); 
         if (ed) { 
        tinyMCE.execCommand('mceAddControl', false, edID); 
         } 
        }); 
    
  2. Cuando el usuario cambia/difumina desde el control TinyMCE, queremos asegurarnos de que la área de texto/cuadro de texto se actualiza correctamente:

    ed.onChange.add(function(ed, l) { 
         tinyMCE.triggerSave(true, true); 
    }); 
    

Ahora me han tratado este código de ponerlo en su propia etiqueta de script, poniendo al comenzar y solicitudes extremo en sus propias etiquetas de script y poner el ed.onChange en el page_load, poniendo todo en la página_carga, y poniendo los 3 en su propia etiqueta de script En todos los casos, nunca funcionó, e incluso algunas veces rompió el jquery que también está en mi page_load ... (y sí, cambié el código anterior para que se ajuste a mi página)

¿Alguien puede hacer que esto funcione u ofrecer una solución?

El código

Respuesta

0

bien había dos maneras que obtuve para que funcione, lo cual realmente no solucionó el problema simplemente evítelo.

Una fue para usar el control FCKeditor .net, este volvió a cargar horriblemente lento para mí, como 2-3 segundos. Así que decidí simplemente hacer que el formulario tenga dos paneles de actualización, y coloque el área de texto entre entonces, esencialmente sacando el área de texto del panel de actualización. Esto se sintió como un truco barato que no debería ser necesario, pero funciona bien. Ninguna de las soluciones o sugerencias que alguien publicó funcionó para mí, así que eso es lo que hice. Sin embargo, si tuviera que poner el área de texto en el panel de actualización, esto no habría funcionado.

2

Creo que desea buscar en este aviso: How to make TinyMCE work inside an UpdatePanel?

Asegúrese de que para registrarlo init función con el scriptmanager

ScriptManager.RegisterStartupScript(this.Page, 
     this.Page.GetType(), mce.ClientID, "pageLoad();", true); 
+0

He visto ese hilo y lo he hecho, si lees la respuesta debajo de la respuesta marcada, dice que puedes registrar el script de inicio o ponerlo en la función page_load JavaScript. Elegí este último y funciona porque no estoy teniendo el mismo problema que esa persona.Esa persona pierde el control después de la devolución, no tengo ese problema, mi problema es que incluso antes de una única devolución (y después) cuando llene el área de texto e intento enviar, me está diciendo que tbDescription.text esta vacio. – SventoryMang

0

Una cosa que me encontré al poner TinyMCE en un panel de actualización fue que tenía que hacer todo tipo de trucos para que funcione bien. Tenga en cuenta cómo funciona el panel de actualización, cuando desea actualizarlo, reemplaza completamente el DOM dentro de él, incluido el TinyMCE.

La solución que utilicé fue eliminar el TinyMCE del panel de actualización y ajustar todo lo que necesitaba para actualizar dinámicamente en un panel de actualización. Luego agregaría datos a TinyMCE a través de la API de javascript que proporciona si necesitaba que el contenido de TinyMCE fuera dinámico.

1

Usted tiene que activar la función de guardar al publicar atrás, use Page.RegisterOnSubmitStatement Para registrar la secuencia tinyMCE.triggerSave();

me di cuenta que la función de TinyMCE init sólo puede llamarse la selección de todos las áreas de texto o áreas de texto con una cierta clase. El exact no funciona.

2

Me gustaría agregar mi solución a esta publicación, ya que había estado luchando con el mismo problema por un par de días. Me doy cuenta de que esta es una publicación anterior, pero tal vez mi respuesta ayude a alguien, ya que creo que la pregunta aún es relevante.

Estoy desarrollando una aplicación de formularios web ASP.NET, y una de las páginas tiene un control de texto contenida dentro de un UpdatePanel. tinyMCE se une a este textarea.El texto para el área de texto proviene de un cuadro de texto vinculado dentro de un control de repetidor, porque quiero obtener el texto de un control ObjectDataSource, y esta es una manera un poco díficil de hacerlo. En mi opinión, los controles ObjectDataSource son convenientes y se ejecutan rápidamente.

Aquí está mi marcado que contiene el control ObjectDataSource, el repetidor, el cuadro de texto encuadernado y el área de texto (un asp: TextBox configurado en líneas múltiples). Tenga en cuenta que el cuadro de texto enlazado se establece en "display: none":

<asp:ObjectDataSource ID="odsDetailText" runat="server" TypeName="Data.Document" SelectMethod="GetDocumentDetailText" /> 
<asp:Repeater ID="repBody" runat="server" DataSourceID="odsDetailText"> 
    <ItemTemplate> 
     <asp:TextBox ID="tbxBodyBound" runat="server" Text='<%# Eval("Body") %>' CssClass="hidden" /> 
    </ItemTemplate> 
</asp:Repeater> 
<asp:TextBox ID="tbxBody" runat="server" TextMode="MultiLine" /> 

también tengo un asp: Button para guardar mensajes de texto en TinyMCE a SQL Server. Todos estos controles están contenidos dentro de un UpdatePanel.

He colocado todos mis códigos jQuery y JavaScript en un archivo separado. Incluyo los bits relevantes a continuación. Como resumen:

  • Inicializo tinyMCE en el evento pageLoad de JavaScript. Tenga en cuenta que este evento se activa para las devoluciones de datos completas y parciales (asincrónicas), por lo que tinyMCE siempre se muestra y no desaparece entre las devoluciones de datos completas o parciales.

  • También en el evento pageLoad, si una devolución de datos es asíncrona, empiezo a escuchar un evento BeginRequest generado por ASP.NET PageRequestManager. Dejo de escuchar el evento BeginRequest en el evento JavaScript pageUnload. Esto evita que se agreguen más y más oyentes cada vez que se dispara pageLoad.

  • Cuando se activa el controlador de eventos para el evento BeginRequest (cuando se hace clic en el botón Guardar en mi página), obtengo el contenido HTML del editor de texto tinyMCE y lo guardo en una cookie. Yo uso el plugin de cookies jQuery para hacer esto: https://github.com/carhartl/jquery-cookie. El HTML está codificado en la cookie, por seguridad.

  • Ahora, en el código del servidor que se ejecuta cuando se hace clic en el botón Guardar, el texto de la cookie (que es HTML codificado) se recupera y se guarda en el servidor SQL. La cookie ahora está eliminada.

  • ASP.NET enlaza los datos guardados al texto oculto mediante el control ObjectDataSource, el valor del control textarea se establece en el cuadro de texto oculto, y la parte de la página dentro del UpdatePanel se devuelve al navegador.

  • tinyMCE ahora muestra este texto desde el área de texto, pero está codificado en HTML y no es legible para el ser humano.

  • Por lo tanto, en el evento pageLoad de JavaScript, formateo el texto de tinyMCE decodificando el HTML.

  • ¡Trabajo hecho!

Estas son las partes pertinentes de mi archivo de script:

// ######################################################### 
// Events 
// ######################################################### 
// --------------------------------------------------------- 
// Check for full and partial postbacks 
// --------------------------------------------------------- 
function pageLoad(sender, args) { 

    // Register event handler for async postback beginning 
    var prm = Sys.WebForms.PageRequestManager.getInstance(); 
    if (!prm.get_isInAsyncPostBack()) { 
     prm.add_beginRequest(onBeginRequest); 
    }; 

    // Configure HTML editor 
    HTMLEditorConfig(); 

    // Format HTML editor text 
    HTMLEditorFormat(); 
}; 

// --------------------------------------------------------- 
// When page unloads after full or partial postback 
// --------------------------------------------------------- 
function pageUnload(sender, args) { 

    // Deregister event handler for async postback beginning 
    Sys.WebForms.PageRequestManager.getInstance().remove_beginRequest(onBeginRequest); 
}; 

// --------------------------------------------------------- 
// Event handler for async postback beginning 
// --------------------------------------------------------- 
function onBeginRequest() { 

    // Check whether to save text editor text 
    HTMLEditorSave(); 
}; 

// ######################################################### 
// Functions 
// ######################################################### 
// --------------------------------------------------------- 
// Configure HTML text editor. tinyMCE converts standard textarea controls 
// --------------------------------------------------------- 
function HTMLEditorConfig() { 

    // Determine edit mode 
    var editMode = $('input:hidden[id*=hfEditMode]').val().toLowerCase(); 

    // If not in edit mode, prevent edits 
    var editorReadOnly = null; 
    var editorHeight = null; 
    if (editMode == 'true') { 
     editorReadOnly = ''; 
     editorHeight = '332'; 
    } else { 
     editorReadOnly = 'true'; 
     editorHeight = '342'; 
    }; 

    // Initialise HTML text editor 
    tinyMCE.init({ 
     mode: "textareas", 
     plugins: "advhr,insertdatetime,print,preview,fullscreen", 
     width: "488", 
     height: editorHeight, 

     // Theme options 
     theme: "advanced", 
     theme_advanced_buttons1: "newdocument,|,print,preview,|,cut,copy,paste,|,undo,redo,removeformat,|,bold,italic,underline,strikethrough,sub,sup,|,forecolor,backcolor", 
     theme_advanced_buttons2: "justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,outdent,indent,|,fontselect,fontsizeselect", 
     theme_advanced_buttons3: "insertdate,inserttime,|,advhr,|,charmap,|,fullscreen", 
     theme_advanced_toolbar_location: "top", 
     theme_advanced_toolbar_align: "left", 
     theme_advanced_statusbar_location: "none", 
     theme_advanced_resizing: false, 

     // Skin options 
     skin: "o2k7", 
     skin_variant: "silver", 

     // Custom css 
     content_css: "../../Script/tiny_mce/custom.css", 

     // Allow edits? 
     readonly: editorReadOnly 
    }); 
}; 

// --------------------------------------------------------- 
// Format HTML editor text by ensuring its HTML is decoded 
// --------------------------------------------------------- 
function HTMLEditorFormat() { 

    // Check bound textbox containing HTML for text editor 
    var bodyText = $('input:text[id*=tbxBody]').val(); 

    // If HTML exists, decode it 
    if (bodyText !== null) { 
     tinyMCE.activeEditor.setContent(decodeURIComponent(bodyText)); 
    }; 
}; 

// --------------------------------------------------------- 
// Save HTML text editor text to cookie for server-side processing. 
// Can't save to hidden field or asp control as this function fires after viewstate is captured (I think). 
// Extra content in viewstate would slow down page load anyway. 
// --------------------------------------------------------- 
function HTMLEditorSave() { 

    // Determine edit mode 
    var editMode = $('input:hidden[id*=hfEditMode]').val().toLowerCase(); 

    // If in edit mode, create cookie with encoded text editor HTML. Server code will save this to database. 
    if (editMode == 'true') { 
     var textToSave = tinyMCE.activeEditor.getContent(); 
     $.cookie('HTMLEditorText', textToSave); 
    } 
}; 

que aquí hay una porción del código de servidor que se activa cuando se hace clic en el botón Guardar:

Private Sub Save() 

    'Retrieve tinyMCE text from cookie 
    Dim cookieName As String = "tinyMCEText" 
    Dim cookies As HttpCookieCollection = Request.Cookies 
    Dim text As String = cookies(cookieName).Value 

    'Save text to database... 

    'Delete cookie 
    cookies.Remove(cookieName) 

    'Databind text for tinyMCE 
    repeaterTinyMCE.DataBind() 
    Dim encodedText As String = DirectCast(repeaterTinyMCE.Controls(0).Controls(1), TextBox).Text 
    textboxTinyMCE.Text = encodedText 
End Sub 

Esperanza esta ayuda a alguien

Cuestiones relacionadas