类Excel的公式输入框的实现

504 阅读1分钟

类Excel公式输入框的实现

github: github.com/hellozhaoxu…

Excel中有一个公式输入框,用于编辑公式。其功能:
  • 当输入=时自动弹出所有可使用的公式选择框,采用下框的形式供用户选择。
  • 当光标的前一位字符能关联出公式时,在光标附近弹出所有关联出的公式,共用户选择。

1.Excel效果图

在这里插入图片描述
在这里插入图片描述

2.最终实现效果图

在这里插入图片描述
在这里插入图片描述

3.实现

其中引入的jquery.caret.js,请去github自取。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>类Excel随光标移动公式选择器</title>

	<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
	 <script src="../js/jquery-caret/jquery.caret.js"></script>
	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

<script type="text/javascript">
	var ruleList = ['SUM()', 'IF()', 'COUNT()', 'MAX()', 'SIN()', 'SUMIF()', 'AVERAGE()'];	
</script>

<body>
	<div class="container-fluid">
		<div class="row">
	    	<div class="col-md-2" style="padding: 0">
	    		<input style="width: 100%">
	    	</div>
	    	<div class="col-md-1" style="padding: 0">
	    		<input style="width: 100%">
	    	</div>
	    	<div class="col-md-9" style="padding: 0">
	    		<!-- 公式输入框 -->
	    		<input id="ruleInput" oninput="onRuleInput()" onblur="onblurRuleInput()" style="width: 100%">
	    		<!-- 公式选择器 -->
	            <div id="ruleSelect" hidden style="position:absolute; background: white; width:200px;">
	              <table class="table table-hover table-bordered"> <tbody id="ruleSelectBody"></tbody> </table>
	            </div>
	    	</div>
		</div>
	</div>
</body>

<script type="text/javascript">
	// 公式输入事件
	function onRuleInput(){
		var ruleContent = $("#ruleInput").val();
	    var pos = $('#ruleInput').caret();	// 当前光标位置
	    var filter = '-1';

	    if(ruleContent.length < 1){
	      filter = '-1';
	    }else if(ruleContent === '='){	// 开始输入公式,不筛选
	      filter = '';
	    }else{
	      ruleContent = ruleContent.substring(0, pos);
	      var inputList = ruleContent.split(/(\+|\-|\*|\/|\=|\(|\))/);	// 按运算符拆分
	      var lastStr = inputList[inputList.length-1];

	      if(lastStr=='=' || lastStr=='+' || lastStr=='-' || lastStr=='*' || lastStr=='/' || lastStr=='' || lastStr=='('|| lastStr==')'){
	        filter = '-1';
	      }else{
	        filter = lastStr;
	      }
	    }

	    var ruleList = ruleFilter(filter);

	    if(ruleList.length == 0){
	      // 隐藏公式编辑器div
	      $("#ruleSelect").hide();

	    }else{
	      var tbodyHtml = '';
	      ruleList.forEach(function(value){
	        tbodyHtml = tbodyHtml + '<tr onclick ="insertRule(\'' + filter + '\',\'' + value + '\')"> <td height="35">' + value + '</td> </tr>';
	      });

	      $("#ruleSelectBody").html(tbodyHtml);
	      $("#ruleSelect").attr("style","margin-left:"+pos*7+"px; position:absolute; background: white; width:200px;");
	      $("#ruleSelect").show();
	    }

	}

	// 公式取消输入事件
	function onblurRuleInput(){
		setTimeout(function(){
		    $("#ruleSelect").hide();
		},200);
	}

	/*
	* 公式选中插入
	* oldRule: 已输入的部分
	* rule: 选中的公式
	*/
	function insertRule(oldRule,rule){
		// 确定要新增的部分字符串
	    if(oldRule != ''){
	      rule = rule.substring(oldRule.length);
	    }

	    var ruleInput = document.getElementById('ruleInput');
	    if (window.getSelection) {
	      // 非IE浏览器
	      ruleInput.setRangeText(rule);
	      // 重新设置光标位置
	      ruleInput.selectionStart += rule.length;
	      ruleInput.focus()

	    } else if (document.selection) {
	      // IE浏览器
	      ruleInput.focus();
	      var sel = document.selection.createRange();
	      sel.text = rule;
	    }

	    $("#ruleSelect").hide();
	}

	// 公式筛选
	function ruleFilter(start){
      if (start.length == '') {
        return ruleList;
      }

      var resultList = [];
      ruleList.forEach(function(value) {
        if (value.indexOf(start) == 0) {
          resultList.push(value);
        }
      });

      return resultList;
    }
</script>
</html>