现在的位置: 首页 > 综合 > 正文

自定义表单中计算控件的插件代码

2017年12月16日 ⁄ 综合 ⁄ 共 9023字 ⁄ 字号 评论关闭

现公布自定义表单控件的部分代码,这个纯属个人利用空闲时间所做,欢迎大家交流。

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;
	}
}

?>

抱歉!评论已关闭.