写了个类似TreeGrid的控件

最近公司要求写个类似TreeGrid的控件,先上效果图:
这里写图片描述

其实就是传入一个tree数据集合,将需要合并的数据进行合并展示。合并的列可能是一列也可能是多列。

这里写图片描述

提前申明 需要依赖jquery

调用代码:

  initQueryGrid:function(){
        //获取表格展示的列
        function getColumn() {
            var arr = [
                {display: "序号", width: 60, type: "sysOrderNum", name: null, textAlign: "center"},
                {display: "分类", width: 180, type: "treeLevel", name: "type", textAlign: "center"},
                {display: "流程模板名称", width: 129, type: "content", name: "workflowSubject", textAlign: "left"},
                {display: "对应表单", width: 139, type: "content", name: "formSubject", textAlign: "left"},
                {display: "所属人", width: '*', type: "content", name: "memberName", textAlign: "left"},
                {display: "流程归属部门", width: 179, type: "content", name: "workflowDepartmentName", textAlign: "left"}
            ];
            return arr;
        }

        var grid = new GoTreeGrid({
            parent: "queryGrid",
            width: (document.body.clientWidth-228)*0.98,
            managerName: "test",
            managerMethod: "test",
            colModel: getColumn()
        });

        grid.addTreeRows(returnVal);
    },

组件代码如下:

//GoTreeGrid对象
function GoTreeGrid(options) {
    this.parent = options["parent"];
    this.managerName = options["managerName"];
    this.managerMethod = options["managerMethod"];
    //放置后台列名称,主要是用于从后台返回数据中获取相应字段的值
    this.colNames = [];
    this.alignCols = [];
    this.colTypes = [];
    //每列的列宽
    this.colWidths = [];
    this.rowIndex = 0;
    this.colIndex = 0;
    this.levelColWid = 100;
    this.tableId = __uid();
    //当前所有列对应的宽度 包含分类列
    this.curColWid = 0;
    this.contentCols = [];
    if (options["width"] && (options["width"] + "").indexOf("%") < 0) {
        this.pWidth = parseFloat(options["width"]);
    } else {
        //如果为空则设置为100%
        if(options["width"]==null){
            options["width"]='100%';
        }
        $('<table class="goTreeGrid" id="test_header" style="width: '+options["width"]+'%"><tbody><tr><td>#</td></tr></tbody></table>').appendTo($("#" + this.parent));
        this.pWidth = $("#test_header").get(0).offsetWidth;
        $("#test_header").remove();
        alert( this.pWidth)
    }
    //初始化标头数组
    this.columns = this.initTreeLevels(options["colModel"]);
    this.starsCols = [];
    this._createGridHeader();
    this._createGridBody();
    表格的头进行合并操作后,会有像素差,所有需要进行修正
    if (_isIE8) {
        this._initColspanWidth();
    }

}
/**
 * 动态追加5列 层级作为分类使用
 * @param colModels
 * @returns {Array}
 */
GoTreeGrid.prototype.initTreeLevels = function (colModels) {
    var newColumns = [];
    this.conStartColNum = 0;
    for (var num = 0; num < colModels.length; num++) {
        newColumns.push(colModels[num]);
        if (colModels[num]["type"] == "treeLevel") {
            this.levelColWid = colModels[num]["width"];
            this.addNewColspan(newColumns, 5);
            this.conStartColNum = num + 5;
        }
    }
    return newColumns;
}

GoTreeGrid.prototype.addNewColspan = function (newColumns, nums) {
    for (var num = 0; num < nums; num++) {
        newColumns.push({display: "#cspan", width: 0, type: "colspanCol", name: null, textAlign: "center"})
    }
}
/*
 * 表格的头进行合并操作后,会有像素差,所有需要进行修正
 * */
