现公布自定义表单控件的部分代码,这个纯属个人利用空闲时间所做,欢迎大家交流。
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;" οnclick="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;
}
}
?>