hello !
I searched in the documentation and didnt find anything related to this question. How to make CKEditor readonly at runtime (or even better, right when calling 'replace') ?
The following works for one part :
but the problem is that even though I can't type to the editor any more, some keystrokes like TAB or simple mouse clicks generate newlines and sometimes JS errors.
Is there a command or a call to put the editor in complete readonly mode ?
Thanks
I searched in the documentation and didnt find anything related to this question. How to make CKEditor readonly at runtime (or even better, right when calling 'replace') ?
The following works for one part :
editorInstance.document.$.body.disabled = true; editorInstance.document.$.body.contentEditable = false; editorInstance.document.$.designMode="off"
but the problem is that even though I can't type to the editor any more, some keystrokes like TAB or simple mouse clicks generate newlines and sometimes JS errors.
Is there a command or a call to put the editor in complete readonly mode ?
Thanks

What would a read only instance of CKeditor provide over a regular readonly textarea?
The reason is to have the same code on the page, and being able to put the editor in readonly mode in runtime (maybe in load time) depending on specific external events in order to prevent concurrent modification of the same rich text content by different users, for example.
And btw Eggbert, the editor already uses an iframe. Removing the iframe's design mode works ok, but there appears to be other CKEditor specific stuff that still keeps modifying the iframe contents and sometimes throw errors in IE ...
Is it possible to disable the Save function to prevent content being saved?
Here I hope I could provide a temporary workaround for it:
// Temporary workaround for providing editor 'read-only' toggling functionality. ( function() { var cancelEvent = function( evt ) { evt.cancel(); }; CKEDITOR.editor.prototype.readOnly = function( isReadOnly ) { // Turn off contentEditable. this.document.$.body.disabled = isReadOnly; CKEDITOR.env.ie ? this.document.$.body.contentEditable = !isReadOnly : this.document.$.designMode = isReadOnly ? "off" : "on"; // Prevent key handling. this[ isReadOnly ? 'on' : 'removeListener' ]( 'key', cancelEvent, null, null, 0 ); this[ isReadOnly ? 'on' : 'removeListener' ]( 'selectionChange', cancelEvent, null, null, 0 ); // Disable all commands in wysiwyg mode. var command, commands = this._.commands, mode = this.mode; for ( var name in commands ) { command = commands[ name ]; isReadOnly ? command.disable() : command[ command.modes[ mode ] ? 'enable' : 'disable' ](); this[ isReadOnly ? 'on' : 'removeListener' ]( 'state', cancelEvent, null, null, 0 ); } } } )();Thanks !
I tried the above solution, but received an error of:
"Object doesn't support this property or method".
I hope this could help.
David Ayala
Developer @GT
Hi, thanks for the bug reporting
I just downloaded the last version of CKEditor in order to be able to create a read-only CKEditor but when I tried to call I get the following message:
"TypeError: CKEDITOR.instances.my_editor.readOnly is not a function".
And when I check at runtime, this function is not defined on the object...
Could you tell me what should I do in order to get the function available?
Thanks in advance
I've added the code given a few post before into the CKEDITOR file and the method is now available BUT it doesn't work... The editor is still modifiable...
Any idea?
// Prevent key handling.
this[ isReadOnly ? 'on' : 'removeListener' ]( 'key', cancelEvent, null, null, 0 );
this[ isReadOnly ? 'on' : 'removeListener' ]( 'selectionChange', cancelEvent, null, null, 0 );
any ideas?
adico
I've tried putting in ckeditor.js, but got the following error from browser
"this.document.$" is null or not an object
And a side question, what the $ represents? I don't quite understand the code
P.S use when posting code
//////////////////////////////////////////////////////////////////////////////////////////////////////////// // Temporary workaround for providing editor 'read-only' toggling functionality. ( function(){ var cancelEvent = function( evt ){ evt.cancel(); }; CKEDITOR.editor.prototype.readOnly = function( isReadOnly ){ // Turn off contentEditable /* if ( this.document ){ this.document.$.body.disabled = isReadOnly; if ( CKEDITOR.env.ie ){ this.document.$.body.contentEditable = !isReadOnly; }else{ this.document.$.designMode = (isReadOnly ? "off" : "on"); } } */ // Prevent key handling. this[ isReadOnly ? 'on' : 'removeListener' ]( 'key', cancelEvent, null, null, 0 ); this[ isReadOnly ? 'on' : 'removeListener' ]( 'selectionChange', cancelEvent, null, null, 0 ); // Disable all commands in wysiwyg mode. var command, commands = this._.commands, mode = this.mode; for ( var name in commands ){ if (name != "ReadonlyCmd"){ command = commands[ name ]; if ( isReadOnly ) { command.disable(); }else{ command[ command.modes[ mode ] ? 'enable' : 'disable' ](); } this[ isReadOnly ? 'on' : 'removeListener' ]( 'state', cancelEvent, null, null, 0 ); } } var i,j,k; var toolbars = this.toolbox.toolbars; for ( i = 0; i < toolbars.length; i++ ){ var toolbarItems = toolbars[i].items; for ( j = 0; j < toolbarItems.length; j++ ){ var combo = toolbarItems[j].combo; if ( combo ){ combo.setState( isReadOnly ? CKEDITOR.TRISTATE_DISABLED : CKEDITOR.TRISTATE_OFF ); } var button = toolbarItems[j].button; if ( button && button.createPanel ){ button.setState( isReadOnly ? CKEDITOR.TRISTATE_DISABLED : CKEDITOR.TRISTATE_OFF ); } } } } } )();Can anyone please guide me how/where to implement this code?
I have my ckeditor in my aspx(.net) page
<body> <form id="form1" runat="server"> <div> <textarea id="Content" runat="server" /> <script type="text/javascript" src="UserControls/ckeditor/ckeditor.js"></script> <script type="text/javascript"> CKEDITOR.replace('<%= Content.ClientID %>', { baseHref: '<%= ResolveUrl("~/UserControls/ckeditor/") %>', Toolbar: 'Full', height: 400 }); </script> </div> </form> </body>http://dev.fckeditor.net/ticket/1376
http://dev.fckeditor.net/ticket/3944
<textarea id=editor1 />
$("#cke_editor1").hide();
works like a charm
This is nice solution but I get this.toolbox.toolbars is undefined error. Can you help with this?
Perhaps the problem is with the location of this code. Nobody defines the position of this code. Would you clarify this?
Please help
Chris
//////////////////////////////////////////////////////////////////////////////////////////////////////////// // Temporary workaround for providing editor 'read-only' toggling functionality. ( function(){ var cancelEvent = function( evt ){ evt.cancel(); }; CKEDITOR.editor.prototype.readOnly = function( isReadOnly ){ // Turn off contentEditable /* if ( this.document ){ this.document.$.body.disabled = isReadOnly; if ( CKEDITOR.env.ie ){ this.document.$.body.contentEditable = !isReadOnly; }else{ this.document.$.designMode = (isReadOnly ? "off" : "on"); } } */ // Prevent key handling. this[ isReadOnly ? 'on' : 'removeListener' ]( 'key', cancelEvent, null, null, 0 ); this[ isReadOnly ? 'on' : 'removeListener' ]( 'selectionChange', cancelEvent, null, null, 0 ); // Disable all commands in wysiwyg mode. var command, commands = this._.commands, mode = this.mode; for ( var name in commands ){ if (name != "ReadonlyCmd"){ command = commands[ name ]; if ( isReadOnly ) { command.disable(); }else{ command[ command.modes[ mode ] ? 'enable' : 'disable' ](); } this[ isReadOnly ? 'on' : 'removeListener' ]( 'state', cancelEvent, null, null, 0 ); } } var i,j,k; var toolbars = this.toolbox.toolbars; for ( i = 0; i < toolbars.length; i++ ){ var toolbarItems = toolbars[i].items; for ( j = 0; j < toolbarItems.length; j++ ){ var combo = toolbarItems[j].combo; if ( combo ){ combo.setState( isReadOnly ? CKEDITOR.TRISTATE_DISABLED : CKEDITOR.TRISTATE_OFF ); } var button = toolbarItems[j].button; if ( button && button.createPanel ){ button.setState( isReadOnly ? CKEDITOR.TRISTATE_DISABLED : CKEDITOR.TRISTATE_OFF ); } } } } } )();// Temporary workaround for providing editor 'read-only' toggling functionality. ( function(){ var cancelEvent = function( evt ){ evt.cancel(); }; CKEDITOR.editor.prototype.readOnly = function( isReadOnly ){ // Turn off contentEditable /* if ( this.document ){ this.document.$.body.disabled = isReadOnly; if ( CKEDITOR.env.ie ){ this.document.$.body.contentEditable = !isReadOnly; }else{ this.document.$.designMode = (isReadOnly ? "off" : "on"); } } */ // Prevent key handling. this[ isReadOnly ? 'on' : 'removeListener' ]( 'key', cancelEvent, null, null, 0 ); this[ isReadOnly ? 'on' : 'removeListener' ]( 'selectionChange', cancelEvent, null, null, 0 ); // Disable all commands in wysiwyg mode. var command, commands = this._.commands, mode = this.mode; for ( var name in commands ){ if (name != "ReadonlyCmd"){ command = commands[ name ]; if ( isReadOnly ) { command.disable(); }else{ command[ command.modes[ mode ] ? 'enable' : 'disable' ](); } this[ isReadOnly ? 'on' : 'removeListener' ]( 'state', cancelEvent, null, null, 0 ); } } var i,j,k; var toolbars = this.toolbox.toolbars; for ( i = 0; i < toolbars.length; i++ ){ var toolbarItems = toolbars[i].items; for ( j = 0; j < toolbarItems.length; j++ ){ var combo = toolbarItems[j].combo; if ( combo ){ combo.setState( isReadOnly ? CKEDITOR.TRISTATE_DISABLED : CKEDITOR.TRISTATE_OFF ); } var button = toolbarItems[j].button; if ( button && button.createPanel ){ button.setState( isReadOnly ? CKEDITOR.TRISTATE_DISABLED : CKEDITOR.TRISTATE_OFF ); } } } } } )(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function addUploadButton(editor){ CKEDITOR.on('dialogDefinition', function( ev ){ var dialogName = ev.data.name; var dialogDefinition = ev.data.definition; if ( dialogName == 'image' ){ var infoTab = dialogDefinition.getContents( 'info' ); infoTab.add({ type : 'button', id : 'upload_image', align : 'center', label : 'Upload', style : 'display:inline-block;margin-top:12px;', onClick : function( evt ){ var thisDialog = this.getDialog(); var txtUrlObj = thisDialog.getContentElement('info', 'txtUrl'); var txtUrlId = txtUrlObj.getInputElement().$.id; addNestedImage(txtUrlId); } }, 'browse'); //place front of the browser button } }); } function addReadonlyButton(editor, theMode){ editor.on('pluginsLoaded', function( ev ){ var savedState = CKEDITOR.TRISTATE_OFF; var i,j,k; editor.addCommand( 'ReadonlyCmd', { exec : function (e){ switch (this.state){ case CKEDITOR.TRISTATE_OFF : editor.readOnly(true); break; case CKEDITOR.TRISTATE_ON : editor.readOnly(false); break; } this.toggleState(); savedState = this.state; }, canUndo : false }); editor.ui.addButton( 'Readonly', { label : 'Readonly', command : 'ReadonlyCmd', icon : '/images/edit/view.gif' //style on below }); editor.on( 'mode', function() { editor.getCommand( 'ReadonlyCmd' ).setState( savedState ); }, null, null, 100 ); }); setReadonlyButtonStyle(); } function setReadonlyButtonStyle(){ var cssText = '' + '.cke_button_ReadonlyCmd .cke_icon{' + ' width:32px;' + ' height:32px;' + ' display: inline-table !important;' + '}' + '.cke_button_ReadonlyCmd .cke_label{' + ' display: inline-table !important;' + ' margin-top: 0px !important;' + '}'; importStyle(cssText); } function initEditor(theName, theMode, theWidth, theHeight){ var editor = CKEDITOR.replace(theName, { language : 'en', skin : 'office2003', startupFocus : true, resize_minWidth : 700, image_previewText : ' ', //can not empty, when empty will show default content toolbar : [ //remove Save, NewPage, Form and input elements, add Readonly ['Source','-','Readonly','-','Templates'], ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], '/', ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['Link','Unlink','Image','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'], '/', ['Styles','Format','Font','FontSize'], ['TextColor','BGColor'], ['Maximize', 'ShowBlocks','-','About'] ], width : theWidth, height : theHeight }); addUploadButton(editor); addReadonlyButton(editor); if (theMode == "VIEW"){ setTimeout(function(){ editor.execCommand('ReadonlyCmd'); //click readonly }, 500); } setTimeout(function(){ var tmpObj = document.getElementById("cke_" + theName); var tmpInputs = tmpObj.getElementsByTagName("input"); if (tmpInputs.length > 0){ tmpInputs[0].style.display = "none"; } }, 500); }and on the html head import
<script type="text/javascript" src="ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="myeditor.js"></script>
<script type="text/javascript">
document.onload = function(){
initEditor("<%=[Content]%>", "<%=[Mode]%>", "<%=[Width]%>", "<%=[Height]%>");
}
</script>
i have user your code in my application for readOnly. Everything goes fine but only if i have once instancs of CKeditor. If I have two or more instance in the same page, the toolbars change state correctly but is impossible to write in the editors.
The problem seems to be here:
Some idea?
Thank you
window.onload = function () {
CKEDITOR.on("instanceReady", function (ev) {
var bodyelement = ev.editor.document.$.body;
bodyelement.setAttribute("contenteditable", false);
});
CKEDITOR.replace('editor1');
};
</script>
Sometimes, for functionality, I agree that the editor is not active until either a case ... because a checkbox is not activated, because a user does not have permission, etc..
Make a read-only editor is not so farfetched. It is an interesting case, but whoever does not happen to you is no reason for rejecting a proposal.
-----------------
Me acabo de dar cuenta que eres español, Alfonso
Where should I put that code exactly? I guess the first code in the file ckeditor.js, but the second code?