GoTreeGrid.prototype._initColspanWidth = function () {
    var gridObj = this;
    $(".header td").each(function () {
        var colSpan = $(this).prop("colspan");
        if (colSpan != null && colSpan > 1) {
            var colIndex = $(this).attr("colIndex");
            var oldWidth = gridObj.colWidths[colIndex - 1];
            $($(this).parent().prev().find("th").get(colIndex - 1)).css("width", parseFloat(oldWidth) + parseFloat((colSpan - 2)));
        }
    })
}
//创建grid表格头
GoTreeGrid.prototype._createGridHeader = function () {
    var gridObj = this;
    var htmls = [], headerLabel = [], headerLabels = []
    htmls.push('<table class="goTreeGrid" style="table-layout: fixed;width:' + this.pWidth + 'px;" id="' + this.tableId + '_header"  cellpadding="0" cellspacing="0" ><tbody>');
    htmls.push('<tr style="height: auto;">');
    $.each(this.columns, function (index, item) {
        if (item["type"] === "content") {
            gridObj.contentCols.push(item);
        }
        //获取每列的列宽
        var colWidth = gridObj.getColWidth(item["width"], index);
        //缓存起每列的列宽信息
        gridObj.colWidths.push(colWidth);
        gridObj.colNames.push(item["name"]);
        if (item["type"] == "colspanCol") {
            htmls.push('<th class="colspanCol" colIndex="' + (index + 1) + '" style="height: 0px; width: ' + colWidth + 'px;"></th>');
        } else {
            htmls.push('<th colIndex="' + (index + 1) + '" style="height: 0px; width: ' + colWidth + 'px;"></th>');
        }

    });
    htmls.push('</tr>');

    htmls.push('<tr class="header">');
    $.each(this.columns, function (index, item) {
        gridObj.colIndex = ++gridObj.colIndex;
        var textStr = item["textAlign"] ? "style='text-align:" + item["textAlign"] + "'" : "";
        //将字体的摆放位置缓存起来
        gridObj.alignCols.push(textStr);
        //将每列的数据类型存放起来
        gridObj.colTypes.push(item["type"] || "field");
        if (item["display"] === "#cspan") {
            htmls.push('<td colIndex="' + (index + 1) + '" class="_cspan_col" ' + textStr + '><div>' + item["display"] + '</div></td>');
        } else {
            htmls.push('<td colIndex="' + (index + 1) + '" ' + textStr + '><div>' + item["display"] + '</div></td>');
        }
    });
    htmls.push('</tr>');
    htmls.push('</tbody></table>');
    $(htmls.join("")).appendTo($("#" + this.parent));
    如果传入的列中包含*号的列 则需要重新计算
    if (this.starsCols.length > 0) {
        this._initStartsColWidth();
    }

    this._initHeaderLabel();
}
/*
 * 初始化表格头的label 因为可能存在列头的合并操作
 * */
GoTreeGrid.prototype._initHeaderLabel = function () {
    $("._cspan_col").each(function () {
        var prevObj = $(this).prev();
        var colSpan = prevObj.attr("colspan") || 1;
        prevObj.attr("colSpan", ++colSpan);
        $(this).remove();
    });
}
/*
 * 因为有列宽设置了* 则需要重新计算*号对应的列 需要将剩余的宽度都分给相应的*号列
 * */
