JS 组件系列之BootstrapTable的treegrid功能

上篇给大家介绍了,下面重点给大家介绍JS 组件系列之BootstrapTable的treegrid功能,需要的的朋友一起学习吧!

一、效果预览

全部折叠

展开一级

全部展开

二、代码示例

怎么样?效果还行吧。给出js的源码供大家参考。

1) { func = window; $.each(names,f) { func = func[f]; }); } else { func = window[name]; } } if (typeof func === 'object') { return func; } if (typeof func === 'function') { return func.apply(self,args); } if (!func && typeof name === 'string' && sprintf.apply(this,[name].concat(args))) { return sprintf.apply(this,[name].concat(args)); } return defaultValue; }; var getItemField = function (item,field) { var value = item; if (typeof field !== 'string' || item.hasOwnProperty(field)) { return item[field]; } var props = field.split('.'); for (var p in props) { value = value[props[p]]; } return value; }; var getParent = function (node,source,field) { var data = []; var items = $.grep(source,function (item,index) { return node.ParentId == item[field]; }); $.each(items,function (index,item) { data.splice(0,item); var child = getParent(item,field); $.each(child,n) { data.splice(0,n); }); }); return data; }; var getChild = function (node,index) { return item.ParentId == node[field]; }); $.each(items,item) { data.push(item); var child = getChild(item,n) { data.push(n); }); }); return data; }; //调用bootstrapTable组件的构造器得到对象 var BootstrapTable = $.fn.bootstrapTable.Constructor,_initData = BootstrapTable.prototype.initData,_initPagination = BootstrapTable.prototype.initPagination,_initBody = BootstrapTable.prototype.initBody; //重写bootstrapTable的initData方法 BootstrapTable.prototype.initData = function () { _initData.apply(this,Array.prototype.slice.apply(arguments)); var that = this; if (that.options.treeView && this.data.length > 0) { var rows = []; var roots = $.grep(this.data,function (row,index) { return row.Level == that.options.treeRootLevel; }); $.each(roots,item) { rows.push(item); var child = getChild(item,that.data,that.options.treeId); $.each(child,n) { if (that.options.treeCollapseAll) { n.hidden = true; } rows.push(n); }); }); that.options.data = that.data = rows; } }; //重写bootstrapTable的initPagination方法 BootstrapTable.prototype.initPagination = function () { //理论情况下,treegrid是不支持分页的,所以默认分页参数为false this.options.pagination = false; //调用“父类”的“虚方法” _initPagination.apply(this,Array.prototype.slice.apply(arguments)); }; //重写bootstrapTable的initBody方法 BootstrapTable.prototype.initBody = function (fixedScroll) { var that = this,html = [],data = this.getData(); this.trigger('pre-body',data); this.$body = this.$el.find('tbody'); if (!this.$body.length) { this.$body = $('').appendTo(this.$el); } if (!this.options.pagination || this.options.sidePagination === 'server') { this.pageFrom = 1; this.pageTo = data.length; } for (var i = this.pageFrom - 1; i < this.pageTo; i++) { var key,item = data[i],style = {},csses = [],data_ = '',attributes = {},htmlAttributes = []; if (item.hidden) continue; style = calculateObjectValue(this.options,this.options.rowStyle,[item,i],style); if (style && style.css) { for (key in style.css) { csses.push(key + ': ' + style.css[key]); } } attributes = calculateObjectValue(this.options,this.options.rowAttributes,attributes); if (attributes) { for (key in attributes) { htmlAttributes.push(sprintf('%s="%s"',key,escapeHTML(attributes[key]))); } } if (item._data && !$.isEmptyObject(item._data)) { $.each(item._data,function (k,v) { if (k === 'index') { return; } data_ += sprintf(' data-%s="%s"',k,v); }); } html.push('' ); if (this.options.cardView) { html.push(sprintf('',sprintf('',this.options.iconsPrefix,this.options.icons.detailOpen),'','dindex(that.columns,field)]; if (!column.visible) { return; } style = sprintf('style="%s"',csses.concat(that.header.styles[j]).join('; ')); value = calculateObjectValue(column,that.header.formatters[j],[value,item,value); if (item['_' + field + '_id']) { id_ = sprintf(' id="%s"',item['_' + field + '_id']); } if (item['_' + field + '_class']) { class_ = sprintf(' class="%s"',item['_' + field + '_class']); } if (item['_' + field + '_rowspan']) { rowspan_ = sprintf(' rowspan="%s"',item['_' + field + '_rowspan']); } if (item['_' + field + '_title']) { title_ = sprintf(' title="%s"',item['_' + field + '_title']); } cellStyle = calculateObjectValue(that.header,that.header.cellStyles[j],cellStyle); if (cellStyle.classes) { class_ = sprintf(' class="%s"',cellStyle.classes); } if (cellStyle.css) { var csses_ = []; for (var key in cellStyle.css) { csses_.push(key + ': ' + cellStyle.css[key]); } style = sprintf('style="%s"',csses_.concat(that.header.styles[j]).join('; ')); } if (item['_' + field + '_data'] && !$.isEmptyObject(item['_' + field + '_data'])) { $.each(item['_' + field + '_data'],v) { if (k === 'index') { return; } data_ += sprintf(' data-%s="%s"',v); }); } if (column.checkBox || column.radio) { type = column.checkBox ? 'checkBox' : type; type = column.radio ? 'radio' : type; text = [that.options.cardView ? '
Box">','',that.header.formatters[j] && typeof value === 'string' ? value : '',that.options.cardView ? '
' : '%spx;">',(item.Level - that.options.treeRootLevel) * 15); var child = $.grep(data,function (d,i) { return d.ParentId == item[that.options.treeId] && !d.hidden; }); icon = sprintf('%s" style="cursor: pointer; margin: 0px 5px;">',child.length > 0 ? that.options.expandIcon : that.options.collapseIcon); //icon = sprintf('%s" style="cursor: pointer; margin: 0px 5px;">',child.length > 0 ? that.options.expandIcon : ""); } text = that.options.cardView ? ['
%s',style,getPropertyFromOther(that.columns,'field','title',field)) : '',sprintf('%s',value),'
' ].join('') : [sprintf('',id_,class_,data_,rowspan_,title_),indent,icon,value,'display && value === '') { text = ''; } } html.push(text); }); if (this.options.cardView) { html.push('%s">%s tr[data-index] > td').off('click dblclick').on('click dblclick',function (e) { var $td = $(this),$tr = $td.parent(),item = that.data[$tr.data('index')],index = $td[0].cellIndex,field = that.header.fields[that.options.detailView && !that.options.cardView ? index - 1 : index],field)],field); if ($td.find('.detail-icon').length) { return; } that.trigger(e.type === 'click' ? 'click-cell' : 'dbl-click-cell',field,$td); that.trigger(e.type === 'click' ? 'click-row' : 'dbl-click-row',$tr); if (e.type === 'click' && that.options.clickToSelect && column.clickToSelect) { var $selectItem = $tr.find(sprintf('[name="%s"]',that.options.selectItemName)); if ($selectItem.length) { $selectItem[0].click(); } } }); this.$body.find('> tr[data-index] > td > .detail-icon').off('click').on('click',function () { debugger; var $this = $(this),$tr = $this.parent().parent(),index = $tr.data('index'),row = data[index]; if ($tr.next().is('tr.detail-view')) { $this.find('i').attr('class',sprintf('%s %s',that.options.iconsprefix,that.options.icons.detailOpen)); $tr.next().remove(); that.trigger('collapse-row',index,row); } else { $this.find('i').attr('class',that.options.icons.detailClose)); $tr.after(sprintf('%s">%s tr[data-index] > td > .tree-icon').off('click').on('click',function (e) { debugger; e.stopPropagation(); var $this = $(this),row = data[index]; var icon = $(this); var child = getChild(data[index],data,c) { $.each(that.data,item) { if (item[that.options.treeId] == c[that.options.treeId]) { item.hidden = icon.hasClass(that.options.expandIcon); that.uncheck(index); return; } }); }); if (icon.hasClass(that.options.expandIcon)) { icon.removeClass(that.options.expandIcon).addClass(that.options.collapseIcon); } else { icon.removeClass(that.options.collapseIcon).addClass(that.options.expandIcon); } that.options.data = that.data; that.initBody(true); }); this.$selectItem = this.$body.find(sprintf('[name="%s"]',this.options.selectItemName)); this.$selectItem.off('click').on('click',function (event) { event.stopImmediatePropagation(); var $this = $(this),checked = $this.prop('checked'),row = that.data[$this.data('index')]; if (that.options.maintainSelected && $(this).is(':radio')) { $.each(that.options.data,row) { row[that.header.stateField] = false; }); } row[that.header.stateField] = checked; if (that.options.singleSelect) { that.$selectItem.not(this).each(function () { that.data[$(this).data('index')][that.header.stateField] = false; }); that.$selectItem.filter(':checked').not(this).prop('checked',false); } that.updateSelected(); that.trigger(checked ? 'check' : 'uncheck',$this); }); $.each(this.header.events,events) { if (!events) { return; } if (typeof events === 'string') { events = calculateObjectValue(null,events); } var field = that.header.fields[i],fieldindex = $.inArray(field,that.getVisibleFields()); if (that.options.detailView && !that.options.cardView) { fieldindex += 1; } for (var key in events) { that.$body.find('tr').each(function () { var $tr = $(this),$td = $tr.find(that.options.cardView ? '.card-view' : 'td').eq(fieldindex),index = key.indexOf(' '),name = key.substring(0,index),el = key.substring(index + 1),func = events[key]; $td.find(el).off(name).on(name,function (e) { var index = $tr.data('index'),row = that.data[index],value = row[field]; func.apply(this,[e,index]); }); }); } }); this.updateSelected(); this.resetView(); this.trigger('post-body'); }; //给组件增加认参数列表 $.extend($.fn.bootstrapTable.defaults,{ treeView: false,//treeView视图 treeField: "id",//treeView视图字段 treeId: "id",treeRootLevel: 0,//根节点序号 treeCollapseAll: false,//是否全部展开 collapseIcon: "glyphicon glyphicon-chevron-right",//折叠样式 expandIcon: "glyphicon glyphicon-chevron-down"//展开样式 }); })(jQuery);

