2009-02-13 144 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) 
    { 

    } 
}