diff --git a/Bootstrap.Admin/Views/Admin/Menus.cshtml b/Bootstrap.Admin/Views/Admin/Menus.cshtml
index 6a334df2..b4e84cf6 100644
--- a/Bootstrap.Admin/Views/Admin/Menus.cshtml
+++ b/Bootstrap.Admin/Views/Admin/Menus.cshtml
@@ -1,218 +1,223 @@
-@model NavigatorBarModel
-@{
- ViewBag.Title = "菜单管理";
- Layout = "_Default";
-}
-@section css {
-
-
-
-
-
-
-
-}
-@section javascript {
-
-
-
-
-
-
-
-
-
-}
-@section query {
-
-}
-@section toolbar {
-
-
-
-
-
-}
-@section modal {
-
-
-}
-@section customModal {
- @await Html.PartialAsync("RoleConfig")
-
- @await Html.PartialAsync("NavigatorConfig")
+@model NavigatorBarModel
+@{
+ ViewBag.Title = "菜单管理";
+ Layout = "_Default";
+}
+@section css {
+
+
+
+
+
+
+
+
+}
+@section javascript {
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+@section query {
+
+}
+@section toolbar {
+
+
+
+
+
+}
+@section modal {
+
+
+}
+@section customModal {
+ @await Html.PartialAsync("RoleConfig")
+
+ @await Html.PartialAsync("NavigatorConfig")
}
\ No newline at end of file
diff --git a/Bootstrap.Admin/libman.json b/Bootstrap.Admin/libman.json
index 8eca1d02..9c12404c 100644
--- a/Bootstrap.Admin/libman.json
+++ b/Bootstrap.Admin/libman.json
@@ -57,7 +57,19 @@
"bootstrap-table.js",
"bootstrap-table.min.css",
"extensions/export/bootstrap-table-export.js",
- "extensions/export/bootstrap-table-export.min.js"
+ "extensions/export/bootstrap-table-export.min.js",
+ "extensions/treegrid/bootstrap-table-treegrid.js",
+ "extensions/treegrid/bootstrap-table-treegrid.min.js"
+ ]
+ },
+ {
+ "provider": "cdnjs",
+ "library": "jquery-treegrid@0.2.0",
+ "destination": "wwwroot/lib/treegrid/",
+ "files": [
+ "css/jquery.treegrid.css",
+ "js/jquery.treegrid.js",
+ "js/jquery.treegrid.min.js"
]
},
{
diff --git a/Bootstrap.Admin/wwwroot/js/menus.js b/Bootstrap.Admin/wwwroot/js/menus.js
index 5a75ad9f..39293dd8 100644
--- a/Bootstrap.Admin/wwwroot/js/menus.js
+++ b/Bootstrap.Admin/wwwroot/js/menus.js
@@ -1,4 +1,4 @@
-$(function () {
+$(function () {
var $dialog = $('#dialogNew');
var $pickIcon = $('#pickIcon');
var $dialogNew = $dialog;
@@ -22,8 +22,8 @@
};
var state = [];
-
- $('table').lgbTable({
+ var $table = $('table');
+ $table.lgbTable({
url: Menu.url,
dataBinder: {
map: {
@@ -80,11 +80,19 @@
},
columns: [
{
- title: "父级菜单", field: "ParentName", sortable: true, formatter: function (value, row, index) {
- return (value === "0" || value === null) ? "" : value;
+ title: "菜单名称", field: "Name", sortable: true, formatter: function (value, row, index) {
+ return $.format('', value);
+ },
+ events: {
+ 'click .menu': function (e, value, row, index) {
+ var $plus = $(this).prev();
+ if ($plus.hasClass('fa')) {
+ $plus.trigger('click');
+ }
+ return false;
+ }
}
},
- { title: "菜单名称", field: "Name", sortable: true },
{ title: "菜单序号", field: "Order", sortable: true },
{
title: "菜单图标", field: "Icon", sortable: false, align: 'center', formatter: function (value, row, index) {
@@ -128,7 +136,29 @@
return $('#app').next().find('[data-val="' + value + '"]:first').text();
}
}
- ]
+ ],
+ idField: "Id",
+ //在哪一列展开树形
+ treeShowField: 'Name',
+ //指定父id列
+ parentIdField: 'ParentId',
+
+ onResetView: function (data) {
+ //console.log('load');
+ $table.treegrid({
+ treeColumn: 2,
+ expanderExpandedClass: 'fa fa-chevron-circle-down',
+ expanderCollapsedClass: 'fa fa-chevron-circle-down',
+ onChange: function () {
+ $table.bootstrapTable('resetWidth');
+ }
+ });
+ //只展开树形的第一级节点
+ $table.treegrid('getRootNodes').treegrid('expand');
+ },
+ onCheckRoot: function (row, data) {
+ return row[this.options.parentIdField] === '' || row[this.options.parentIdField] === '0';
+ }
}
});
diff --git a/Bootstrap.Admin/wwwroot/lib/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.js b/Bootstrap.Admin/wwwroot/lib/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.js
new file mode 100644
index 00000000..476d406a
--- /dev/null
+++ b/Bootstrap.Admin/wwwroot/lib/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.js
@@ -0,0 +1,95 @@
+/**
+ * @author: YL
+ * @version: v1.0.0
+ */
+!function ($) {
+ 'use strict';
+ $.extend($.fn.bootstrapTable.defaults, {
+ treeShowField: null,
+ idField: 'id',
+ parentIdField: 'pid',
+ onGetNodes: function (row, data) {
+ var that = this;
+ var nodes = [];
+ $.each(data, function (i, item) {
+ if (row[that.options.idField] === item[that.options.parentIdField]) {
+ nodes.push(item);
+ }
+ });
+ return nodes;
+ },
+ onCheckRoot: function (row, data) {
+ var that = this;
+ return !row[that.options.parentIdField];
+ }
+ });
+
+ var BootstrapTable = $.fn.bootstrapTable.Constructor,
+ _initRow = BootstrapTable.prototype.initRow,
+ _initHeader = BootstrapTable.prototype.initHeader;
+
+ // td
+ BootstrapTable.prototype.initHeader = function () {
+ var that = this;
+ _initHeader.apply(that, Array.prototype.slice.apply(arguments));
+ var treeShowField = that.options.treeShowField;
+ if (treeShowField) {
+ $.each(this.header.fields, function (i, field) {
+ if (treeShowField === field) {
+ that.treeEnable = true;
+ return false;
+ }
+ });
+ }
+ };
+
+ var initTr = function (item, idx, data, parentDom) {
+ var that = this;
+ var nodes = that.options.onGetNodes.apply(that, [item, data]);
+ item._nodes = nodes;
+ parentDom.append(_initRow.apply(that, [item, idx, data, parentDom]));
+
+ // init sub node
+ var len = nodes.length - 1;
+ for (var i = 0; i <= len; i++) {
+ var node = nodes[i];
+ node._level = item._level + 1;
+ node._parent = item;
+ if (i === len)
+ node._last = 1;
+ // jquery.treegrid.js
+ that.options.rowStyle = function (item, idx) {
+ var id = item[that.options.idField] ? item[that.options.idField] : 0;
+ var pid = item[that.options.parentIdField] ? item[that.options.parentIdField] : 0;
+ return {
+ classes: 'treegrid-' + id + ' treegrid-parent-' + pid
+ };
+ };
+ initTr.apply(that, [node, $.inArray(node, data), data, parentDom]);
+ }
+ };
+
+ // tr
+ BootstrapTable.prototype.initRow = function (item, idx, data, parentDom) {
+ var that = this;
+ if (that.treeEnable) {
+ // init root node
+ if (that.options.onCheckRoot.apply(that, [item, data])) {
+ if (item._level === undefined) {
+ item._level = 0;
+ }
+ // jquery.treegrid.js
+ that.options.rowStyle = function (item, idx) {
+ var x = item[that.options.idField] ? item[that.options.idField] : 0;
+ return {
+ classes: 'treegrid-' + x
+ };
+ };
+ initTr.apply(that, [item, idx, data, parentDom]);
+ return true;
+ }
+ return false;
+ }
+ return _initRow.apply(that, Array.prototype.slice.apply(arguments));
+ };
+}(jQuery);
\ No newline at end of file
diff --git a/Bootstrap.Admin/wwwroot/lib/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.min.js b/Bootstrap.Admin/wwwroot/lib/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.min.js
new file mode 100644
index 00000000..c3a8cd16
--- /dev/null
+++ b/Bootstrap.Admin/wwwroot/lib/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.min.js
@@ -0,0 +1,7 @@
+/*
+* bootstrap-table - v1.12.1 - 2018-03-12
+* https://github.com/wenzhixin/bootstrap-table
+* Copyright (c) 2018 zhixin wen
+* Licensed MIT License
+*/
+!function(a){"use strict";a.extend(a.fn.bootstrapTable.defaults,{treeShowField:null,idField:"id",parentIdField:"pid",onGetNodes:function(b,c){var d=this,e=[];return a.each(c,function(a,c){b[d.options.idField]===c[d.options.parentIdField]&&e.push(c)}),e},onCheckRoot:function(a){var b=this;return!a[b.options.parentIdField]}});var b=a.fn.bootstrapTable.Constructor,c=b.prototype.initRow,d=b.prototype.initHeader;b.prototype.initHeader=function(){var b=this;d.apply(b,Array.prototype.slice.apply(arguments));var c=b.options.treeShowField;c&&a.each(this.header.fields,function(a,d){return c===d?(b.treeEnable=!0,!1):void 0})};var e=function(b,d,f,g){var h=this,i=h.options.onGetNodes.apply(h,[b,f]);b._nodes=i,g.append(c.apply(h,[b,d,f,g]));for(var j=i.length-1,k=0;j>=k;k++){var l=i[k];l._level=b._level+1,l._parent=b,k===j&&(l._last=1),h.options.rowStyle=function(a){var b=a[h.options.idField]?a[h.options.idField]:0,c=a[h.options.parentIdField]?a[h.options.parentIdField]:0;return{classes:"treegrid-"+b+" treegrid-parent-"+c}},e.apply(h,[l,a.inArray(l,f),f,g])}};b.prototype.initRow=function(a,b,d,f){var g=this;return g.treeEnable?g.options.onCheckRoot.apply(g,[a,d])?(void 0===a._level&&(a._level=0),g.options.rowStyle=function(a){var b=a[g.options.idField]?a[g.options.idField]:0;return{classes:"treegrid-"+b}},e.apply(g,[a,b,d,f]),!0):!1:c.apply(g,Array.prototype.slice.apply(arguments))}}(jQuery);
\ No newline at end of file
diff --git a/Bootstrap.Admin/wwwroot/lib/treegrid/css/jquery.treegrid.css b/Bootstrap.Admin/wwwroot/lib/treegrid/css/jquery.treegrid.css
new file mode 100644
index 00000000..55e47e09
--- /dev/null
+++ b/Bootstrap.Admin/wwwroot/lib/treegrid/css/jquery.treegrid.css
@@ -0,0 +1,31 @@
+.treegrid-indent {
+ width:16px;
+ height: 16px;
+ display: inline-block;
+ position: relative;
+}
+
+.treegrid-expander {
+ width:16px;
+ height: 16px;
+ display: inline-block;
+ transition: all .3s ease;
+ transform: rotate(0);
+ margin-right: 2px;
+}
+
+ .treegrid-expander.fa {
+ cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ color: #17a2b8;
+ }
+
+ .treegrid-expander.fa + .menu {
+ cursor: pointer;
+ }
+
+ .treegrid-collapsed .treegrid-expander {
+ transform: rotate(-90deg);
+ }
diff --git a/Bootstrap.Admin/wwwroot/lib/treegrid/js/jquery.treegrid.js b/Bootstrap.Admin/wwwroot/lib/treegrid/js/jquery.treegrid.js
new file mode 100644
index 00000000..1785e531
--- /dev/null
+++ b/Bootstrap.Admin/wwwroot/lib/treegrid/js/jquery.treegrid.js
@@ -0,0 +1,619 @@
+/*
+ * jQuery treegrid Plugin 0.2.0
+ * https://github.com/maxazan/jquery-treegrid
+ *
+ * Copyright 2013, Pomazan Max
+ * Licensed under the MIT licenses.
+ */
+(function($) {
+
+ var methods = {
+ /**
+ * Initialize tree
+ *
+ * @param {Object} options
+ * @returns {Object[]}
+ */
+ initTree: function(options) {
+ var settings = $.extend({}, this.treegrid.defaults, options);
+ return this.each(function() {
+ var $this = $(this);
+ $this.treegrid('setTreeContainer', $(this));
+ $this.treegrid('setSettings', settings);
+ settings.getRootNodes.apply(this, [$(this)]).treegrid('initNode', settings);
+ });
+ },
+ /**
+ * Initialize node
+ *
+ * @param {Object} settings
+ * @returns {Object[]}
+ */
+ initNode: function(settings) {
+ return this.each(function() {
+ var $this = $(this);
+ $this.treegrid('setTreeContainer', settings.getTreeGridContainer.apply(this));
+ $this.treegrid('getChildNodes').treegrid('initNode', settings);
+ $this.treegrid('initExpander').treegrid('initIndent').treegrid('initEvents').treegrid('initState').treegrid("initSettingsEvents");
+ });
+ },
+ /**
+ * Initialize node events
+ *
+ * @returns {Node}
+ */
+ initEvents: function() {
+ var $this = $(this);
+ //Save state on change
+ $this.on("change", function() {
+ var $this = $(this);
+ $this.treegrid('render');
+ if ($this.treegrid('getSetting', 'saveState')) {
+ $this.treegrid('saveState');
+ }
+ });
+ //Default behavior on collapse
+ $this.on("collapse", function() {
+ var $this = $(this);
+ $this.removeClass('treegrid-expanded');
+ $this.addClass('treegrid-collapsed');
+ });
+ //Default behavior on expand
+ $this.on("expand", function() {
+ var $this = $(this);
+ $this.removeClass('treegrid-collapsed');
+ $this.addClass('treegrid-expanded');
+ });
+
+ return $this;
+ },
+ /**
+ * Initialize events from settings
+ *
+ * @returns {Node}
+ */
+ initSettingsEvents: function() {
+ var $this = $(this);
+ //Save state on change
+ $this.on("change", function() {
+ var $this = $(this);
+ if (typeof ($this.treegrid('getSetting', 'onChange')) === "function") {
+ $this.treegrid('getSetting', 'onChange').apply($this);
+ }
+ });
+ //Default behavior on collapse
+ $this.on("collapse", function() {
+ var $this = $(this);
+ if (typeof ($this.treegrid('getSetting', 'onCollapse')) === "function") {
+ $this.treegrid('getSetting', 'onCollapse').apply($this);
+ }
+ });
+ //Default behavior on expand
+ $this.on("expand", function() {
+ var $this = $(this);
+ if (typeof ($this.treegrid('getSetting', 'onExpand')) === "function") {
+ $this.treegrid('getSetting', 'onExpand').apply($this);
+ }
+
+ });
+
+ return $this;
+ },
+ /**
+ * Initialize expander for node
+ *
+ * @returns {Node}
+ */
+ initExpander: function() {
+ var $this = $(this);
+ var cell = $this.find('td').get($this.treegrid('getSetting', 'treeColumn'));
+ var tpl = $this.treegrid('getSetting', 'expanderTemplate');
+ var expander = $this.treegrid('getSetting', 'getExpander').apply(this);
+ if (expander) {
+ expander.remove();
+ }
+ $(tpl).prependTo(cell).click(function() {
+ $($(this).closest('tr')).treegrid('toggle');
+ });
+ return $this;
+ },
+ /**
+ * Initialize indent for node
+ *
+ * @returns {Node}
+ */
+ initIndent: function() {
+ var $this = $(this);
+ $this.find('.treegrid-indent').remove();
+ for (var i = 0; i < $(this).treegrid('getDepth'); i++) {
+ $($this.treegrid('getSetting', 'indentTemplate')).insertBefore($this.find('.treegrid-expander'));
+ }
+ return $this;
+ },
+ /**
+ * Initialise state of node
+ *
+ * @returns {Node}
+ */
+ initState: function() {
+ var $this = $(this);
+ if ($this.treegrid('getSetting', 'saveState') && !$this.treegrid('isFirstInit')) {
+ $this.treegrid('restoreState');
+ } else {
+ if ($this.treegrid('getSetting', 'initialState') === "expanded") {
+ $this.treegrid('expand');
+ } else {
+ $this.treegrid('collapse');
+ }
+ }
+ return $this;
+ },
+ /**
+ * Return true if this tree was never been initialised
+ *
+ * @returns {Boolean}
+ */
+ isFirstInit: function() {
+ var tree = $(this).treegrid('getTreeContainer');
+ if (tree.data('first_init') === undefined) {
+ tree.data('first_init', $.cookie(tree.treegrid('getSetting', 'saveStateName')) === undefined);
+ }
+ return tree.data('first_init');
+ },
+ /**
+ * Save state of current node
+ *
+ * @returns {Node}
+ */
+ saveState: function() {
+ var $this = $(this);
+ if ($this.treegrid('getSetting', 'saveStateMethod') === 'cookie') {
+
+ var stateArrayString = $.cookie($this.treegrid('getSetting', 'saveStateName')) || '';
+ var stateArray = (stateArrayString === '' ? [] : stateArrayString.split(','));
+ var nodeId = $this.treegrid('getNodeId');
+
+ if ($this.treegrid('isExpanded')) {
+ if ($.inArray(nodeId, stateArray) === -1) {
+ stateArray.push(nodeId);
+ }
+ } else if ($this.treegrid('isCollapsed')) {
+ if ($.inArray(nodeId, stateArray) !== -1) {
+ stateArray.splice($.inArray(nodeId, stateArray), 1);
+ }
+ }
+ $.cookie($this.treegrid('getSetting', 'saveStateName'), stateArray.join(','));
+ }
+ return $this;
+ },
+ /**
+ * Restore state of current node.
+ *
+ * @returns {Node}
+ */
+ restoreState: function() {
+ var $this = $(this);
+ if ($this.treegrid('getSetting', 'saveStateMethod') === 'cookie') {
+ var stateArray = $.cookie($this.treegrid('getSetting', 'saveStateName')).split(',');
+ if ($.inArray($this.treegrid('getNodeId'), stateArray) !== -1) {
+ $this.treegrid('expand');
+ } else {
+ $this.treegrid('collapse');
+ }
+
+ }
+ return $this;
+ },
+ /**
+ * Method return setting by name
+ *
+ * @param {type} name
+ * @returns {unresolved}
+ */
+ getSetting: function(name) {
+ if (!$(this).treegrid('getTreeContainer')) {
+ return null;
+ }
+ return $(this).treegrid('getTreeContainer').data('settings')[name];
+ },
+ /**
+ * Add new settings
+ *
+ * @param {Object} settings
+ */
+ setSettings: function(settings) {
+ $(this).treegrid('getTreeContainer').data('settings', settings);
+ },
+ /**
+ * Return tree container
+ *
+ * @returns {HtmlElement}
+ */
+ getTreeContainer: function() {
+ return $(this).data('treegrid');
+ },
+ /**
+ * Set tree container
+ *
+ * @param {HtmlE;ement} container
+ */
+ setTreeContainer: function(container) {
+ return $(this).data('treegrid', container);
+ },
+ /**
+ * Method return all root nodes of tree.
+ *
+ * Start init all child nodes from it.
+ *
+ * @returns {Array}
+ */
+ getRootNodes: function() {
+ return $(this).treegrid('getSetting', 'getRootNodes').apply(this, [$(this).treegrid('getTreeContainer')]);
+ },
+ /**
+ * Method return all nodes of tree.
+ *
+ * @returns {Array}
+ */
+ getAllNodes: function() {
+ return $(this).treegrid('getSetting', 'getAllNodes').apply(this, [$(this).treegrid('getTreeContainer')]);
+ },
+ /**
+ * Mthod return true if element is Node
+ *
+ * @returns {String}
+ */
+ isNode: function() {
+ return $(this).treegrid('getNodeId') !== null;
+ },
+ /**
+ * Mthod return id of node
+ *
+ * @returns {String}
+ */
+ getNodeId: function() {
+ if ($(this).treegrid('getSetting', 'getNodeId') === null) {
+ return null;
+ } else {
+ return $(this).treegrid('getSetting', 'getNodeId').apply(this);
+ }
+ },
+ /**
+ * Method return parent id of node or null if root node
+ *
+ * @returns {String}
+ */
+ getParentNodeId: function() {
+ return $(this).treegrid('getSetting', 'getParentNodeId').apply(this);
+ },
+ /**
+ * Method return parent node or null if root node
+ *
+ * @returns {Object[]}
+ */
+ getParentNode: function() {
+ if ($(this).treegrid('getParentNodeId') === null) {
+ return null;
+ } else {
+ return $(this).treegrid('getSetting', 'getNodeById').apply(this, [$(this).treegrid('getParentNodeId'), $(this).treegrid('getTreeContainer')]);
+ }
+ },
+ /**
+ * Method return array of child nodes or null if node is leaf
+ *
+ * @returns {Object[]}
+ */
+ getChildNodes: function() {
+ return $(this).treegrid('getSetting', 'getChildNodes').apply(this, [$(this).treegrid('getNodeId'), $(this).treegrid('getTreeContainer')]);
+ },
+ /**
+ * Method return depth of tree.
+ *
+ * This method is needs for calculate indent
+ *
+ * @returns {Number}
+ */
+ getDepth: function() {
+ if ($(this).treegrid('getParentNode') === null) {
+ return 0;
+ }
+ return $(this).treegrid('getParentNode').treegrid('getDepth') + 1;
+ },
+ /**
+ * Method return true if node is root
+ *
+ * @returns {Boolean}
+ */
+ isRoot: function() {
+ return $(this).treegrid('getDepth') === 0;
+ },
+ /**
+ * Method return true if node has no child nodes
+ *
+ * @returns {Boolean}
+ */
+ isLeaf: function() {
+ return $(this).treegrid('getChildNodes').length === 0;
+ },
+ /**
+ * Method return true if node last in branch
+ *
+ * @returns {Boolean}
+ */
+ isLast: function() {
+ if ($(this).treegrid('isNode')) {
+ var parentNode = $(this).treegrid('getParentNode');
+ if (parentNode === null) {
+ if ($(this).treegrid('getNodeId') === $(this).treegrid('getRootNodes').last().treegrid('getNodeId')) {
+ return true;
+ }
+ } else {
+ if ($(this).treegrid('getNodeId') === parentNode.treegrid('getChildNodes').last().treegrid('getNodeId')) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ /**
+ * Method return true if node first in branch
+ *
+ * @returns {Boolean}
+ */
+ isFirst: function() {
+ if ($(this).treegrid('isNode')) {
+ var parentNode = $(this).treegrid('getParentNode');
+ if (parentNode === null) {
+ if ($(this).treegrid('getNodeId') === $(this).treegrid('getRootNodes').first().treegrid('getNodeId')) {
+ return true;
+ }
+ } else {
+ if ($(this).treegrid('getNodeId') === parentNode.treegrid('getChildNodes').first().treegrid('getNodeId')) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ /**
+ * Return true if node expanded
+ *
+ * @returns {Boolean}
+ */
+ isExpanded: function() {
+ return $(this).hasClass('treegrid-expanded');
+ },
+ /**
+ * Return true if node collapsed
+ *
+ * @returns {Boolean}
+ */
+ isCollapsed: function() {
+ return $(this).hasClass('treegrid-collapsed');
+ },
+ /**
+ * Return true if at least one of parent node is collapsed
+ *
+ * @returns {Boolean}
+ */
+ isOneOfParentsCollapsed: function() {
+ var $this = $(this);
+ if ($this.treegrid('isRoot')) {
+ return false;
+ } else {
+ if ($this.treegrid('getParentNode').treegrid('isCollapsed')) {
+ return true;
+ } else {
+ return $this.treegrid('getParentNode').treegrid('isOneOfParentsCollapsed');
+ }
+ }
+ },
+ /**
+ * Expand node
+ *
+ * @returns {Node}
+ */
+ expand: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ if (!$this.treegrid('isLeaf') && !$this.treegrid("isExpanded")) {
+ $this.trigger("expand");
+ $this.trigger("change");
+ }
+ });
+ },
+ /**
+ * Expand all nodes
+ *
+ * @returns {Node}
+ */
+ expandAll: function() {
+ var $this = $(this);
+ $this.treegrid('getRootNodes').treegrid('expandRecursive');
+ return $this;
+ },
+ /**
+ * Expand current node and all child nodes begin from current
+ *
+ * @returns {Node}
+ */
+ expandRecursive: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ $this.treegrid('expand');
+ if (!$this.treegrid('isLeaf')) {
+ $this.treegrid('getChildNodes').treegrid('expandRecursive');
+ }
+ });
+ },
+ /**
+ * Collapse node
+ *
+ * @returns {Node}
+ */
+ collapse: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ if (!$this.treegrid('isLeaf') && !$this.treegrid("isCollapsed")) {
+ $this.trigger("collapse");
+ $this.trigger("change");
+ }
+ });
+ },
+ /**
+ * Collapse all nodes
+ *
+ * @returns {Node}
+ */
+ collapseAll: function() {
+ var $this = $(this);
+ $this.treegrid('getRootNodes').treegrid('collapseRecursive');
+ return $this;
+ },
+ /**
+ * Collapse current node and all child nodes begin from current
+ *
+ * @returns {Node}
+ */
+ collapseRecursive: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ $this.treegrid('collapse');
+ if (!$this.treegrid('isLeaf')) {
+ $this.treegrid('getChildNodes').treegrid('collapseRecursive');
+ }
+ });
+ },
+ /**
+ * Expand if collapsed, Collapse if expanded
+ *
+ * @returns {Node}
+ */
+ toggle: function() {
+ var $this = $(this);
+ if ($this.treegrid('isExpanded')) {
+ $this.treegrid('collapse');
+ } else {
+ $this.treegrid('expand');
+ }
+ return $this;
+ },
+ /**
+ * Rendering node
+ *
+ * @returns {Node}
+ */
+ render: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+
+ if ($this.treegrid('isOneOfParentsCollapsed')) {
+ $this.hide();
+ } else {
+ $this.show();
+ }
+ if (!$this.treegrid('isLeaf')) {
+ $this.treegrid('renderExpander');
+ $this.treegrid('getChildNodes').treegrid('render');
+ }
+ });
+ },
+ /**
+ * Rendering expander depends on node state
+ *
+ * @returns {Node}
+ */
+ renderExpander: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ var expander = $this.treegrid('getSetting', 'getExpander').apply(this);
+ if (expander) {
+
+ if (!$this.treegrid('isCollapsed')) {
+ expander.removeClass($this.treegrid('getSetting', 'expanderCollapsedClass'));
+ expander.addClass($this.treegrid('getSetting', 'expanderExpandedClass'));
+ } else {
+ expander.removeClass($this.treegrid('getSetting', 'expanderExpandedClass'));
+ expander.addClass($this.treegrid('getSetting', 'expanderCollapsedClass'));
+ }
+ } else {
+ $this.treegrid('initExpander');
+ $this.treegrid('renderExpander');
+ }
+ });
+ }
+ };
+ $.fn.treegrid = function(method) {
+ if (methods[method]) {
+ return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1));
+ } else if (typeof method === 'object' || !method) {
+ return methods.initTree.apply(this, arguments);
+ } else {
+ $.error('Method with name ' + method + ' does not exists for jQuery.treegrid');
+ }
+ };
+ /**
+ * Plugin's default options
+ */
+ $.fn.treegrid.defaults = {
+ initialState: 'expanded',
+ saveState: false,
+ saveStateMethod: 'cookie',
+ saveStateName: 'tree-grid-state',
+ expanderTemplate: '',
+ indentTemplate: '',
+ expanderExpandedClass: 'treegrid-expander-expanded',
+ expanderCollapsedClass: 'treegrid-expander-collapsed',
+ treeColumn: 0,
+ getExpander: function() {
+ return $(this).find('.treegrid-expander');
+ },
+ getNodeId: function() {
+ var template = /treegrid-([A-Za-z0-9_-]+)/;
+ if (template.test($(this).attr('class'))) {
+ return template.exec($(this).attr('class'))[1];
+ }
+ return null;
+ },
+ getParentNodeId: function() {
+ var template = /treegrid-parent-([A-Za-z0-9_-]+)/;
+ if (template.test($(this).attr('class'))) {
+ return template.exec($(this).attr('class'))[1];
+ }
+ return null;
+ },
+ getNodeById: function(id, treegridContainer) {
+ var templateClass = "treegrid-" + id;
+ return treegridContainer.find('tr.' + templateClass);
+ },
+ getChildNodes: function(id, treegridContainer) {
+ var templateClass = "treegrid-parent-" + id;
+ return treegridContainer.find('tr.' + templateClass);
+ },
+ getTreeGridContainer: function() {
+ return $(this).closest('table');
+ },
+ getRootNodes: function(treegridContainer) {
+ var result = $.grep(treegridContainer.find('tr'), function(element) {
+ var classNames = $(element).attr('class');
+ var templateClass = /treegrid-([A-Za-z0-9_-]+)/;
+ var templateParentClass = /treegrid-parent-([A-Za-z0-9_-]+)/;
+ return templateClass.test(classNames) && !templateParentClass.test(classNames);
+ });
+ return $(result);
+ },
+ getAllNodes: function(treegridContainer) {
+ var result = $.grep(treegridContainer.find('tr'), function(element) {
+ var classNames = $(element).attr('class');
+ var templateClass = /treegrid-([A-Za-z0-9_-]+)/;
+ return templateClass.test(classNames);
+ });
+ return $(result);
+ },
+ //Events
+ onCollapse: null,
+ onExpand: null,
+ onChange: null
+
+ };
+})(jQuery);
\ No newline at end of file
diff --git a/Bootstrap.Admin/wwwroot/lib/treegrid/js/jquery.treegrid.min.js b/Bootstrap.Admin/wwwroot/lib/treegrid/js/jquery.treegrid.min.js
new file mode 100644
index 00000000..d1f8b9c5
--- /dev/null
+++ b/Bootstrap.Admin/wwwroot/lib/treegrid/js/jquery.treegrid.min.js
@@ -0,0 +1 @@
+(function($){var methods={initTree:function(options){var settings=$.extend({},this.treegrid.defaults,options);return this.each(function(){var $this=$(this);$this.treegrid("setTreeContainer",$(this));$this.treegrid("setSettings",settings);settings.getRootNodes.apply(this,[$(this)]).treegrid("initNode",settings)})},initNode:function(settings){return this.each(function(){var $this=$(this);$this.treegrid("setTreeContainer",settings.getTreeGridContainer.apply(this));$this.treegrid("getChildNodes").treegrid("initNode",settings);$this.treegrid("initExpander").treegrid("initIndent").treegrid("initEvents").treegrid("initState").treegrid("initSettingsEvents")})},initEvents:function(){var $this=$(this);$this.on("change",function(){var $this=$(this);$this.treegrid("render");if($this.treegrid("getSetting","saveState")){$this.treegrid("saveState")}});$this.on("collapse",function(){var $this=$(this);$this.removeClass("treegrid-expanded");$this.addClass("treegrid-collapsed")});$this.on("expand",function(){var $this=$(this);$this.removeClass("treegrid-collapsed");$this.addClass("treegrid-expanded")});return $this},initSettingsEvents:function(){var $this=$(this);$this.on("change",function(){var $this=$(this);if(typeof $this.treegrid("getSetting","onChange")==="function"){$this.treegrid("getSetting","onChange").apply($this)}});$this.on("collapse",function(){var $this=$(this);if(typeof $this.treegrid("getSetting","onCollapse")==="function"){$this.treegrid("getSetting","onCollapse").apply($this)}});$this.on("expand",function(){var $this=$(this);if(typeof $this.treegrid("getSetting","onExpand")==="function"){$this.treegrid("getSetting","onExpand").apply($this)}});return $this},initExpander:function(){var $this=$(this);var cell=$this.find("td").get($this.treegrid("getSetting","treeColumn"));var tpl=$this.treegrid("getSetting","expanderTemplate");var expander=$this.treegrid("getSetting","getExpander").apply(this);if(expander){expander.remove()}$(tpl).prependTo(cell).click(function(){$($(this).closest("tr")).treegrid("toggle")});return $this},initIndent:function(){var $this=$(this);$this.find(".treegrid-indent").remove();for(var i=0;i<$(this).treegrid("getDepth");i++){$($this.treegrid("getSetting","indentTemplate")).insertBefore($this.find(".treegrid-expander"))}return $this},initState:function(){var $this=$(this);if($this.treegrid("getSetting","saveState")&&!$this.treegrid("isFirstInit")){$this.treegrid("restoreState")}else{if($this.treegrid("getSetting","initialState")==="expanded"){$this.treegrid("expand")}else{$this.treegrid("collapse")}}return $this},isFirstInit:function(){var tree=$(this).treegrid("getTreeContainer");if(tree.data("first_init")===undefined){tree.data("first_init",$.cookie(tree.treegrid("getSetting","saveStateName"))===undefined)}return tree.data("first_init")},saveState:function(){var $this=$(this);if($this.treegrid("getSetting","saveStateMethod")==="cookie"){var stateArrayString=$.cookie($this.treegrid("getSetting","saveStateName"))||"";var stateArray=stateArrayString===""?[]:stateArrayString.split(",");var nodeId=$this.treegrid("getNodeId");if($this.treegrid("isExpanded")){if($.inArray(nodeId,stateArray)===-1){stateArray.push(nodeId)}}else if($this.treegrid("isCollapsed")){if($.inArray(nodeId,stateArray)!==-1){stateArray.splice($.inArray(nodeId,stateArray),1)}}$.cookie($this.treegrid("getSetting","saveStateName"),stateArray.join(","))}return $this},restoreState:function(){var $this=$(this);if($this.treegrid("getSetting","saveStateMethod")==="cookie"){var stateArray=$.cookie($this.treegrid("getSetting","saveStateName")).split(",");if($.inArray($this.treegrid("getNodeId"),stateArray)!==-1){$this.treegrid("expand")}else{$this.treegrid("collapse")}}return $this},getSetting:function(name){if(!$(this).treegrid("getTreeContainer")){return null}return $(this).treegrid("getTreeContainer").data("settings")[name]},setSettings:function(settings){$(this).treegrid("getTreeContainer").data("settings",settings)},getTreeContainer:function(){return $(this).data("treegrid")},setTreeContainer:function(container){return $(this).data("treegrid",container)},getRootNodes:function(){return $(this).treegrid("getSetting","getRootNodes").apply(this,[$(this).treegrid("getTreeContainer")])},getAllNodes:function(){return $(this).treegrid("getSetting","getAllNodes").apply(this,[$(this).treegrid("getTreeContainer")])},isNode:function(){return $(this).treegrid("getNodeId")!==null},getNodeId:function(){if($(this).treegrid("getSetting","getNodeId")===null){return null}else{return $(this).treegrid("getSetting","getNodeId").apply(this)}},getParentNodeId:function(){return $(this).treegrid("getSetting","getParentNodeId").apply(this)},getParentNode:function(){if($(this).treegrid("getParentNodeId")===null){return null}else{return $(this).treegrid("getSetting","getNodeById").apply(this,[$(this).treegrid("getParentNodeId"),$(this).treegrid("getTreeContainer")])}},getChildNodes:function(){return $(this).treegrid("getSetting","getChildNodes").apply(this,[$(this).treegrid("getNodeId"),$(this).treegrid("getTreeContainer")])},getDepth:function(){if($(this).treegrid("getParentNode")===null){return 0}return $(this).treegrid("getParentNode").treegrid("getDepth")+1},isRoot:function(){return $(this).treegrid("getDepth")===0},isLeaf:function(){return $(this).treegrid("getChildNodes").length===0},isLast:function(){if($(this).treegrid("isNode")){var parentNode=$(this).treegrid("getParentNode");if(parentNode===null){if($(this).treegrid("getNodeId")===$(this).treegrid("getRootNodes").last().treegrid("getNodeId")){return true}}else{if($(this).treegrid("getNodeId")===parentNode.treegrid("getChildNodes").last().treegrid("getNodeId")){return true}}}return false},isFirst:function(){if($(this).treegrid("isNode")){var parentNode=$(this).treegrid("getParentNode");if(parentNode===null){if($(this).treegrid("getNodeId")===$(this).treegrid("getRootNodes").first().treegrid("getNodeId")){return true}}else{if($(this).treegrid("getNodeId")===parentNode.treegrid("getChildNodes").first().treegrid("getNodeId")){return true}}}return false},isExpanded:function(){return $(this).hasClass("treegrid-expanded")},isCollapsed:function(){return $(this).hasClass("treegrid-collapsed")},isOneOfParentsCollapsed:function(){var $this=$(this);if($this.treegrid("isRoot")){return false}else{if($this.treegrid("getParentNode").treegrid("isCollapsed")){return true}else{return $this.treegrid("getParentNode").treegrid("isOneOfParentsCollapsed")}}},expand:function(){return $(this).each(function(){var $this=$(this);if(!$this.treegrid("isLeaf")&&!$this.treegrid("isExpanded")){$this.trigger("expand");$this.trigger("change")}})},expandAll:function(){var $this=$(this);$this.treegrid("getRootNodes").treegrid("expandRecursive");return $this},expandRecursive:function(){return $(this).each(function(){var $this=$(this);$this.treegrid("expand");if(!$this.treegrid("isLeaf")){$this.treegrid("getChildNodes").treegrid("expandRecursive")}})},collapse:function(){return $(this).each(function(){var $this=$(this);if(!$this.treegrid("isLeaf")&&!$this.treegrid("isCollapsed")){$this.trigger("collapse");$this.trigger("change")}})},collapseAll:function(){var $this=$(this);$this.treegrid("getRootNodes").treegrid("collapseRecursive");return $this},collapseRecursive:function(){return $(this).each(function(){var $this=$(this);$this.treegrid("collapse");if(!$this.treegrid("isLeaf")){$this.treegrid("getChildNodes").treegrid("collapseRecursive")}})},toggle:function(){var $this=$(this);if($this.treegrid("isExpanded")){$this.treegrid("collapse")}else{$this.treegrid("expand")}return $this},render:function(){return $(this).each(function(){var $this=$(this);if($this.treegrid("isOneOfParentsCollapsed")){$this.hide()}else{$this.show()}if(!$this.treegrid("isLeaf")){$this.treegrid("renderExpander");$this.treegrid("getChildNodes").treegrid("render")}})},renderExpander:function(){return $(this).each(function(){var $this=$(this);var expander=$this.treegrid("getSetting","getExpander").apply(this);if(expander){if(!$this.treegrid("isCollapsed")){expander.removeClass($this.treegrid("getSetting","expanderCollapsedClass"));expander.addClass($this.treegrid("getSetting","expanderExpandedClass"))}else{expander.removeClass($this.treegrid("getSetting","expanderExpandedClass"));expander.addClass($this.treegrid("getSetting","expanderCollapsedClass"))}}else{$this.treegrid("initExpander");$this.treegrid("renderExpander")}})}};$.fn.treegrid=function(method){if(methods[method]){return methods[method].apply(this,Array.prototype.slice.call(arguments,1))}else if(typeof method==="object"||!method){return methods.initTree.apply(this,arguments)}else{$.error("Method with name "+method+" does not exists for jQuery.treegrid")}};$.fn.treegrid.defaults={initialState:"expanded",saveState:false,saveStateMethod:"cookie",saveStateName:"tree-grid-state",expanderTemplate:'',indentTemplate:'',expanderExpandedClass:"treegrid-expander-expanded",expanderCollapsedClass:"treegrid-expander-collapsed",treeColumn:0,getExpander:function(){return $(this).find(".treegrid-expander")},getNodeId:function(){var template=/treegrid-([A-Za-z0-9_-]+)/;if(template.test($(this).attr("class"))){return template.exec($(this).attr("class"))[1]}return null},getParentNodeId:function(){var template=/treegrid-parent-([A-Za-z0-9_-]+)/;if(template.test($(this).attr("class"))){return template.exec($(this).attr("class"))[1]}return null},getNodeById:function(id,treegridContainer){var templateClass="treegrid-"+id;return treegridContainer.find("tr."+templateClass)},getChildNodes:function(id,treegridContainer){var templateClass="treegrid-parent-"+id;return treegridContainer.find("tr."+templateClass)},getTreeGridContainer:function(){return $(this).closest("table")},getRootNodes:function(treegridContainer){var result=$.grep(treegridContainer.find("tr"),function(element){var classNames=$(element).attr("class");var templateClass=/treegrid-([A-Za-z0-9_-]+)/;var templateParentClass=/treegrid-parent-([A-Za-z0-9_-]+)/;return templateClass.test(classNames)&&!templateParentClass.test(classNames)});return $(result)},getAllNodes:function(treegridContainer){var result=$.grep(treegridContainer.find("tr"),function(element){var classNames=$(element).attr("class");var templateClass=/treegrid-([A-Za-z0-9_-]+)/;return templateClass.test(classNames)});return $(result)},onCollapse:null,onExpand:null,onChange:null}})(jQuery);
\ No newline at end of file