基于jQuery的TreeGrid组件

/**
 * @author 陈举民
 * @version 1.0
 * @link http://chenjumin.iteye.com/blog/419522
 */
TreeGrid = function (_config) {
    _config = _config || {};

    var s = "";
    var rownum = 0;
    var __root;

    var __selectedData = null;
    var __selectedId = null;
    var __selectedIndex = null;

    var folderOpenIcon = (_config.folderOpenIcon || TreeGrid.FOLDER_OPEN_ICON);
    var folderCloseIcon = (_config.folderCloseIcon || TreeGrid.FOLDER_CLOSE_ICON);
    var defaultLeafIcon = (_config.defaultLeafIcon || TreeGrid.DEFAULT_LEAF_ICON);

    //显示表头行
    drowHeader = function () {
        s += "<tr class=‘header‘ height=‘" + (_config.headerHeight || "25") + "‘>";
        var cols = _config.columns;
        for (i = 0; i < cols.length; i++) {
            var col = cols[i];
            s += "<td align=‘" + (col.headerAlign || _config.headerAlign || "center") + "‘ width=‘" + (col.width || "") + "‘>" + (col.headerText || "") + "</td>";
        }
        s += "</tr>";
    }

    //递归显示数据行
    drowData = function () {
        var rows = _config.data;
        var cols = _config.columns;
        drowRowData(rows, cols, 1, "");
    }

    //局部变量i、j必须要用 var 来声明,否则,后续的数据无法正常显示
    drowRowData = function (_rows, _cols, _level, _pid) {
        var folderColumnIndex = (_config.folderColumnIndex || 0);

        for (var i = 0; i < _rows.length; i++) {
            var id = _pid + "_" + i; //行id
            var row = _rows[i];

            s += "<tr id=‘TR" + id + "‘ data-pid=‘" + ((_pid == "") ? "0" : ("TR" + _pid)) + "‘ data-open=‘Y‘ data-row=\"" + TreeGrid.json2str(row) + "\" data-rowIndex=‘" + rownum++ + "‘>";
            for (var j = 0; j < _cols.length; j++) {
                var col = _cols[j];
                s += "<td align=‘" + (col.dataAlign || _config.dataAlign || "left") + "‘";

                //层次缩进
                if (j == folderColumnIndex) {
                    s += " style=‘text-indent:" + (parseInt((_config.indentation || "20")) * (_level - 1)) + "px;‘> ";
                } else {
                    s += ">";
                }

                //节点图标
                if (j == folderColumnIndex) {
                    if (row.children) { //有下级数据
                        s += "<img data-folder=‘Y‘ data-trid=‘TR" + id + "‘ src=‘" + folderOpenIcon + "‘ class=‘image_hand‘>";
                    } else {
                        s += "<img src=‘" + defaultLeafIcon + "‘ class=‘image_nohand‘>";
                    }
                }

                //单元格内容
                if (col.handler) {
                    s += (eval(col.handler + ".call(new Object(), row, col)") || "") + "</td>";
                } else {
                    s += (row[col.dataField] || "") + "</td>";
                }
            }
            s += "</tr>";

            //递归显示下级数据
            if (row.children) {
                drowRowData(row.children, _cols, _level + 1, id);
            }
        }
    }

    //主函数
    this.show = function () {
        this.id = _config.id || ("TreeGrid" + TreeGrid.COUNT++);

        s += "<table id=‘" + this.id + "‘ cellspacing=0 cellpadding=0 width=‘" + (_config.width || "100%") + "‘ class=‘TreeGrid‘>";
        drowHeader();
        drowData();
        s += "</table>";

        __root = jQuery("#" + _config.renderTo);
        __root.append(s);

        //初始化动作
        init();
    }

    init = function () {
        //以新背景色标识鼠标所指行
        if ((_config.hoverRowBackground || "false") == "true") {
            __root.find("tr").hover(
                function () {
                    if (jQuery(this).attr("class") && jQuery(this).attr("class") == "header") return;
                    jQuery(this).addClass("row_hover");
                },
                function () {
                    jQuery(this).removeClass("row_hover");
                }
            );
        }

        //将单击事件绑定到tr标签
        __root.find("tr").bind("click", function () {
            __root.find("tr").removeClass("row_active");
            jQuery(this).addClass("row_active");

            //获取当前行的数据
            __selectedData = jQuery(this).attr(‘data-row‘);
            __selectedId = jQuery(this).attr(‘id‘);
            __selectedIndex = jQuery(this).attr(‘data-rowIndex‘);

            //行记录单击后触发的事件
            if (_config.itemClick) {
                eval(_config.itemClick + "(__selectedId, __selectedIndex, TreeGrid.str2json(__selectedData))");
            }
        });

        //展开、关闭下级节点
        __root.find("img[data-folder=‘Y‘]").bind("click", function () {
            var trid = jQuery(this).attr("data-trid");
            var isOpen = __root.find("#" + trid).attr("data-open");

            isOpen = (isOpen == "Y") ? "N" : "Y";
            __root.find("#" + trid).attr("data-open", isOpen);
            showHiddenNode(trid, isOpen);
        });
    }

    //显示或隐藏子节点数据
    showHiddenNode = function (_trid, _open) {
        if (_open == "N") { //隐藏子节点
            __root.find("#" + _trid).find("img[data-folder=‘Y‘]").attr("src", folderCloseIcon);
            __root.find("tr[id^=" + _trid + "_]").css("display", "none");
        } else { //显示子节点
            __root.find("#" + _trid).find("img[data-folder=‘Y‘]").attr("src", folderOpenIcon);
            showSubs(_trid);
        }
    }

    //递归检查下一级节点是否需要显示
    showSubs = function (_trid) {
        var isOpen = __root.find("#" + _trid).attr("data-open");
        if (isOpen == "Y") {
            var trs = __root.find("tr[data-pid=" + _trid + "]");
            trs.css("display", "");

            for (var i = 0; i < trs.length; i++) {
                showSubs(trs[i].id);
            }
        }
    }

    //展开或收起所有节点
    this.expandAll = function (isOpen) {
        var trs = __root.find("tr[data-pid=‘0‘]");
        for (var i = 0; i < trs.length; i++) {
            var trid = trs[i].id || trs[i].getAttribute("id");
            showHiddenNode(trid, isOpen);
        }
    }

    //取得当前选中的行记录
    this.getSelectedItem = function () {
        return new TreeGridItem(__root, __selectedId, __selectedIndex, TreeGrid.str2json(__selectedData));
    }

};

