Autosaving with jQuery and TinyMCE

Creating an auto-save feature for the TinyMCE editor was a lot easier than I thought it would be. This can be due to the ease of working with TinyMCE or the ease of working with jQuery (my javascript library of choice), or both. Here I’m going to explain how to create an auto-save and recovery feature with a MySQL database. Let’s begin!

Click here to download the files used in this tutorial: Auto-save file – jQuery and TinyMCE

Now this article assumes that you already have TinyMCE running properly on your web site. This article also assumes that you already have the jQuery javascript file included. For example, your <head> tags should include:

<script type="text/javascript" src="path/to/jquery.js"></script>
<script type="text/javascript" src="path/to/tiny_mce.js"></script>

Finally, this article also assumes that you already have a database table setup that you wish to house your auto-saved content. In this example we’ll call the table auto_save_table.

Now in the <head> of your document, inside the <script type=”text/javascript”> tags, let’s add the following code:

// -- Your tinyMCE.init settings go here -- //

// First we tell this to run when the page is loaded
$(document).ready(function()
{
  $(function()
  {
    // Here we have the auto_save() function run every 30 secs
    // We also pass the argument 'editor_id' which is the ID for the textarea tag
    setInterval("auto_save('editor_id')",30000);
  });
});

// Here is the auto_save() function that will be called every 30 secs
function auto_save(editor_id)
{
  // First we check if any changes have been made to the editor window
  if(tinyMCE.getInstanceById(editor_id).isDirty())
  {
    // If so, then we start the auto-save process
    // First we get the content in the editor window and make it URL friendly
    var content = tinyMCE.get(editor_id);
    var notDirty = tinyMCE.get(editor_id);
    content = escape(content.getContent());
    content = content.replace("+", "%2B");
    content = content.replace("/", "%2F");

    // We then start our jQuery AJAX function
    $.ajax(
    {
      url: "save.php", // the path/name that will process our request
      type: "POST", 
      data: "content=" + content, 
      success: function(msg)
      {
        alert(msg);

        // Here we reset the editor's changed (dirty) status
        // This prevents the editor from performing another auto-save
        // until more changes are made
        notDirty.isNotDirty = true;
      }
    });

  // If nothing has changed, don't do anything
  } 
  else
  {
    return false;
  }
}

So in the above example we have a function that runs every 30 seconds (30000 milliseconds). The name of the function is called auto_save() and the argument is the ID of the editor. Make sure to change this argument to match your editor’s ID.

Now we need to create the save.php file that will process our request and save the data into the database. Here is an example of what this file will look like:

<?php

// -- Include your database connection information here -- //

// First we get the content that was passed to this script and assign it to a variable$content = $_POST['content'];

// Next we construct our query to insert this content into the database
// You can also add the current date/time, an item id, etc into the table if you wish
$query = "INSERT INTO auto_save_table VALUES('$content')";
mysql_query($query);

// Finally, we print out a success message to feed back to the AJAX script
echo 'Success! Your content was just auto-saved!';

?>

That should take care of auto-saving your content into a database. So every 30 seconds the auto_save() function will run. If the content in the editor window has changed then it will run the AJAX script to save the content into the database. Upon success, we’ll then get an alert (pop-up) letting us know that the auto-save worked.

But now let’s talk about recovering this saved data. First, let’s create a PHP script that will check the database for any auto-saved content, and notify you if there is any. It will then give you the option to load this content or not. This script you’ll want to include in your web site, on the same page where TinyMCE loads.

<?php

// -- Include your database connection information here -- //

// First we query the database to look for any saved content
$query = mysql_query("SELECT * FROM auto_save_table");

if (mysql_num_rows($query) > 0)
{
  // If we have content in the database, then do the following
  echo '<p>There is auto-saved data in the database.</p>';

  // Next we'll give the user an option to load the data
  echo '<p>Load this data? <a href="#" id="load_yes">YES</a></p>';
}
?>

Now let’s get that YES link working. As you can see in the above script, the link doesn’t actually go anywhere, but instead we’ll use its ID to run some functions via jQuery. So, looking back at the first script again inside the $(document).ready(function() { area, let’s add the following command:

// When the YES link is clicked, it will run the auto_load() function
// The argument it's using is the ID of the editor - make sure it matches yours
$("#load_yes").click(function()
{
  auto_load('editor_id');
});

Again, this script will go somewhere in the $(document).ready(function() { area, above or below the current function (setInterval) that’s in there. Now let’s create the auto_load() function to take the saved data in the database and load it into the TinyMCE editor window. So, in the <script type=”text/javascript”> below the auto_save() function, let’s add the following:

function auto_load(editor_id)
{
  // First we assign our editor window to a variablevar 
  ed = tinyMCE.get(editor_id);

  // Then we start our AJAX jQuery function
  $.ajax(
  {
    url: "load.php", // the path/name that will recover our content
    beforeSend: function()
    {
      ed.setProgressState(1);
    },
    success: function(msg)
    {
      ed.setContent(msg);
      ed.setProgressState(0);
    }
  });
}

So, when we click on the YES link, it will run the above function. This function will run an AJAX script to get the content from the load.php file, and insert it into the TinyMCE window.

Now we need to create the load.php file to retrieve the content from the database and return it to the AJAX function. The load.php file should look something like this:

<?php

// -- Include your database connection information here -- //

// First we create the query to retrieve the data from the database
$query = mysql_query("SELECT content FROM auto_save_table");
$row = mysql_fetch_assoc($query);

// Then we return the results to the AJAX handler
echo $row['content'];

?>

And that’s it! The content that was in the database should of now loaded into the TinyMCE editor window. Anything that was in the window before will be overwriten, and the auto-saved content will display.

Now along with this tutorial, you may also want to include a query to delete auto-saves from your database. This can be done prior to auto-saving or inserting new data into the database.

Finally, click the following link to see the final product for all three files: Auto-save file – jQuery and TinyMCE

Nick Villescas

I'm an IT professional, musician, and PC gamer with a particular fondness of all things tech-related. Feel free to connect with me on Facebook, Twitter, and LinkedIn.

2 Responses

  1. Savas Vedova says:

    Nice article Nick!

    I gotta say something though. This code may be useful only if the form is composed of tinyMCE. So if you have other inputs, like the title, the status etc… you’ll have to include them in ajax post. To overcome this problem I’ve written a plugin for tinyMCE 4 which saves the whole form every x seconds and it does not use AJAX. You just copy and paste the code, and there you go it is ready for use 🙂

    You can check the whole code here on this page!

    I appreciate any feedback!

  2. Tim Dearborn says:

    Great tutorial. Very helpful! One addition…

    In function auto_load(editor_id) I needed to unescape the content which was previously escaped.

    msg = unescape(msg);
    ed.setContent(msg);