首先从官网下载ckeditor包(http://ckeditor.com/download)。这里根据需要不同的版本,因为我做的功能是实现图片和文字显示,很简单的功能,所以选择的是standard package。将ckeditor包放在webapp下。
在html中使用textarea 标签加载插件
<script src="../../ckeditor/ckeditor.js"></script>
<textarea class="easyui-validatebox" name="newsMatter" id="newsMatter" rows="20" cols="70" data-options="required:true"> </textarea>
然后在js文件中加载ckeditor
CKEDITOR.replace('newsMatter', {
height : 300,
filebrowserImageUploadUrl : baseurl + "/imageUpload.do"
});
js中获取textarea 中的值:
$('#newsMatter').each(function () {
var $textarea = $(this);
var data=CKEDITOR.instances[$textarea.attr('name')].getData();
data=data.replace(/“/g,'\"');//转义“ 左双引号
data=data.replace(/”/g,'\"');//转义“ 右双引号
$textarea.val(data);
});
这里的filebrowserImageUploadUrl 是文件上传的路径,有值才会显示上传卡片。
这里是maven项目,所以直接在pom.xml中使用依赖
<dependency>
<groupId>com.ckeditor</groupId>
<artifactId>ckeditor-java-core</artifactId>
<version>3.5.3</version>
</dependency>
至此,环境大体是搭建完成。但是做成想要的样子还需要修改js文件。
ckeditor/config.js中配置如下:
CKEDITOR.editorConfig = function( config ) {
// Define changes to default configuration here.
// For complete reference see:
// http://docs.ckeditor.com/#!/api/CKEDITOR.config
// The toolbar groups arrangement, optimized for two toolbar rows.
/* config.toolbarGroups = [
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
{ name: 'links' },
{ name: 'insert' },
{ name: 'forms' },
{ name: 'tools' },
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'others' },
'/',
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
{ name: 'styles' },
{ name: 'colors' },
{ name: 'about' }
];
*/
config.toolbar=[
{name:'insert',items:['Image']}
];
// Remove some buttons provided by the standard plugins, which are
// not needed in the Standard(s) toolbar.
// Set the most common block elements.
config.format_tags = 'p;h1;h2;h3;pre';
// Simplify the dialog windows.
config.removeDialogTabs = 'image:advanced;link:advanced';
// config.filebrowserImageUploadUrl = 'upload.do?type=Image';
config.enterMode = CKEDITOR.ENTER_BR;
config.shiftEnterMode = CKEDITOR.ENTER_P;
};
ckeditor/plugins/image/dialogs/image.js文件如下:
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
(function()
{
var imageDialog = function( editor, dialogType )
{
// Load image preview.
var IMAGE = 1,
LINK = 2,
PREVIEW = 4,
CLEANUP = 8,
regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i,
regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,
pxLengthRegex = /^\d+px$/;
var onSizeChange = function()
{
var value = this.getValue(), // This = input element.
dialog = this.getDialog(),
aMatch = value.match( regexGetSize ); // Check value
if ( aMatch )
{
if ( aMatch[2] == '%' ) // % is allowed - > unlock ratio.
switchLockRatio( dialog, false ); // Unlock.
value = aMatch[1];
}
// Only if ratio is locked
if ( dialog.lockRatio )
{
var oImageOriginal = dialog.originalElement;
if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
{
if ( this.id == 'txtHeight' )
{
if ( value && value != '0' )
value = Math.round( oImageOriginal.$.width * ( value / oImageOriginal.$.height ) );
if ( !isNaN( value ) )
dialog.setValueOf( 'info', 'txtWidth', value );
}
else //this.id = txtWidth.
{
if ( value && value != '0' )
value = Math.round( oImageOriginal.$.height * ( value / oImageOriginal.$.width ) );
if ( !isNaN( value ) )
dialog.setValueOf( 'info', 'txtHeight', value );
}
}
}
updatePreview( dialog );
};
var updatePreview = function( dialog )
{
//Don't load before onShow.
if ( !dialog.originalElement || !dialog.preview )
return 1;
// Read attributes and update imagePreview;
dialog.commitContent( PREVIEW, dialog.preview );
return 0;
};
// Custom commit dialog logic, where we're intended to give inline style
// field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute
// by other fields.
function commitContent()
{
var args = arguments;
var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' );
inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args );
this.foreach( function( widget )
{
if ( widget.commit && widget.id != 'txtdlgGenStyle' )
widget.commit.apply( widget, args );
});
}
// Avoid recursions.
var incommit;
// Synchronous field values to other impacted fields is required, e.g. border
// size change should alter inline-style text as well.
function commitInternally( targetFields )
{
if ( incommit )
return;
incommit = 1;
var dialog = this.getDialog(),
element = dialog.imageElement;
if ( element )
{
// Commit this field and broadcast to target fields.
this.commit( IMAGE, element );
targetFields = [].concat( targetFields );
var length = targetFields.length,
field;
for ( var i = 0; i < length; i++ )
{
field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) );
// May cause recursion.
field && field.setup( IMAGE, element );
}
}
incommit = 0;
}
var switchLockRatio = function( dialog, value )
{
if ( !dialog.getContentElement( 'info', 'ratioLock' ) )
return null;
var oImageOriginal = dialog.originalElement;
// Dialog may already closed. (#5505)
if( !oImageOriginal )
return null;
// Check image ratio and original image ratio, but respecting user's preference.
if ( value == 'check' )
{
if ( !dialog.userlockRatio && oImageOriginal.getCustomData( 'isReady' ) == 'true' )
{
var width = dialog.getValueOf( 'info', 'txtWidth' ),
height = dialog.getValueOf( 'info', 'txtHeight' ),
originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height,
thisRatio = width * 1000 / height;
dialog.lockRatio = false; // Default: unlock ratio
if ( !width && !height )
dialog.lockRatio = true;
else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) )
{
if ( Math.round( originalRatio ) == Math.round( thisRatio ) )
dialog.lockRatio = true;
}
}
}
else if ( value != undefined )
dialog.lockRatio = value;
else
{
dialog.userlockRatio = 1;
dialog.lockRatio = !dialog.lockRatio;
}
var ratioButton = CKEDITOR.document.getById( btnLockSizesId );
if ( dialog.lockRatio )
ratioButton.removeClass( 'cke_btn_unlocked' );
else
ratioButton.addClass( 'cke_btn_unlocked' );
ratioButton.setAttribute( 'aria-checked', dialog.lockRatio );
// Ratio button hc presentation - WHITE SQUARE / BLACK SQUARE
if ( CKEDITOR.env.hc )
{
var icon = ratioButton.getChild( 0 );
icon.setHtml( dialog.lockRatio ? CKEDITOR.env.ie ? '\u25A0': '\u25A3' : CKEDITOR.env.ie ? '\u25A1' : '\u25A2' );
}
return dialog.lockRatio;
};
var resetSize = function( dialog )
{
var oImageOriginal = dialog.originalElement;
if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
{
var widthField = dialog.getContentElement( 'info', 'txtWidth' ),
heightField = dialog.getContentElement( 'info', 'txtHeight' );
widthField && widthField.setValue( oImageOriginal.$.width );
heightField && heightField.setValue( oImageOriginal.$.height );
}
updatePreview( dialog );
};
var setupDimension = function( type, element )
{
if ( type != IMAGE )
return;
function checkDimension( size, defaultValue )
{
var aMatch = size.match( regexGetSize );
if ( aMatch )
{
if ( aMatch[2] == '%' ) // % is allowed.
{
aMatch[1] += '%';
switchLockRatio( dialog, false ); // Unlock ratio
}
return aMatch[1];
}
return defaultValue;
}
var dialog = this.getDialog(),
value = '',
dimension = this.id == 'txtWidth' ? 'width' : 'height',
size = element.getAttribute( dimension );
if ( size )
value = checkDimension( size, value );
value = checkDimension( element.getStyle( dimension ), value );
this.setValue( value );
};
var previewPreloader;
var onImgLoadEvent = function()
{
// Image is ready.
var original = this.originalElement;
original.setCustomData( 'isReady', 'true' );
original.removeListener( 'load', onImgLoadEvent );
original.removeListener( 'error', onImgLoadErrorEvent );
original.removeListener( 'abort', onImgLoadErrorEvent );
// Hide loader
CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
// New image -> new domensions
if ( !this.dontResetSize )
resetSize( this );
if ( this.firstLoad )
CKEDITOR.tools.setTimeout( function(){ switchLockRatio( this, 'check' ); }, 0, this );
this.firstLoad = false;
this.dontResetSize = false;
};
var onImgLoadErrorEvent = function()
{
// Error. Image is not loaded.
var original = this.originalElement;
original.removeListener( 'load', onImgLoadEvent );
original.removeListener( 'error', onImgLoadErrorEvent );
original.removeListener( 'abort', onImgLoadErrorEvent );
// Set Error image.
var noimage = CKEDITOR.getUrl( editor.skinPath + 'images/noimage.png' );
if ( this.preview )
this.preview.setAttribute( 'src', noimage );
// Hide loader
CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
switchLockRatio( this, false ); // Unlock.
};
var numbering = function( id )
{
return CKEDITOR.tools.getNextId() + '_' + id;
},
btnLockSizesId = numbering( 'btnLockSizes' ),
btnResetSizeId = numbering( 'btnResetSize' ),
imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ),
previewLinkId = numbering( 'previewLink' ),
previewImageId = numbering( 'previewImage' );
return {
title : editor.lang.image[ dialogType == 'image' ? 'title' : 'titleButton' ],
minWidth : 420,
minHeight : 360,
onShow : function()
{
this.imageElement = false;
this.linkElement = false;
// Default: create a new element.
this.imageEditMode = false;
this.linkEditMode = false;
this.lockRatio = true;
this.userlockRatio = 0;
this.dontResetSize = false;
this.firstLoad = true;
this.addLink = false;
var editor = this.getParentEditor(),
sel = editor.getSelection(),
element = sel && sel.getSelectedElement(),
link = element && element.getAscendant( 'a' );
//Hide loader.
CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
// Create the preview before setup the dialog contents.
previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );
this.preview = CKEDITOR.document.getById( previewImageId );
// Copy of the image
this.originalElement = editor.document.createElement( 'img' );
this.originalElement.setAttribute( 'alt', '' );
this.originalElement.setCustomData( 'isReady', 'false' );
if ( link )
{
this.linkElement = link;
this.linkEditMode = true;
// Look for Image element.
var linkChildren = link.getChildren();
if ( linkChildren.count() == 1 ) // 1 child.
{
var childTagName = linkChildren.getItem( 0 ).getName();
if ( childTagName == 'img' || childTagName == 'input' )
{
this.imageElement = linkChildren.getItem( 0 );
if ( this.imageElement.getName() == 'img' )
this.imageEditMode = 'img';
else if ( this.imageElement.getName() == 'input' )
this.imageEditMode = 'input';
}
}
// Fill out all fields.
if ( dialogType == 'image' )
this.setupContent( LINK, link );
}
if ( element && element.getName() == 'img' && !element.data( 'cke-realelement' )
|| element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' )
{
this.imageEditMode = element.getName();
this.imageElement = element;
}
if ( this.imageEditMode )
{
// Use the original element as a buffer from since we don't want
// temporary changes to be committed, e.g. if the dialog is canceled.
this.cleanImageElement = this.imageElement;
this.imageElement = this.cleanImageElement.clone( true, true );
// Fill out all fields.
this.setupContent( IMAGE, this.imageElement );
}
else
this.imageElement = editor.document.createElement( 'img' );
// Refresh LockRatio button
switchLockRatio ( this, true );
// Dont show preview if no URL given.
if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) )
{
this.preview.removeAttribute( 'src' );
this.preview.setStyle( 'display', 'none' );
}
},
onOk : function()
{
// Edit existing Image.
if ( this.imageEditMode )
{
var imgTagName = this.imageEditMode;
// Image dialog and Input element.
if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) )
{
// Replace INPUT-> IMG
imgTagName = 'img';
this.imageElement = editor.document.createElement( 'img' );
this.imageElement.setAttribute( 'alt', '' );
editor.insertElement( this.imageElement );
}
// ImageButton dialog and Image element.
else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ))
{
// Replace IMG -> INPUT
imgTagName = 'input';
this.imageElement = editor.document.createElement( 'input' );
this.imageElement.setAttributes(
{
type : 'image',
alt : ''
}
);
editor.insertElement( this.imageElement );
}
else
{
// Restore the original element before all commits.
this.imageElement = this.cleanImageElement;
delete this.cleanImageElement;
}
}
else // Create a new image.
{
// Image dialog -> create IMG element.
if ( dialogType == 'image' )
this.imageElement = editor.document.createElement( 'img' );
else
{
this.imageElement = editor.document.createElement( 'input' );
this.imageElement.setAttribute ( 'type' ,'image' );
}
this.imageElement.setAttribute( 'alt', '' );
}
// Create a new link.
if ( !this.linkEditMode )
this.linkElement = editor.document.createElement( 'a' );
// Set attributes.
this.commitContent( IMAGE, this.imageElement );
this.commitContent( LINK, this.linkElement );
// Remove empty style attribute.
if ( !this.imageElement.getAttribute( 'style' ) )
this.imageElement.removeAttribute( 'style' );
// Insert a new Image.
if ( !this.imageEditMode )
{
if ( this.addLink )
{
//Insert a new Link.
if ( !this.linkEditMode )
{
editor.insertElement( this.linkElement );
this.linkElement.append( this.imageElement, false );
}
else //Link already exists, image not.
editor.insertElement( this.imageElement );
}
else
editor.insertElement( this.imageElement );
}
else // Image already exists.
{
//Add a new link element.
if ( !this.linkEditMode && this.addLink )
{
editor.insertElement( this.linkElement );
this.imageElement.appendTo( this.linkElement );
}
//Remove Link, Image exists.
else if ( this.linkEditMode && !this.addLink )
{
editor.getSelection().selectElement( this.linkElement );
editor.insertElement( this.imageElement );
}
}
},
onLoad : function()
{
if ( dialogType != 'image' )
this.hidePage( 'Link' ); //Hide Link tab.
var doc = this._.element.getDocument();
if ( this.getContentElement( 'info', 'ratioLock' ) )
{
this.addFocusable( doc.getById( btnResetSizeId ), 5 );
this.addFocusable( doc.getById( btnLockSizesId ), 5 );
}
this.commitContent = commitContent;
},
onHide : function()
{
if ( this.preview )
this.commitContent( CLEANUP, this.preview );
if ( this.originalElement )
{
this.originalElement.removeListener( 'load', onImgLoadEvent );
this.originalElement.removeListener( 'error', onImgLoadErrorEvent );
this.originalElement.removeListener( 'abort', onImgLoadErrorEvent );
this.originalElement.remove();
this.originalElement = false; // Dialog is closed.
}
delete this.imageElement;
},
contents : [
{
id : 'info',
label : editor.lang.image.infoTab,
accessKey : 'I',
elements :
[
{
type : 'vbox',
padding : 0,
children :
[
{
type : 'hbox',
widths : [ '280px', '110px' ],
align : 'right',
children :
[
{
id : 'txtUrl',
type : 'text',
label : editor.lang.common.url,
required: true,
onChange : function()
{
var dialog = this.getDialog(),
newUrl = this.getValue();
//Update original image
if ( newUrl.length > 0 ) //Prevent from load before onShow
{
dialog = this.getDialog();
var original = dialog.originalElement;
dialog.preview.removeStyle( 'display' );
original.setCustomData( 'isReady', 'false' );
// Show loader
var loader = CKEDITOR.document.getById( imagePreviewLoaderId );
if ( loader )
loader.setStyle( 'display', '' );
original.on( 'load', onImgLoadEvent, dialog );
original.on( 'error', onImgLoadErrorEvent, dialog );
original.on( 'abort', onImgLoadErrorEvent, dialog );
original.setAttribute( 'src', newUrl );
// Query the preloader to figure out the url impacted by based href.
previewPreloader.setAttribute( 'src', newUrl );
dialog.preview.setAttribute( 'src', previewPreloader.$.src );
updatePreview( dialog );
}
// Dont show preview if no URL given.
else if ( dialog.preview )
{
dialog.preview.removeAttribute( 'src' );
dialog.preview.setStyle( 'display', 'none' );
}
},
setup : function( type, element )
{
if ( type == IMAGE )
{
var url = element.data( 'cke-saved-src' ) || element.getAttribute( 'src' );
var field = this;
this.getDialog().dontResetSize = true;
field.setValue( url ); // And call this.onChange()
// Manually set the initial value.(#4191)
field.setInitValue();
}
},
commit : function( type, element )
{
if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
{
element.data( 'cke-saved-src', this.getValue() );
element.setAttribute( 'src', this.getValue() );
}
else if ( type == CLEANUP )
{
element.setAttribute( 'src', '' ); // If removeAttribute doesn't work.
element.removeAttribute( 'src' );
}
},
validate : CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing )
},
{
type : 'button',
id : 'browse',
// v-align with the 'txtUrl' field.
// TODO: We need something better than a fixed size here.
style : 'display:inline-block;margin-top:10px;',
align : 'center',
label : editor.lang.common.browseServer,
hidden : false,
filebrowser : 'info:txtUrl'
}
]
}
]
},
{
id : 'txtAlt',
type : 'text',
label : editor.lang.image.alt,
accessKey : 'T',
'default' : '',
onChange : function()
{
updatePreview( this.getDialog() );
},
setup : function( type, element )
{
if ( type == IMAGE )
this.setValue( element.getAttribute( 'alt' ) );
},
commit : function( type, element )
{
if ( type == IMAGE )
{
if ( this.getValue() || this.isChanged() )
element.setAttribute( 'alt', this.getValue() );
}
else if ( type == PREVIEW )
{
element.setAttribute( 'alt', this.getValue() );
}
else if ( type == CLEANUP )
{
element.removeAttribute( 'alt' );
}
}
},
{
type : 'hbox',
children :
[
{
id : 'basic',
type : 'vbox',
children :
[
{
type : 'hbox',
widths : [ '50%', '50%' ],
children :
[
{
type : 'vbox',
padding : 1,
children :
[
{
type : 'text',
width: '50px',
id : 'txtWidth',
label : editor.lang.common.width,
onKeyUp : onSizeChange,
onChange : function()
{
commitInternally.call( this, 'advanced:txtdlgGenStyle' );
},
validate : function()
{
var aMatch = this.getValue().match( regexGetSizeOrEmpty ),
isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 );
if ( !isValid )
alert( editor.lang.common.invalidWidth );
return isValid;
},
setup : setupDimension,
commit : function( type, element, internalCommit )
{
var value = this.getValue();
if ( type == IMAGE )
{
if ( value )
element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
else
element.removeStyle( 'width' );
!internalCommit && element.removeAttribute( 'width' );
}
else if ( type == PREVIEW )
{
var aMatch = value.match( regexGetSize );
if ( !aMatch )
{
var oImageOriginal = this.getDialog().originalElement;
if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
element.setStyle( 'width', oImageOriginal.$.width + 'px');
}
else
element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
}
else if ( type == CLEANUP )
{
element.removeAttribute( 'width' );
element.removeStyle( 'width' );
}
}
},
{
type : 'text',
id : 'txtHeight',
width: '50px',
label : editor.lang.common.height,
onKeyUp : onSizeChange,
onChange : function()
{
commitInternally.call( this, 'advanced:txtdlgGenStyle' );
},
validate : function()
{
var aMatch = this.getValue().match( regexGetSizeOrEmpty ),
isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 );
if ( !isValid )
alert( editor.lang.common.invalidHeight );
return isValid;
},
setup : setupDimension,
commit : function( type, element, internalCommit )
{
var value = this.getValue();
if ( type == IMAGE )
{
if ( value )
element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
else
element.removeStyle( 'height' );
!internalCommit && element.removeAttribute( 'height' );
}
else if ( type == PREVIEW )
{
var aMatch = value.match( regexGetSize );
if ( !aMatch )
{
var oImageOriginal = this.getDialog().originalElement;
if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
element.setStyle( 'height', oImageOriginal.$.height + 'px' );
}
else
element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
}
else if ( type == CLEANUP )
{
element.removeAttribute( 'height' );
element.removeStyle( 'height' );
}
}
}
]
},
{
id : 'ratioLock',
type : 'html',
style : 'margin-top:30px;width:40px;height:40px;',
onLoad : function()
{
// Activate Reset button
var resetButton = CKEDITOR.document.getById( btnResetSizeId ),
ratioButton = CKEDITOR.document.getById( btnLockSizesId );
if ( resetButton )
{
resetButton.on( 'click', function( evt )
{
resetSize( this );
evt.data && evt.data.preventDefault();
}, this.getDialog() );
resetButton.on( 'mouseover', function()
{
this.addClass( 'cke_btn_over' );
}, resetButton );
resetButton.on( 'mouseout', function()
{
this.removeClass( 'cke_btn_over' );
}, resetButton );
}
// Activate (Un)LockRatio button
if ( ratioButton )
{
ratioButton.on( 'click', function(evt)
{
var locked = switchLockRatio( this ),
oImageOriginal = this.originalElement,
width = this.getValueOf( 'info', 'txtWidth' );
if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width )
{
var height = oImageOriginal.$.height / oImageOriginal.$.width * width;
if ( !isNaN( height ) )
{
this.setValueOf( 'info', 'txtHeight', Math.round( height ) );
updatePreview( this );
}
}
evt.data && evt.data.preventDefault();
}, this.getDialog() );
ratioButton.on( 'mouseover', function()
{
this.addClass( 'cke_btn_over' );
}, ratioButton );
ratioButton.on( 'mouseout', function()
{
this.removeClass( 'cke_btn_over' );
}, ratioButton );
}
},
html : '<div>'+
'<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.lockRatio +
'" class="cke_btn_locked" id="' + btnLockSizesId + '" role="checkbox"><span class="cke_icon"></span><span class="cke_label">' + editor.lang.image.lockRatio + '</span></a>' +
'<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
'" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+
'</div>'
}
]
},
{
type : 'vbox',
padding : 1,
children :
[
{
id : 'cmbAlign',
type : 'select',
widths : [ '35%','65%' ],
style : 'width:90px',
label : editor.lang.common.align,
'default' : '',
items :
[
[ editor.lang.common.notSet , ''],
[ editor.lang.common.alignLeft , 'left'],
[ editor.lang.common.alignRight , 'right']
// Backward compatible with v2 on setup when specified as attribute value,
// while these values are no more available as select options.
// [ editor.lang.image.alignAbsBottom , 'absBottom'],
// [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
// [ editor.lang.image.alignBaseline , 'baseline'],
// [ editor.lang.image.alignTextTop , 'text-top'],
// [ editor.lang.image.alignBottom , 'bottom'],
// [ editor.lang.image.alignMiddle , 'middle'],
// [ editor.lang.image.alignTop , 'top']
],
onChange : function()
{
updatePreview( this.getDialog() );
commitInternally.call( this, 'advanced:txtdlgGenStyle' );
},
setup : function( type, element )
{
if ( type == IMAGE )
{
var value = element.getStyle( 'float' );
switch( value )
{
// Ignore those unrelated values.
case 'inherit':
case 'none':
value = '';
}
!value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
this.setValue( value );
}
},
commit : function( type, element, internalCommit )
{
var value = this.getValue();
if ( type == IMAGE || type == PREVIEW )
{
if ( value )
element.setStyle( 'float', value );
else
element.removeStyle( 'float' );
if ( !internalCommit && type == IMAGE )
{
value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
switch( value )
{
// we should remove it only if it matches "left" or "right",
// otherwise leave it intact.
case 'left':
case 'right':
element.removeAttribute( 'align' );
}
}
}
else if ( type == CLEANUP )
element.removeStyle( 'float' );
}
}
]
}
]
},
{
type : 'vbox',
height : '250px',
children :
[
{
type : 'html',
id : 'htmlPreview',
style : 'width:95%;',
html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+
'<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+
'<div class="ImagePreviewBox"><table><tr><td>'+
'<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">'+
'<img id="' + previewImageId + '" alt="" /></a>' +
( editor.config.image_previewText ||'' ) +
'</td></tr></table></div></div>'
}
]
}
]
}
]
},
{
id : 'Link',
hidden : true,
label : editor.lang.link.title,
padding : 0,
elements :
[
{
id : 'txtUrl',
type : 'text',
label : editor.lang.common.url,
style : 'width: 100%',
'default' : '',
setup : function( type, element )
{
if ( type == LINK )
{
var href = element.data( 'cke-saved-href' );
if ( !href )
href = element.getAttribute( 'href' );
this.setValue( href );
}
},
commit : function( type, element )
{
if ( type == LINK )
{
if ( this.getValue() || this.isChanged() )
{
var url = decodeURI( this.getValue() );
element.data( 'cke-saved-href', url );
element.setAttribute( 'href', url );
if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )
this.getDialog().addLink = true;
}
}
}
},
{
type : 'button',
id : 'browse',
filebrowser :
{
action : 'Browse',
target: 'Link:txtUrl',
url: editor.config.filebrowserImageBrowseLinkUrl
},
style : 'float:right',
hidden : false,
label : editor.lang.common.browseServer
},
{
id : 'cmbTarget',
type : 'select',
label : editor.lang.common.target,
'default' : '',
items :
[
[ editor.lang.common.notSet , ''],
[ editor.lang.common.targetNew , '_blank'],
[ editor.lang.common.targetTop , '_top'],
[ editor.lang.common.targetSelf , '_self'],
[ editor.lang.common.targetParent , '_parent']
],
setup : function( type, element )
{
if ( type == LINK )
this.setValue( element.getAttribute( 'target' ) || '' );
},
commit : function( type, element )
{
if ( type == LINK )
{
if ( this.getValue() || this.isChanged() )
element.setAttribute( 'target', this.getValue() );
}
}
}
]
},
{
id : 'Upload',
hidden : false,
filebrowser : 'uploadButton',
label : editor.lang.image.upload,
elements :
[
{
type : 'file',
id : 'upload',
label : editor.lang.image.btnUpload,
style: 'height:40px',
size : 38
},
{
type : 'fileButton',
id : 'uploadButton',
filebrowser : 'info:txtUrl',
label : editor.lang.image.btnUpload,
'for' : [ 'Upload', 'upload' ]
}
]
},
{
id : 'advanced',
label : editor.lang.common.advancedTab,
elements :
[
{
type : 'hbox',
widths : [ '50%', '25%', '25%' ],
children :
[
{
type : 'text',
id : 'linkId',
label : editor.lang.common.id,
setup : function( type, element )
{
if ( type == IMAGE )
this.setValue( element.getAttribute( 'id' ) );
},
commit : function( type, element )
{
if ( type == IMAGE )
{
if ( this.getValue() || this.isChanged() )
element.setAttribute( 'id', this.getValue() );
}
}
},
{
id : 'cmbLangDir',
type : 'select',
style : 'width : 100px;',
label : editor.lang.common.langDir,
'default' : '',
items :
[
[ editor.lang.common.notSet, '' ],
[ editor.lang.common.langDirLtr, 'ltr' ],
[ editor.lang.common.langDirRtl, 'rtl' ]
],
setup : function( type, element )
{
if ( type == IMAGE )
this.setValue( element.getAttribute( 'dir' ) );
},
commit : function( type, element )
{
if ( type == IMAGE )
{
if ( this.getValue() || this.isChanged() )
element.setAttribute( 'dir', this.getValue() );
}
}
},
{
type : 'text',
id : 'txtLangCode',
label : editor.lang.common.langCode,
'default' : '',
setup : function( type, element )
{
if ( type == IMAGE )
this.setValue( element.getAttribute( 'lang' ) );
},
commit : function( type, element )
{
if ( type == IMAGE )
{
if ( this.getValue() || this.isChanged() )
element.setAttribute( 'lang', this.getValue() );
}
}
}
]
},
{
type : 'text',
id : 'txtGenLongDescr',
label : editor.lang.common.longDescr,
setup : function( type, element )
{
if ( type == IMAGE )
this.setValue( element.getAttribute( 'longDesc' ) );
},
commit : function( type, element )
{
if ( type == IMAGE )
{
if ( this.getValue() || this.isChanged() )
element.setAttribute( 'longDesc', this.getValue() );
}
}
},
{
type : 'hbox',
widths : [ '50%', '50%' ],
children :
[
{
type : 'text',
id : 'txtGenClass',
label : editor.lang.common.cssClass,
'default' : '',
setup : function( type, element )
{
if ( type == IMAGE )
this.setValue( element.getAttribute( 'class' ) );
},
commit : function( type, element )
{
if ( type == IMAGE )
{
if ( this.getValue() || this.isChanged() )
element.setAttribute( 'class', this.getValue() );
}
}
},
{
type : 'text',
id : 'txtGenTitle',
label : editor.lang.common.advisoryTitle,
'default' : '',
onChange : function()
{
updatePreview( this.getDialog() );
},
setup : function( type, element )
{
if ( type == IMAGE )
this.setValue( element.getAttribute( 'title' ) );
},
commit : function( type, element )
{
if ( type == IMAGE )
{
if ( this.getValue() || this.isChanged() )
element.setAttribute( 'title', this.getValue() );
}
else if ( type == PREVIEW )
{
element.setAttribute( 'title', this.getValue() );
}
else if ( type == CLEANUP )
{
element.removeAttribute( 'title' );
}
}
}
]
},
{
type : 'text',
id : 'txtdlgGenStyle',
label : editor.lang.common.cssStyle,
validate : CKEDITOR.dialog.validate.inlineStyle( editor.lang.common.invalidInlineStyle ),
'default' : '',
setup : function( type, element )
{
if ( type == IMAGE )
{
var genStyle = element.getAttribute( 'style' );
if ( !genStyle && element.$.style.cssText )
genStyle = element.$.style.cssText;
this.setValue( genStyle );
var height = element.$.style.height,
width = element.$.style.width,
aMatchH = ( height ? height : '' ).match( regexGetSize ),
aMatchW = ( width ? width : '').match( regexGetSize );
this.attributesInStyle =
{
height : !!aMatchH,
width : !!aMatchW
};
}
},
onChange : function ()
{
commitInternally.call( this,
[ 'info:cmbFloat', 'info:cmbAlign',
'info:txtVSpace', 'info:txtHSpace',
'info:txtBorder',
'info:txtWidth', 'info:txtHeight' ] );
updatePreview( this );
},
commit : function( type, element )
{
if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
{
element.setAttribute( 'style', this.getValue() );
}
}
}
]
}
]
};
};
CKEDITOR.dialog.add( 'image', function( editor )
{
return imageDialog( editor, 'image' );
});
CKEDITOR.dialog.add( 'imagebutton', function( editor )
{
return imageDialog( editor, 'imagebutton' );
});
})();
做出的显示效果如下。
点击图片按钮显示图片上传界面
java中上传图片代码如下
@RequestMapping("imageUpload")
public void imageUpload(HttpServletRequest request, HttpServletResponse response) {
String DirectoryName = "upload/";
try {
ImageUploadUtil.ckeditor(request, response, DirectoryName);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
/**
* @ClassName: ImageUploadUtil
* @Description: 图片上传工具类,包括ckeditor操作
* @author manman
*/
public class ImageUploadUtil {
private static Logger logger=Logger.getLogger(ImageUploadUtil.class);
// 图片类型
private static List<String> fileTypes = new ArrayList<String>();
static {
fileTypes.add(".jpg");
fileTypes.add(".jpeg");
fileTypes.add(".bmp");
fileTypes.add(".gif");
fileTypes.add(".png");
}
public static String upload(HttpServletRequest request, String DirectoryName)
throws IllegalStateException, IOException {
// 创建一个通用的多部分解析器
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
request.getSession().getServletContext());
// 图片名称
String fileName = null;
// 判断 request 是否有文件上传,即多部分请求
if (multipartResolver.isMultipart(request)) {
// 转换成多部分request
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
// 取得request中的所有文件名
Iterator<String> iter = multiRequest.getFileNames();
while (iter.hasNext()) {
// 记录上传过程起始时的时间,用来计算上传时间
// int pre = (int) System.currentTimeMillis();
// 取得上传文件
MultipartFile file = multiRequest.getFile(iter.next());
if (file != null) {
// 取得当前上传文件的文件名称
String myFileName = file.getOriginalFilename();
// 如果名称不为“”,说明该文件存在,否则说明该文件不存在
if (myFileName.trim() != "") {
// 获得图片的原始名称
String originalFilename = file.getOriginalFilename();
// 获得图片后缀名称,如果后缀不为图片格式,则不上传
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
if (!fileTypes.contains(suffix)) {
continue;
}
// 获得上传路径的绝对路径地址(/upload)-->
String realPath = request.getSession().getServletContext().getRealPath("/" + DirectoryName);
// 如果路径不存在,则创建该路径
File realPathDirectory = new File(realPath);
if (realPathDirectory == null || !realPathDirectory.exists()) {
realPathDirectory.mkdirs();
}
// 重命名上传后的文件名 111112323.jpg
fileName = DateUtil.getCurrentDate("yyyyMMddHHmmss")+ suffix;
// 定义上传路径 .../upload/111112323.jpg
File uploadFile = new File(realPathDirectory + "\\" + fileName);
logger.error("图片的路径:"+uploadFile);
file.transferTo(uploadFile);
}
}
// 记录上传该文件后的时间
// int finaltime = (int) System.currentTimeMillis();
// System.out.println(finaltime - pre);
}
}
return fileName;
}
/**
* ckeditor文件上传功能,回调,传回图片路径,实现预览效果。
*
* @Title ckeditor
* @param request
* @param response
* @param DirectoryName
* 文件上传目录:比如upload(无需带前面的/) upload/..
* @throws IOException
*/
public static void ckeditor(HttpServletRequest request, HttpServletResponse response, String DirectoryName)
throws IOException {
String fileName = upload(request, DirectoryName);
// 结合ckeditor功能
// imageContextPath为图片在服务器地址,如upload/123.jpg,非绝对路径
String imageContextPath = request.getContextPath() + "/" + DirectoryName + "/" + fileName;
response.setContentType("text/html;charset=UTF-8");
String callback = request.getParameter("CKEditorFuncNum");
PrintWriter out = response.getWriter();
out.println("<script type=\"text/javascript\">");
out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'" + imageContextPath + "',''" + ")");
out.println("</script>");
out.flush();
out.close();
}
}