2009-02-13 8 views
13

Ich versuche etwas zu tun, was viele Leute zu tun scheinen, aber das ich keine Lösung implementieren kann. Das Steuerelement TinyMCE funktioniert ziemlich gut in einer Asp.net-Form, bis Sie es mit einem UpdatePanel umschließen, die dann nach dem Postback bricht. Ich habe einige Korrekturen wie die RegisterClientScriptBlock-Methode versucht, aber bin immer noch nicht erfolgreich, ich verliere immer noch das tinyMCE-Steuerelement nach dem Postback.Wie funktioniert TinyMCE in einem UpdatePanel?

Unten ist ein vollständiges Testprojekt (VS 2008) mit einem Control außerhalb von UpdatePanel und einem innerhalb, mit einer Schaltfläche auf jedem, um Postback zu generieren. Auch im Projekt habe ich ein EditorTest-Steuerelement, das einen kommentierten Code einiger Aufrufe enthält, die ich ausprobiert habe, falls es irgendjemand irgendwelche Ideen gibt.

CODE SAMPLE

Hier sind einige Quellen für einige Lösungen auf dem MCE-Forum:
AJAX
UpdatePanel

Antwort

-2

TinyMCE (wie auch andere WYSIWYG-Editoren, FCKEditor usw.) leidet unter Postback-Validierungsproblemen. Standardmäßig wird bei jeder ASP.Net-Seite auf Postback der Inhalt überprüft, und bei nicht codiertem HTML wird der Postback-Validierungsfehler ausgelöst.

Jetzt empfehlen viele Leute, einschließlich in diesen Foren, die Postbackvalidierung zu deaktivieren, validierequest = "false", aber dies macht Sie anfällig für Skriptangriffe, die beste Sache ist, eine Funktion an das asynchrone Postbackereignis zu binden, das ausgelöst wird kurz vor dem asynchronen Postback. Diese JavaScript-Funktion muss die TinyMCE-Daten, die auf den Server zurückgeschickt werden, in HTML-Code codieren. Dadurch wird die Postback-Validierung bestanden und Sie sind in Ordnung.

Ich glaube, TinyMCE und andere Editoren tun dies richtig auf Postbacks, aber nicht asynchronen Postbacks daher das Problem, in der Tat, wenn Sie die Quelle von TinyMCE betrachten, können Sie wahrscheinlich ihre Funktion finden, die dies tut und einfach die Ereignisbindung hinzufügen.

this helps

+0

Das hat nichts mit meinem Problem zu tun, wo meine Postbacks arbeiten, es ist das tinyMCE Layout, wird nicht wiederhergestellt. Die Codierung des <> -Tags behebt das validationRequest-Problem und ich habe es bereits getan. Das bereitgestellte Codebeispiel enthält solche Fehler nicht. –

0

Sie haben das Initialisierungsverfahren des TinyMCE zu rufen, wenn das Update-Panel aktualisiert wird.

Dazu müssen Sie entweder zum Aufruf dieser Methode (tinyMCE.init) von einer Registerstartup Methode oder eine Seite zu laden Javascript-Funktion im Kopfbereich der Seite wie diese zu erstellen:

function pageLoad() { 
    tinyMCE.init(); 
} 

Dieses Die Funktion wird jedes Mal ausgeführt, wenn das Update-Panel aktualisiert wird.

4

Ok, Ihr Problem ist zweifach.Stefy versorgen Sie mit einem Teil der Antwort, die, die Sie haben TinyMCE auf dem Postbacks zu initialisieren, indem Startskript Registrierung wie folgt:

using System.Web.UI; 

namespace TinyMCEProblemDemo 
{ 
    public partial class EditorClean : UserControl 
    { 
     protected void Page_Load(object sender, System.EventArgs e) 
     {     
       ScriptManager.RegisterStartupScript(this.Page, 
        this.Page.GetType(), mce.ClientID, "callInt" + mce.ClientID + "();", true); 
     } 
    } 
} 

