
In the process of working on a small web project, I needed a component to display a tree of elements on the page. The component should allow expanding / collapsing tree nodes, processing a click on an element, adding new nodes to the tree, in general providing the most basic functions of the treeview.
In this case, the conditions for using the component are somewhat different from those generally accepted for the better - modern (IE9 +) browsers will be used as the execution environment (the web project is supposed to be used within a fully controlled internal network). Another point is the platform on which the server side is developed. This is ASP.NET MVC, which means that it is desirable that the component be delivered, including in the form of a NuGet package that is friendly to the typical ASP.NET MVC application directory structure.
In the process of working on the issue, I studied the existing options and, as usual, invented the next bike, but at the same time my own,
with blackjack and gateways .
At the time of this writing, on the Internet you can find the
six most popular components for displaying a tree of elements.
- jsTree . Judging by last year’s jsTree discussion on Habrahabr, some of the developers prefer Dynatree.
- jqTree . Makes the most pleasant impression. Perhaps because of the good design and detailed documentation.
- jQuery TreeView plugin . The author reports that the project is no longer actively developed and recommends using jqTree.
- Dynatree .
- dhtmlxTree .
- dTree .
Some conclusions.
- For all the characteristic overhead costs to support old customers.
- The first four require jquery for their work. The fifth uses its own framework. Only the latter is self-sufficient.
- At the same time, the latter is a relatively ancient "dinosaur" (2003) and is available only as a zip archive.
- Public version control is only present in the first four. At the same time, only the first three repositories are located on GitHub. The Dynatree repository is located on Google Code . Here it should be noted that apparently Dynatree is evolving into a project Fancytree, which is already located on GitHub .
- None of the projects include the NuGet package.
After weighing all the pros and cons, I decided to invent my own bike with the following characteristics: the most simple, friendly to the standard application template based on ASP.NET MVC and Visual Studio 2012, without the burden of support for outdated browsers. The bike was invented. Its distinctive features are:
- implementation based on TypeScript and LESS ,
- working with the informational tree model in accordance with the Composite template.
To isolate CSS rules, a simple but, in my opinion, the most correct approach is used.
- The class name is added to the container element of the tree, corresponding to the namespace.
- Selectors of all CSS rules for the component are context- child , where the class from the previous clause is specified as the only mandatory root parent.
Thus, CSS rules can be built on the basis of tag selectors, without creating a special class for each element. Using LESS makes the source code for such CSS rules pretty intuitive.
LESS | CSS |
---|
.resnyanskiy-tree > ul.container { border: 1px dotted gray; font-family: Tahoma; font-size: 10pt; padding: 1px; li { list-style-type: none; background-image: url(images/vline.png); background-repeat: repeat-y; ul { padding-left: 16px; } span { span { height: 16px; } } ... }
| .resnyanskiy-tree > ul.container { border: 1px dotted gray; font-family: Tahoma; font-size: 10pt; padding: 1px; } .resnyanskiy-tree > ul.container li { list-style-type: none; background-image: url(images/vline.png); background-repeat: repeat-y; } .resnyanskiy-tree > ul.container li ul { padding-left: 16px; } .resnyanskiy-tree > ul.container li span span { height: 16px; } ... |
The main
Tree
TypeScript class has three public members.
- The
updateNode(...)
method adds items to the specified node. - The
onBranchExpand
and onNodeClick
are used to specify the corresponding event handlers.
The two private methods,
renderNodeItemsTo(...)
and
toggleNodeItemsVisible(...)
implement the underlying logic. Changing the visibility of tree elements is implemented by adding / removing DOM elements (
Element.removeChild(...)
-
jsperf is used for
deletion ).
The
toggleNodeItemsVisible(...)
method returns
false
if the specified tree node (JS object) has no elements. Due to this, the condition of calling the
onBranchExpand
handler looks quite laconic:
')
if(!this.toggleNodeItemsVisible(node) && (this.onBranchExpand instanceof Function)) { this.onBranchExpand(nodeId); }
The use of TypeScript + LESS in the implementation of a component, among other things, greatly simplifies its use in its projects and refinement for its needs.
GitHub -
github.com/resnyanskiy/js.treeNuGet -
nuget.org/packages/resnyanskiy.js.tree