Reputation: 389
I have drag and drop image uploads working using CKEditor 4.5.1. Very nice feature! On the server side I am resizing large images. My JSON response returns the resized image url (set by 'url' in the response) and that is the image that is shown in the CKEditor window after the successful file upload. But the img tag inserted has the height and width attributes set with the values from the original image, not my resized image. Is there a way to return the new height and width values? Or does anyone have an idea of how to hack around this?
And more generally, is there any resource which describes all possible values in the JSON response? I saw it mentioned somewhere that it wasn't documented yet but hopefully someone might know and take the time to share.
Upvotes: 5
Views: 7505
Reputation: 47
I just came across this post because I had the same issue with uploaded images that ware resized on server side. The images where resized correctly on the server and also the image data was added as a base64 string to the editor content in the desired size but the dimensions set on the image tag were the one of the originally dropped image. So I began to implement the solution above. After adding the changed width and height to the response (asp.net mvc application in c#) like this:
var result = new
{
uploaded = uploaded,
fileName = fileName,
url = imageUrl,
width = imgWidth,
height = imgHeight,
error = new
{
message = message
}
};
The Image inside the editor was resized via inline styles to the width and height set in the response without any further implementation. Is this some kind of hidden feature of ckeditor? I am using version 4.14 due to dependencies that cannot easily be updated.
Upvotes: 0
Reputation: 99
@Michael , thanks for answer. I yet tested and can say that fileUploadResponse is not required.
Responce data can be reach from instanceReady like this (if present in responce from server ofcource)
__ckeditor.on( 'instanceReady', function() {
__ckeditor.widgets.registered.uploadimage.onUploaded = function( upload ) {
console.log(upload);
this.replaceWith( '<img src="' + upload.url + '" ' +
'width="' + upload.responseData.width + '" ' +
'height="' + upload.responseData.height + '">' );
}
} );
Upvotes: 0
Reputation: 1006
When uploading an image finishes, CKEditor replaces an upload widget (which contains an image with Base64 data in the source) with the final HTML. The uploaded image has the same dimensions as the one being uploaded to prevent from blinking during this replacement. Here are the lines that do this replacement.
If blinking when an image is uploaded is not a problem for you, then you can simple overwrite this method:
editor.on( 'instanceReady', function() {
editor.widgets.registered.uploadimage.onUploaded = function ( upload ) {
this.replaceWith( '<img src="' + upload.url + '">' );
}
} );
Now, where can we get the image dimensions from?
One option is to load the image (upload.url
) and read its dimensions in the browser. However, this is an asynchronous operation, so it may affect the undo manager and I would not recommend it.
Therefore, if you know the new dimensions you can send then in the server response. If you put them in your JSON response like this:
{
"uploaded": 1,
"fileName": "foo.jpg",
"url": "/files/foo.jpg",
"width:" 300,
"height:" 200
}
You need to handle them in the response (we'll most likely simplify this bit soon):
editor.on( 'fileUploadResponse', function( evt ) {
var fileLoader = evt.data.fileLoader,
xhr = fileLoader.xhr,
data = evt.data;
try {
var response = JSON.parse( xhr.responseText );
// Error message does not need to mean that upload finished unsuccessfully.
// It could mean that ex. file name was changes during upload due to naming collision.
if ( response.error && response.error.message ) {
data.message = response.error.message;
}
// But !uploaded means error.
if ( !response.uploaded ) {
evt.cancel();
} else {
data.fileName = response.fileName;
data.url = response.url;
data.width = response.width;
data.height = response.height;
// Do not call the default listener.
evt.stop();
}
} catch ( err ) {
// Response parsing error.
data.message = fileLoader.lang.filetools.responseError;
window.console && window.console.log( xhr.responseText );
evt.cancel();
}
} );
To learn more check the editor#fileUploadResponse
event and the Uploading Dropped or Pasted Files guide.
Then you can use them in the upload widget:
editor.on( 'instanceReady', function() {
editor.widgets.registered.uploadimage.onUploaded = function( upload ) {
this.replaceWith( '<img src="' + upload.url + '" ' +
'width="' + upload.width + '" ' +
'height="' + upload.height + '">' );
}
} );
PS. We were considering including such a feature in the core, but because the release was huge we had to limit it at some point to bring it finally to life. There is a great chance that such a feature will be included in the core soon, and only configuration will be needed.
Upvotes: 14