fancytree_childcounter.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Extending Fancytree
  2. // ===================
  3. //
  4. // See also the [live demo](http://wwwendt.de/tech/fancytree/demo/sample-ext-childcounter.html) of this code.
  5. //
  6. // Every extension should have a comment header containing some information
  7. // about the author, copyright and licensing. Also a pointer to the latest
  8. // source code.
  9. // Prefix with `/*!` so the comment is not removed by the minifier.
  10. /*!
  11. * jquery.fancytree.childcounter.js
  12. *
  13. * Add a child counter bubble to tree nodes.
  14. * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
  15. *
  16. * Copyright (c) 2008-2017, Martin Wendt (http://wwWendt.de)
  17. *
  18. * Released under the MIT license
  19. * https://github.com/mar10/fancytree/wiki/LicenseInfo
  20. *
  21. * @version 2.22.1
  22. * @date 2017-04-21T05:55:46Z
  23. */
  24. // To keep the global namespace clean, we wrap everything in a closure
  25. ;(function($, undefined) {
  26. // Consider to use [strict mode](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/)
  27. "use strict";
  28. // The [coding guidelines](http://contribute.jquery.org/style-guide/js/)
  29. // require jshint compliance.
  30. // But for this sample, we want to allow unused variables for demonstration purpose.
  31. /*jshint unused:false */
  32. // Adding methods
  33. // --------------
  34. // New member functions can be added to the `Fancytree` class.
  35. // This function will be available for every tree instance:
  36. //
  37. // var tree = $("#tree").fancytree("getTree");
  38. // tree.countSelected(false);
  39. $.ui.fancytree._FancytreeClass.prototype.countSelected = function(topOnly){
  40. var tree = this,
  41. treeOptions = tree.options;
  42. return tree.getSelectedNodes(topOnly).length;
  43. };
  44. // The `FancytreeNode` class can also be easily extended. This would be called
  45. // like
  46. // node.updateCounters();
  47. //
  48. // It is also good practice to add a docstring comment.
  49. /**
  50. * [ext-childcounter] Update counter badges for `node` and its parents.
  51. * May be called in the `loadChildren` event, to update parents of lazy loaded
  52. * nodes.
  53. * @alias FancytreeNode#updateCounters
  54. * @requires jquery.fancytree.childcounters.js
  55. */
  56. $.ui.fancytree._FancytreeNodeClass.prototype.updateCounters = function(){
  57. var node = this,
  58. $badge = $("span.fancytree-childcounter", node.span),
  59. extOpts = node.tree.options.childcounter,
  60. count = node.countChildren(extOpts.deep);
  61. node.data.childCounter = count;
  62. if( (count || !extOpts.hideZeros) && (!node.isExpanded() || !extOpts.hideExpanded) ) {
  63. if( !$badge.length ) {
  64. $badge = $("<span class='fancytree-childcounter'/>").appendTo($("span.fancytree-icon", node.span));
  65. }
  66. $badge.text(count);
  67. } else {
  68. $badge.remove();
  69. }
  70. if( extOpts.deep && !node.isTopLevel() && !node.isRoot() ) {
  71. node.parent.updateCounters();
  72. }
  73. };
  74. // Finally, we can extend the widget API and create functions that are called
  75. // like so:
  76. //
  77. // $("#tree").fancytree("widgetMethod1", "abc");
  78. $.ui.fancytree.prototype.widgetMethod1 = function(arg1){
  79. var tree = this.tree;
  80. return arg1;
  81. };
  82. // Register a Fancytree extension
  83. // ------------------------------
  84. // A full blown extension, extension is available for all trees and can be
  85. // enabled like so (see also the [live demo](http://wwwendt.de/tech/fancytree/demo/sample-ext-childcounter.html)):
  86. //
  87. // <script src="../src/jquery.fancytree.js"></script>
  88. // <script src="../src/jquery.fancytree.childcounter.js"></script>
  89. // ...
  90. //
  91. // $("#tree").fancytree({
  92. // extensions: ["childcounter"],
  93. // childcounter: {
  94. // hideExpanded: true
  95. // },
  96. // ...
  97. // });
  98. //
  99. /* 'childcounter' extension */
  100. $.ui.fancytree.registerExtension({
  101. // Every extension must be registered by a unique name.
  102. name: "childcounter",
  103. // Version information should be compliant with [semver](http://semver.org)
  104. version: "2.22.1",
  105. // Extension specific options and their defaults.
  106. // This options will be available as `tree.options.childcounter.hideExpanded`
  107. options: {
  108. deep: true,
  109. hideZeros: true,
  110. hideExpanded: false
  111. },
  112. // Attributes other than `options` (or functions) can be defined here, and
  113. // will be added to the tree.ext.EXTNAME namespace, in this case `tree.ext.childcounter.foo`.
  114. // They can also be accessed as `this._local.foo` from within the extension
  115. // methods.
  116. foo: 42,
  117. // Local functions are prefixed with an underscore '_'.
  118. // Callable as `this._local._appendCounter()`.
  119. _appendCounter: function(bar){
  120. var tree = this;
  121. },
  122. // **Override virtual methods for this extension.**
  123. //
  124. // Fancytree implements a number of 'hook methods', prefixed by 'node...' or 'tree...'.
  125. // with a `ctx` argument (see [EventData](http://www.wwwendt.de/tech/fancytree/doc/jsdoc/global.html#EventData)
  126. // for details) and an extended calling context:<br>
  127. // `this` : the Fancytree instance<br>
  128. // `this._local`: the namespace that contains extension attributes and private methods (same as this.ext.EXTNAME)<br>
  129. // `this._super`: the virtual function that was overridden (member of previous extension or Fancytree)
  130. //
  131. // See also the [complete list of available hook functions](http://www.wwwendt.de/tech/fancytree/doc/jsdoc/Fancytree_Hooks.html).
  132. /* Init */
  133. // `treeInit` is triggered when a tree is initalized. We can set up classes or
  134. // bind event handlers here...
  135. treeInit: function(ctx){
  136. var tree = this, // same as ctx.tree,
  137. opts = ctx.options,
  138. extOpts = ctx.options.childcounter;
  139. // Optionally check for dependencies with other extensions
  140. /* this._requireExtension("glyph", false, false); */
  141. // Call the base implementation
  142. this._superApply(arguments);
  143. // Add a class to the tree container
  144. this.$container.addClass("fancytree-ext-childcounter");
  145. },
  146. // Destroy this tree instance (we only call the default implementation, so
  147. // this method could as well be omitted).
  148. treeDestroy: function(ctx){
  149. this._superApply(arguments);
  150. },
  151. // Overload the `renderTitle` hook, to append a counter badge
  152. nodeRenderTitle: function(ctx, title) {
  153. var node = ctx.node,
  154. extOpts = ctx.options.childcounter,
  155. count = (node.data.childCounter == null) ? node.countChildren(extOpts.deep) : +node.data.childCounter;
  156. // Let the base implementation render the title
  157. // We use `_super()` instead of `_superApply()` here, since it is a little bit
  158. // more performant when called often
  159. this._super(ctx, title);
  160. // Append a counter badge
  161. if( (count || ! extOpts.hideZeros) && (!node.isExpanded() || !extOpts.hideExpanded) ){
  162. $("span.fancytree-icon", node.span).append($("<span class='fancytree-childcounter'/>").text(count));
  163. }
  164. },
  165. // Overload the `setExpanded` hook, so the counters are updated
  166. nodeSetExpanded: function(ctx, flag, opts) {
  167. var tree = ctx.tree,
  168. node = ctx.node;
  169. // Let the base implementation expand/collapse the node, then redraw the title
  170. // after the animation has finished
  171. return this._superApply(arguments).always(function(){
  172. tree.nodeRenderTitle(ctx);
  173. });
  174. }
  175. // End of extension definition
  176. });
  177. // End of namespace closure
  178. }(jQuery));