Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Update to only show nodeIcon for leaf nodes #361

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,34 @@ $('#tree').treeview('expandNode', [ nodeId, { levels: 2, silent: true } ]);

Triggers `nodeExpanded` event; pass silent to suppress events.

#### findNodeIdByCustomId(customId)

Find the `nodeId` of a node in the tree whose `customId` matches the given customId. If no match can be
found then `undefined` is returned.

```javascript
$('#tree').treeview('findNodeIdByCustomId', 3)
```

Triggers `findNodeIdByCustomIdComplete` event.

#### findNodesByCustomIds(customIds)

Find nodes in the tree whose `customId` matches those given in `customIds`. The return value is
an object with three properties:
* `customIds` - the customIds given to the function
* `nodeIds` - the tree node ids of the nodes that matched
* `nodesMap` - an object that maps the customId to an array of matching tree nodes (an array is
used because its possible one custom id is represented multiple times in the tree).

```javascript
// we have to wrap the ids in an array because jQuery treats the arguments as an array
// of individual arguments and the goal is to pass an entire array
$('#tree').treeview('findNodesByCustomIds', [[3, 4, 5]]);
```

Triggers `findNodesByCustomIdsComplete` event.

#### getCollapsed()

Returns an array of collapsed nodes e.g. state.expanded = false.
Expand Down Expand Up @@ -727,6 +755,8 @@ $('#tree').on('nodeSelected', function(event, data) {

### List of Events

`findNodeIdByCustomIdComplete(event, {nodeId: <id>, customId: <custom id>})` - a node was found

`nodeChecked (event, node)` - A node is checked.

`nodeCollapsed (event, node)` - A node is collapsed.
Expand Down
139 changes: 117 additions & 22 deletions src/js/bootstrap-treeview.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Additional changes made in a fork located at:
* https://github.com/mindscratch/bootstrap-treeview
* ========================================================= */

;(function ($, window, document, undefined) {
Expand Down Expand Up @@ -55,6 +58,7 @@
highlightSearchResults: true,
showBorder: true,
showIcon: true,
showLeafIconOnly: true,
showCheckbox: false,
showTags: false,
multiSelect: false,
Expand All @@ -69,7 +73,9 @@
onNodeUnchecked: undefined,
onNodeUnselected: undefined,
onSearchComplete: undefined,
onSearchCleared: undefined
onSearchCleared: undefined,
onFindNodeIdByCustomIdComplete: undefined,
onFindNodesByCustomIdsComplete: undefined
};

_default.options = {
Expand Down Expand Up @@ -142,7 +148,10 @@

// Search methods
search: $.proxy(this.search, this),
clearSearch: $.proxy(this.clearSearch, this)
clearSearch: $.proxy(this.clearSearch, this),

findNodeIdByCustomId: $.proxy(this.findNodeIdByCustomId, this),
findNodesByCustomIds: $.proxy(this.findNodesByCustomIds, this),
};
};

Expand Down Expand Up @@ -246,6 +255,14 @@
if (typeof (this.options.onSearchCleared) === 'function') {
this.$element.on('searchCleared', this.options.onSearchCleared);
}

if (typeof (this.options.onFindNodeIdByCustomIdComplete) === 'function') {
this.$element.on('findNodeIdByCustomIdComplete', this.options.onFindNodeIdByCustomIdComplete);
}

if (typeof (this.options.onFindNodesByCustomIdsComplete) === 'function') {
this.$element.on('findNodesByCustomIdsComplete', this.options.onFindNodesByCustomIdsComplete);
}
};

/*
Expand Down Expand Up @@ -321,22 +338,28 @@
var target = $(event.target);
var node = this.findNode(target);
if (!node || node.state.disabled) return;

var classList = target.attr('class') ? target.attr('class').split(' ') : [];
if ((classList.indexOf('expand-icon') !== -1)) {

this.toggleExpandedState(node, _default.options);
this.render();
}
else if ((classList.indexOf('check-icon') !== -1)) {

this.toggleCheckedState(node, _default.options);
this.render();
}
else {

if (node.selectable) {
this.toggleSelectedState(node, _default.options);

// if a node is selected and it's not expanded, then expand it
// this allows clicking on a node label to expand it
if (!node.state.expanded) {
this.toggleExpandedState(node, _default.options);
}
} else {
this.toggleExpandedState(node, _default.options);
}
Expand Down Expand Up @@ -516,8 +539,9 @@
.addClass(node.state.checked ? 'node-checked' : '')
.addClass(node.state.disabled ? 'node-disabled': '')
.addClass(node.state.selected ? 'node-selected' : '')
.addClass(node.searchResult ? 'search-result' : '')
.addClass(node.searchResult ? 'search-result' : '')
.attr('data-nodeid', node.nodeId)
.attr('data-custom-id', node.customId || '')
.attr('style', _this.buildStyleOverride(node));

// Add indent/spacer to mimic tree structure
Expand All @@ -527,34 +551,43 @@

// Add expand, collapse or empty spacer icons
var classList = [];
if (node.nodes) {
if (node.nodes && node.nodes.length > 0) {
classList.push('expand-icon');
if (node.state.expanded) {
classList.push(_this.options.collapseIcon);
classList.push(node.collapseIcon || _this.options.collapseIcon);
}
else {
classList.push(_this.options.expandIcon);
classList.push(node.expandIcon || _this.options.expandIcon);
}
}
else {
classList.push(_this.options.emptyIcon);
}

treeItem
.append($(_this.template.icon)
.addClass(classList.join(' '))
);

// only add the 'icon' template if it's not a leaf node
if (node.nodes && node.nodes.length > 0) {
treeItem
.append($(_this.template.icon)
.addClass(classList.join(' '))
);
}

// Add node icon
if (_this.options.showIcon) {

var displayIcon = false;
if (_this.options.showLeafIconOnly) {
if (!node.nodes || node.nodes.length == 0) {
displayIcon = true;
}
} else if (_this.options.showIcon) {
displayIcon = true;
}
if (displayIcon) {
var classList = ['node-icon'];

classList.push(node.icon || _this.options.nodeIcon);
if (node.state.selected) {
classList.pop();
classList.push(node.selectedIcon || _this.options.selectedIcon ||
classList.push(node.selectedIcon || _this.options.selectedIcon ||
node.icon || _this.options.nodeIcon);
}

Expand All @@ -569,7 +602,7 @@

var classList = ['check-icon'];
if (node.state.checked) {
classList.push(_this.options.checkedIcon);
classList.push(_this.options.checkedIcon);
}
else {
classList.push(_this.options.uncheckedIcon);
Expand Down Expand Up @@ -935,7 +968,7 @@
this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
this.toggleExpandedState(node, options);
}, this));

this.render();
};

Expand Down Expand Up @@ -1085,7 +1118,7 @@

$.each(identifiers, $.proxy(function (index, identifier) {
callback(this.identifyNode(identifier), options);
}, this));
}, this));
};

/*
Expand Down Expand Up @@ -1156,12 +1189,74 @@
});

if (options.render) {
this.render();
this.render();
}

this.$element.trigger('searchCleared', $.extend(true, {}, results));
};

/**
* Find the node that matches the given custom id.
* @param {Number} customId - the customId property to find
* @return {Number} the node id
*/
Tree.prototype.findNodeIdByCustomId = function(customId) {
var nodeId = undefined;
for (var i = 0; i < this.nodes.length; i++) {
if (this.nodes[i].customId == customId) {
nodeId = this.nodes[i].nodeId;
break;
}
}

this.$element.trigger('findNodeIdByCustomIdComplete', {nodeId: nodeId, customId: customId});

return nodeId;
};

/**
* Find the nodes that match the given custom ids.
*
* Will fire the 'findNodesByCustomIdsComplete' event when complete. The
* event handler will receive two parameters, the event and the results. The
* results will be an object with three properties: customIds (the ids given
* when performing the find operation), nodeIds (an array of matching tree node ids),
* and nodesMap (an object that maps the custom id to an array of matching tree node objects).
*
* @param {Number[]} customIds - the custom ids to search for
* @return {Object} - containing three parameters, 'customIds', 'nodeIds' and 'nodesMap'.
*/
Tree.prototype.findNodesByCustomIds = function(customIds) {
var nodesMap = {};
var matchingNodeIds = [];
var result = {customIds: customIds, nodeIds: matchingNodeIds, nodesMap: nodesMap};

if (customIds == undefined || customIds.length == 0) {
this.$element.trigger('findNodesByCustomIdsComplete', result);
return result;
}

var customId = undefined;
var node = undefined;
for (var i = 0; i < customIds.length; i++ ) {
customId = customIds[i];
for (var j = 0; j < this.nodes.length; j++) {
node = this.nodes[j];

if (node.customId == customId) {
var matchingNodes = nodesMap[customId] || [];
matchingNodes.push(node);
nodesMap[customId] = matchingNodes;
matchingNodeIds.push(node.nodeId);
break;
}
}
}

this.$element.trigger('findNodesByCustomIdsComplete', result);
return result;
};

/**
Find nodes that match a given criteria
@param {String} pattern - A given string to match against
Expand Down