//公共静态变量
TreeGrid.FOLDER_OPEN_ICON = "images/folderOpen.gif";
TreeGrid.FOLDER_CLOSE_ICON = "images/folderClose.gif";
TreeGrid.DEFAULT_LEAF_ICON = "images/defaultLeaf.gif";
TreeGrid.COUNT = 1;

//将json对象转换成字符串
TreeGrid.json2str = function(obj){
    var arr = [];

    var fmt = function(s){
        if(typeof s == ‘object‘ && s != null){
            if(s.length){
                var _substr = "";
                for(var x=0;x<s.length;x++){
                    if(x>0) _substr += ", ";
                    _substr += TreeGrid.json2str(s[x]);
                }
                return "[" + _substr + "]";
            }else{
                return TreeGrid.json2str(s);
            }
        }
        return /^(string|number)$/.test(typeof s) ? "‘" + s + "‘" : s;
    }

    for(var i in obj){
        if(typeof obj[i] != ‘object‘){ //暂时不包括子数据
            arr.push(i + ":" + fmt(obj[i]));
        }
    }

    return ‘{‘ + arr.join(‘, ‘) + ‘}‘;
}

TreeGrid.str2json = function(s){
    var json = null;
    if(jQuery.browser.msie){
        json = eval("(" + s + ")");
    }else{
        json = new Function("return " + s)();
    }
    return json;
}