Das zweite Problem, das Sie haben, ist bei der Implementierung einer benutzerdefinierten Kontrolle. Entwerfen benutzerdefinierter Steuerelemente liegt außerhalb des Bereichs dieser Antwort. Google kann Ihnen dabei helfen.

Sie haben mehrere Instanzen Ihres Steuerelements auf der Seite, die Probleme mit dem Skript verursachen können, da es mehrmals gerendert wird. Dies ist, wie ich geändert Markup Ihr ​​Problem (Hinweis dynamische Benennung Ihrer Skriptfunktionen, benutzerdefinierte Steuerelemente eigenständig und Modus werden sollten: „exakt“ auf dem tinyMCE.init): zu lösen

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EditorClean.ascx.cs" 
    Inherits="TinyMCEProblemDemo.EditorClean" %> 
<script type="text/javascript" src="Editor/tiny_mce.js"></script> 

<script type="text/javascript"> 
    function myCustomCleanup<%= mce.ClientID%>(type, value) { 
     if (type == "insert_to_editor") { 
      value = value.replace(/&lt;/gi, "<"); 
      value = value.replace(/&gt;/gi, ">"); 
     } 
     return value; 
    } 
    function myCustomSaveContent<%= mce.ClientID%>(element_id, html, body) { 
     html = html.replace(/</gi, "&lt;"); 
     html = html.replace(/>/gi, "&gt;"); 
     return html; 
    } 

    function callInt<%= mce.ClientID%>() { 

     tinyMCE.init({ 
      mode: "exact", 
      elements: "<%= mce.ClientID%>", 
      theme: "advanced", 
      skin: "o2k7", 
      plugins: "inlinepopups,paste,safari", 
      theme_advanced_buttons1: "fontselect,fontsizeselect,|,forecolor,backcolor,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,outdent,indent,blockquote,|,cut,copy,paste,pastetext,pasteword", 
      theme_advanced_buttons2: "", 
      theme_advanced_buttons3: "", 
      theme_advanced_toolbar_location: "top", 
      theme_advanced_toolbar_align: "left", 
      cleanup_callback: "myCustomCleanup<%= mce.ClientID%>", 
      save_callback: "myCustomSaveContent<%= mce.ClientID%>" 
     }); 
    } 
</script> 
<textarea runat="server" id="mce" name="editor" cols="50" rows="15">Enter your text here...</textarea> 
+0

Hat meine Antwort Ihr Problem gelöst? –

+1

Sie können den 'mode'" exact "nicht verwenden, es funktioniert nicht richtig in einem UpdatePanel. Sie können statt dessen 'textareas' oder einen' classselector' verwenden. Und für mich war der 'save_callback' ziemlich fehlerhaft, stattdessen habe ich' RegisterOnSubmitStatement' benutzt um 'tinyMCE.triggerSave()' aufzurufen. Es funktioniert gut für mich. – BrunoLM

+1

Ich habe den Modus exact in UpdatePanels ohne Problem verwendet, alle Anforderungen und Implementierungsdetails sind unterschiedlich. –

1

Ich habe die folgende :

Zuerst habe ich die dieses Javascript auf meiner Seite hinzugefügt:

<script type="text/javascript"> 
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler); 

function endRequestHandler(sender,args) 
{ 
    tinyMCE.idCounter=0; 
    tinyMCE.execCommand('mceAddControl',false,'htmlContent'); 
} 

function UpdateTextArea() 
{ 
    tinyMCE.triggerSave(false,true); 
} 
</script> 

Weil ich eine ASP.NET und verwenden und ASP.NET-Knopf in meiner Seite bin zu schaffen, hatte ich folgendes zu der hinzufügen Seitenlast:

protected void Page_Load(object sender, EventArgs e) 
{ 
    Button1.Attributes.Add("onclick", "UpdateTextArea()"); 
} 
2

Der richtige Weg tinyMCE Arbeit in einem Update zu machen:

1) Erstellen Sie einen Handler für das OnClientClick Ihrer Schaltfläche "Senden".

2) Führen Sie tinyMCE.execCommand aus ("mceRemoveControl", false, '<% = txtMCE.ClientID%>'); im Handler, um die tinyMCE-Instanz vor dem Postback zu entfernen.

