Replacing CKEditor on the Fly While Enabling Save Button Using jQuery

I was working on a project yesterday when I encountered the need to have DIVs change into text editors upon double-click. It was fairly easy since I was using CKEditor as a rich-text editor and there was an example on the CKEditor website on how to do that. The DIV to be replaced by CKEditor looks like this:

[html]
<div class="editable">
<h3>Part 1</h3>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras et ipsum quis mi
semper accumsan. Integer pretium dui id massa. Suspendisse in nisl sit amet urna
rutrum imperdiet. Nulla eu tellus. Donec ante nisi, ullamcorper quis, fringilla
nec, sagittis eleifend, pede. Nulla commodo interdum massa. Donec id metus. Fusce
eu ipsum. Suspendisse auctor. Phasellus fermentum porttitor risus.
</p>
</div>
[/html]

While the script on the demo page looks like this:

[javascript]
window.onload = function()
{
// Listen to the double click event.
if ( window.addEventListener )
document.body.addEventListener( ‘dblclick’, onDoubleClick, false );
else if ( window.attachEvent )
document.body.attachEvent( ‘ondblclick’, onDoubleClick );
};

function onDoubleClick( ev )
{
// Get the element which fired the event. This is not necessarily the
// element to which the event has been attached.
var element = ev.target || ev.srcElement;
// Find out the div that holds this element.
var name;
do
{
element = element.parentNode;
}
while ( element && ( name = element.nodeName.toLowerCase() ) && ( name != ‘div’ || element.className.indexOf( ‘editable’ ) == -1 ) && name != ‘body’ )
if ( name == ‘div’ && element.className.indexOf( ‘editable’ ) != -1 )
replaceDiv( element );
}
var editor;
function replaceDiv( div )
{
if ( editor )
editor.destroy();
editor = CKEDITOR.replace( div );
}
[/javascript]

I have to say that the code works well. But the project that I’m doing uses jQuery, so I had to convert the above script to utilize it. Please take note that this project uses the included jQuery adapter.

The downside of the code above is that the Save button only works if it is inside a FORM element. If the CKEditor is not within a form, then the Save button will be disabled automatically. So after knowing this, many of you, including me, will just wrap the whole div inside a form and try to test out the Save button.

[html highlight=”1,12″]
<form action="actionpage" method="post">
<div class="editable">
<h3>Part 1</h3>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras et ipsum quis mi
semper accumsan. Integer pretium dui id massa. Suspendisse in nisl sit amet urna
rutrum imperdiet. Nulla eu tellus. Donec ante nisi, ullamcorper quis, fringilla
nec, sagittis eleifend, pede. Nulla commodo interdum massa. Donec id metus. Fusce
eu ipsum. Suspendisse auctor. Phasellus fermentum porttitor risus.
</p>
</div>
</form>
[/html]

To our surprise, the button is still disabled! After a few seconds of pondering, we will find out that the culprit lies within our HTML code. Come to think of it, according to the documentation, CKEditor works like a textarea inside our form and just submit the contents of our editor as such. Also, the Save button works just like a Submit button, which in turn, pass the content of our CKEditor to the form. But wait, we don’t have a textarea! Yes, if you used the HTML code above, our CKEditor was a div and not a textarea, so logically, a form cannot submit the value from a div, which in turn, makes our Save button disabled.

Some of you probably opted to replace the DIV from your HTML to a textarea but figured out it would defeat the purpose of editing on the fly. Others probably will hack into the CKEditor to create a new Save button that will do everything that they wanted to! But I thought, why not just change the DOM of the document so a textarea could be inserted to the form, then just replace the textarea into CKEditor instead of the div. Well, I think it was a better idea instead of creating a new plugin. Here’s a how I did it:

[javascript]
/** Here are the global variables **/
var ceditor; //This is for our CKEditor editor
var divcontent=""; //This will save the contents of our div (Not really necessary, just for illustration purposes)

//I wanted it to execute after the DOM is ready.
$(document).ready(function(){
//Handle the doubleclick event for the div
$(".editable").dblclick(function(){

//Destroy first our editor if it exists
if(ceditor)
{
$(ceditor).ckeditorGet().destroy();
}

divcontent = $(this).html(); //Save the content of our div (Stored it in a variable just for clarity)

//Insert the textarea inside the div with the contents of our div as it’s value
$(this).html("<textarea name=’txtArea’>"+divcontent+"");

//Time to replace the textarea to a CKEditor editor
//Notice that it’s not using the jQuery adapter’s method since it doesn’t modify the textarea’s value upon submission of the form
//It’s better to use the native CKEditor in this case
ceditor =  CKEDITOR.replace($(this).children("textarea").get(0));
});
});
[/javascript]

Works fine for me, the Save button is now enabled and can submit the form just fine. If we double-click on another div, the previously edited div retains the modified text on the DOM. So what if if we want to cancel the editing of a div by double-clicking outside the editor and upon canceling, rolls back to the previous value of the div? Fairly easy, especially if all you have to do is copy-paste:

[javascript]
/** Here are the global variables **/
var ceditor; //This is for our CKEditor editor
var ceditor_container; //Saves the container of our editor (DIV).
var divcontent=""; //This will save the contents of our div