//数据行对象
function TreeGridItem (_root, _rowId, _rowIndex, _rowData){
    var __root = _root;

    this.id = _rowId;
    this.index = _rowIndex;
    this.data = _rowData;

    this.getParent = function(){
        var pid = jQuery("#" + this.id).attr("data-pid");
        if(pid!=""){
            var rowIndex = jQuery("#" + pid).attr("data-rowIndex");
            var data = jQuery("#" + pid).attr("data-row");
            return new TreeGridItem(_root, pid, rowIndex, TreeGrid.str2json(data));
        }
        return null;
    }

    this.getChildren = function(){
        var arr = [];
        var trs = jQuery(__root).find("tr[data-pid=‘" + this.id + "‘]");
        for(var i=0;i<trs.length;i++){
            var tr = trs[i];
            arr.push(new TreeGridItem(__root, tr.id, tr.rowIndex, TreeGrid.str2json(tr.data)));
        }
        return arr;
    }
};
body{
    font-size:11px;
}
.TreeGrid{
    border-collapse: collapse;
    font-size: 11px;
    border: 1px solid #778899;
}

.TreeGrid .header{
    background-color: #87CEEB;
    font-size: 11px;
    font-weight: 600;
}

.TreeGrid td{
    border: 1px solid #E6E6FA;
    padding: 4px 3px 2px 3px;
}

.TreeGrid a{
    text-decoration: underline;
    color: black;
}

.TreeGrid a:hover{
    color: blue;
}

.TreeGrid .image_hand{
    border: 0;
    cursor:hand;
    align:absmiddle;
}

.TreeGrid .image_nohand{
    border: 0;
    align:absmiddle;
}

.TreeGrid .row_hover{
    background-color: #E6E6FA;
}

.TreeGrid .row_active{
    background-color: #E0FFFF;
}
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <link href="css/treeGrid/TreeGrid.css" rel="stylesheet" type="text/css" />
    <script src="js/jquery.min.js" type="text/javascript"></script>
    <script src="js/TreeGrid.js" type="text/javascript"></script>
</head>
<body>
    <div id="div1">
    </div>
    <input type="button" value="关闭所有节点" onclick="expandAll(‘N‘)">
    <input type="button" value="展开所有节点" onclick="expandAll(‘Y‘)">
    <input type="button" value="取得当前行的数据" onclick="selectedItem()"><br>
    当前选中的行:
    <input type="text" id="currentRow" size="110" />
    <script type="text/javascript">
        var config = {
            id: "tg1",
            width: "800",
            renderTo: "div1",
            headerAlign: "left",
            headerHeight: "30",
            dataAlign: "left",
            indentation: "20",
            folderOpenIcon: "/images/folderOpen.gif",
            folderCloseIcon: "/images/folderClose.gif",
            defaultLeafIcon: "/images/defaultLeaf.gif",
            hoverRowBackground: "false",
            folderColumnIndex: "0",
            itemClick: "itemClickEvent",
            columns: [
            //{ headerText: "", headerAlign: "center", dataAlign: "center", width: "20", handler: "customCheckBox" },
                {headerText: "", headerAlign: "center", dataAlign: "center", width: "20" },
                { headerText: "名称", dataField: "name", headerAlign: "center", handler: "customOrgName" },
                { headerText: "拼音码", dataField: "code", headerAlign: "center", dataAlign: "center", width: "100" },
                { headerText: "负责人", dataField: "assignee", headerAlign: "center", dataAlign: "center", width: "100" }
            ],
            data: [
                { name: "城区分公司", code: "CQ", assignee: "", children: [
                    { name: "城区卡品分销中心" },
                    { name: "先锋服务厅", children: [
                        { name: "chlid1" },
                        { name: "chlid2" },
                        { name: "chlid3", children: [
                            { name: "chlid3-1" },
                            { name: "chlid3-2" },
                            { name: "chlid3-3" },
                            { name: "chlid3-4" }
                        ]
                        }
                    ]
                    },
                    { name: "半环服务厅" }
                ]
                },
                { name: "清新分公司", code: "QX", assignee: "", children: [] },
                { name: "英德分公司", code: "YD", assignee: "", children: [] },
                { name: "佛冈分公司", code: "FG", assignee: "", children: [] }
            ]
        };

        /*
        单击数据行后触发该事件
        id:行的id
        index:行的索引。
        data:json格式的行数据对象。
        */
        function itemClickEvent(id, index, data) {
            jQuery("#currentRow").val(id + ", " + index + ", " + TreeGrid.json2str(data));
        }

        /*
        通过指定的方法来自定义栏数据
        */
        function customCheckBox(row, col) {
            return "<input type=‘checkbox‘>";
        }

        function customOrgName(row, col) {
            var name = row[col.dataField] || "";
            return name;
        }

        function customLook(row, col) {
            return "<a href=‘‘ style=‘color:blue;‘>查看</a>";
        }

        //创建一个组件对象
        var treeGrid = new TreeGrid(config);
        treeGrid.show();

        /*
        展开、关闭所有节点。
        isOpen=Y表示展开,isOpen=N表示关闭
        */
        function expandAll(isOpen) {
            treeGrid.expandAll(isOpen);
        }

        /*
        取得当前选中的行,方法返回TreeGridItem对象
        */
        function selectedItem() {
            var treeGridItem = treeGrid.getSelectedItem();
            if (treeGridItem != null) {
                //获取数据行属性值
                //alert(treeGridItem.id + ", " + treeGridItem.index + ", " + treeGridItem.data.name);

                //获取父数据行
                var parent = treeGridItem.getParent();
                if (parent != null) {
                    //jQuery("#currentRow").val(parent.data.name);
                }

                //获取子数据行集
                var children = treeGridItem.getChildren();
                if (children != null && children.length > 0) {
                    jQuery("#currentRow").val(children[0].data.name);
                }
            }
        }
    </script>
