Dot-Net

帶有 AJAX(更新面板)的 TinyMCE 永遠不會有價值

  • November 4, 2011

我想將富文本編輯器用於更新面板內的文本區域。

我通過這個問題找到了這篇文章: http ://www.queness.com/post/212/10-jquery-and-non-jquery-javascript-rich-text-editors:需要 ASP.Net/MVC 富文本編輯器

決定使用 TinyMCE,因為我以前在非 AJAX 情況下使用它,並且在該列表中說它與 AJAX 兼容。好吧,我做得很好,tinyMCE.init({ //settings here }); 測試一下,在更新面板更新後它消失了。我從這裡的一個問題中發現它應該在page_load函式中,因此它甚至可以在非同步回發時執行。好吧,這樣做,面板就會保留。但是,在嘗試從我的 textarea 送出值時,它的文本總是返回為空,因為我的表單驗證器總是說“您必須輸入描述”,即使我在其中輸入文本也是如此。這發生在頁面第一次載入和對頁面進行非同步回發之後。

好吧,我找到了這個http://www.dallasjclark.com/using-tinymce-with-ajax/並且不能從同一個 AJAX TinyMCE textarea 發布兩次。我嘗試在 tinyMCE.init 之後將此程式碼添加到我的頁面載入函式中。這樣做會破壞我所有的 jquery 在它之後的 page_load 中被呼叫,它仍然有同樣的問題。

我仍然是客戶端腳本的初學者,所以也許我需要將程式碼放在與 page_load 不同的位置?不確定我連結的文章對於該程式碼的放置位置不是很清楚。

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

現在我目前的程式碼沒有tinyMCE.execCommand("mceAddControl",true,'content');應該添加的那個問題。我確實嘗試添加它,但再次不確定將它放在哪裡,只是將它放在 page_load 中似乎沒有任何效果。

文本框控制項:

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

如何獲取這些值,以便後面的程式碼實際上可以獲取在 textarea 中輸入的內容,並且我的驗證器不會出現說它是空的?即使在非同步回發之後,因為我在表單上有多個按鈕可以在實際送出之前對其進行更新。

謝謝!

編輯:為了進一步澄清,我在後端有表單驗證,如下所示:

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

並且此錯誤將始終導致錯誤消息顯示。

編輯:

好吧,我在這裡變得絕望,我已經花了幾個小時在這上面。我終於找到了我認為是專家交流的贏家,其中說明了以下內容(有一部分關於在 xml 中編碼值,但我跳過了):http ://www.experts-exchange.com/Programming/Languages /C_Sharp/Q_25059848.html

對於任何想要將 tinyMCE 與 AJAX.Net 一起使用的人:

  1. 將開始/結束處理程序附加到 AJAX 請求對象。這些將在發送數據之前刪除 tinyMCE 控制項(開始),並將重新創建 tinyMCE 控制項(結束):
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);
     }
  });
  1. 當使用者從 tinyMCE 控制項更改/模糊時,我們要確保 textarea/textbox 正確更新:
  ed.onChange.add(function(ed, l) {
      tinyMCE.triggerSave(true, true);
});

現在我已經嘗試將這段程式碼放在它自己的腳本標籤中,將開始和結束請求放在他們自己的腳本標籤中,並將 ed.onChange 放在 page_load 中,將所有內容放在 page_load 中,並將所有 3 個放在它自己的腳本標籤中. 在所有情況下,它都無法正常工作,甚至有時會破壞我 page_load 中的 jquery …(是的,我更改了上面的程式碼以適合我的頁面)

任何人都可以讓它工作或提供解決方案嗎?

編碼

我只想將我的解決方案添加到這篇文章中,因為我已經為同一個問題苦苦掙扎了幾天。我意識到這是一篇舊文章,但也許我的回答會對某人有所幫助,因為我相信這個問題仍然相關。

我正在開發一個 ASP.NET Web 表單應用程序,其中一個頁面有一個包含在 UpdatePanel 中的 textarea 控制項。tinyMCE 綁定到這個文本區域。textarea 的文本來自轉發器控制項中的綁定文本框,因為我想從 ObjectDataSource 控制項中獲取文本,這是一種稍微笨拙的方法。在我看來,ObjectDataSource 控制項很方便,而且執行速度很快。

這是我的標記,其中包含 ObjectDataSource 控制項、轉發器、綁定文本框和文本區域(設置為多行的 asp:TextBox)。請注意,綁定的文本框設置為“顯示:無”:

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

我還有一個 asp:Button 用於將 tinyMCE 中的文本保存到 SQL Server。所有這些控制項都包含在 UpdatePanel 中。

我已將所有 jQuery 和 JavaScript 程式碼放在一個單獨的文件中。我包括下面的相關位。作為概述:

  • 我在 JavaScript pageLoad 事件中初始化 tinyMCE。請注意,此事件會針對完整和部分(非同步)回發觸發,因此 tinyMCE 始終會顯示並且不會在完整或部分回發之間消失。
  • 同樣在 pageLoad 事件中,如果回發是非同步的,我將開始偵聽由 ASP.NET PageRequestManager 引發的 BeginRequest 事件。我停止偵聽 JavaScript pageUnload 事件中的 BeginRequest 事件。這可以防止每次 pageLoad 觸發時添加越來越多的偵聽器。
  • 當 BeginRequest 事件的事件處理程序觸發時(點擊我頁面上的保存按鈕時),我獲取 tinyMCE 文本編輯器的 HTML 內容並將其保存到 cookie。我使用 jQuery cookie 外掛來執行此操作:https ://github.com/carhartl/jquery-cookie 。為了安全起見,HTML 編碼在 cookie 中。
  • 現在,在點擊“保存”按鈕時執行的伺服器程式碼中,將檢索 cookie 的文本(編碼為 HTML)並將其保存到 SQL 伺服器。cookie 現在已被刪除。
  • ASP.NET 通過 ObjectDataSource 控制項將保存的數據綁定到隱藏的 textobx,將 textarea 控制項的值設置為隱藏的文本框,並將 UpdatePanel 中的頁面部分呈現回瀏覽器。
  • tinyMCE 現在顯示來自 textarea 的文本,但它是編碼的 HTML,不是人類可讀的。
  • 因此,在 JavaScript pageLoad 事件中,我通過解碼 HTML 來格式化 tinyMCE 文本。
  • 任務完成!

以下是我的腳本文件的相關部分:

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

這是點擊“保存”按鈕時觸發的伺服器程式碼的一部分:

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

希望這可以幫助某人。

我想你想看看這個文章: 如何讓 TinyMCE 在 UpdatePanel 中工作?

確保init使用scriptmanager

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

引用自:https://stackoverflow.com/questions/2821042