组件的使用如下:

1、首先引用这个js文件

2、然后初始化组件

rush:js;"> $('#tb').bootstrapTable({ url: ActionUrl + 'GetMenuList',toolbar: '#toolbar',sidePagination: 'client',pagination: false,treeView: true,treeId: "Id",treeField: "Name",treeRootLevel: 1,clickToSelect: true,//collapseIcon: "glyphicon glyphicon-triangle-right",//折叠样式 //expandIcon: "glyphicon glyphicon-triangle-bottom"//展开样式 });

treeView:true表示启用树表格模式;

treeId:'Id'表示每一行tree的id;

treeField:'Name'表示要对那一列进行展开;

treeRootLevel:1表示树根的级别。

还有一个地方需要注意,要建立记录之间的父子级关系,必然后有一个ParentId的概念,所以在从后端返回的结果集里面,每条记录势必有一个ParentId的属性,如果是根节点,ParentId为null。比如我们后台得到的结果集的json格式如下:

rush:js;"> [{Id: 1,Name: "系统设置",Url: null,ParentId: null,Level: 1,CreateTime: null,Status: 1,SortOrder: 1,…},{Id: 2,Name: "菜单管理",Url: "/Systems/Menu/Index",ParentId: 1,Level: 2,{Id: 3,Name: "订单管理",CreateTime: "2017-05-31 17:05:27",{Id: 4,Name: "基础数据",CreateTime: "2017-05-31 17:05:55",{Id: 5,Name: "新增订单",Url: "/order/add",ParentId: 3,CreateTime: "2017-05-31 17:07:03",…}]

三、组件需要完善的地方

上述封装给大家提供一个扩展bootstrapTable组件treeview功能,还有很多地方需要完善,比如:

1、我们的叶子节点前面的图标可以去掉;

2、增加展开所有、折叠所有的功能

3、Level字段可以去掉,通过ParentId为null来确定根节点。

有兴趣的小伙伴可以自己试试。

四、总结

至此本文就结束了,这篇针对上篇做了一个补充,使得我们可以根据项目的需求自己选择用哪种方式,如果我们项目使用的是bootstrapTable作为数据展示的组件,可以考虑上述扩展;如果没有使用bootstrapTable,可以试试上篇的组件。

相关文章

Bootstrip HTML 查询搜索常用格式模版 &lt;form class=&...
如何在按钮上加红色数字 您可以使用Bootstrap的badge组件来在...
要让两个按钮左右排列,你可以使用 Bootstrap 的网格系统将它...
是的,可以将status设置为布尔类型,这样可以在前端使用复选...
前端工程师一般用的是Bootstrap的框架而不是样式,样式一般自...
起步导入:<linkrel="stylesheet"href="b...