现公布自定义表单控件的部分代码,这个纯属个人利用空闲时间所做,欢迎大家交流。
ckeditor插件代码
插件配置文件plugin.js,该文件放在ckeditor下的plugins目录下
/** * 自定义表单设计器 计算控件 * author tony 2012-08-14 */ CKEDITOR.plugins.add('xd_calcu',{ init : function(editor){ var pluginName = 'xd_calcu'; editor.addCommand(pluginName,new CKEDITOR.dialogCommand(pluginName)); editor.ui.addButton(pluginName,{ label:'计算控件', command:pluginName, icon : CKEDITOR.plugins.getPath(pluginName) + 'calc.gif' }); CKEDITOR.dialog.add(pluginName,this.path + 'dialogs/xd_calcu.js'); if ( editor.addMenuItems ) { editor.addMenuItems( { xd_calcu : { label : '日历控件', command : 'xd_calcu', group : 'textfield', icon : CKEDITOR.plugins.getPath('xd_calcu') + 'calc.gif' } }); } if ( editor.contextMenu ) { editor.contextMenu.addListener( function( element ) { if ( element && !element.isReadOnly() ) { var name = element.getName(); var input_type = element.getAttribute('input_type'); if ( name == 'input' && input_type === 'calc'){ return { xd_calcu : CKEDITOR.TRISTATE_ON }; } } }); } editor.on( 'doubleclick', function( evt ) { var element = evt.data.element; if ( element.is( 'input' ) ) evt.data.dialog = 'xd_calcu'; }); } });
对话框文件xd_calcu.js
/** * 智能表单 计算控件 * @author tony 2012-08-14 */ //显示公式说明 function displayRemark(){ var displayDom = document.getElementById('displayRemark'); if(displayDom){ if(displayDom.style.display === 'none'){ displayDom.style.display = 'block'; } else { displayDom.style.display = 'none'; } } } CKEDITOR.dialog.add('xd_calcu',function(editor){ var elements = [ { id : 'calcName', type : 'text', widths : ['100px','150px'], label : '控件名称:', labelLayout : 'horizontal', labelStyle : 'font-weight:bold', style : 'width:150px;margin-left:25px;' }, { id : 'calcValue', type : 'textarea', widths : ['100px','150px'], rows : '3', cols : '45', label : '计算公式:', labelLayout : 'horizontal', labelStyle : 'font-weight:bold', style : 'width:150px;margin-left:25px;' }, { type : 'html', widths : ['10%','80%'], html : '<div style="text-align:center;width:300px;"> <a href="javascript:void(0);" style="color:blue;" onclick="displayRemark()">查看计算公式填写说明</a></div>' }, { type : 'html', widths : ['10px','300px'], html : '<div id="displayRemark" style="width:340px;height:150px;overflow-x:scroll;float:right;font-size: 10pt;font-family:宋体;color:blue;display:none;text-align:left;">' + '计算公式支持+ - * / ^和英文括号以及特定计算<br>函数,例如:(数值1+数值2)*数值3-ABS(数值4)<br>' + '其中数值1、数值2等为表单控件名称。<br>' + '<b>当前版本所支持的计算函数:</b><br>' + '1、MAX(数值1,数值2,数值3...) 输出最大值,<br> 英文逗号分割;<br>' + '2、MIN(数值1,数值2,数值3...) 输出最小值,<br> 英文逗号分割;<br>' + '3、ABS(数值1) 输出绝对值;<br>' + '4、MOD(数值1,数值2) 计算数值1和数值2的余数;<br>' + '5、AVG(数值1,数值2,数值3) 输出平均值;<br>' + '6、RMB(数值1) 输出人民币大写形式,<br> 数值范围0~9999999999.99;<br>' + '7、DAY(日期1-日期2) 输出时间差的整数天数;<br>' + '8、HOUR(日期1-日期2) 输出时间差的小时数;<br>' + '9、DATE(日期1-日期2) 输出时间差,<br> 形如:xx天xx小时xx分xx秒;<br>' + '10、LIST(列表控件名,第几列) 计算列表控件<br>指定列的和;<br>' + '<b>注意:参与日期计算的控件必须为日期类型<br>或者日期+时间类型。</b><br>' + '</div>' }, { id : 'calcPrec', type : 'text', 'default' : '4', widths : ['100px','150px'], label : '计算结果精度:', labelLayout : 'horizontal', labelStyle : 'font-weight:bold', style : 'width:150px' }, { id : 'calcFontSize', type : 'text', widths : ['100px','150px'], label : '字体大小:', labelLayout : 'horizontal', labelStyle : 'font-weight:bold', style : 'width:150px;margin-left:25px' }, { id : 'calcWidth', type : 'text', widths : ['100px','150px'], label : '控件宽度:', labelLayout : 'horizontal', labelStyle : 'font-weight:bold', style : 'width:150px;margin-left:25px' }, { id : 'calcHeight', type : 'text', widths : ['100px','150px'], label : '控件高度:', labelLayout : 'horizontal', labelStyle : 'font-weight:bold', style : 'width:150px;margin-left:25px' } ]; var dataSelect = [['---选择数据源---','0']]; if(typeof(MODULE_CONFIG) !== 'undefined'){ for(var key in MODULE_CONFIG){ var item = MODULE_CONFIG[key]; dataSelect.push([item,key]); } elements.push({ id : 'module_field', type : 'select', widths : ['5%','100px'], label : '业务表单字段:', labelLayout : 'horizontal', labelStyle : 'font-weight:bold', style : 'width:150px', 'default' : '0', items : dataSelect }); } return { title : '计算控件属性', width : 350, height : 300, resizable : false, style : 'overflow:scroll', onShow : function(){ delete this.xd_calcu; var element = this.getParentEditor().getSelection().getSelectedElement(); if ( element ) { this.xd_calcu = element; this.setupContent( element ); this.getContentElement('xd_calcu','calcName').setValue(element.getAttribute('title')); this.getContentElement('xd_calcu','calcValue').setValue(element.getAttribute('value')); this.getContentElement('xd_calcu','calcPrec').setValue(element.getAttribute('prec')); var styleString = element.getAttribute('style'); var styleArray = styleString.split(';'); for(var i = 0; i < styleArray.length; i++){ var itemArray = styleArray[i].split(':'); if(itemArray[0] === 'font-size'){ this.getContentElement('xd_calcu','calcFontSize').setValue(itemArray[1].substr(0,(itemArray[1].length - 2))); } if(itemArray[0] === 'width'){ this.getContentElement('xd_calcu','calcWidth').setValue(itemArray[1].substr(0,(itemArray[1].length - 2))); } if(itemArray[0] === 'height'){ this.getContentElement('xd_calcu','calcHeight').setValue(itemArray[1].substr(0,(itemArray[1].length - 2))); } } if(typeof(MODULE_CONFIG) !== 'undefined'){ this.getContentElement('xd_calcu','module_field').setValue(element.getAttribute('module_field')); } } }, onOk : function(){ var editor, element = this.xd_calcu, isInsertMode = !element; if ( isInsertMode ) { editor = this.getParentEditor(); element = editor.document.createElement( 'input' ); element.setAttribute( 'class', 'CALCU' ); element.setAttribute('align','absMiddle'); element.setAttribute('input_type','calc'); var element_index = XD_FORM_ELEMENT_INDEX(); element.setAttribute('name','DATA_' + element_index); element.setAttribute('id','DATA_' + element_index); editor.insertElement( element ); } element.setAttribute('title',this.getContentElement('xd_calcu','calcName').getValue()); element.setAttribute('value',this.getContentElement('xd_calcu','calcValue').getValue()); element.setAttribute('prec',this.getContentElement('xd_calcu','calcPrec').getValue()); var styleString = ''; var calcuFontSize = this.getContentElement('xd_calcu','calcFontSize').getValue(); var calcuWidth = this.getContentElement('xd_calcu','calcWidth').getValue(); var calcuHeight = this.getContentElement('xd_calcu','calcHeight').getValue(); if(calcuFontSize){ styleString += ('font-size:' + calcuFontSize + 'px;'); } if(calcuWidth){ styleString += ('width:' + calcuWidth + 'px;'); } if(calcuHeight){ styleString += ('height:' + calcuHeight + 'px;'); } element.setAttribute('style',styleString); element.setAttribute('element_type','xd_calcu'); if(typeof(MODULE_CONFIG) !== 'undefined'){ element.setAttribute('module_field',this.getContentElement('xd_calcu','module_field').getValue()); } this.commitContent( { element : element } ); }, contents : [ { id : 'xd_calcu', label : '计算控件属性', title : '计算控件属性', elements : elements } ] }; });
控件的php解析代码
<?php /** * 表单智能设计器 * 计算控件 * @author tony 2012-08-31 * @copyright www.sunairs.com */ require_once('Control.php'); class Sunairs_Calcu_Control extends Sunairs_Control{ public function parseControl($html,$opType="w",$formData=array()){ $calcus = $html->find('input[element_type="xd_calcu"]'); if(!empty($calcus)){ foreach($calcus as $e){ if($opType === 'w'){ $name = $e->name; $index = explode('_',$name); $value = $e->value; $elementValue = $value; if(isset($formData[$name]) && $formData[$name]){ $elementValue = $formData[$name]; } $htmlText = '<input value="'.$elementValue.'" name="'.$name.'" title="'.($e->title).'" type="text" class="CALC" classname="CALC" prec="'.($e->prec).'">'; //获取计算项 $elementArray = array(); $calcuElement = $html->find('input'); foreach($calcuElement as $calcuE){ if(strpos($value,$calcuE->title) >= 0){ $elementArray[] = $calcuE; } } $calcuString = $this->calculate($value,$elementArray); $htmlText .= '<script type="text/javascript">function calc_'.$index[1].'(){var myvalue=eval("'.$calcuString.'");if(myvalue==Infinity) document.form1.DATA_'.$index[1].'.value="无效结果";else if(!isNaN(myvalue)) {var prec=document.form1.DATA_'.$index[1].'.getAttribute(\'prec\');var vPrec;if(!prec) vPrec=10000;else vPrec=Math.pow(10,prec);var result = new Number(parseFloat(Math.round(myvalue*vPrec)/vPrec));document.form1.DATA_'.$index[1].'.value=result.toFixed(prec);}else document.form1.DATA_'.$index[1].'.value=myvalue;setTimeout(calc_'.$index[1].',1000);}setTimeout(calc_'.$index[1].',3000);</script>'; $e->outertext = $htmlText; } else { $name = $e->name; $outertext = isset($formData[$name]) ? $formData[$name] : ''; $e->outertext = $outertext; } } } return $html; } public function calculate( $VALUE, $ELEMENT_QUERY ){ if ( $VALUE == "" ) { return; } $VALUE = str_replace( array( "ABS(", "RMB(", "MAX(", "MIN(", "MOD(", "DAY(", "HOUR(", "AVG(", "DATE(", "LIST(" ), array( "calc_abs(", "calc_rmb(", "calc_max(", "calc_min(", "calc_mod(", "calc_day(", "calc_hour(", "calc_avg(", "calc_date(", "calc_list(" ), $VALUE ); $flag = FALSE; if ( preg_match( "/[\\+|\\-|\\*|\\/|,]+/i", $VALUE ) == 0 ) { $flag = TRUE; } foreach ( $ELEMENT_QUERY as $ELEMENT ) { $ETITLE1 = $ELEMENT->title; $nameArray = explode('_',$ELEMENT->name); $ITEM_ID1 = $nameArray[1]; if ( $flag && $ETITLE1 == $VALUE ) { $VALUE = "calc_getval('DATA_".$ITEM_ID1."')"; } else { if ( strstr( $ETITLE1, "/" ) ) { $ETITLE1 = str_replace( array( "/", "+", "-" ), array( "\\/", "\\+", "\\-" ), $ETITLE1 ); } $pattern = "/([\\+|\\-|\\*|\\/|\\(|,]+)".$ETITLE1."([\\+|\\-|\\*|\\/|\\)|,]+)/i"; $VALUE = preg_replace( $pattern, "\$1calc_getval('DATA_".$ITEM_ID1."')\$2", $VALUE ); $pattern = "/([\\+|\\-|\\*|\\/|,]+)".$ETITLE1."\$/i"; $VALUE = preg_replace( $pattern, "\$1calc_getval('DATA_".$ITEM_ID1."')", $VALUE ); $pattern = "/^".$ETITLE1."([\\+|\\-|\\*|\\/|,]+)/i"; $VALUE = preg_replace( $pattern, "calc_getval('DATA_".$ITEM_ID1."')\$1", $VALUE ); } } return $VALUE; } } ?>