3) Verwenden Sie in Ihrem asynchronen Postback den ScriptManager.RegisterStartupScript, um tinyMCE.execCommand auszuführen ("mceAddControl", true, "<% = txtMCE.ClientID%>");

Im Grunde müssen Sie nur den Befehl mceRemoveControl vor dem asynchronen Postback ausführen und ein Startskript registrieren, um den Befehl mceAddControl nach dem asynchronen Postback auszuführen. Nicht zu hart.

12

Um den init jedes Mal die UpdatePanel Änderungen führen Sie das Skript mit ScriptManager registrieren müssen:

// control is your UpdatePanel 
ScriptManager.RegisterStartupScript(control, control.GetType(), control.UniqueID, "your_tinymce_initfunc();", true); 

HINWEIS: Sie nicht exact Modus auf Ihrer init-Funktion verwenden können, können Sie entweder textareas oder ein class selector verwenden oder sonst wird es nicht richtig funktionieren.

Sie haben auch

ScriptManager.RegisterOnSubmitStatement(this, this.GetType(), "", "tinyMCE.triggerSave();"); 

Auf einem Postbacks eines Update der Editor Inhalt der Textbox wird nicht gespeichert verwenden, da das Standardverhalten nur für form.submit ist, also, wenn Sie etwas eintragen sparen der Text vor dem Posten.

Auf den Code hinter, um den Wert zu erhalten, müssen Sie nur Zugriff auf TextBox.Text Eigentum.

HINWEIS: Wenn Sie das .NET GZipped verwenden, müssen Sie es wahrscheinlich fallen lassen, ich konnte es nicht funktionieren, ich musste das vollständig entfernen.

1

Dies ist eine alte Frage, aber nach stundenlangem Suchen und Herumspielen auf der Suche nach der Antwort fühle ich mich verpflichtet, die Lösung, die mir einfällt, zu posten.

Es scheint, zumindest in der Implementierung, die ich benutze (mehrere Editoren in einem UpdatePanel), dass tinyMCE darüber informiert werden muss, dass das Steuerelement weggeht, wenn das UpdatePanel es absetzt oder es sich weigert, es erneut zu laden.

So, zusätzlich zu dem Code Init TinyMCE (die nur muss ausgeführt werden, wenn die gesamte Seite geladen wird) benötigen Sie diese Textfelder für jedes Ihrer MCE zu tun:

ScriptManager.RegisterStartupScript(this, this.GetType(), elm1.UniqueID+"Add", 
    "tinyMCE.execCommand('mceAddControl', true,'" + elm1.ClientID + "');", true); 
ScriptManager.RegisterOnSubmitStatement(this, this.GetType(), elm1.UniqueID + "Remove", 
    "tinyMCE.execCommand('mceRemoveControl', true,'" + elm1.ClientID + "');"); 

elm1 ist, was auch immer die tinyMCE Element ist. Meine ist ein Textfeld, das sich in einem UserControl befindet, aber Sie können es auf jedes Element anwenden, das Sie an Ihr Textfeld binden möchten.

+2

Ich habe auch stundenlang gesucht. In Version 4 wurden die obigen TinyMCE-Befehle durch 'mceAddEditor' /' mceRemoveEditor' ersetzt. Http://www.tinymce.com/forum/viewtopic.php?id=31256 –

0

i löste dieses Problem als Anruf winzige mce nach der Reaktion Generation des Ajax-Aufruf

function edittemp(name) { 

xmlhttp=GetXmlHttpObject(); 
if (xmlhttp==null) 
{ 
alert ("Your browser does not support XMLHTTP!"); 
return; 
} 


var url="edit_temp.php"; 
url=url+"?id="+name; 





xmlhttp.onreadystatechange=stateChanged3; 
xmlhttp.open("GET",url,true); 
xmlhttp.send(null); 


} 
function stateChanged3() 
{ 
if (xmlhttp.readyState==4) 
{ 
spl_txt=xmlhttp.responseText.split("~~~"); 


document.getElementById("edit_message").innerHTML=spl_txt[0]; 
tinyMCE.init({ 
theme : "advanced", 
mode: "exact", 
elements : "elm1", 
theme_advanced_toolbar_location : "top", 
theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator," 
+ "justifyleft,justifycenter,justifyright,justifyfull,formatselect," 
+ "bullist,numlist,outdent,indent", 
theme_advanced_buttons2 : "link,unlink,anchor,image,separator," 
+"undo,redo,cleanup,code,separator,sub,sup,charmap", 
theme_advanced_buttons3 : "", 
height:"350px", 
width:"600px" 
}); 
} 
} 