</body>
</html>

一、TreeGrid组件相关的类

1、TreeGrid(_config)

_config:json格式的数据,组件所需要的数据都通过该参数提供。

2、TreeGridItem(_root, _rowId, _rowIndex, _rowData)

_root:显示组件实例的目标容器对象。

_rowId:选中行的id。

_rowIndex:选中行的索引。

_rowData:json格式的行数据。

二、_config参数详解

id:组件实例的id。

width:组件实例的宽度。

renderTo:用于显示组件实例的容器对象的id。一般用div作为容器。

headerAlign:标题行的对齐方式。

headerHeight:标题行的高度。

dataAlign:数据行的对齐方式。

indentation:层级缩进量。

folderColumnIndex:显示图标的数据列的索引,从0开始。

folderOpenIcon:节点展开时的图标。

folderCloseIcon:节点关闭时的图标。

defaultLeafIcon:叶节点的图标。

hoverRowBackground:鼠标滑过数据行时,背景色是否改变。

itemClick:单击数据行后触发的事件。事件方法包含三个参数,分别是:行的id、行的索引、行数据。

expandLayer:初始展开层数,默认只展开第1层。

columns:值为数组,数组元素为json对象。定义数据栏相关信息。

数组元素的属性:

headerText:栏的标题。

dataField:栏数据对应的字段名。

headerAlign:栏头对齐方式。

dataAlign:栏数据对齐方式。

width:栏的宽度。

handler:通过指定的方法来自定义栏数据。

folderHidden:在文件夹行隐藏单元格值。

data:组件的数据集。

三、TreeGrid的方法

show:显示填充数据后的组件对象。

expandAll:展开、关闭所有节点。该方法有一个参数,参数值为Y时表示展开,参数值为N时表示关闭。

getSelectedItem:获取当前选中的数据行,返回TreeGridItem对象。

四、TreeGridItem组件

1、组件属性

id:数据行的id。

index:数据行的索引。

data:json格式的行数据。

2、组件方法

getParent:获取父数据行。方法返回TreeGridItem对象。

getChildren:获取子数据行集。方法返回一个数组,数组元素为TreeGridItem对象。

demo下载

本文参考http://chenjumin.iteye.com/blog/419522 修改了里面的部分代码来兼容HTML5如果有侵犯您的权益,请你及时联系我,我会立即删除。

时间: 2024-10-10 14:05:11

基于jQuery的TreeGrid组件的相关文章

基于jQuery的TreeGrid组件详解

一.TreeGrid组件相关的类 1.TreeGrid(_config) _config:json格式的数据,组件所需要的数据都通过该参数提供. 2.TreeGridItem(_root, _rowId, _rowIndex, _rowData) _root:显示组件实例的目标容器对象. _rowId:选中行的id. _rowIndex:选中行的索引. _rowData:json格式的行数据. 二._config参数详解 id:组件实例的id. width:组件实例的宽度. renderTo:用