//I wanted it to execute after the DOM is ready.
$(document).ready(function(){
//Stop bubbling of event, so the handler for double-clicking the body doesn’t executed
event.stopPropagation();

//Handle the doubleclick event for the div
$(".editable").dblclick(function(){

//Destroy first our editor if it exists then rollback the previous value of our div
if(ceditor)
{
$(ceditor).ckeditorGet().destroy();
$(ceditor_container).html(divcontent);
}

divcontent = $(this).html(); //Save the content of our div so we can rollback later

//Insert the textarea inside the div with the contents of our div as it’s value
$(this).html("<textarea name=’txtArea’>"+divcontent+"");

//Time to replace the textarea to a CKEditor editor
ceditor =  CKEDITOR.replace($(this).children("textarea").get(0));

//Save the div container for retrieval later
ceditor_container = $(this);
});

//Handle double-click from anywhere on the page.
$("body").dblclick(function(){
//Destroy the editor and rollback the previous value
if(ceditor)
{
$(ceditor).ckeditorGet().destroy();
ceditor = null; //Set it to null since upon the destroying the CKEditor, the value of the variable is not destroyed (not destroyed by reference)
$(ceditor_container).html(divcontent);
}
});
});
[/javascript]

What do you think about the code? I hastily modified the code from the project I was working on, like variable names, etc. Notify me if you found some errors.

Google+ API Now Released

Developers rejoice! Google has now released the API for Google+!! For the uninitiated, in the simplest term possible, “Google+ is the answer of Google to Facebook.” For years now, developers have developed applications, tools and everything you can think of that utilizes the APIs of the top social networking sites such as Facebook and Twitter. And upon the entry of Google+, developers are craving to incorporate the power and innovation of this new service from Google into their applications. Probably the most requested feature that users, especially marketers, are craving for is to automatically post to Google+ via an API to instantly update their stream without logging in to the site. It has been long implemented on Facebook, and countless number of users are utilizing it, usually, to manage all of their updates to multiple social networks in one place.

As of now, the API focuses on public data only, meaning, the API can only access the posts made publicly available by the user. To get started, you must first turn the API on via your Google API Console located at https://code.google.com/apis/console/. You may notice that you have a limit of 1,000 queries per day. I think the courtesy limit gives too little courtesy to the developers. I think it can be increased by enabling billing and pay for the excess queries that you fetch every day. It would be bad for large-scale applications that are developed by small-time individuals, simply because it won’t scale unless you pay for it. Imagine paying for an API access, especially when Facebook, the top social network lets you use their API with more than 100x the limit given by Google. Let us see what will happen in the following months.

To get an overview of what the Google+ API can offer, I used Google’s APIs Explorer and noticed that as of now, there are only three methods available:

  1. activities.get
    Get an activity.
  2. activities.list
    List all of the activities in the specified collection for a particular user.
  3. people.get
    Get a person’s profile.

Using the APIs Explorer, testing the queries is such a breeze. First, we must enable Private Access since the request needs to be authorized via OAuth. I tried out the activities.list method by selecting the method and filling up the userId with “me” and collection with “public”. Take note that “public” is the only value permitted in the collection field as of now, since the API can only access public data for the mean time. It also seem that JSON is the only output format that the API supports. The fields editor is very handy, since you can simply select the fields that you want returned. After clicking the Execute button, the APIs Explorer instantly returned the response to my request as seen from the picture above.

At this stage, only “reading” the data from Google+ is possible with the API. “Writing” data however is still missing in action. So far, only apps that fetch data from Google+ will benefit from this initial release of the API, we still need to wait before third-party apps can post to your stream and before we can see an app named Facebook to Google+.

Update: It seems that billing is not yet enabled for the Google+ API, though you can request to raise the courtesy limit, it still depends on Google whether they’ll approve of the request.

Chitika Relevant Ads (Sarcasm)

Last month, I was searching for Google Adsense alternatives to complement my Adsense earnings and decided to try Chitika. The feature that convinced me to try it is that it pays publishers via PayPal, which Google doesn’t, plus the minimum PayPal payout is $10, which in my opinion is the deal-maker for Chitika. Google’s minimum payout is $100 via check or Western Union, and for small businesses and personal blogs which rarely get decent page views per day, would take years before I can get my first payout. Signing up for Chitika was a breeze, although you have to wait before your application as a publisher is approved, but it took me around 24 hours, and I think it’s fast enough. Setting the ads up were pretty easy, though unlike Adsense, Chitika doesn’t save your ads on your account, it only gives you an embed code, thus, you need to modify your page if you want to modify your ads.

After running the ads for some time, I noticed that the ads never change. Yes, it’s true that the ads’ text changes depending on how it was referred by search engines. Other than that, nothing more. I’m not sure about the Gold-level ads on Chitika (I’m on Silver, by the way), but the ads are ridiculous. I understand that Chitika aims to be responsive to the search query, but in this case, I think it is better to just show a random ad than show a text ad every time that says,

Aitenshiproject near Makati, D9
<search query> near <your ISP location>


As a consumer, I don’t think that I will ever click ads of that type and quality. There’s a higher chance that I will click a random ad that shows purses and makeup even though I’m a guy who never use them (well, who knows?). I maybe ranting for the wrong reasons, but I believe that Chitika’s ad relevancy still has rooms for improvement. The part about responding to search engine queries is quite good, since it can dynamically adapt to what a visitor is searching for. But this technique only considers that a visitor is a casual one, one who is just led to the site through a Google search. But for the frequent visitors to the site who usually just click their bookmarks to load the page, it will only be a nuisance since all they are presented are a bunch of nuisance advertisements that can hinder their browsing experience. Though Chitika offers fallback options so that advertisements won’t show if there are no relevant ads, as a publisher, I think it is more profitable that advertisements are still shown regardless of the type of visitor, since there still lies a possibility that a frequent visitor may click an ad link (for the sake of pity) than click on a non existent ad.

It’s hard to comment on this topic based on how Chitika ads, in general, works since I’m not on the Gold-level ads, which they claim offers much more relevant advertising than the other types of ads. But based on my experience, and probably other small-scale publishers who never get more than 5,000 page views  to qualify for a gold-level, probably need relevant advertising that suits the site that they worked hard for.