und der von Ajax-Aufruf caaled Seite ist

<?php 
$name=$_GET['id']; 
include 'connection.php'; 
$result=mysql_query("SELECT * FROM `templete` WHERE temp_name='$name' and status=1"); 

$row = mysql_fetch_array($result); 
$Content=$row['body']; 
?> 
<html> 
<head> 
<title>editing using tiny_mce</title> 
<script language="..." src="tinymce/jscripts/tiny_mce /tiny_mce.js"></script> 
</head> 
<body> 
<h2>change the template here</h2> 
<form method="post" action="save_temp.php?name=<?php echo $name;?>"> 
<textarea id="elm1" name="elm1" rows="15" cols="80"><?php echo $Content;?></textarea> 
<br /> 
<input type="submit" name="save" value="Submit" /> 
<input type="reset" name="reset" value="Reset" /> 
</form> 
</body> 
</html> 

in einer solchen Situation sehr nützlich sein.

0

I di dieses

<script language="javascript" type="text/javascript"> 
    function pageLoad(sender, args) { 
     aplicartinyMCE();  
    } 
    function aplicartinyMCE() { 
     tinyMCE.init({ 
      mode: "specific_textareas", 
      editor_selector: "mceEditor", 
      ..... 
     }); 
    } 
</script> 

, dass der Editor nach jedem asynchronen Postbacks initialisieren, auch wenn

Dann in page_load Ereignis

ScriptManager.RegisterOnSubmitStatement(this, this.GetType(), "salvarEditorMCE", "tinyMCE.triggerSave();"); 
1

die Antwort auf diese Frage Aktualisierung für diejenigen mit .NET Framework 4, konnte ich TinyMCE erfolgreich an eine TextBox in einem Update-Panel anhängen, indem ich Folgendes einfügte:

In Markup im <Kopf> </head > Region:

<script src="scripts/tinymce/tinymce.min.js" type="text/javascript"></script> 
<script type="text/javascript"> 

    tinyMCE.init({ 
     selector: ".tinymcetextarea", 
     mode: "textareas", 

     plugins: [ 
      "advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker", 
      "searchreplace visualblocks visualchars code fullscreen autoresize insertdatetime media nonbreaking", 
      "save table contextmenu directionality emoticons template paste textcolor", 
      "autosave codesample colorpicker image imagetools importcss layer" 
     ], 

     toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | print preview media | forecolor backcolor emoticons", 
     style_formats: [ 
      { title: 'Bold text', inline: 'b' }, 
      { title: 'Red text', inline: 'span', styles: { color: '#ff0000' } }, 
      { title: 'Red header', block: 'h1', styles: { color: '#ff0000' } }, 
      { title: 'Example 1', inline: 'span', classes: 'example1' }, 
      { title: 'Example 2', inline: 'span', classes: 'example2' }, 
      { title: 'Table styles' }, 
      { title: 'Table row 1', selector: 'tr', classes: 'tablerow1' } 
     ] 
    }); 

</script> 

Im Markup im < Körper > </body > Region:

<asp:TextBox ID="tbContentHtml" CssClass="tinymcetextarea" Wrap="true" runat="server" Width="90%" TextMode="MultiLine" /> 

Und Schließlich in Codebehind in dem Page_Load-Ereignis:

ScriptManager.RegisterStartupScript(this, this.GetType(), tbContentHtml.UniqueID + "Add", "tinyMCE.execCommand('mceAddEditor', true,'" + tbContentHtml.ClientID + "');", true); 
ScriptManager.RegisterOnSubmitStatement(this, this.GetType(), tbContentHtml.UniqueID + "Remove", "tinyMCE.execCommand('mceRemoveEditor', true,'" + tbContentHtml.ClientID + "');"); 
2

