2009/08/30

Creating an instance of CKEditor

This is the second post about CKEditor, be sure to read first the prerequisites to use CKEditor.

As explained in the integration guide you must add the CKEditor library to the head of your document. I would like to add a little remark for the moment: instead of ckeditor.js you can use ckeditor_basic.js if you don't need the features before the page is loaded, it will load only a small stub and delay the full load to make the page ready quicker. I explain this feature in detail here.

So go ahead and add it:

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

Now the CKEDITOR object is ready to be used in your page. This is the entry point for all the CKEditor functionality.

The most common situation is to use a textarea for your content and replace it with CKEditor:

<textarea cols="80" id="editor1" name="editor1" rows="10">
&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://www.fckeditor.net/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;
</textarea>
<script type="text/javascript"> 
  CKEDITOR.replace( 'editor1' ); 
</script>

This approach means that if the user is using an old browser that it's not supported by CKEditor, or they have disabled javascript they will get a plain textarea and they can still use your site.

Ok, so far I haven't said anything interesting, but I think that it's better to start step by step, reviewing what's available before explaining new things. So the next step is to look at the CKEDITOR object.

What about automatically converting the textareas to CKEditors without any javascript (besides the library of course)?

You just need to add the class "ckeditor" to you textareas and you're done! Look at the _samples/replacebyclass.html file.

If you want to the magic to work with other class names then you must use the replaceClass property. This is how your page would look if you have already some textareas with the class "html" and you want to use now CKEditor without any further changes:

<head>
 ...
 <script type="text/javascript" src="/ckeditor/ckeditor.js"></script>
</head>
<body>
<script type="text/javascript"> 
  CKEDITOR.replaceClass = 'html'; 
</script>
...

As you can see, with minimal changes to your existing pages you can use CKEditor.

Other times you might want to use CKEditor in all the textareas of your page, no matter what are their classes. Then replaceAll is your friend. As the replace call, you must use it only after your textarea, or if you must add it in the head of the document, use the document "onload" event (be careful: if you assign directly document.onload other script might want to also use it in the same "stupid" way and will erase your listener, or you could erase that other listener)

In fact, the replaceClass and replaceByClassEnabled is just some syntactic sugar to easily use the replaceAll at page load with a className.

The replaceAll method can be called in three ways:

  • No parameters: All the textareas are replaced
  • A string parameter: Only the textareas that have their class matching that parameter will be replaced
  • A function parameter: This is the most powerful option, each textarea will be passed to that function, along an empty config object that can be used to apply custom configuration options to each instance.

So if you want to replace all the textareas in the page, except those that have a class of "text" or whose id is "summary" you should use this code at the end of the page (or on the onload event):

<script type="text/javascript">
 CKEDITOR.replaceAll( function(textarea, config) {
  if (textarea.className=="text") return false;
  if (textarea.id=="summary") return false;

  return true;
 });
</script>

 Finally there's the appendTo method, but for the moment I can't figure out why that is interesting, so I won't bother to explain it need to study it better to give my impressions about it.

24 comments:

FredCK said...

Hey Alfonso! I'm really enjoying your recent articles about CKEditor.

The appendTo is quite useful if you're building a so called "Ajax like" application, where the UI is built by code on the fly. So, if you need an editor instance, you simply create it inside a container element (with appendTo), destroying it later, instead of creating a textarea and replacing it with an editor instance.

Alfonso said...

I'm glad that you like this.

Yes, I thought that it was related to using it in a dynamic environment, but it's not really clear to me that the method is "useful", I mean, if I pass a div to contain the editor, it's not clear to me how I can specify the name of the editor.

I need to test it and try to create a real example in order to verify it.

Vincent said...

Great tutorials on using the CKeditor instance! Tell me, do you think you will be writing a blog on how to create a custom plugin for CKeditor? That would be most helpful.

Alfonso said...

Yes, I plan to post something about plugins, but I think that it must be done in order.

As FredCK has pointed out there's the appendTo and in general, an explanation about how to create instances on the fly. I've also left out the "delayed loading" feature.

Then the next step would be to cover how to configure the editor, and that can be quite extensive in order to provide detailed explanations about the most common requests and adjustments.

Only then I would start writing about plugins, and that's a big topic, with a plugin you can do anything, so it requires to explain almost every object in order to explain how to work at the full potential.

vwisntead said...

Yup, that's a very good point. There must be a lot of parts involved when making a custom plugin. I look forward to seeing a lot more blogs!

Anonymous said...

I have a simple page which lets me use ckeditor. However, I can't seem to get the javascript portion to work. It will alert with the version but it doesn't recognize any instances. Am I missing something? :
<head>
<title>Sample - CKEditor</title>
<meta content='text/html; charset=utf-8' http-equiv='content-type'/> <script type='text/javascript' src='ckeditor/ckeditor.js'></script>
<script src='ckeditor/_samples/sample.js'
type='text/javascript'></script>
<link href='ckeditor/_samples/sample.css' rel='stylesheet'
type='text/css'/>
</head>
<body>
<textarea class='ckeditor' cols='80' id='editor1' name='editor1'
rows='10'>
blah

</textarea>
<script type="text/javascript">
//alert( CKEDITOR.version );
alert( CKEDITOR.instances.editor1.name );

</script>
</body>

Alfonso said...

