How to get ajax call to save data of ckeditor on save button plugin.
Here I attached image.
The task was to use inline ckeditor in order to edit div contents and save by sending ajax request to the server.
I have stuck to a problem that ckeditor save button did not appear on the toolbar. So here is a solution for that. The most important part is highlighted with bold.
Just replace the "save" plugin contents. You can find it in ckeditor/plugins/save/plugin.js
(function() {
var saveCmd = { modes:{wysiwyg:1,source:1 },
readOnly: 1,
exec: function( editor ) {
var data = editor.getData();
jQuery.post(editor.config.saveSubmitURL,
{text: data},
function(response){
alert('Data sent to server!!!');
});
}
};
var pluginName = 'save';
// Register a plugin named "save".
CKEDITOR.plugins.add( pluginName, {
lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en-au,en-ca,en-gb,en,eo,es,et,eu,fa,fi,fo,fr-ca,fr,gl,gu,he,hi,hr,hu,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt-br,pt,ro,ru,sk,sl,sr-latn,sr,sv,th,tr,ug,uk,vi,zh-cn,zh', // %REMOVE_LINE_CORE%
icons: 'save', // %REMOVE_LINE_CORE%
init: function( editor ) {
var command = editor.addCommand( pluginName, saveCmd );
//command.modes = { wysiwyg: !!( editor.element.$.form ) };
editor.ui.addButton( 'Save', {
label: editor.lang.save.toolbar,
command: pluginName,
toolbar: 'clipboard,50'
});
}
});
})();
Additionally you will need to update the config.js file for the ckeditor and add the following lines
config.saveSubmitURL = 'URL_TO_YOUR_SERVER_SCRIPT.php';
Related
In a CKEditor plugin, you can specify a toolbar for a button with this :
init:function(editor){
editor.ui.addButton('myplug',{
label:'my plug',
command:'myplug',
toolbar:'mytoolbar'
With widget, I don't find this possibility. Is there a way to do that without move the node in JS, that is a bit complicated ?
You can do the same with widgets. Here's a widget's plugin.js file with a button and toolbar declaration under the init function:
CKEDITOR.plugins.add( 'mywidget', {
requires: 'widget',
icons: 'mywidget',
init: function( editor ) {
CKEDITOR.dialog.add('mywidget', this.path + 'dialogs/mywidget.js')
editor.widgets.add( 'mywidget' , {
//
// Your widget logic is here ...
//
});
editor.ui.addButton('mywidget', {
label: 'My Widget'
command: 'mywidget'
toolbar: 'mytoolbar, 1'
});
}
} );
You'll need to add the "mytoolbar" toolbar in your config.js file, but I suppose you already have because you mentioned being able to add a button for a plug-in.
I have a Dygraphs chart that works perfectly when I provide a file URL for a data source. When I embedded the data directly into the HTML wrapper, however, the functions in my drawCallback don't fire. Tracing with Firebug, I find that is_initial is True when I load the page with the URL reference, but False when I embed the data (and labels) in native format, even if I place onLoad="drawCallback(vGraph,True);" within the <body> tag. I've "solved" this by setting my own variable to test for first-time execution.
Here's the original, functional, code for an external data source:
var vGraph = new Dygraph(document.getElementById("dgraphChartContainer"),
ExternalDataSource.csv,
{ //options
connectSeparatedPoints: true,
labelsDiv: "dygraphLabelsContainer",
...
}
);
vGraph.updateOptions({
highlightCallback: function(event, xdate, points_array, rowNumber, seriesName) {
...
},
unhighlightCallback: function(event) {
...
},
drawCallback: function(g, is_initial) {
if (!is_initial) return;
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
}
});
As I said, this works great, even with the blind g parameter in the drawCallback.
This is the work-around I developed for the scenario when I embed the data source.
var vFirstTime = true;
var vGraph = new Dygraph(document.getElementById("dgraphChartContainer"),
[
[ new Date("2011/10/15 00:04:55"),null,null,-9.2,null,null,null,null,null,null],
[ new Date("2011/10/24 10:39:32"),null,null,null,null,null,-9.2,null,null,null],
...
[ new Date("2011/10/25 21:02:30"),null,null,null,null,null,null,null,20.3,null],
[ new Date("2013/10/28 08:49:52"),null,null,-17.9,null,null,null,null,null,null]
],
{ //options
labels: ["Event_Date","code-32565","code-32566","code-32568","code-32569","code-32573","code-32574","code-32575","code-32577","code-32578"],
connectSeparatedPoints: true,
labelsDiv: "dygraphLabelsContainer",
...
}
);
vGraph.updateOptions({
highlightCallback: function(event, xdate, points_array, rowNumber, seriesName) {
...
},
unhighlightCallback: function(event) {
...
},
// drawCallback: function(g, is_initial) {
// if (!is_initial) return;
drawCallback: function() {
if (!vFirstTime) return;
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
vFirstTime=false;
}
});
Is there something I can do to use is_initial in my drawCallback call regardless of the data source?
Your first example will work if you move your callbacks into the constructor:
var vGraph = new Dygraph(document.getElementById("dgraphChartContainer"),
ExternalDataSource.csv,
{ //options
connectSeparatedPoints: true,
labelsDiv: "dygraphLabelsContainer",
highlightCallback: function(event, xdate, points_array, rowNumber, seriesName) {
...
},
unhighlightCallback: function(event) {
...
},
drawCallback: function(g, is_initial) {
if (!is_initial) return;
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
},
...
});
So, what's going on here?
The drawCallback gets fired with is_initial = true when the chart draws for the first time. In your original code, this happens after the XMLHttpRequest for the data comes back.
The order of operations is:
constructor
updateOptions
drawCallback(is_initial=true)
When you inline your data, dygraphs doesn't need to wait for the XHR to come back. Now, the order of operations is:
constructor
drawCallback(is_initial=true)
updateOptions
drawCallback(is_initial=false)
The second drawCallback happens because you called updateOptions(). So drawCallback is getting fired with is_initial = true, it's just that you're not listening for it early enough.
dygraphs provides a .ready() method to let you avoid all this intricacy. You may be happier using it instead:
var vGraph = new Dygraph( ... );
vGraph.ready(function() {
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
});
I created a plugin named timestamp.
Code for plugin.js is this:
CKEDITOR.plugins.add( 'timestamp',
{
init: function( editor )
{
editor.addCommand( 'insertTimestamp',
{
exec : function( editor )
{
var timestamp = new Date();
editor.insertHtml( timestamp.toString() );
}
});
editor.ui.addButton( 'Timestamp',
{
label: 'Insert Timestamp',
command: 'insertTimestamp',
icon: this.path + '/icons/timestamp.png'
} );
}
} );
Icon is in /_source/plugins/timestamp/icons
But when I tried to add plugin in ./samples/fullpage.html, even toolbar not appearing
code:
<script>
CKEDITOR.replace( 'editor1', {
fullPage: true,
extraPlugins: 'wysiwygarea,timestamp',
toolbar :
[
[ 'Bold', 'Italic', '-', 'NumberedList' ],
[ 'Timestamp' ]
]
});
</script>
If i tried to add this plugin in config.js, toolbar appear but without timestamp(my custom plugin)
code:
config.extraPlugins ='timestamp';
please let me know whats going wrong.Thanks
Just remove extraPlugin: 'wysiwygarea' or extraPlugins : 'docprops' is not required in full.html. Hopfully it will work:)
Your toolbar stopped appearing after you've added your plugin much probably because you've got some JS error in that plugin which breaks everything. Check your console and paste info here (or try to fix the issue by yourself :)).
What I am ultimately trying to do is to implement some simple code highlighter (/Syntax Highlighter) since there was nothing available in ckEditor. For this reason I am thinking to add a new button ( or modify one of the existing buttons) by clicking which the selected text changes in the following manner:
1- gets mono-space font to preserve indentations in source code (e.g. "Courier New")
2- the font color changes to blue
Since I don't know how to add a new button I was thinking to use one of the existing buttons, say block quote button, to do the job.
added note:
by the way I just noticed that the ckEditor 4 is out too: ckeditor 4
where the plugins are customizable too:ckeditor 4 builder
You can consider the following plugin I created from scratch in hurry (this is not a full solution but it shows the right direction):
(function() {
'use strict';
CKEDITOR.plugins.add( 'prettify', {
icons: 'prettify',
init: function( editor ) {
editor.on( 'mode', function( event ) {
if( editor.mode == 'wysiwyg' )
insertResources( editor );
});
editor.addCommand( 'prettify', {
exec: function( editor ) {
var selection = editor.getSelection(),
startElement = selection.getStartElement();
if ( startElement.hasClass( 'prettyprint' ) )
return;
var contents = startElement.getText();
// Naive pre-processing.
contents = contents.replace( /\n/g ,'<br>' );
contents = contents.replace( /\t/g ,' ' );
contents = contents.replace( / /g ,' ' );
startElement.setHtml( prettyPrintOne( contents, 'js', 0 ) );
startElement.addClass( 'prettyprint' );
}
});
editor.ui.addButton( 'Prettify', {
label: 'Prettify',
command: 'prettify',
toolbar: 'insert'
});
}
});
function insertResources( editor ) {
var outerHead = CKEDITOR.document.getHead(),
innerHead = editor.document.getHead(),
path = CKEDITOR.plugins.getPath( 'prettify' );
outerHead.append( CKEDITOR.document.createElement( 'script', {
attributes: {
type: 'text/javascript',
async: 'true',
src: path + 'lib/prettify.js'
}
}));
innerHead.append( CKEDITOR.document.createElement( 'link', {
attributes: {
rel: 'stylesheet',
href: path + 'lib/prettify.css'
}
}));
}
})();
To run it, extract Google Prettify library into lib directory of prettify plugin. Then try the following HTML and use the button in the toolbar to prettify pre:
<textarea cols="80" id="editor1" name="editor1" rows="10">
<pre>function insertResources( editor ) {
var outerHead = CKEDITOR.document.getHead(),
innerHead = editor.document.getHead(),
path = CKEDITOR.plugins.getPath( 'prettify' );
</pre>
<p>Foo:</p>
<pre>outerHead.append( CKEDITOR.document.createElement( 'script', {
attributes: {
type: 'text/javascript',
async: 'true',
src: path + 'lib/prettify.js'
}
}));</pre>
<p>Bar:</p>
<pre>innerHead.append( CKEDITOR.document.createElement( 'link', {
attributes: {
rel: 'stylesheet',
href: path + 'lib/prettify.css'
}
}));
}</pre>
</textarea>
<script>
CKEDITOR.replace( 'editor1', {
extraPlugins: 'prettify',
toolbar: [
[ 'Source', '-', 'NewPage', 'Preview', '-', 'Templates' ],
[ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ],
[ 'Bold', 'Italic' ],
'/',
[ 'Prettify']
]
} );
</script>
A WYSIWYG editor generates an HTML markup or encoded HTML at the back to store your formatting, let’s say for the quote it might be generating this code at the back:
<blockquote> … </blockquote>
(However this varies from one editor to another)
The easiest way to do it is to find out the tag it is generating in the background and apply CSS style to it as you want.
//.CSS
blockquote{
//Styles here…
}
Hope it helps.
Not sure what is your full use case, but here's mine, which ended up with a custom plugin
I wanted to be able to insert code snippets into CKEditor using a dialog window (not sure why you prefer the blockquote element)
I wanted to have these code snippets somehow visually marked in CKEditor, I did not care about having real syntax highlighter in CKEditor
At the end, after saving the content, I wanted to apply real syntax formatting to the inserted element without spending too much work on it. I used prettify for that.
Feel free to check the plugin and modify it to your needs.
I just found this super easy solution:
open the contents.css in the root of ckeditor
add the following:
blockquote {
color: blue;
font-family: "Courier New",
Courier,
monospace;
}
I have a form with various textfields and two buttons - Export to Excel and Export to CSV.
The user can provide the values to different fields in the form and click one of the buttons.
Expected behaviour is that an Ajax request should be fired carrying the values of fields as parameters and the chosen file (Excel/CSV as per the button click) should get downloaded (I am not submitting the form as there needs to be done some processing at the values before submit).
I have been using the following code in success function of Ajax request for the download:
result = Ext.decode(response.responseText);
try {
Ext.destroy(Ext.get('testIframe'));
}
catch(e) {}
Ext.core.DomHelper.append(document.body, {
tag: 'iframe',
id:'testIframe',
css: 'display:none;visibility:hidden;height:0px;',
src: result.filename,
frameBorder: 0,
width: 0,
height: 0
});
The above code has been working fine in the case when the file is created physically at the server. But in my current project, the file is not created at the server, rather the contents are just streamed to the browser with proper headers.
Thus, is there a way to download a file using Ajax when the file is not present at the server physically? Just to add that I have a long list of parameters which I need to send to the server and hence can not add them all to the src of iframe.
Could anyone guide at this?
Thanks for any help in advance.
You may use component like this:
Ext.define('CMS.view.FileDownload', {
extend: 'Ext.Component',
alias: 'widget.FileDownloader',
autoEl: {
tag: 'iframe',
cls: 'x-hidden',
src: Ext.SSL_SECURE_URL
},
stateful: false,
load: function(config){
var e = this.getEl();
e.dom.src = config.url +
(config.params ? '?' + Ext.urlEncode(config.params) : '');
e.dom.onload = function() {
if(e.dom.contentDocument.body.childNodes[0].wholeText == '404') {
Ext.Msg.show({
title: 'Attachment missing',
msg: 'The document you are after can not be found on the server.',
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
})
}
}
}
});
Put it somewhere in viewport, for example:
{
region: 'south',
html: 'South',
items: [
{
xtype: 'FileDownloader',
id: 'FileDownloader'
}
]
}
Do not forget to require it in your viewport class:
requires: [
'CMS.view.FileDownload'
]
Action handler may look like this:
var downloader = Ext.getCmp('FileDownloader')
downloader.load({
url: '/attachments/' + record.get('id') + '/' + record.get('file')
});
It's very important to have Content-Disposition header in response, otherwise nothing is downloaded.
Regards go to http://www.quispiam.com/blog/post.php?s=2011-06-09-download-a-file-via-an-event-for-extjs4
This thing works for me.