Diese Lösung funktioniert nicht mehr für TinyMCE 4.2.3. Anstatt tinymce.mceRemoveControl() zu verwenden, müssen Sie nun tinymce.remove() verwenden.Hier ist ein voll funktionierendes Beispiel:

Die Seite

<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPages/Frame.master" AutoEventWireup="true" CodeFile="FullImplementation.aspx.cs" 
    Inherits="TinyMCE" ValidateRequest="false" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="cphContent" Runat="Server"> 

    <asp:ScriptManager runat="server"/> 


    <asp:UpdatePanel runat="server" id="upUpdatPanel"> 
    <ContentTemplate> 

     <asp:TextBox runat="server" id="tbHtmlEditor" TextMode="MultiLine"> 
     Default editor text 
     </asp:TextBox> 

     <asp:Dropdownlist runat="server" ID="ddlTest" AutoPostBack="true" OnSelectedIndexChanged="ddlTest_SelectedIndexChanged"> 
     <Items> 
      <asp:ListItem Text="A"></asp:ListItem> 
      <asp:ListItem Text="B"></asp:ListItem> 
     </Items> 
     </asp:Dropdownlist> 

     <asp:Button runat="server" ID="butSaveEditorContent" OnClick="butSaveEditorContent_Click" Text="Save Html Content"/>  

    </ContentTemplate> 
    </asp:UpdatePanel> 

    <script type="text/javascript"> 

     $(document).ready(function() { 
     /* initial load of editor */ 
     LoadTinyMCE(); 
     }); 

     /* wire-up an event to re-add the editor */  
     Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler_Page); 

     /* fire this event to remove the existing editor and re-initialize it*/ 
     function EndRequestHandler_Page(sender, args) { 
     //1. Remove the existing TinyMCE instance of TinyMCE 
     tinymce.remove("#<%=tbHtmlEditor.ClientID%>"); 
     //2. Re-init the TinyMCE editor 
     LoadTinyMCE(); 
     } 

     function BeforePostback() { 
     tinymce.triggerSave(); 
     } 

     function LoadTinyMCE() { 

     /* initialize the TinyMCE editor */ 
     tinymce.init({ 
      selector: "#<%=tbHtmlEditor.ClientID%>", 
      plugins: "link, autolink", 
      default_link_target: "_blank", 
      toolbar: "undo redo | bold italic | link unlink | cut copy paste | bullist numlist", 
      menubar: false, 
      statusbar: false 
     }); 
     } 

    </script> 




</asp:Content> 

Code-Behind:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

public partial class TinyMCE : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
    // we have to tell the editor to re-save the date on Submit 
    if (!ScriptManager.GetCurrent(Page).IsInAsyncPostBack) 
    { 
     ScriptManager.RegisterOnSubmitStatement(this, this.GetType(), "SaveTextBoxBeforePostBack", "SaveTextBoxBeforePostBack()"); 
    } 

    } 

    protected void butSaveEditorContent_Click(object sender, EventArgs e) 
    { 
    string htmlEncoded = WebUtility.HtmlEncode(tbHtmlEditor.Text); 

    } 

    private void SaveToDb(string htmlEncoded) 
    { 
    /// save to database column 
    } 

    protected void ddlTest_SelectedIndexChanged(object sender, EventArgs e) 
    { 

    } 
} 
+0

Dies ist definitiv die Lösung. Es funktioniert auch für TinyMCE Version 4.5.4 und funktioniert über alle Browser (getestet in Chrome Version 56, IE 9, 10, 11 und Microsoft Edge 38). Andere mögliche Lösungen, die nicht .remove() verwenden, konnten nicht mit anderen Browsern als IE funktionieren. Außerdem können Sie den Klassennamen an .remove () übergeben, was ich tue und großartig funktioniert. Danke @bperniciaro für diese Lösung! – Jaime

+0

Große Lösung (y) –