You are using the automatic replacement, but it's obvious that you are trying to use the CKEditor instance before the onload event, so that replacement still hasn't happened.

michele said...

hi alfonso,

have you ever experienced the ckeditor disappearing after a partial page refresh (PPR)? however if i refresh the browser, the editor comes back - can i somehow force the page to refresh?

thanks, m

Alfonso said...

Hi Michele.

Sorry but I don't know what's a "partial page refresh".

Just be sure that the javascript is executing and there are no errors in the console

Anonymous said...

Using the third option of replaceAll, how do you pass a config for each instance?

CKEDITOR.replaceAll( function(textarea, config) {
if (textarea.className=="text") return false;
if (textarea.id=="summary") return false;
//configuration????
return true;
});

Alfonso said...

You just need to use the "config" parameter to the function. That's the object that will be used for the current textarea

Anonymous said...

Thank you for your prompt response, I am sorry - I am new to programming and I don't really know a lot of things.

When I try to replace config in the function call with a string, I get a 'missing formal parameter' error.

For example, to set the toolbar : 'Basic' for all instances, how would the syntax be?

I have been through the documentation but it makes no sense to me. Thank you again

Alfonso said...

You just need to follow the example in this case:
http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.toolbar

// Load toolbar_Name where Name = Basic.
config.toolbar = 'Basic';

For other situations, you need to learn javascript and know if you are creating an object or you are working with an object (as this case)

Anonymous said...

It always amazes me when people refuse to understand what they are told, it is even more amazing when someone refuses to understand what they read..

The link you provided its not about passing a configuration as an object, which was the original question, but how to configure the toolbar. Maybe I wasnt clear enough with my question, though I thought I was.

Thank you for your lesson in orientation, I guess I needed to hear that from you though a simple answer with just the syntax would be enough.

Thank you anyway

PS. Now I understand.. I found a comment of yours in this thread and it all became clear.. You seem to think you know better than everyone else! Good luck with yourself! Geez!!

Alfonso said...

It's clear that you need to study a lot if you are unable to put that instruction in place.

You asked how to use the config for each instance, I told you to use the parameter and then clarified with a link to the docs what's the property to setup the toolbar as you asked.

Now you state that I'm not being helpful, that I am to blame for you not knowing javascript and that when I state that the requested feature in a forum is complex but there's a much simpler solution I'm arrogant.

Ok, good luck in your life.

If you don't trust me that you need to learn a lot, just look how you must place the instruction that I told you in the function (exactly in the place where you asked):

CKEDITOR.replaceAll( function(textarea, config) {
if (textarea.className=="text") return false;
if (textarea.id=="summary") return false;

config.toolbar = 'Basic';

return true;
});

Qamar said...

hi, i have tried to integrate ckeditor in my asp.net mvc view, it works fine. But when i try to use it in jquery ui dialog it becomes uneditable. any ideas?
I have tried to use older 2X version of ckeditor in jquery ui dialog i can edit but when i click on submit button it throws an javascript error "A is null". any ideas?

Lam Nguyen said...

If you have 2 instances of CKEDITOR on a page. And you have a plugin available on two instances of CKEDITOR. The plugin is very simple as a plugin insert a string "helloworld" to CKEDITOR.How can i detect the plugin of which instances? Because i have problem when i want to use plugin of the first instance, but the string "helloworld" only insert the second instance.

Alfonso said...

I guess that you are using the wrong editor variable in your plugin.

Follow the available examples or the source plugins and you'll see how you must do it.

sm said...

Hi,
I recently installed CKEditor successfully.I have now added a submit button to display the text entered.But when I click on Submit, it doesn't do anything.
Could you please let me know as to what I am missing?

Thanks in advance,
Shilpa

Code:
form id="myForm" method="post" >

textarea id="editor1" class="ckeditor" name="editor1"> Sample data /textarea>
input type="submit" value="Submit" />


script type="text/javascript">
CKEDITOR.replace('editor1');
document.myForm.onsubmit();
/script>
/form>

Alfonso said...

Take a look at the javascript console to check if there's any error.

Anyway I see that you've already posted to the CKEditor forums, that's a better place to find a solution instead of this post.

Jayaraj.v.a said...

Hello Alfonso, very good tutorial.

Can you explain,How can I catch keyboard events in configuration section for each instance.

CKEDITOR.replaceAll( function(textarea, config) {
if (textarea.className!="textEditor") return false;
else
//configuration
});

Alfonso said...

It will be much easier if you create a little plugin to do whatever you want.
Using event handlers in the configuration it's possible, but for your situation it's more complex than just putting the code in a plugin (there are other situations where setting the handlers from the config is a must, but not for this task).

Joe Guynan said...

Hi, I have 4 TEXTAREAs on the page, I run the following code in a JQuery document.ready()

CKEDITOR.replaceAll('ckeditor', {
extraPlugins: 'uploadimage,image2',
height: 250,
uploadUrl: '[myurl]',response type is set to JSON).
imageUploadUrl: '[myurl]',
image2_disableResizer: false,
disableNativeSpellChecker: false
} );

When the page loads all the TEXTAREAs get the ckeditor but the drag and drop plugin no longer works. If I use the code above with the replace method and specify each TEXTAREAs ID they all work.

All TEXTAREAs have a unique ID.

Alfonso said...

Hi Joe,

I don't know what might be wrong in your case because I don't use that plugin. It came out too late and it's still missing features for me.