2009-02-13 145 views
13

我试图做很多人似乎已经能够做的事情,但我无法实现任何解决方案。 TinyMCE控件在asp.net窗体中工作得很好,直到用一个UpdatePanel封装它,然后在回发后中断。我尝试了一些像RegisterClientScriptBlock方法的修复方法,但仍然不成功,回发后我仍然失去了tinyMCE控件。如何让TinyMCE在UpdatePanel中工作?

下面是一个完整的测试项目(VS 2008),提供了一个UpdatePanel外部的控件,一个内部,每个项目上都有一个按钮用于生成回发。同样在这个项目中,我有一个EditorTest控件,其中包含我尝试过的一些调用的注释代码,以防给任何人任何想法。

CODE SAMPLE

这里有一些来源的MCE论坛的一些解决方案:
AJAX
UpdatePanel

回答

-2

TinyMCE(以及其他所见即所得编辑器,FCKEditor等)遭遇回发验证问题。默认情况下,回发中的任何ASP.Net页面都会检查其内容,并且任何未编码的HTML都会引发回发验证错误。

现在很多人,包括在这些论坛上都建议禁用回发验证,validaterequest =“false”,但这会让您容易受到脚本攻击,最好的办法是将函数绑定到异步回发事件就在异步回发之前。这个JavaScript函数需要HTML编码发布回服务器的TinyMCE数据,然后这将通过回发验证,你会没事的。

我相信TinyMCE和其他编辑器在回发上正确地做到这一点,但不是异步回发,因此这个问题,事实上,如果你看TinyMCE的源代码,你可能会发现它们的功能,并简单地添加事件绑定。

希望这有助于

+0

这无关我的问题,在我的回发的工作,这是TinyMCE的布局不重建。编码<>标记修复了validationRequest问题,我已经做到了。提供的代码示例不包含此类错误。 – 2009-02-16 16:09:16

0

你要拨打的TinyMCE的初始化方法,只要更新面板刷新。

对于这一点,你或者从的RegisterStartupScript方法调用此方法(tinyMCE.init),或在页面像这样的头部分可以创建一个页面加载javascript函数:

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

这功能将在每次更新面板刷新时执行。

4

好的,你的问题是双重的。Stefy提供您的答复,这是你必须通过注册启动脚本,像这样初始化TinyMCE的上回发的一部分:

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

你的第二个问题是你实现一个自定义的控制。设计自定义控件不在此答案的范围内。谷歌可以帮助你。

在页面上有多个控件实例可能会导致脚本问题,因为它会多次渲染。这是我如何修改您的标记,以解决您的问题(你的脚本函数通知动态命名,自定义控件应当自包含的,模式:在tinyMCE.init“精确”):

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

我的答案解决了你的问题吗? – 2010-08-13 17:45:46

+1

您无法使用“模式”“确切”,它在UpdatePanel中无法正常工作。您可以使用`textareas`或者`class selector`。而对于我来说`save_callback`很麻烦,而我使用`RegisterOnSubmitStatement`来调用`tinyMCE.triggerSave()`。它对我来说工作得很好。 – BrunoLM 2010-08-26 23:48:13

+1

我已经在UpdatePanels中正确使用了模式,没有问题,每个人的要求和实现细节都不一样。 – 2010-08-27 13:16:52

1

我做了以下:

首先我加入了这个Javascript来我的页面:

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

因为我创建一个ASP.NET,在我的页面上,使用和ASP.NET按钮,我不得不添加下面的页面加载:

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

正确的方法,使在一个UpdatePanel tinyMCE的工作:

1)为您的“提交”按钮的OnClientClick的处理程序。 2)运行tinyMCE.execCommand(“mceRemoveControl”,false,'<%= txtMCE.ClientID%>');运行tinyMCE.execCommand(“mceRemoveControl”,false,'<%= txtMCE.ClientID%>');在处理程序中,以便在回发之前移除tinyMCE实例。

3)在异步回发中,使用ScriptManager.RegisterStartupScript运行tinyMCE.execCommand(“mceAddControl”,true,'<%= txtMCE.ClientID%>');

基本上,您需要做的只是在异步回发之前使用mceRemoveControl命令并注册启动脚本以在异步回发之后运行mceAddControl命令。不太强悍。

12

要执行init每次你需要使用ScriptManager注册脚本UpdatePanel变化:

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

注:不能使用exact方式对你的初始化功能,您可以使用textareasclass selector ,否则它将无法正常工作。

您还可以使用

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

在一个UpdatePanel的编辑内容不会被保存在文本框的回传,因为默认行为是仅适用于form.submit,所以当你提交任何东西会节省它发布之前的文本。

关于获得该值的代码,您将只需访问TextBox.Text属性。

NOTE:如果您使用.NET GZip,您可能需要删除它,但我无法完成它的工作,我必须彻底删除它。

1

这是一个古老的问题,但经过几个小时寻找答案后,我觉得有义务发布我提出的解决方案。

看来,至少在我使用的实现中(UpdatePanel内的多个编辑器),必须告知tinyMCE,UpdatePanel提交时控件将消失,否则它将拒绝再次加载它。

因此,除了代码初始化TinyMCE的(只需要当整个页面加载运行),你需要为每个MCE文本框的做到这一点:

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是什么TinyMCE的元素是。 Mine是一个位于UserControl中的textarea,但是您可以将它应用于任何要绑定/解除绑定textarea的项目。

0

我响应产生Ajax调用

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

和页面通过Ajax调用caaled后解决了这个问题,因为 呼叫微小的MCE是

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

可能是在这样的情况很有帮助。

0

我二叔这个

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

,在Page_Load事件

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

每个异步回发后初始化编辑器即使

然后更新这个问题的答案对于那些使用.NET框架4,我通过插入以下内容成功地将TinyMCE附加到更新面板中的TextBox:

在标记中的<头内> < /头>区域:

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

在<主体内的标记> < /体>区域:

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

而最后在Page_Load事件中隐藏代码:

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

这种解决方案不再适用于TinyMCE的4.2.3。现在不需要使用tinymce.mceRemoveControl(),而需要使用tinymce.remove()。这是一个完整的工作示例:

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

隐藏代码:

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

    } 
}