GoTreeGrid.prototype._initStartsColWidth = function () {
    //只有有剩余列宽才需要重新计算
    var gridObj = this;
    var syWid = parseFloat(this.pWidth) - this.curColWid;

    if (syWid > 0) {
        var colSyWid = syWid / this.starsCols.length;
        var newWidth = (100 + colSyWid);
        $.each(this.starsCols, function (index, colIndex) {

            $($("#" + gridObj.tableId + '_header').find("th").get(colIndex)).css("width", newWidth + "px");
            gridObj.colWidths[colIndex] = newWidth;
            newWidth = null;
        })
    }
}
//获取列宽
GoTreeGrid.prototype.getColWidth = function (width, colIndex) {
    if (width == parseFloat(width)) {
        this.curColWid = this.curColWid + parseFloat(width) + 1;
        return width;
    } else {
        this.starsCols.push(colIndex);
        this.curColWid = this.curColWid + parseFloat(100);
        return 100;
    }
}
GoTreeGrid.prototype._createGridBody = function () {
    var gridObj = this;
    var htmls = [];
    var headerHt = $($("#" + this.tableId + '_header').find("tr").get(0));
    htmls.push('<table style="table-layout: fixed;width:' + this.pWidth + 'px;" class="goTreeGridBody" id="' + this.tableId + '_body"  cellpadding="0" cellspacing="0" ><tbody>');
    htmls.push('<tr style="height: auto;">' + headerHt.html() + '</tr>');
    htmls.push('</tbody></table>');
    $(htmls.join("")).appendTo($("#" + this.parent));
    //如果传入的列中包含*号的列 则需要重新计算
    if (this.starsCols.length > 0) {
        this._initStartsColWidth();
    }
}
//添加一行数据
GoTreeGrid.prototype.addRow = function (rowsData) {
    var htmls = [];
    this._addRow(htmls, [rowsData], 0);
    $(htmls.join()).appendTo($("#" + this.tableId + '_body'))
}
GoTreeGrid.prototype.getEmptyRow = function (rowsData) {
    var htmls = [];
    for (var num = 0; num < this.colNames.length; num++) {
        htmls.push(" ");
    }
    return htmls.join("");
}
GoTreeGrid.prototype.addEmptyRow = function (rowSize) {
    var htmls = [];
    var rowIds = [];
    for (var num = 0; num < rowSize; num++) {
        rowIds.push(this._addRow(htmls, [this.getEmptyRow()], 0));
    }
    $(htmls.join("")).appendTo($("#" + this.tableId + '_body'));
    return rowIds;
}

/*
 * 添加行数据
 * */
GoTreeGrid.prototype._addRow = function (htmls, rowsDataAry, rowIndex) {
    this.rowIndex = ++this.rowIndex;
    var odd = this.rowIndex % 2 == 1 ? "even" : "odd";
    var rowId = __uid();
    var gridObj = this;
    htmls.push('<tr class="dataTr ' + odd + '" id="' + rowId + '" rowIndex="' + this.rowIndex + '">');
    $.each(rowsDataAry[rowIndex], function (index, item) {
        //获取当前列的 字体摆放样式
        var colStyle = gridObj.alignCols[index];
        //获取当前列的类型
        var curColType = gridObj.colTypes[index];
        if (curColType == "sysOrderNum") {
            htmls.push('<td id="' + rowId + '_' + index + '" ' + colStyle + '><div>' + gridObj.rowIndex + '</div></td>');
        } else {
            htmls.push('<td id="' + rowId + '_' + index + '" ' + colStyle + '><div>' + item + '</div></td>');
        }
    });
    htmls.push('</tr>');
    gridObj = null;
    htmls = null;
    return rowId;
}
//添加多行数据
GoTreeGrid.prototype.addRows = function (rowsDataAry) {
    var htmls = [];
    for (var num = 0; num < rowsDataAry.length; num++) {
        this._addRow(htmls, rowsDataAry, num);
    }
    $(htmls.join()).appendTo($("#" + this.tableId + '_body'))
}

/*
 * 根据colNum来进行列分组操作
 * */
function rowSpanToPre(trObjs, startNum, colIndex, index) {
    if (startNum - 2 - index >= 0) {
        var theLastTrId = $(trObjs[startNum - 1 - index]).attr("id");
        var theLastTd = $("#" + theLastTrId + "_" + colIndex);
        var preTrId = $(trObjs[startNum - 2 - index]).attr("id");
        var preTd = $("#" + preTrId + "_" + colIndex);
        if (theLastTd.html() != null && theLastTd.html() == preTd.html()) {
            preTd.attr("rowspan", parseFloat(parseFloat(theLastTd.attr("rowspan") || 1) + parseFloat(preTd.attr("rowspan") || 1)));
            theLastTd.remove();
        }
    }
}
/*
 * 对行内内容进行分组
 * */
GoTreeGrid.prototype.groupBy = function (colIndex) {
    var trObjs = $("#" + this.tableId + '_body .dataTr');
    var startNum = trObjs.length;
    var index = 0;
    for (var num = startNum; num >= 0; num--) {
        rowSpanToPre(trObjs, startNum, colIndex, index);
        index = index + 1;
    }
};

