The system is composed of a Visualforce page using TinyMCE as the rich text editor. TinyMCE has a (somewhat buggy) function that will tell you if an editor instance "is dirty". We set a timer to check this attribute every few seconds. If the attribute returns true, we can execute a controller method via javascript remoting.
Putting it all together:
A visual indicator (to show the user that the auto save ran):
<div id="saving" class="minitext" style="color:#666; font-style:italic; display: none">AutoSaving...</div>
The timer:
var $j = jQuery.noConflict();
// First we tell this to run when the page is loaded
$j(document).ready(function()
{
$j(function()
{
setInterval("auto_save('{!$Component.theform.thepageblock.thepbs.somefield}')",5000);
});
});
The auto_save function referenced in the timer:
function auto_save(inputs)
{
// First we check if any changes have been made to the editor window
if(tinyMCE.getInstanceById(inputs).isDirty())
{
$j('#saving').show();
var content = tinyMCE.get(inputs);
var notDirty = tinyMCE.get(inputs);
saveTestField('Some_Field__c', content.getContent());
notDirty.isNotDirty = true;
}
else
{
$j('#saving').hide();
return false;
}
function saveField(fieldName, fieldValue)
{
Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.AutoSave.updateFieldValue}', recId, fieldName, fieldValue,
function(result, event){
if (event.status) {
} else if (event.type === 'exception') {
console.log(event.message);
}
},
{escape: true}
);
}
The Apex method:
@RemoteAction
public static Boolean updateFieldValue(Id recordId, String fieldName, Object fieldValue)
{
String sObjectName = recordId.getSObjectType().getDescribe().getName();
String queryString = 'Select Id, ' + String.escapeSingleQuotes(fieldName) + ' From ' + String.escapeSingleQuotes(sObjectName) + ' Where Id = \'' + String.escapeSingleQuotes(recordId) + '\'';
Sobject record = Database.query(queryString);
record.put(fieldName, fieldValue);
update record;
return true;
}
Observations:
- UI validations are completely ignored. If you have a required field in your UI, the field will still commit, without error.
- The auto save only commits the field passed to the controller. No other field is saved.
Issues
- One issue that I observed while assembling this was that the isDirty attribute wasn't always reliable. It turns out that you have to tell TinyMCE to save at some point for the attribute to reset itself. You can do it by adding this line: tinyMCE.get(inputs).save();
- Another issue: this recipe works well for existing records (records with Id). If you're inserting a new record, you'll need to modify accordingly.
Credits
This was assembled with some helpful tips and tricks from other folks sharing their solutions. Thank you for sharing!
https://github.com/pbattisson/Visualforce-Autosave/
http://webnv.net/2008/02/10/autosaving-with-jquery-and-tinymce/
No comments:
Post a Comment