CKEditor for jQuery

Posted by tobiasz.cudnik

The new jQuery Adapter is our first integration effort for popular JavaScript libraries. We're proposing features tightly integrated with jQuery, while not introducing too many new methods to it. This article illustrates it, including some sample code snippets.

Creating editor instances

To create editor instances, other than the usual CKEditor core script, you need to load the jQuery Adapter file in the page, in the following order:

<script type="text/javascript" src="/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="/ckeditor/adapters/jquery.js"></script>

At this point, any textarea, p or div element can be transformed into a rich text editor by simply using the ckeditor() method:

$( 'textarea.editor' ).ckeditor();

jQuery chaining can also be used:

$( '.section-x' )
    .find( 'textarea.editor' )
        .ckeditor()
    .end()
    .find( 'a' )
        .addClass( 'mylink' )
    .end();

The ckeditor() is the main method in the jQuery adapter. It accepts two optional parameters:

  1. A callback function to be execute when the editor is ready;
  2. Configuration options specific to the created editor instance.

The configurations options are passed through a simple object containing properties, each one related to a specific editor setting.

$('.jquery_ckeditor')
    .ckeditor( function() { /* callback code */ }, { skin : 'office2003' } );

The "this" reference inside the callback function points to the the CKEDITOR.editor object representing the editor instance.

Code interaction with editor instances

As soon as an editor instance is ready (after the above callback call), the ckeditorGet() method can then be used to retrieve a CKEDITOR.editor object that represents an editor instance. For example:

var editor = $('.jquery_ckeditor').ckeditorGet();
alert( editor.checkDirty() );

Because setting and retrieving the editor data is a common operation, the jQuery Adapter also provides the dedicated val() method:

// Get the editor data.
var data = $( 'textarea.editor' ).val();
// Set the editor data.
$( 'textarea.editor' ).val( 'my new content' );

This feature can be disabled by setting CKEDITOR.config.jqueryOverrideVal to false, before loading the adapter code.

For textareas, the editor will automatically return it's content back to the form when it is submitted. CKEditor also works with the official jQuery Form Plugin for AJAX based forms. It doesn't require anything from the developer side.

Events handling

Although CKEditor uses its own event system, there are four main events which we're exposing to the jQuery event system. All events use the event namespace, which is simply named ".ckeditor".

The following events are available:

  • instanceReady.ckeditor: fired when the editor is created, but before any callback being passed to the ckeditor() method.
  • setData.ckeditor: fired when data is set into the editor.
  • getData.ckeditor: fired when data is fetched from the editor. The current editor data is also passed in the arguments.
  • destroy.ckeditor: fired when the editor gets destroyed. It can be used, for example, to execute some cleanup on the page.

The editor instance is always passed as the first data argument for the listener. Both getData and setData are often used internally so listening to them should be done with care.

jQuery events DO bubble up through the DOM, so they can be listened selectively on certain parts of the document.

Feedback

