views:

738

answers:

4

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-rich-text-editors via this question: http://stackoverflow.com/questions/1207382/need-asp-net-mvc-rich-text-editor

Decided to go with TinyMCE as I used it before in non AJAX situations, and it says in that list it is AJAX compatible. Alright I do the good ol' tinyMCE.init({ //settings here }); Test it out and it disappears after doing a update panel update. I figure out from a question on here that it should be in the page_load function so it gets run even on async postbacks. Alright do that and the panel stays. However, upon trying to submit the value from my textarea, the text of it always comes back as empty because my form validator always says "You must enter a description" even when I enter text into it. This happens the first time the page loads and after async postbacks have been done to the page.

Alright I find this http://www.dallasjclark.com/using-tinymce-with-ajax/ and http://stackoverflow.com/questions/699615/cant-post-twice-from-the-same-ajax-tinymce-textarea. I try to add this code into my page load function right after the tinyMCE.init. Doing this breaks all my jquery being called also in the page_load after it, and it still has the same problem.

I am still pretty beginner to client side scripting stuff, so maybe I need to put the code in a different spot than page_load? Not sure the posts I linked weren't very clue on where to put that code.

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

Now my current code doesn't have the tinyMCE.execCommand("mceAddControl",true,'content'); which that one question indicated should also be added. I did try adding it but, again, wasn't sure where to put it and just putting it in the page_load seemed to have no effect.

Textbox control:

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

How can I get these values so that the code behind can actually get what is typed in the textarea and my validator won't come up as saying it's empty? Even after async postbacks, since I have multiple buttons on the form that update it prior to actual submission.

Thanks!

Edit: For further clarification I have form validation on the back-end like so:

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

And this error will always cause the error message to be dispalyed.

Edit:

Alright I am getting desperate here, I have spent hours on this. I finally found what I thought to be a winner on experts exchange which states the following (there was a part about encoding the value in xml, but I skipped that): http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_25059848.html

For anyone who wants to use tinyMCE with AJAX.Net:

  1. Append begin/end handlers to the AJAX Request object. These will remove the tinyMCE control before sending the data (begin), and it will recreate the tinyMCE control (end):

    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);
          }
       });
    
  2. When the user changes/blurs from the tinyMCE control, we want to ensure that the textarea/textbox gets updated properly:

       ed.onChange.add(function(ed, l) {
           tinyMCE.triggerSave(true, true);
     });
    

Now I have tried this code putting it in its own script tag, putting the begin and end requests into their own script tags and putting the ed.onChange in the page_load, putting everything in the page_load, and putting all 3 in it's own script tag. In all cases it never worked, and even sometimes broke the jquery that is also in my page_load... (and yes I changed the above code to fit my page)

Can anyone get this to work or offer a solution?

The code

+2  A: 

I think you want to look at this posting: http://stackoverflow.com/questions/547327/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);
Glennular
I've seen that thread and I've done that, if you read the answer below the marked answer, it says you can either register the start-up script or put it into the page_load JavaScript function. I chose the latter and it works because I am not having the same problem that person had. That person loses the control after the post-back, I don't have that problem, my problem is that even before a single postback (and after) when I fill out the textarea and try to submit, it is telling me tbDescription.text is empty.
sah302
A: 

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.

sah302
A: 

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.

Jonathan S.
A: 

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.

BrunoLM