Skip to content
jquery.jgsttable.js 11.6 KiB
Newer Older
Jack Dan's avatar
Jack Dan committed

(function ($) {
    $.fn.jgstTable = function (options) {
        var debug = true;
        var rowCount = 0;
        var $rows = null;
        var statInfos;
        var defaults = {
            highValue: 30,
            highStyle1: 'high1',
            highStyle2: 'high2',
            lowValue: -30,
            lowStyle1: 'low1',
            lowStyle2: 'low2',
            row1Style: "r1",
            row2Style: "r2",
            rowHoverStyle: "rover",
            rowActiveStyle: "ractive"
        };


        var lastEditRow;
        var dStart = new Date().getTime();

        var opts = $.extend(defaults, options);
        this.each(function () {
            statInfos = new Array();

            $this = $(this);

            //隐藏
            $this.hide();

            //取表头
            $thr = $this.children(0);
            //根据表头信息取统计设置
            $thr.find("th[statField]").each(function (index, domEle) {
                $thStat = $(domEle);
                var statInfo = new StatInfo();

                //统计字段索引值
                statInfo._StatField = $(domEle).index();

                //统计类型
                statInfo._Type = $thStat.attr("statType");

                //统计对象相关信息
                var statFields = $thStat.attr("statField").split(",");
                //统计数据字段1
                statInfo._FirstField = $thr.find("." + statFields[0]).index();
                //统计数据字段2
                statInfo._SecondField = $thr.find("." + statFields[1]).index();
                //前缀
                statInfo._Prefix = $thStat.attr("prefix");
                //后缀
                statInfo._Suffix = $thStat.attr("suffix");
                //合计
                statInfo._TotalContainer = $thStat.attr("totalContainer");

                statInfo._FirstArray = new Array();
                statInfo._SecondArray = new Array();

                //if (statInfo._Type == "sum") {
                statInfo._StatArray = new Array();
                statInfo._TotalVal = 0;
                //}
                statInfos[index] = statInfo;
            });

            //遍历内容行
            $rows = $this.find("tr:not(:first)");
            rowCount = $rows.size();
            $rows.each(function (index) {
                $row = $(this);

                //绑定悬停事件
                $row.hover(
                    function () {
                        if (!$(this).hasClass(defaults.rowActiveStyle)) {
                            $(this).addClass(defaults.rowHoverStyle);
                        }
                    },
                    function () {
                        if (!$(this).hasClass(defaults.rowActiveStyle)) {
                            $(this).removeClass(defaults.rowHoverStyle);
                        }
                    }
                );


                /*
                //设置交替颜色
                if (index % 2 == 0) {
                $row.addClass(defaults.row1Style);
                }
                else {
                $row.addClass(defaults.row2Style);
                }
                */

                //处理统计字段
                $(statInfos).each(function (statInfoIndex) {

                    $rowCells = $row.children();
                    //获取相关单元格
                    var sf = $rowCells.get(this._StatField);
                    var fc = $rowCells.get(this._FirstField);
                    var sc = $rowCells.get(this._SecondField);

                    var firstval = GetCellVal(fc);
                    var secondval = GetCellVal(sc);
                    this._FirstArray[index] = firstval;
                    this._SecondArray[index] = secondval;

                    if (this._Type == "sum") {
                        var total = accMul(firstval, secondval);
                        this._StatArray[index] = total;
                        if (this._TotalContainer) {

                            this._TotalVal = accAdd(this._TotalVal, total);
                        }
                    }

                    //初始化统计字段值
                    SetRowStatVal(this, index, sf);

                    //绑定键盘事件以及焦点时间
                    var $fcInput = $(fc).find("input[type='text']");
                    var $scInput = $(sc).find("input[type='text']");
                    
                    if ($fcInput.get(0)) {
                        $fcInput
                        .bind("keyup", { WhichEle: 0, InputEle: $fcInput, StatInfoIndex: statInfoIndex, DataIndex: index, StatField: sf }, FireInputValChanged)
                        .bind("focus", { row: $row }, SetActive)
                        .bind("keydown", { theRow: $row, cellIndex: this._FirstField }, BindSwitchRow);
                    }
                    if ($scInput.get(0)) {
                        $scInput
                        .bind("keyup", { WhichEle: 1, InputEle: $scInput, StatInfoIndex: statInfoIndex, DataIndex: index, StatField: sf }, FireInputValChanged)
                        .bind("focus", { row: $row }, SetActive)
                        .bind("keydown", { theRow: $row, cellIndex: this._FirstField }, BindSwitchRow);
                    }
                });

            });

            //显示
            $this.show();

            $(statInfos).each(function () {
                if (this._Type == "sum" && this._TotalContainer) {
                    $(this._TotalContainer).text(this._TotalVal);
                }
            });

            DebugOut(new Date().getTime() - dStart);
        });

        function BindSwitchRow(event) {

            DebugOut(event.keyCode);
            var $currRow = $(event.data.theRow);
            var cellIndex = event.data.cellIndex;

            if (event.shiftKey) {
                if (event.keyCode == 9) {
                    var $prevRow = $currRow.prev("tr");
                    if ($prevRow.index() >= 0) {
                        FocusCellInput($prevRow, cellIndex);
                    }
                    return false;
                }
            }
            else {
                if (event.keyCode == 9 || event.keyCode == 13 || event.keyCode == 40) {
                    //Tab或Enter直接进入下一行
                    var $nextRow = $currRow.next("tr");

                    FocusCellInput($nextRow, cellIndex);
                    return false;
                }
                else if (event.keyCode == 38) {
                    var $prevRow = $currRow.prev("tr");
                    if ($prevRow.index() >= 0) {
                        FocusCellInput($prevRow, cellIndex);
                    }
                    return false;
                }
            }
        }

        function FocusCellInput(theRow, cellIndex) {
            $($(theRow).children().get(cellIndex)).find("input[type='text']").focus();
        }

        function DebugOut(str) {
            if (debug) {
                $("#msg").html(str);
            }
        }

        //设为行编辑状态
        function SetActive(event) {
            
            $(lastEditRow).removeClass(defaults.rowActiveStyle).removeClass(defaults.rowHoverStyle);
            lastEditRow = event.data.row;
            $(lastEditRow).addClass(defaults.rowActiveStyle).addClass(defaults.rowHoverStyle);
            $(event.target).select();
        }

        function FireInputValChanged(event) {
            var whichEle = event.data.WhichEle;
            var inputEle = event.data.InputEle;
            var newVal = $(inputEle).val();
            var statInfoIndex = event.data.StatInfoIndex;
            var dataIndex = event.data.DataIndex;
            var statField = event.data.StatField;

            var statInfo = statInfos[statInfoIndex];
            var diffVal = 0;


            if (whichEle == 0) {
                diffVal = newVal - statInfo._FirstArray[dataIndex];
                statInfo._FirstArray[dataIndex] = newVal;
            }
            else {
                diffVal = newVal - statInfo._SecondArray[dataIndex];
                statInfo._SecondArray[dataIndex] = newVal;
            }
            statInfo._StatArray[dataIndex] = accMul(statInfo._FirstArray[dataIndex], statInfo._SecondArray[dataIndex]);

            SetRowStatVal(statInfo, dataIndex, statField);
            CalTotal(statInfo);
        }

        function CalTotal(statInfo) {
            if (statInfo._Type == "sum" && statInfo._TotalContainer) {
                var dStart = new Date().getTime();
                var total = 0;
                for (i = 0; i < statInfo._StatArray.length; i++) {
                    total = accAdd(total, statInfo._StatArray[i]);
                }

                $(statInfo._TotalContainer).text(total);
                //DebugOut(new Date().getTime() - dStart);
            }
        }

        function SetRowStatVal(statInfo, dataIndex, statField) {
            var firstval = statInfo._FirstArray[dataIndex];
            var secondval = statInfo._SecondArray[dataIndex];
            var statVal = "";
            if (statInfo._Type == "sum") {
                //合计
                statVal = statInfo._Prefix + statInfo._StatArray[dataIndex] + statInfo._Suffix;
            } else {
                //浮动
                var perc = 0;
                if (secondval != 0) {
                    perc = parseInt((firstval - secondval) * 100 / secondval);
                }
                //设置浮动样式
                SetFloadStyle(statField, perc);
                statVal = statInfo._Prefix + perc + statInfo._Suffix;
            }
            $(statField).text(statVal);
        }

        function SetFloadStyle(statField, perc) {
            switch (true) {
                case perc >= defaults.highValue:
                    $(statField).addClass(defaults.highStyle2);
                    break;
                case perc <= defaults.lowValue:
                    $(statField).addClass(defaults.lowStyle2);
                    break;
                case perc > 0 && perc < defaults.highValue:
                    $(statField).addClass(defaults.highStyle1);
                    break;
                case perc < 0 && perc > defaults.lowValue:
                    $(statField).addClass(defaults.lowStyle1);
                    break;
                default:
                    $(statField).removeClass(defaults.highStyle1)
					    .removeClass(defaults.highStyle2)
					    .removeClass(defaults.lowStyle1)
					    .removeClass(defaults.lowStyle2);
                    break;
            }
        }


        //获取字段值
        function GetCellVal(cell) {
            var ipt = $(cell).find("input[type='text']").get(0);
            if ($(ipt).size() == 0) {
                return parseFloat(0 + $(cell).text());
            } else {
                return parseFloat(0 + $(ipt).val());
            }
        }

        //统计信息类
        function StatInfo() {
            var _Type, _FirstField, _SecondField, _StatField, _Prefix, _Suffix, _TotalContainer;
            var _TotalVal;
            var _FirstArray, _SecondArray, _StatArray;
        }

        function accMul(arg1, arg2) {
            var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
            try { m += s1.split(".")[1].length } catch (e) { }
            try { m += s2.split(".")[1].length } catch (e) { }
            return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
        }

        function accAdd(arg1, arg2) {
            var r1, r2, m;
            try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 }
            try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 }
            m = Math.pow(10, Math.max(r1, r2))
            return (arg1 * m + arg2 * m) / m
        }
    };
})(jQuery);