前面基本环境都做得差不多了,这篇我们来介绍自定义插件的开发。
我们以"文本框“为例,
先来看效果:
点击确定,即可插入一个文本框
实现方式:
1、在ckeditor目录下 plugins文件夹下,新建如下结构:
plugin.js
- CKEDITOR.plugins.add( 'ths_textfield', {
- icons: 'ths_textfield',
- init: function( editor ) { //初始化
- var pluginName = 'ths_textfield'; //控件名称
- editor.addCommand( pluginName, new CKEDITOR.dialogCommand( pluginName ) ); //给编辑器注册一个打开弹出窗命令
- editor.ui.addButton(pluginName, { //在工具栏上增加一个按钮,绑定按钮事件
- label: '单行文本框',
- command: pluginName
- });
- if ( editor.contextMenu ) { //为文本框加右键属性菜单
- editor.addMenuGroup( 'textFieldGroup' );
- editor.addMenuItem( 'textFieldItem', {
- label: '文本框属性',
- command:pluginName,
- group: 'textFieldGroup'
- });
- //右键菜单的监听器,判断是否显示菜单
- editor.contextMenu.addListener( function( element ) {
- if ( element && !element.isReadOnly() ) {
- var name = element.getName();
- if ( name == 'input' ) {
- var type = element.getAttribute( 'type' ) || 'text';
- if ( type=='text' ){
- return { textFieldItem: CKEDITOR.TRISTATE_OFF };
- }
- }
- }
- });
- }
- //增加弹出窗
- CKEDITOR.dialog.add( pluginName, this.path + 'dialogs/'+pluginName+'.js' );
- //为文本框双击事件绑定一个事件,即显示弹出窗
- editor.on( 'doubleclick', function( evt ) {
- var element = evt.data.element;
- if ( element.is( 'input' ) ) {
- var type = element.getAttribute( 'type' ) || 'text';
- if ( type=='text' ){
- evt.data.dialog =pluginName;
- }
- }
- })
- }
- });
不喜欢讲代码,大家结合文档看注释
ths_textfield.js
- CKEDITOR.dialog.add( 'ths_textfield', function( editor ) {
- return {
- title: '单行文本框属性',
- minWidth: 400,
- minHeight: 200,
- //弹出窗上显示的内容
- contents: [
- {
- id: 'tab-basic',
- label: '基本属性',
- elements:[ {
- type: 'hbox',
- widths: [ '50%', '50%' ],
- children:
- [
- ths_editor_field(editor),
- ths_editor_value(editor)
- ]
- },
- {
- type: 'hbox',
- widths: [ '50%', '50%' ],
- children:
- [ths_editor_relative_width(editor) ,
- ths_editor_style(editor)
- ]
- }
- ]
- },
- {
- id: 'tab-validate',
- label: '数据校验',
- elements: [
- {
- type: 'checkbox',
- id: 'required',
- label: '必填',
- setup: function( element ) {
- if(element.getAttribute( "required" )){
- this.setValue(true);
- }
- },
- commit: function ( element ) {
- var required = this.getValue();
- if ( required )
- element.setAttribute( 'required', 'true' );
- else if ( !this.insertMode )
- element.removeAttribute( 'required' );
- }
- }
- ]
- },
- {
- id: 'tab-event',
- label: '事件',
- elements: [
- ths_editor_onblur(editor),
- ths_editor_onfocus(editor),
- ths_editor_onclick(editor),
- ths_editor_onchange(editor)
- ]
- }
- ],
- //弹出窗显示事件
- onShow: function() {
- var selection = editor.getSelection();
- var element = selection.getStartElement();
- if ( !element || element.getName() != 'input' || element.getAttribute( 'type' )!='text' ) {
- this.insertMode = true;
- }else{
- this.insertMode = false;
- }
- this.element = element;
- if ( !this.insertMode ){
- this.setupContent( this.element );
- }
- },
- //弹出窗确定按钮事件
- onOk: function() {
- submitElement(this,editor,'text');
- }
- };
- });
补充js函数
这是针对所有表单组件的js
- function submitElement(dialog,editor,type){
- if ( dialog.insertMode ){ //如果是新建状态
- var div=editor.document.createElement( 'div' );
- var label;
- var element;
- //为不同的元素赋值
- switch ( type ) {
- case 'select':
- element = editor.document.createElement( 'select' );
- if(dialog.getValueOf( 'tab-basic', 'dictionary')){element.setAttribute( 'dictionary', dialog.getValueOf( 'tab-basic', 'dictionary') )};
- break;
- case 'textarea':
- element = editor.document.createElement( 'textarea' );
- if(dialog.getValueOf( 'tab-basic', 'value')){element.setAttribute( 'value', dialog.getValueOf( 'tab-basic', 'value') )};
- break;
- case 'text':
- element = editor.document.createElement( 'input' );
- element.setAttribute( 'type', type );
- //if(dialog.getValueOf( 'tab-basic', 'size')!='default'){element.addClass( dialog.getValueOf( 'tab-basic', 'size') )};
- if(dialog.getValueOf( 'tab-basic', 'value')){element.setAttribute( 'value', dialog.getValueOf( 'tab-basic', 'value') )};
- break;
- case 'checkbox':
- label=editor.document.createElement( 'label' );
- label.addClass( 'checkbox-inline' );
- element = editor.document.createElement( 'input' );
- element.setAttribute( 'type', type );
- if(dialog.getValueOf( 'tab-basic', 'dictionary')){element.setAttribute( 'dictionary', dialog.getValueOf( 'tab-basic', 'dictionary') )};
- break;
- case 'radio':
- label=editor.document.createElement( 'label' );
- label.addClass( 'radio-inline' );
- element = editor.document.createElement( 'input' );
- element.setAttribute( 'type', type );
- if(dialog.getValueOf( 'tab-basic', 'dictionary')){element.setAttribute( 'dictionary', dialog.getValueOf( 'tab-basic', 'dictionary') )};
- break;
- case 'hidden':
- element = editor.document.createElement( 'input' );
- element.setAttribute( 'type', type );
- element.setAttribute( 'name', dialog.getValueOf( 'tab-basic', 'name' ) );
- if(dialog.getValueOf( 'tab-basic', 'value')){element.setAttribute( 'value', dialog.getValueOf( 'tab-basic', 'value') )};
- editor.insertElement( element );
- return;
- }
- element.addClass( 'form-control' );
- element.setAttribute( 'name', dialog.getValueOf( 'tab-basic', 'name' ) );
- if(dialog.getValueOf( 'tab-basic', 'style' )){
- element.setAttribute( 'style', element.getAttribute('style') ? element.getAttribute('style')+dialog.getValueOf( 'tab-basic', 'style' ):dialog.getValueOf( 'tab-basic', 'style' ) )
- };
- if(dialog.getValueOf( 'tab-basic', 'width' )) {div.addClass(dialog.getValueOf( 'tab-basic', 'width'))};
- if(dialog.getValueOf( 'tab-event', 'onclick')){element.setAttribute( 'onclick', dialog.getValueOf( 'tab-event', 'onclick') )};
- if(dialog.getValueOf( 'tab-event', 'onfocus')){element.setAttribute( 'onfocus', dialog.getValueOf( 'tab-event', 'onfocus') )};
- if(dialog.getValueOf( 'tab-event', 'onblur')){element.setAttribute( 'onblur', dialog.getValueOf( 'tab-event', 'onblur') )} ;
- if(dialog.getValueOf( 'tab-event', 'onchange')){element.setAttribute( 'onchange', dialog.getValueOf( 'tab-event', 'onchange') )} ;
- if(dialog.getValueOf( 'tab-validate', 'required' )){element.setAttribute( 'required', dialog.getValueOf( 'tab-validate', 'required' ) )};
- if(label){
- label.append(element);
- div.append(label);
- }else{
- div.append(element);
- }
- editor.insertElement( div );
- }else{
- dialog.commitContent( dialog.element );
- }
- }
弹出窗中,显示文本域的示例:
- function ths_editor_size(editor){
- var editor_size={
- type : 'select',
- id: 'size',
- label: '大小:',
- style: 'width:190px',
- 'default' : 'default',
- items :
- [
- [ '大', 'input-lg' ],
- [ '默认', 'default' ],
- [ '小', 'input-sm' ]
- ],
- setup: function( element ) { //弹出窗初始化时会调用
- var classStr=element.getAttribute( "class" ) ? element.getAttribute( "class" ) : 'default';
- if(classStr.indexOf('input')>=0){
- classStr=classStr.substring(classStr.indexOf('input'),classStr.indexOf('input')+8);
- this.setValue(classStr);
- }else{
- return;
- }
- },
- commit: function( element ) { //提交时会调用
- var classStr = this.getValue();
- if(element.hasClass('input-lg')) element.removeClass('input-lg');
- if(element.hasClass('input-sm')) element.removeClass('input-sm');
- if ( classStr && classStr!='default'){
- element.addClass(classStr);
- }
- }
- }
- return editor_size;
- }
不想贴代码,感觉代码真的很无力,但想说明白一件事,似乎代码来得更直接些,上面代码均为核心代码。
随后会把代码开源,请留意
如果你英文比较好,推荐看如下两篇文章:
http://docs.ckeditor.com/#!/guide/plugin_sdk_sample_1
http://docs.ckeditor.com/#!/guide/plugin_sdk_sample_2