Fckeditor 3.6.1 integration in SmartClient 8.2
based on this thread http://forums.smartclient.com/showthread.php?t=20175&goto=nextoldest
I'm using ckeditor 3.6.1
I've included this CkeditorIntegration.js file:
CkeditorIntegration.js
CKEDITOR.config.customConfig = '../com/juve/classes/ckeditor/ckeditorConfig.js'; // HACK 1 - variable to hold setValue() calls made before the editor is ready var ckInitValue = null; CKEDITOR.on('instanceReady', function(ev) { isc.Log.logInfo("Editor Ready!: " + ev.editor.id); if (ckInitValue) { ev.editor.setData(ckInitValue); ckInitValue = null; } }); isc.defineClass("Ckeditor", "Canvas").addProperties({ overflow: "visible", canDragResize: true, redrawOnResize: true, zIndex: 0, getInnerHTML: function() { return "<textarea STYLE='width:100%;height:100%' ID=" + this.getCkId() + "></textarea>"; }, redrawOnResize: false, draw: function() { this.Super("draw", arguments); this.loadEditor(); return this; }, getCkId: function() { return this.getID() + ckeditorIntegrationCanvasIdSuffix; }, loadEditor: function() { if (this.ckLoaded == null) { isc.Log.logInfo("Creating editor:" + this.getCkId()); CKEDITOR.replace(this.getCkId(), { // toolbar: [['Styles', 'Format'], ['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link']] }); isc.Log.logInfo("Editor Setup initiated..."); this.ckLoaded = true; } }, resetDirty:function() { CKEDITOR.instances[this.getCkId()].resetDirty(); }, checkDirty:function() { return CKEDITOR.instances[this.getCkId()].checkDirty(); }, getValue:function() { return CKEDITOR.instances[this.getCkId()].getData(); }, setValue:function(value) { if (CKEDITOR.instances[this.getCkId()]) { CKEDITOR.instances[this.getCkId()].setData(value); } else { ckInitValue = value; } } }); isc.defineClass("CkeditorItem", "CanvasItem").addProperties({ canvasConstructor: "Ckeditor", getValue: function() { var superValue = this.Super("getValue", arguments); var editorValue = null; isc.Log.logInfo("Super Value: " + superValue); if (CKEDITOR.instances[this.canvas.getCkId()].getData()) { editorValue = CKEDITOR.instances[this.canvas.getCkId()].getData(); isc.Log.logInfo("Editor value:" + editorValue); // HACK 2 - we need to work out a better way of keeping the underlying item's value in sync // - this could be a SC bug - why not calling getValue() - using direct access instead? if (superValue != editorValue) this.Super("setValue", editorValue); return editorValue; } else { return superValue; } }, setValue: function(value) { isc.Log.logInfo("Setting value:" + value); // HACK 1 - setValue is called before the editor is ready, so we need to keep hold of the value until it is loaded. if (CKEDITOR.instances[this.canvas.getCkId()]) { CKEDITOR.instances[this.canvas.getCkId()].setData(value); } else { ckInitValue = value; } return this.Super("setValue", arguments); } });
and this is the ckeditorConfig.js file:
/* Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ CKEDITOR.editorConfig = function( config ) { // Define changes to default configuration here. For example: // config.uiColor = '#AADC6E'; config.baseFloatZIndex = 1000000; config.language = 'it'; config.toolbar = 'Full'; config.width = 850; config.height = 450; config.resize_enabled = false; config.removePlugins = 'elementspath'; // config.saveFunction = function(data) { // alert(data) // } config.entities = false; config.toolbar_Full_isc_save_toolbar = [ { name: 'document', items : [ 'Source','-','Isc_save','NewPage','DocProps','Preview','Print','-','Templates' ] }, { name: 'clipboard', items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] }, { name: 'editing', items : [ 'Find','Replace','-','SelectAll','-','SpellChecker', 'Scayt' ] }, { name: 'forms', items : [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] }, '/', { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ] }, { name: 'paragraph', items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl' ] }, { name: 'links', items : [ 'Link','Unlink','Anchor' ] }, { name: 'insert', items : [ 'Image',/*'Flash',*/'Table','HorizontalRule','Smiley','SpecialChar','PageBreak' ] }, '/', { name: 'styles', items : [ 'Styles','Format','Font','FontSize' ] }, { name: 'colors', items : [ 'TextColor','BGColor' ] }, { name: 'tools', items : [ 'Maximize', 'ShowBlocks','-','About' ] } ]; config.extraPlugins = 'isc_save'; config.toolbar = 'Full_isc_save_toolbar'; };
this is the code I use to display it in a modal window:
isc.defineClass("ModalWindow", "Window").addProperties({ showMinimizeButton:false, showHeaderIcon:false, autoSize:true, autoCenter:true, isModal:true, showModalMask:true, dismissOnOutsideClick:true }); var showCkeditor = function (value, callback) { if (window.editorWindow) { editorWindow.show(); editorWindow.setValue(value); editorWindow.delayCall('resetDirty', [], 500); editorWindow.callback = callback; } else { isc.Ckeditor.create({ showEdges: true, ID: "AnFCKeditor", align: "left", height: 572, save:function() { this.editorWindow.save(); }, width: 857 }); isc.ModalWindow.create({ ID: "editorWindow", title:"Editor", editor: AnFCKeditor, callback: callback, save:function() { this.callback(this.getValue()); }, closeClick:function() { if (this.checkDirty()) { isc.confirm("There are unsaved changes.<br>Close anyway?", function(value){ if (value) { editorWindow.hide(); } }); } else { this.hide(); } }, resetDirty:function() { this.editor.resetDirty(); }, checkDirty:function() { return this.editor.checkDirty(); }, setValue:function(value) { this.editor.setValue(value); }, getValue:function() { return this.editor.getValue(); }, initWidget:function() { this.addItem(this.editor); this.Super("initWidget", arguments); AnFCKeditor.editorWindow = this; } }); editorWindow.setValue(value); editorWindow.animateShow(defaultAnimationEffect, function(){ editorWindow.delayCall('resetDirty', [], 500); }); } };
I open it this way:
showCkeditor(record[fieldName], function(value){ record[fieldName] = value; myDataSource.updateData(record, "if(dsResponse.status >= 0) editorWindow.resetDirty();"); });
where the function(value) is a callback which will be used to save the edited html.
Saving is triggered by the Isc_save custom button which requires the ckeditor-3.6.1/ckeditor/plugins/isc_save/plugin.js:
CKEDITOR.plugins.add('isc_save', { init: function(editor) { var pluginName = 'isc_save'; editor.addCommand(pluginName, { exec : function(editor) { // the Ckeditor class defined in CkeditorIntegration.js adds ckeditorIntegrationCanvasIdSuffix (defined in index.jsp) to the Canvas ID to obtain textarea ID var editorName = editor.name.substr(0, editor.name.length - ckeditorIntegrationCanvasIdSuffix.length); isc.logEcho(editorName) eval(editorName).save(); }, canUndo : true }); /* editor.addCommand(pluginName, new CKEDITOR.dialogCommand(pluginName) ); */ editor.ui.addButton('Isc_save', { label: 'Save', command: pluginName, className : 'cke_button_save' }); } });
finally, in my jsp:
<script type="text/javascript"> var ckeditorIntegrationCanvasIdSuffix = '_ta'; </script> <script type="text/javascript" charset="UTF-8" src="./shared/ui/ckeditor/ckeditor.js"></script> <script type="text/javascript" charset="UTF-8" src="./shared/ui/com/juve/classes/ckeditor/CkeditorIntegration.js"></script>