/*
 * 添加数据进body
 * */
GoTreeGrid.prototype._addRowToBody = function (para) {
    //加载数据
    this.populate(para);
};
/*
 ajax数据加载
 * */
GoTreeGrid.prototype.ajaxgridLoad = function (para) {
    //加载数据
    this.populate(para);
};
GoTreeGrid.prototype.populate = function (tempMap, backFun) { // get latest data
    if (this.loading) {
        return true;
    }
    var pageSize = ($.ctx && $.ctx._pageSize) ? $.ctx._pageSize : 20;
    var fp = {
        page: 1,
        size: pageSize
    };
    var gridObj = this;
    this.loading = true;
    callBackendMethod(this.managerName, this.managerMethod, tempMap, {
        success: function (returnVal) {
            //gridObj.addRows(returnVal);
            if (backFun != null) {
                backFun();
            } else {
                gridObj.addTreeRows(returnVal);
            }
        }
    });

};
GoTreeGrid.prototype._getNodeMaxSize = function (jsonObj) {
    return jsonObj["allCount"];
};
GoTreeGrid.prototype.getMaxRecordSize = function (itemObj, sonFields, jsonObj) {
    var sonList = itemObj[sonFields];
    var obj = this;
    if (sonList != null && sonList.length > 0) {
        if (sonList.length > jsonObj["maxRecordSize"]) {
            jsonObj["maxRecordSize"] = sonList.length;
        }
        $.each(sonList, function (index, item) {
            obj.getMaxRecordSize(item, sonFields, jsonObj);
        });
    }
};

GoTreeGrid.prototype._addSonTreeRows = function (treeObj, sonFields, rowIds, parentNode) {
    var marRowSize = this._getNodeMaxSize(treeObj, sonFields, treeObj);
    var startNum = parentNode["startNum"];
    for (var num1 = startNum; num1 < startNum + marRowSize; num1++) {
        $("#" + rowIds[num1] + "_" + treeObj["level"]).html(treeObj["name"]);
        ++parentNode["startNum"];

        var obj = this;
        treeObj["startNum"] = 0;
        var sonList = treeObj[sonFields];
        if (sonList != null && sonList.length > 0) {
            $.each(sonList, function (index, item) {
                if (item.type == "category") {
                    obj._addSonTreeRows(item, sonFields, rowIds, treeObj);
                } else {
                    //如果是模板界面 则需要加载模板字段信息
                    for (var cols = 0; cols < obj.contentCols.length; cols++) {
                        obj.setCellValue(rowIds[startNum] + "_" + obj.getContentColIndex(cols), obj.getContent(item, cols));
                    }
                }
                treeObj["startNum"] = ++treeObj["startNum"];
            });
        }
    }
};
GoTreeGrid.prototype._addTreeRows = function (treeObj, sonFields) {
    treeObj["startNum"] = 0;
    treeObj["maxRecordSize"] = 1;
    var marRowSize = this._getNodeMaxSize(treeObj, sonFields, treeObj);
    var rowIds = this.addEmptyRow(3);
    for (var num1 = 0; num1 < rowIds.length; num1++) {
        $("#" + rowIds[num1] + "_" + treeObj["level"]).html(treeObj["name"]);
    }

    var obj = this;
    var sonList = treeObj[sonFields];
    if (sonList != null && sonList.length > 0) {
        $.each(sonList, function (index, item) {
            if (item.type == "category") {
                obj._addSonTreeRows(item, sonFields, rowIds, treeObj);
            } else {
                //如果是模板界面 则需要加载模板字段信息
                for (var cols = 0; cols < obj.contentCols.length; cols++) {
                    obj.setCellValue(rowIds[treeObj["startNum"]] + "_" + obj.getContentColIndex(cols), obj.getContent(item, cols));
                }
            }
        });
    }

};
/*
 * 根据序号获取当前对象对应字段的值
 * */