CMDB项目CURD组件之基于jQuery扩展封装组件

request.body from django.shortcuts import render,HttpResponse from django.views import View import json class AssetView(View): def get(self,request,*args,**kwargs): # 数据库中获取数据 return render(request,'asset.html') class AssetJsonView(View): def get(sel

基于jquery开发的UI框架整理分析

根据调查得知,现在市场中的UI框架差不多40个左右,不知大家都习惯性的用哪个框架,现在市场中有几款UI框架稍微的成熟一些,也是大家比较喜欢的一种UI框架,那应该是jQuery,有部分UI框架都是根据jQuery研发出来的产品,现在也很常见了. 国产jQuery UI框架 (jUI) DWZ DWZ富客户端框架(jQuery RIA framework), 是中国人自己开发的基于jQuery实现的Ajax RIA开源框架.设计目标是简单实用,快速开发,降低ajax开发成本. jQuery 部件布局

10款基于jQuery的图片滑块焦点图插件

1.Material UI – Material Design CSS 框架 Material Design 是谷歌推出的全新的设计理念,采用大胆的色彩.流畅的动画播放,以及卡片式的简洁设计.Material Design 风格的设计拥有干净的排版和简单的布局,容易理解,内容才是焦点.Material UI 是一个 CSS 框架和一组实现谷歌 Material Design 设计规范的 React 组件.可以作为 NPM 安装包,使用 browserify 和 reactify 的依赖管理和 J

easyUI中treegrid组件构造树形表格(简单数据类型)+ssm后台

这几天做的项目要求用树形表格的形式展示一部分数据,于是就想到了使用easyUI的treegrid组件,但几经翻查各种资料,发现数据类型大多采取标准数据类型,即包含children元素的数据类型,小编查遍各种资料,几经实验,小编找到了一种使用简单数据类型的展示树形表格的方法.在这里介绍给大家,仅供参考: 框架使用的是ssm框架,数据库用的是oracle,其中数据库中要展示的表设计成大致如下的样子: 参考了一下easyUI的demo中给出的数据类型,如下格式: 打开里面显示如下: 这是一个json串

一个基于jQuery的简单树形菜单

在工作中的项目使用的是一个前端基于 jQuery easyui 的一个系统,其中左侧的主菜单使用的是 easyui 中的 tree 组件,不是太熟悉,不过感觉不是太好用. 比如 easyui 中的 tree 需要单击分叉节点前的小三角,才能够展开或关闭节点.另外,它还必需要求浏览器在兼容模式下才能正常使用(这个项目中使用的 easyUI 是 1.2.2 版本,新版的 Tree 不存在该问题),很是不方便. 想修改又无从下手,所以有单独写一个简单的树形菜单的想法,趁下班的时间,抽空写了一个简单的J

基于Jquery 的 Chart

 Flot Flot一个纯javascript绘画库,基于jQuery开发.它能够在客户端根据任何数据集快速生成图片.目前只能绘制线状图和柱状. Flot  jQuery  jQchart 基于Canvas+jQuery,可拖放/交互的简单图形控件. jQchart  jQuery  Open Flash Chart Open Flash Chart是一个开源的Flash制图组件. Open Flash Chart  Plotkit PlotKit是一个纯javascript绘图工具包.它支持H

jquery 返回顶端组件

自己写了一个基于jquery的返回页面顶端的组件. (function($) { var g; $.backtop = function(options) { extend($.backtop.config, options); this.config = $.backtop.config; this.init(); g = this; }; $.backtop.config = { title : null,// 返回顶端文字说明 df_color : "#77AA55"// 组件默

EasyUI之tree组件与treegrid组件

最近做了一个使用EasyUI的基于角色的权限分配系统,在这个过程中为了有更好的用户体验(也在网上找了挺多关于该系统的界面),先上我做的截图: 虽然,后台的逻辑上并不难,但是这个EasyUI的tree组件和treegrid组件,确实让我废了一大把力气>>好了废话不多说,开始正题: 一:tree组件 每个节点都具备以下属性: id:节点ID,对加载远程数据很重要. text:显示节点文本. state:节点状态,'open' 或 'closed',默认:'open'.如果为'closed'的时候,