Share your thoughts about our very first adapter. What's the best feature? What's missing? Which other adapters should we work on? Stay in touch!

  1. zbrong's picture

    zbrong

    Reply

    very good,I blive it a good one ,evry one will like it.

    thank u.

  2. ajpiano's picture

    ajpiano

    Reply

    There's no real need for a public ckEditorGet method.  You can just tell users to access the full underlying instance by storing it in .data("ckeditor") 

    var editor = $("textarea").ckeditor().data("ckeditor");

    •  

      Right, there's no need for ckeditorGet() although it's more intuitive and easier to document, so we've decided to provide it as the second one.

      Now you can get to editor instance binded to element by using .data( 'ckeditorInstance' ). Although running it right after ckeditor() method most probably will end in error.

  3. Patrick's picture

    Patrick

    Reply

    The jQuery feature is really good, but

    - I couldn't make the "CKEDITOR_BASEPATH" and "CKEDITOR_GETURL" function definition to work : they seem to be ignored.

    - A missing feature is a function definition on the "save" event to do ajax post
    could be  : .ckeditor( function() { /* callback */ }, { <param>}, function(data){/* code to manage data with ajax*/} )

    •  

      Such things as CKEDITOR_BASEPATH are not touched by adapter at all, but generally you have to set it before loading CKEditor.

      What "save" function you have on mind ?

  4. I have a textarea with a complex name ie.

    <textarea id="editor" name="edit[editor]">{$edit.text}</textarea>

    and I use jQuery Form Plugin, the content of the ckeditor is not being passed to PHP:

    $("#zapisz").click(function(){
      $("form:first").ajaxSubmit();
    });

    unless I do it manually:

    $("#zapisz").click(function(){
    $("#editor").text($("#editor").val());
      $("form:first").ajaxSubmit();
    });

  5. Hi.

    Someone can tell me if is possible to paste text without the original style, or better, I need only to preserve the CSS font established in the general site declaration....

     

    Thanks a lot.

  6. Conar's picture

    Conar

    Reply

    what about adding the CKfinder into this editor instance?  How would you pass the CKFinder.SetupCKEditor function?

    • Conar's picture

      Conar

      Reply

      what about adding the CKfinder into this editor instance?  How would you pass the CKFinder.SetupCKEditor function?

    • There shouldn't be any change for CKFinder integration. You can still do it in 2 ways:

      1. Pass existing instance when it's available. Eg:

      $( 'textarea.editor' ).ckeditor( function()
      {
        CKFinder.SetupCKEditor( this );
      });

      2. Just use SetupCKEditor without passing editor instance, then it will be automatically attached to every new one (using CKEditor event system).

      • Jason's picture

        Jason

        Reply

        When I use this, I receive an error: TypeError: Result of expression 'CKFinder.SetupCKEditor' [undefined] is not a function.

        I've confirmed that ckfinder.js is loaded. I'm using the jquery adapter and jQuery 1.4.2.

        here's the code I'm using:

         

        childElement

          .fadeIn('240')

          .find('textarea.wysiwyg')

          .ckeditor(function(){CKFinder.SetupCKEditor();},

          {

            toolbar: 'Designer'

          });

         

        "childElement" is a var and is working great until I add the CKFinder call

         

        Any ideas?

        • Micah's picture

          Micah

          Reply

          Like Jason posted last June, I'm having the exact same problem

          $('#editor')
                  .ckeditor(function() { CKFinder.SetupCKEditor(this,'/ckfinder/' ); },
                                                 { skin : 'office2003'  }
                                );   

          throws the error "CKFinder.SetupCKEditor is not a function"

          The CKEditor instance loads but doesn't include CKFinder.  I even get the problem when not trying to include it in CKEditor...

          $('button').click(function(){
            CKFinder.popup()
          });

          tells me that "CKFinder.popup is not a function"

          This is driving me nuts.  And it works find if I don't use jQuery to load Finder.

          Anyone have any idea what I'm missing?

          • Miach's picture

            Miach

            Reply

            apparently between version 1.x and 2.0, the function named changed from:

            "SetupCKEditor" to "setupCKEditor" (with a lowercase 's')

            Works for me now!

  7.  I've tried using the editor with JQuery 1.4, but it will not work. I can only get it to work using the online googleapis include. Also while typing this message if i try to past text its placed at the beginning of the file ?

     

    Here is the code that works:

     

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>

    <script type="text/javascript" src="../ckeditor.js"></script>

    <script type="text/javascript" src="../adapters/jquery.js"></script>

     

    But this does not:

     

    <script src="../../javascript/jquery-1.4.js" type="text/javascript" charset="utf-8"></script>

    <script type="text/javascript" src="../ckeditor.js"></script>

    <script type="text/javascript" src="../adapters/jquery.js"></script>

     

    However normal JQuery slectors do work like this:

      

     $('*[required]').addClass('test');

     

     

     

           

  8. Anonymous's picture

    Anonymous

    Reply

    The editor is really coool! I can understand the time and effort you guys have put to develop this, its really tremendous..

    But one simple question i want to ask your team.. Why cant your team consider a least for the documentation. In the above documentation, it is said

    "As soon as an editor instance is ready (after the above callback call), the ckeditorGet() method can then be used to retrieve a CKEDITOR.editor object that represents an editor instance. For example:

    Your code goes here

    "

    But how will a user know the callback function is completed and the editor instance is ready to acccess? As simple as where and when i should call a property on editor instance like, editor.checkDirty() ????

    I feel you guys need to give some importance to documentation too..a developer looking for a quick integration may get pissed off with this docos...you may loose some to TInyMCE..

    Anyways, i like the editor so much and prefer using it....

    • You should use callback always when there's the POSSIBILITY of editor not being ready. Mostly it's up to you to know your code and what's happening when. For eg in multi-step form, in 5th step when editor is instanced in 2nd, it's almost sure that editor IS ready then. On the other hand, when everything is binded to onDocumentReady, you should use callback.

      You can use callback even on existing editors and have them as many as you need to.

      Checking if editor is ready is not so useful information, because you shouldn't write 2 versions of the same code. Although you can check if editor is ready like this:

      $el.data( 'ckeditorInstance' ) && ! $el.data( '_ckeditorInstanceLock' )

      You are also able to know when editor get's instanced using:

      $el.bind( 'instanceReady.ckeditor', function( el ) { alert( this.name ) } )

  9. Louis-Philippe Huberdeau's picture

    Louis-Philippe Huberdeau

    Reply

    I just made an attempt to upgrade from CKEditor 3.0 using the jquery plugin that was in development at the time to 3.1 and the bundled plug-in. I used to have layout issues and those are now fixed, which is very nice.

    I initially came across an issue with not being able to instanciate multiple editors in the same page, or the same one multiple times for that matter. Turns out the problem was that my textarea elements did not have an id, which CKEditor seems to be using to manage the instances internally. Generating unique ids solved the issue.

    The lack of error reporting made the issue hard to diagnose. There were no indications in the error console or FireBug.

    So far, I am very satisfied with this release. My only suggestion would be to either make sure the id is generated on the fly if not present or a warning be reported.

  10. Jack Kerouac's picture

    Jack Kerouac

    Reply

    Works great by itself, but does not work with CKFinder integreation.

    • dima117's picture

      dima117

      Reply

       

      I use this code and it works

      $('.jquery_ckeditor').ckeditor(config);

      var editor = $('.jquery_ckeditor').ckeditorGet();

      CKFinder.SetupCKEditor(editor, '../../');

      CKFinder.SetupCKEditor(editor, '../../');

      • Anonymous's picture

        Anonymous

        Reply

        Thank you. That was really helpful for me.

  11. Matthew's picture

    Matthew

    Reply

    Im still playing around with the ckeditor.  I cant figure out how when i click the save icon, it submits the form but when i look at the form data on the server side, the form field is empty.

    Im looking at doing it via ajax and jquery, but i havent been successful in preventing the form to be submitted when you click on the save icon.

    Any help is appreciated!

  12. Anonymous's picture

    Anonymous

    Reply

    as your steps my codes cann't execute as longer.

    in step 2,it indicates object cannot  support this property or methd.

    can  you give me some completely executalbe codes  using jquery to me?

    best to sent to my e-mail!

    Thank you!

  13. CooPs's picture

    CooPs

    Reply

    ...as I couldn't get the .val() function to read data from my ckeditor instance correctly. I could neither get the editor instance using .ckeditorGet(). The problem was the fact that I used CKEDITOR.replace to initialize the editor. Apparently this method is not compatible with the jQuery way outlined above. If it's not impossible to make theese initialization ways compatible, you guys should really fix this. Thanks.

  14. Charles Potty's picture

    Charles Potty

    Reply

    Great tutorial, easy to follow and shows a good example of the callback function, was looking for something like this to use in a project.

    Regards,
    Charles Potty

  15. Brett's picture

    Brett

    Reply

    Please help :)

    I'm interested in loading a JQUERY plugin that affects the text IN the editor. The actual loading of the JQUERY Plugin would preferably happen outside the editor in the main window.

    I'm interested in runing qTIP: http://craigsworks.com/projects/qtip/

    And having qTIP take note of matched in the actual editor... Any ideas?

    Thank you!

  16. Anonymous's picture

    Anonymous

    Reply

    Unable to see the upload tab in the downloaded sample of ckeditor, which is there in the demo.

  17. Johnny Q's picture

    Johnny Q

    Reply

    When using the jQuery adapter and ckeditor() method instead of CKEDITOR.replace(), the config.htmlEncodeOutput = true set in config.js seems to be ignored. I tried specifying the setting with the method like this: $('#textarea').ckeditor(function() { }, { htmlEncodeOutput : true }), but still no go. Any idea how to work around this?

  18. Johnny Q.'s picture

    Johnny Q.

    Reply

    Looks like the problem is only when I hit the save button embedded in the editor. If I have another submit button and press that, it works and the encoding is preserved.

  19. Anonymous's picture

    Anonymous

    Reply

    Hello Everyone,

    Please anyone can help me.In my ckeditor when i am going to save this code

    "<a href="javascript:OpenPageFancyBox('example.php', 665, 525);">Request Info</a>" then editor will remove it and i have checked it at ckeditor demo it is working.

    So can any buddy can tell me what is the reason and how to fix it.Really any kind of help is very important for me.

    Thankyou

  20. Anonymous's picture

    Anonymous

    Reply

    User jquery ,How to insert html to the editor ?

  21. Ron Balthazor's picture

    Ron Balthazor

    Reply

    Very happy with the jquery/ckeditor marriage, but I have one problem:  the jquery ajaxSubmit after a paste from Word in the gui fails in FF (works fine in Chrome).  When using "forcePasteAsPlainText : true" the ajaxSubmit works in all browsers.  Any advise is welcome.

    • Ron Balthazor's picture

      Ron Balthazor

      Reply

      Very happy with the jquery/ckeditor marriage, but I have one problem:  the jquery ajaxSubmit after a paste from Word in the gui fails in FF (works fine in Chrome).  When using "forcePasteAsPlainText : true" the ajaxSubmit works in all browsers.  Any advise is welcome.

  22. hughm's picture

    hughm

    Reply

    I'm attempting to get this working on a page that also uses jQuery UI plugins (I have tried running the ckeditor/jquery adapter withUI plugin disabled with same results).

    Loading the googleapis/1/jquery.js plus the ckeditor.js and adapters/jquery.js then initialising as:

    //<![CDATA[
    $(function(){

    var config = {

    toolbar:

    [

     ['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', 'Table', '-', 'Link', 'Unlink'],  ['UIColor']

    ]

    };

    $('.jquery_ckeditor').ckeditor(config);

    });
    //]]>

     

    Viewing the DOM source of the page shows that the textarea is having style="visibility:hidden;" added to it, but nothing else happens. The textarea does have a class of jquery_ckeditor and another textarea on the page is unaffected and available.

    What have I missed?

    The UI plugin 'datepicker' is fully functional when the page is loaded as I would like it to be used rt.

    ?

  23. Anonymous's picture

    Anonymous

    Reply

    Hello

    I try to do this:

    $editor = $('textarea.editor).ckeditor();

    $editor.updateElement();

    but fails :(

    implementation of this function updateElement()  is in the adaptation of jquery?

  24. Anonymous's picture

    Anonymous

    Reply

    Save plugin / button apparently does not work with the jQuery wrapper as of 6/21/10. Just a warning so no one loses as much time as I did. 

  25. Anonymous's picture

    Anonymous

    Reply

    how to destroy ckeditor instances

    i did something like

    $('.saveMe').click(function(){
        $('#editorcontents').destroy().ckeditor();

    })

    $('.saveMe').click(function(){
        $('#editorcontents').destroy.ckeditor;

    })
     

    no luck

    any ideas

    the above examples are short and unclear on that point

    • Anonymous's picture

      Anonymous

      Reply

      in reply to my own q

      from
      http://dev.ckeditor.com/ticket/4210

      // remove editor from the page
      $('textarea').ckeditor(function(){
      this.destroy();
      });

  26. Wesley's picture

    Wesley

    Reply

    I'm really struggling to get protected tags working in the jQuery implementation.  I have only one page on my site that's using the jQuery adapter and all of the other pages that aren't using it are working fine.

    I need the CKEditor to protect <script></script> <style></style> and <? ?>, which it's doing fine on the other pages.  I have the PHP and style tags protected in config.js and of course script tags are protected by default.

    The jQuery implementation seems to be ignoring the protectedSource in config.js or something else is going on that I'm not aware of.  It's not ignoring anything else in config.js which makes me think that the problem is elsewhere.  When I put the following into the editor and click save it's stored in the database, and then when the page reloads the script is no longer in the source.

    <script type="text/javascript" src="http://livebusinessonline.com/api/adserver.js?c=1"></script>

     

     

    I've tried adding the following:

    config = {

        protectedSource : /<script[\s\S]*?<\/script>/gi

      };

    $('.jquery_ckeditor').ckeditor(config);

     

    And that didn't solve anything.  Putting the protected source into an array didn't work either.

    protectedSource : new Array(/<script[\s\S]*?<\/script>/gi)

     

    I appreciate all the help I can get on this!

      • Wesley's picture

        Wesley

        Reply

        Thanks for your quick reply.  I figured that was the wrong syntax but was hoping that since the jquery adapter is not well documented it might work.  Also, I mentioned in my post that I understand script tags are automatically protected.  Like I said, on my other pages that use ckeditor, that aren't using the jquery adapter, I have no problems at all.  the protectedSource.push() is working great for PHP and style tags, and ckeditor is automatically protecting script tags as it should.  My main problem is that when I put script tags into the editor on the page that's using the jquery adapter, they are saved in the database when I click save, and they are not in the source when the page reloads.  Somehow the editor is stripping them from the source prior to rendering it - sort of.  If I put in <script>alert('1');</script> and save the page it executes the alert statement (is it supposed to do that?); however, when I view source, the script tags are not there.  It's working fine for <style></style>, <??>, and <link /> which is great.  I just need to know why the script tags have been stripped and how to get them back.  Like I mentioned in my first post, it acts like a protectedSource problem is some ways, and yet since the other tags that are protected are still working, I'm really at a loss to explain it...

        • Wesley's picture

          Wesley

          Reply

          This turns out to have nothing to do with ckeditor or the jquery adapter...  Hopefully the hours I lost to this will help somebody else.  I use the phpLiveX ajax library and was using that to load the editor content.  It finally dawned on me to turn off the ckeditor and see what was in the textarea and that's when I realized that it was the ajax lib - not the jquery adapter - that was causing this problem.  I have no clue why and google didn't turn up any answers.  I was able to get around the problem by using jquery .ajax and adding some new php code to detect the ajax call ($_GET).  It's not nearly as elegant as phpLiveX, but it gets the job done.

  27. kaffesump's picture

    kaffesump

    Reply

    In my opinion, it would be nice to add the other events that are available too. In my application I would have preferred to be able to rewrite "CKEDITOR.on( 'dialogDefinition', function( ev ) {" that line of code to jQuery, but there are most likely more events that would be useful to do the jQuery way.

    Thanks for a great tool!

  28. Jigar's picture

    Jigar

    Reply

    Hi friends, In my web page, I use ckeditor. When a user wants to embed an image in the editor, he has to click the image uploader -> Browse Server ->select the image ->double click on it-> and then click ok.

    This is the procedure that is normally followed.

    What I want to do is when a user wants to embed an image, he clicks on the image uploader button->Browse Server and just drag and drop the image on the ckeditor, which he wishes to embed in his content. This should embed the image in the content.

    Can anyone help me out in achieving this??

  29. Matt L's picture

    Matt L

    Reply

    Hello everyone,

    I'm trying to get the latest version of CKEditor to work on my site by following all the directions (what directions their are) and attempting to understand them all, but because my experience mostly is with ColdFusion I fail to yet 100% grasp some simple things in other languages (like jQuery)

    On top of things this new version on CKEditor is totally different then the older FCKEditor I used in the past.  I'm having two issues:

    First issue is an easy one, I'm just not making the connection(s) I'm sure.  I'm able to bring up the editor, write to it, press the save icon button and display the text from the form value.  But, if I bring the editor up again the default value is still in it.  This could be simple because I'm not pulling the value I just submitted so this may be some elementary answer.  I'm just not seeing it and I've tried so many different ways, I'm at a loss.

    Ref: https://meded-portal-dev.ucsd.edu/test-CKEditor.cfm (to see the page i'm working on)

    Code Below:

    <script src="/tools/js/jquery/jquery-1.3.2.js" type="text/javascript"></script>
    <script src="/tools/js/jquery/jquery.form.js" type="text/javascript"></script>
    <!--- FCKEditor Insert(s) to run the editor tool along with their tools --->
    <script type="text/javascript" src="/core_cure/scripts/jquery/jquery.form.js"></script>  
    <script type="text/javascript" src="/tools/CKeditor/ckeditor.js"></script>
    <script type="text/javascript" src="/tools/CKeditor/adapters/jquery.js"></script>
    <link type="text/css" href="/core_cure/styles/isc.css" rel="stylesheet"/>

    <script type="text/javascript">
        var $j = jQuery.noConflict();
        $j(document).ready(function(){
            // bind 'myForm' and provide a simple callback function
      $j('#frmWebText').ajaxForm(function() {
        alert("Thank you for your comment!");
      });
        });

       .ckeditor( function() { /* callback code */ }, { skin : 'office2003' } );
               
    </script>
    <cfoutput>
        <div class="textBody">
        <br />
        <input type='button' id='editPage' class='calendar-button button' value='Edit This Page' />
       <div id="pageWebText" style="display:none;">
        <cfform id="frmWebText" action="#cgi.HTTP_REFERER#" method="post">
            <span style="float:right;">
           <input type='button' id='updatePage' class='calendar-button button' style="margin-right:80px;" value='Save' onclick='javascript:updateWebText("edit");'  />
         </span>

            <h3>Body:</h3>
         <textarea id="WebTextBody" name="WebTextBody" class="ckWebTextBody" style="width:100%;height:300px;">
             Howdy!
         </textarea>
           </cfform>
       </div>  

                <script type="text/javascript">
                    $j("##editPage").click(function () {
                        $j("##pageWebText").show("slow");
                        $j("##WebTextBody").ckeditor();
                    });
                   
                    // This will expand the ckeditor window as long as the text will be.  If you want the window to stop growing and return to having a scroll bar use the following:
                    // ,autoGrow_maxHeight : 400 (or whatever height you desire) after autogrow.
                    //<![CDATA[
                    CKEDITOR.replace('WebTextBody', {

                        extraPlugins : 'autogrow'
                    });
                    // Deletes instance of CKEditor
        var o=CKEDITOR.instances['WebTextBody'];
        if (o) o.destroy();
                    //]]>
       </script>

    Thank you in advance!

    My second issue is dealing with getitng the link, image, file browsing to work.  I'll leave it for now since I have to get this to work first.

  30. Hello,

    Is it at all possible to have a page that is already loaded, and using a link or button, create a text field with the CKEditor? I can get the field to be dynamically created using jquery. But haven't been successful with creating an instance of CKEditor to it. Right now it looks like my option is going to be reloading the page each time a new instance of the editor is needed on the page.

    Any help will be greatly appreciated before I have to do the reload option.

    Thanks,
    Marc

    • arvind's picture

      arvind

      Reply

      Marc, i have a similar problem. I use jquery to integrate ckeditor but i havent found a way to initialize ckeditor dynamically (AJAX calls for example) any help is greatly appreciated

  31. Andrea's picture

    Andrea

    Reply

    Thank you very mutch for your work!!!