GoTreeGrid.prototype.getContent = function (itemobj, cols) {
    var field = this.contentCols[cols];
    return itemobj[field["name"]];
};
GoTreeGrid.prototype.getContentColIndex = function (cols) {
    return parseFloat(this.conStartColNum) + cols + 1;
};
/*
 * 设置cell的value
 * */
GoTreeGrid.prototype.setCellValue = function (cellId, cellContent) {
    if (cellContent == null || cellContent == "null") {
        cellContent = "";
    }
    $("#" + cellId).html(cellContent);
};
/**
 * 获取当前行数据 从json对象中获取
 * @param jsonObj
 */
GoTreeGrid.prototype.getRowData = function (jsonObj) {

};
GoTreeGrid.prototype.getMaxLevel = function (itemObj, sonFields) {
    if (this.datas[itemObj["level"]] == null) {
        this.datas[itemObj["level"]] = [];
    }
    this.datas[itemObj["level"]].push(itemObj);

    var obj = this;
    var sonList = itemObj[sonFields];
    if (sonList != null && sonList.length > 0) {
        var sonLevel = itemObj["level"] + 1;
        if (sonLevel > obj.level) {
            obj.level = sonLevel;
        }
        $.each(sonList, function (index, item) {
            item["level"] = sonLevel;
            obj.getMaxLevel(item,sonFields);
        });
    }
};
/**
 * 清空所有数据 并将表格信息还原
 * @param jsonObj
 */
GoTreeGrid.prototype.clearAll = function () {
    var index = 0;
    //只有body的行数大于1 才需要进行移除操作
    if ($("#" + this.tableId + "_body tr").length > 1) {
        $("#" + this.tableId + "_body tr").each(function (els) {
            if (index != 0) {
                $(this).remove();
            }
            index++;
        })
    }
    //重新定义列表头信息
    this._initThAgain(this.typeLevel - 1, 0);
};


GoTreeGrid.prototype.addTreeRows = function (treeRecords) {
    this.clearAll();
    var obj = this;
    obj.typeLevel = 1;
    this.datas = {};
    this.level = 0;
    //循环计算出最大的层级
    $.each(treeRecords, function (index, itemObj) {
        treeRecords[index]["level"] = 1;
        obj.getMaxLevel(treeRecords[index], "childWorkflowPropertyList");
    });
    //如果层级大于3 是需要进行特殊显示处理。 类别的层级为最大层级减1
    if (obj.level > 1) {
        obj.typeLevel = obj.level - 1;
        obj._initThAgain(this.typeLevel - 1, obj.levelColWid);
    }

    $.each(treeRecords, function (index, itemObj) {
        obj._addTreeRows(treeRecords[index], "childWorkflowPropertyList");
    });

    //对分类信息进行分组操作。
    for (var num = 1; num <= obj.typeLevel; num++) {
        obj.groupBy(num);
    }

};
/**
 * 重新定义表格头的信息
 * @private
 */
GoTreeGrid.prototype._initThAgain = function (colspanCols, colspanWidth) {
    //调整colspan信息
    var colSpanCols = $("#" + this.tableId + "_header").find(".colspanCol");
    for (var num = 0; num < colspanCols; num++) {
        //如果传入的宽度 不等于本身宽度 则需要进行修改
        var elOldWid = $(colSpanCols.get(num)).css("width");
        if (elOldWid != colspanWidth) {
            $(colSpanCols.get(num)).css("width", colspanWidth);
            //计算this.curColWid的目的是 为了重新计算*号列的列宽
            this.curColWid = this.curColWid + parseFloat(colspanWidth);
        }
    }
    //重新计算*号对应的列宽
    this._initStartsColWidth();

    var headerHt = $($("#" + this.tableId + '_header').find("tr").get(0));
    //移除以前的标头信息 再追加最新th信息
    $($("#" + this.tableId + "_body").find("tr").get(0)).remove();
    $('<tr style="height: auto;">' + headerHt.html() + '</tr>').appendTo($("#" + this.tableId + "_body tbody"));
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值