帶有 AJAX(更新面板)的 TinyMCE 永遠不會有價值
我想將富文本編輯器用於更新面板內的文本區域。
我通過這個問題找到了這篇文章: 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 一起使用的人:
- 將開始/結束處理程序附加到 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); } });
- 當使用者從 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使用scriptmanagerScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), mce.ClientID, "pageLoad();", true);