TinyMCE with AJAX (Update Panel) never has a value

后端 未结 5 556
-上瘾入骨i
-上瘾入骨i 2021-01-11 14:37

I wanted to use a Rich Text Editor for a text area inside an update panel.

I found this post: http://www.queness.com/post/212/10-jquery-and-non-jquery-javascript-ric

相关标签:
5条回答
  • 2021-01-11 14:59

    You have to trigger the save function when posting back, use Page.RegisterOnSubmitStatement to register the script tinyMCE.triggerSave();

    I noticed that tinyMCE's init function can only be called selecting all textareas or textareas with a certain class. The exact doesn't work.

    0 讨论(0)
  • 2021-01-11 15:00

    Well there were two ways I got this to work, which really didn't fix the problem just avoid it.

    One was to use the FCKeditor .net control, this reloaded horribly slow though for me, like 2-3 seconds. So I decided to just make the form have two update panels, and put the text area in between then, essentially taking the text area out of the update panel. This felt kind of like a cheap trick that shouldn't be necessary, but it works fine. None of the solutions or suggestions anyone posted worked for me so that is what I did. If I HAD to put the text area into the update panel though, this wouldn't have worked.

    0 讨论(0)
  • 2021-01-11 15:05

    One thing that I ran into when putting TinyMCE in an update panel was that I had to do all sorts of tricks to make it work right. Keep in mind how the update panel works, when you want to refresh it, it completely replaces the DOM inside of it, including the TinyMCE.

    The workaround that I used was to remove the TinyMCE from the update panel and wrap anything else that needed to dynamically refresh in an update panel. I would then add data to TinyMCE via the javascript API it provides if I needed the TinyMCE content to be dynamic.

    0 讨论(0)
  • 2021-01-11 15:07

    I'd just like to add my solution to this post, as I had been wrestling with the same issue for a couple days. I realise this is an old post, but maybe my answer will help someone, since I believe the question is still relevant.

    I'm developing an ASP.NET web forms application, and one of the pages has a textarea control contained within an UpdatePanel. tinyMCE binds to this textarea. Text for the textarea comes from a bound textbox within a repeater control, because I want to get the text from an ObjectDataSource control, and this is a slightly cludgey way of doing that. To my mind, ObjectDataSource controls are convenient and they execute quickly.

    Here is my markup containing the ObjectDataSource control, the repeater, the bound textbox, and the textarea (an asp:TextBox set to multiline). Note that the bound textbox is set to "display: none":

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

    I also have an asp:Button to save text in tinyMCE to SQL Server. All of these controls are contained within an UpdatePanel.

    I have placed all of my jQuery and JavaScript code in a separate file. I include the relevant bits below. As an overview:

    • I initialise tinyMCE in the JavaScript pageLoad event. Note that this event fires for full and partial (async) postbacks, so tinyMCE is always displayed and doesn't disappear between full or partial postbacks.

    • Also in the pageLoad event, if a postback is async, I begin listening for a BeginRequest event raised by the ASP.NET PageRequestManager. I stop listening for the BeginRequest event in the JavaScript pageUnload event. This prevents more and more listeners being added each time pageLoad fires.

    • When the event handler for the BeginRequest event fires (when the Save button on my page is clicked), I get the HTML contents of the tinyMCE text editor and save it to a cookie. I use the jQuery cookie plugin to do this: https://github.com/carhartl/jquery-cookie. The HTML is encoded in the cookie, for safety.

    • Now, in the server code that executes when the Save button is clicked, the cookie's text (which is encoded HTML) is retrieved and saved to SQL server. The cookie is now deleted.

    • ASP.NET binds the saved data to the hidden textobx via the ObjectDataSource control, the textarea control's value is set to the hidden textbox's, and the portion of the page within the UpdatePanel is rendered back to the browser.

    • tinyMCE now displays this text from the textarea, but it is encoded HTML and not human readable.

    • So, in the JavaScript pageLoad event, I format the tinyMCE text by decoding the HTML.

    • Job done!

    Here are the relevant parts of my script file:

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

    Here is a portion of the server code that fires when the Save button is clicked:

    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
    

    Hope this helps someone.

    0 讨论(0)
  • 2021-01-11 15:17

    I think you want to look at this posting: How to make TinyMCE work inside an UpdatePanel?

    Make sure to register you init function with the scriptmanager

    ScriptManager.RegisterStartupScript(this.Page, 
             this.Page.GetType(), mce.ClientID, "pageLoad();", true);
    
    0 讨论(0)
提交回复
热议问题