/src/Dime/TimetrackerFrontendBundle/Resources/public/js/core/helper/menu.js

https://github.com/phpugl/Dime · JavaScript · 198 lines · 170 code · 17 blank · 11 comment · 45 complexity · 82fc5f322142ea047bafd90690b18d37 MD5 · raw file

  1. 'use strict';
  2. /**
  3. * Dime - core/helper/menu.js
  4. */
  5. (function ($, Backbone, App) {
  6. App.provide('Model.Menu', Backbone.Model.extend({
  7. defaults:{
  8. weight:0,
  9. active:false
  10. },
  11. submenu:undefined,
  12. initialize: function() {
  13. this.submenu = new App.Collection.Menu();
  14. }
  15. }));
  16. App.provide('Collection.Menu', Backbone.Collection.extend({
  17. model: App.Model.Menu,
  18. currentActive:undefined,
  19. comparator:function (first, second) {
  20. if (first && second) {
  21. var opt1 = first.get('weight'), opt2 = second.get('weight');
  22. if (opt1 != undefined && opt2 != undefined) {
  23. if (opt1 > opt2) {
  24. return 1;
  25. } else if (opt1 < opt2) {
  26. return -1;
  27. } else {
  28. opt1 = first.get('title');
  29. opt2 = second.get('title');
  30. if (opt1 > opt2) {
  31. return 1;
  32. } else if (opt1 < opt2) {
  33. return -1;
  34. }
  35. }
  36. }
  37. }
  38. return 0;
  39. },
  40. add: function(item) {
  41. if (item instanceof App.Model.Menu) {
  42. if (item.get('route') && item.get('callback')) {
  43. App.router.route(item.get('route'), item.id, item.get('callback'));
  44. }
  45. return Backbone.Collection.prototype.add.call(this, item);
  46. } else if (item && item.id) {
  47. if (item.route && item.callback) {
  48. App.router.route(item.route, item.id, item.callback);
  49. }
  50. return Backbone.Collection.prototype.add.call(this, item);
  51. }
  52. return this;
  53. },
  54. 'get': function(id) {
  55. if (id && typeof(id) === "string") {
  56. var parts = id.split('.'),
  57. item;
  58. for (var i=0; i<parts.length; i++) {
  59. if (item) {
  60. if (item.submenu && item.submenu.length > 0) {
  61. item = item.submenu.get(parts[i]);
  62. }
  63. } else {
  64. item = Backbone.Collection.prototype.get.call(this, parts[i]);
  65. }
  66. }
  67. return item;
  68. }
  69. return undefined;
  70. },
  71. activateItem:function (id) {
  72. if (id && typeof(id) === "string") {
  73. var model,
  74. parts = id.split('.').reverse();
  75. model = this.get(parts.pop());
  76. if (model) {
  77. this.deactivateItem();
  78. model.set('active', true);
  79. this.currentActive = model;
  80. if (parts.length > 0 && model.submenu && model.submenu.length > 0) {
  81. model.submenu.activateItem(parts.reverse().join('.'));
  82. }
  83. }
  84. }
  85. },
  86. deactivateItem:function () {
  87. if (this.currentActive) {
  88. this.currentActive.set('active', false);
  89. if (this.currentActive.submenu) {
  90. this.currentActive.submenu.deactivateItem();
  91. }
  92. this.currentActive = undefined;
  93. }
  94. }
  95. }));
  96. /**
  97. * add a menu item to main menu
  98. *
  99. * @param item object { name: 'identifier', title: 'Title', weight: 0, route: 'route/to/:id', callback: func}
  100. * @return Dime or menu collection
  101. */
  102. App.provide('menu', new App.Collection.Menu());
  103. App.provide('Views.Core.MenuItem', Backbone.View.extend({
  104. tagName:"li",
  105. item:undefined,
  106. options: {
  107. template:'#tpl-application-menu-item',
  108. templateSubmenu:'#tpl-application-menu-submenu'
  109. },
  110. initialize:function (config) {
  111. if (this.options.template) {
  112. this.template = this.options.template;
  113. }
  114. if (this.options.templateSubmenu) {
  115. this.templateSubmenu = this.options.templateSubmenu;
  116. }
  117. },
  118. render:function () {
  119. var html, submenu = this.model.submenu;
  120. if (submenu && submenu.length > 0) {
  121. html = App.render(this.templateSubmenu, {
  122. uri:this.model.get('route'),
  123. title:this.model.get('title')
  124. });
  125. this.$el.html(html);
  126. var submenuView = new App.Views.Core.Menu({
  127. collection: submenu,
  128. attributes:{
  129. 'class':'dropdown-menu'
  130. }
  131. });
  132. this.$el.append(submenuView.render().el);
  133. this.$el.addClass('dropdown');
  134. } else {
  135. html = App.render(this.template, {
  136. uri:this.model.get('route'),
  137. title:this.model.get('title')
  138. }
  139. );
  140. this.$el.html(html);
  141. }
  142. return this;
  143. }
  144. }));
  145. App.provide('Views.Core.Menu', Backbone.View.extend({
  146. tagName:"ul",
  147. options:{
  148. itemView:App.Views.Core.MenuItem,
  149. itemOptions: {
  150. template: '#tpl-application-menu-item',
  151. templateSubmenu: '#tpl-application-menu-submenu'
  152. }
  153. },
  154. initialize:function (config) {
  155. // Assign function to collection events
  156. if (this.collection) {
  157. this.collection.on('add', this.addOne, this);
  158. this.collection.on('reset', this.render, this);
  159. this.collection.on('change', this.render, this);
  160. }
  161. },
  162. render:function () {
  163. // remove all content
  164. this.$el.html('');
  165. if (this.collection && this.collection.length > 0) {
  166. this.collection.each(this.addOne, this);
  167. }
  168. return this;
  169. },
  170. addOne:function (model) {
  171. var data = _.clone(this.options.itemOptions);
  172. data.model = model;
  173. data.attributes =(model.get('active')) ? {'class':'active'} : {};
  174. var view = new this.options.itemView(data);
  175. if (model.get('active')) {
  176. this.currentActive = model;
  177. }
  178. this.$el.append(view.render().el);
  179. }
  180. }));
  181. })(jQuery, Backbone, Dime);