jQuery - Single RadEditor For Multiple Editable Bodies On Page

12 posts, 0 answers
  1. Debbie Roberts
    Debbie Roberts avatar
    18 posts
    Member since:
    Apr 2009

    Posted 25 Mar 2010 Link to this post

    I have written this jQuery code that allows a single RadEditor instance to be used to edit multiple different editable areas (editable bodies)  on the same page. It is very efficient and vastly improves page loading time but there are a few problems that I am unable to resolve and I hope you may be able to help.

    To use the jQuery code, the markup on the page needs to be similar to this:

    <div class="SKEditorWrapper">  
        <telerik:RadEditor using PageTop Toolbar goes here/> 
    </div> 
     
    <div id="BodyBlockPanel1" class="SKEditableBody">  
        <textarea name="BodyBlockHTML1" rows="2" cols="20" id="BodyBlockHTML1" class="SKEditableBodyText" style="display:none;">  
            This is editable body 1.  
        </textarea> 
    </div> 
     
    <div id="BodyBlockPanel2" class="SKEditableBody">  
        <textarea name="BodyBlockHTML2" rows="2" cols="20" id="BodyBlockHTML2" class="SKEditableBodyText" style="display:none;">  
            This is editable body 2.  
        </textarea> 
    </div> 
     
    <!-- ... and so on. We have 40 editable bodies on our page.--> 

    The jQuery code hides the textareas and inserts a DIV after each of them, to render a WYSIWYG version of the markup. When the user clicks on the DIV, it is replaced with the RadEditor. The RadEditor is used with 'PageTop' toolbar and design mode only, to provide WYSIWYG in-place editing.

    The jQuery code is as follows:

    $(document).ready(function(){  
     
        var $bodyBlock;  
        var $editorBody;  
        var firstEdit = true;  
        var $prevEditableBody = null;  
          
        //Hide the RadEditor and its wrapper.  
        $('SKEditorWrapper').hide();  
        var $radEditor = $('div.RadEditor').hide();  
          
        var saveEditorContent = function(){  
            //Copy the content from the RadEditor back into the TextArea.  
            var editor = $find($radEditor.attr('id'));  
            var edContent = editor.get_html('true');  
            $prevEditableBody  
                .find('.SKEditableBodyText')  
                .val(edContent);  
        };  
     
        var moveEditorToBody = function(event){  
          
            var $editorPanel = $('.SKEditorWrapper');  
            var $editableBody = $(this);  
              
            //Switch off the mouse-over styling on all editable bodies on the page.  
            $('.SKEditableBody')  
                .removeClass('SKEditableBodyHighlight');  
     
            //Attach highlighter class and mousout handlers to transfer editor content  
            //to TextArea when the user clicks 'save'.              
            $editableBody  
                .addClass('SKEditableBodyHighlight')  
                .unbind('mouseenter mouseleave')  
                .mouseleave(saveEditorContent)  
                .blur(saveEditorContent);  
     
            //Remove the RadEditor from its current position in the DOM, replace  
            //it with a DIV to render the markup and copy the editor content into  
            //the TextArea ready for AJAX postback.              
            if (firstEdit){  
                firstEdit = false;  
                $editorPanel.remove();  
            }  
            else {  
                var editor = $find($radEditor.attr('id'));  
                var edContent = editor.get_html('true');  
                $('<div/>')  
                    .addClass('SKEditableBodyBlockContent')  
                    .html(edContent)  
                    .replaceAll($editorPanel);  
                saveEditorContent();  
            }  
     
            //Insert the RadEditor into its new position in the DOM, i.e. in the  
            //editable body the user clicked on.  
            $editableBody.append($editorPanel);  
              
            //Find the DIV showing the rendered markup of this editable body and  
            //replace it with the RadEditor.  
            var editor = $find($radEditor.attr('id'));  
            $bodyBlock = $(event.target).closest('.SKEditableBodyBlockContent');  
            editor.set_html($bodyBlock.html());  
            var editorBody = document.all ? editor.get_document().body : editor.get_document();  
            $editorBody = $(editorBody);  
            $bodyBlock.remove();  
     
            //Show the RadEditor and its wrapper.  
            $editorPanel.show();  
            $radEditor.show();  
              
            //Delay a short time and then apply focus to editor to cause text cursor  
            //to be displayed in the RadEditor.  
            setTimeout(function(){  
                editor.setFocus();  
            },200);  
              
            //Prevent the click event from activating any links from anchor tags in the  
            //editable body.  
            event.preventDefault();  
              
            //Re-Attach click and hover handlers to the editable body that was being  
            //edited previously.  
            if ($prevEditableBody){  
                $prevEditableBody  
                    .one('click', moveEditorToBody)  
                    .unbind('mouseenter mouseleave')  
                    .hover(function(){  
                        $(this).addClass('SKEditableBodyHighlight');  
                    }, function(){  
                        $(this).removeClass('SKEditableBodyHighlight');  
                });  
            }  
            $prevEditableBody = $editableBody;  
     
        };  
          
        //Find the TextAreas for every editable body, hide them and insert a  
        //DIV to show their rendered markup.  
        $('.SKEditableBodyText').each(function(index){  
            $(this).hide();  
            $('<div/>')  
                .addClass('SKEditableBodyBlockContent')  
                .html($(this).val())  
                .insertAfter($(this));  
        });  
     
        //Make the editable bodies editable, using single RadEditor, when the user  
        //clicks them and attach mouse-overs to indicate which bodies are editable.  
        $('.SKEditableBody')  
            .one('click', moveEditorToBody)  
            .hover(function(){  
                $(this).addClass('SKEditableBodyHighlight');  
            }, function(){  
                $(this).removeClass('SKEditableBodyHighlight');  
            });  
     
    }); 

    The problems are:

    1. In IE/Chrome, after an editable body is clicked, the user has to click again before the text insert caret and toolbar will show. Is there a way to make these appear as soon as the user clicks on the editable DIV.
    2. In Firefox, the text insert caret never shows, no matter how many times the user clicks. Sadly, this makes it unusable in Firefox, although if the user enters text it does go into the correct position in the RadEditor. How can I cause the text insert caret to appear in Firefox?

    I hope you can help, as this would be a very efficient solution to the problem of having multiple editable areas on a single page.

  2. Dobromir
    Admin
    Dobromir avatar
    1633 posts

    Posted 29 Mar 2010 Link to this post

    Hi Debbie,

    There is a known issue with RadEditor when moving within the DOM, which applies to the explained scenario. In order to fix this, you need to execute RadEditor's onParentNodeChanged() client method right after appending the RadEditor, e.g.:
    ......
    $editableBody.append($editorPanel);
    //need to be executed after moving editor inside the DOM
    var editor = $find($radEditor.attr('id'));
    editor.onParentNodeChanged();
    ......

    In addition, I suggest to check the following KB article where the functionality that you tried to implement is achieved by using a different approach:
    Setting hidden RadEditor in edit mode on click and putting it in non editable mode onblur

    Sincerely yours,
    Dobromir
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  3. Debbie Roberts
    Debbie Roberts avatar
    18 posts
    Member since:
    Apr 2009

    Posted 30 Mar 2010 Link to this post

    Thank you, Dobromir,

     

    Your suggested solution fixes my first problem but it does not solve my second problem. I had already based my jQuery code on your KB article that you mention.

     

    Luckily, I have discovered the solution to the missing text insert caret in Firefox, quite by accident.

     

    Before the RadEditor is moved in DOM in Firefox, the wrapper containing the RadEditor must be hidden. If the editor is moved without hiding the wrapper, the text insert caret will only appear in the first editable block clicked. It will vanish on all subsequent moves of the editor, making the editor unusable.

    The final changes required to make this jQuery code fully cross-browser are as follows:

            //Hide the editor panel. If this is not done here the text insert caret  
            //disappears in Firefox after the 2nd editable body is clicked.  
            $editorPanel.hide();  
     
            //Insert the RadEditor into its new position in the DOM, i.e. in the  
            //editable body the user clicked on.  
            $editableBody.append($editorPanel);  
              
            //Copy the editable body's markup from the textarea into the RadEditor.  
            var editor = $find($radEditor.attr('id'));  
            editor.onParentNodeChanged();  
            var $bodyBlock = $editableBody.find('.SKEditableBodyText');  
            editor.set_html($bodyBlock.val());  
     

    Kindest Regards,

    Debbie
  4. Debbie Roberts
    Debbie Roberts avatar
    18 posts
    Member since:
    Apr 2009

    Posted 31 Mar 2010 Link to this post

    I am still finding a problem that the user needs to click twice on each editable area before the toolbar and text insert caret will appear, although I do now get the text insert caret in Firefox.

    The scenario is as follows:

    1. The user clicks on an editable area (at this stage it is a DIV).
    2. The editor is moved in the DOM OK and is shown, after a short delay, WITHOUT the toolbar and text insert caret.
    3. The user then clicks again, on what is now the actual RadEditor, and now the toolbar shows and the text insert caret appears.

    Is there any way to simulate the effect of the user having clicked the RadEditor after the editor is moved in the DOM?
    Is there a RadEditor method or event that I can fire that will cause the toolbar 'showonfocus' code to execute after moving the RadEditor? I have tried using a timeout and then calling editor.setFocus() but this does not cause the showonfocus code to execute.
    Is there a way to cause the text insert caret to appear?

  5. Dobromir
    Admin
    Dobromir avatar
    1633 posts

    Posted 01 Apr 2010 Link to this post

    Hi Debbie,

    RadEditor does not offer such feature / method, nevertheless you can use the following code sample to simulate the click:
    .......
    editor.onParentNodeChanged();
    setTimeout(function()
    {
        if ($telerik.isIE)
        {
            editor.fire("Enter");
        }
        else
        {
            editor.pasteHtml("");
        }
        editor.undo(1);
    }, 200);

    This feature is logged into our ToDo list and we will do our best to implement it in one of our upcoming releases.

    Greetings,
    Dobromir
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  6. Debbie Roberts
    Debbie Roberts avatar
    18 posts
    Member since:
    Apr 2009

    Posted 12 Apr 2010 Link to this post

    Hi Dobromir,

    Many thanks for your reply. A method that we could call to activate the ShowOnFocus toolbar and the re-sizing off the editor when receiving focus would be a really nice feature in a new release of the Telerik controls suite.

    You suggested solution works very well in Firefox. However, in IE it erases the existing content of the editable block, so it cannot be used. Firefox was the main browser I was having trouble with, so this is very good for Firefox. In IE, it is useable without this fix, so it is OK.

    Debbie
  7. Debbie Roberts
    Debbie Roberts avatar
    18 posts
    Member since:
    Apr 2009

    Posted 26 Apr 2010 Link to this post

    Just for further interest of anyone following this thread, I have discovered a very reliable way of making the RadEditor behave correctly in Firefox after the RadEditor is moved in the DOM. This displays the text insert caret and toolbar correctly after a single click on another editable area. The solution is to do the following after the the RadEditor has been moved and made visible again:

            //Move the focus away from the editor onto the first visible form input field.  
            //If we don't do this, the text insert caret disappears in Firefox when a 2nd  
            //editable body is clicked.  
            $('input:visible').eq(0).trigger('focus');  
     
            //Delay a short time and then apply focus to editor to cause text cursor  
            //to be displayed in the RadEditor.  
            setTimeout(function(){  
                editor.setFocus();  
     
                //This forces the formatting toolbar to appear in Firefox when an editable  
                //body is clicked.  
                if ($telerik.isFirefox){  
                    setTimeout(function(){  
                        editor.pasteHtml("");  
                        editor.undo(1);  
                    }, 200);  
                };  
                  
            },200);  
              
     

    The trick is to switch the focus to another input field before moving the focus back to the RadEditor. This causes the RadEditor gaining focus events to execute correctly.
  8. Misha
    Misha avatar
    4 posts
    Member since:
    Sep 2011

    Posted 16 Sep 2011 Link to this post

    It looks wonderful, but if on save method we send ajax request - all pretty behaviour is broken.
  9. Rumen
    Admin
    Rumen avatar
    14031 posts

    Posted 19 Sep 2011 Link to this post

    Hi Misha,

    Could you please be a bit more specific regarding the exact issue that you experience? Could you please elaborate what do you mean by "all pretty behaviour is broken"?

    Please, also provide a sample working project which demonstrates the problem. Thus we will be able to examine your code, test it and provide a solution.

    Best regards,
    Rumen
    the Telerik team
    Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal
  10. Misha
    Misha avatar
    4 posts
    Member since:
    Sep 2011

    Posted 19 Sep 2011 Link to this post

    http://www.sitefinity.com/devnet/forums/sitefinity-4-x/bugs-issues/radeditor-blur-focus-after-ajax-request.aspx

    "pretty behaviour" - I mean, ShowOnFocus - toolbar of radeditor which appears after user clicks on content area of radeditor.
    after using radajaxmanger.ajaxrequest("something")  and attaching it to any client event - onblur, onkeyup, selection etc.  - content area becomes disabled, tolbars button also get strange behaviour.
  11. Rumen
    Admin
    Rumen avatar
    14031 posts

    Posted 21 Sep 2011 Link to this post

    Hello Misha,

    Try to hide the toolbar when the blur event occurs:

    var tWnd= editor.get_toolAdapter().get_window();
    tWnd.hide();


    Best wishes,
    Rumen
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
  12. Misha
    Misha avatar
    4 posts
    Member since:
    Sep 2011

    Posted 26 Sep 2011 Link to this post

    Hello, please look at
    http://www.sitefinity.com/devnet/forums/sitefinity-4-x/bugs-issues/radeditor-blur-focus-after-ajax-request.aspx
    I posted example and describe issues and bugs with radeditor.
Back to Top