dashboard.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. class Dashboard {
  2. constructor(options) {
  3. this.options = $.extend({
  4. columnNumber : 1,
  5. lineNumber : 1,
  6. placeHolderPadding : 10
  7. },options);
  8. this.widgets = {};
  9. var grid = '<div class="dashboard-grid" >';
  10. for(var u =0 ; u<options.lineNumber;u++){
  11. for(var i =0 ; i<options.columnNumber;i++){
  12. grid += '<div data-row="'+u+'" data-column="'+i+'" style="grid-row: '+(u+1)+" / "+(u+1)+";grid-column: "+(i+1)+" / "+(i+1)+';padding:'+this.options.placeHolderPadding+'px;" class="dashboard-placeholder"></div>';
  13. }
  14. }
  15. grid += '</div>';
  16. this.grid = $(grid);
  17. this.options.element.addClass('dashboard-container');
  18. this.options.element.css({width:'100%',height:'1000px'});
  19. this.options.element.append(this.grid);
  20. this.widgetTemplate = $('#dashboard-widget-template').html();
  21. this.placeHolders = $('.dashboard-placeholder');
  22. this.triggers = [];
  23. var object = this;
  24. this.placeHolders.droppable({
  25. tolerance : 'pointer',
  26. classes: {
  27. "ui-droppable-hover": 'drag-over'
  28. },
  29. drop: function( event, ui ) {
  30. var data = $(this).data();
  31. var widgetId = ui.draggable.attr('data-id');
  32. object.widgets[widgetId].column = data.column;
  33. object.widgets[widgetId].row = data.row;
  34. object.renderPositions();
  35. object.trigger('move',object.widgetToArray(object.widgets[widgetId]));
  36. }
  37. });
  38. $(window).resize(function() {
  39. object.renderPositions();
  40. });
  41. $(window).mousemove(function(e){
  42. if(!object.resizing) return;
  43. $('.dashboard-widget').css('z-index','');
  44. object.resizing.element.css('z-index',1000);
  45. var objectPosition = object.resizing.element.position();
  46. object.resizing.element.css('width',(e.clientX - objectPosition.left)+'px');
  47. object.resizing.element.css('height',(e.clientY - objectPosition.top - 50)+'px');
  48. });
  49. $(window).mouseup(function(){
  50. if(!object.resizing) return;
  51. $('.dashboard-placeholder').removeClass('bordered');
  52. var firstPlaceHolder = object.placeHolders.eq(0);
  53. var placeholderWidth = firstPlaceHolder.outerWidth();
  54. var placeholderHeight = firstPlaceHolder.outerHeight();
  55. object.widgets[object.resizing.id].width = Math.round(object.resizing.element.outerWidth() / placeholderWidth);
  56. object.widgets[object.resizing.id].height = Math.round(object.resizing.element.outerHeight() / placeholderHeight);
  57. object.renderPositions();
  58. object.trigger('resize',object.widgetToArray(object.widgets[object.resizing.id]) );
  59. object.resizing = null;
  60. });
  61. }
  62. on(event,callback){
  63. if(!this.triggers[event]) this.triggers[event] = [];
  64. this.triggers[event].push(callback);
  65. return this;
  66. }
  67. trigger(event,data){
  68. if(!this.triggers[event]) return;
  69. if(!data) data = {};
  70. var abort = false;
  71. for(var k in this.triggers[event]){
  72. if(this.triggers[event][k](data) === true) abort = true;
  73. }
  74. return abort;
  75. }
  76. //Ajoute un ou plusieurs widgets
  77. addWidgets(widgets){
  78. var object = this;
  79. for(var k in widgets){
  80. var widgetOptions = $.extend({
  81. id : Math.floor(Math.random() * 100)+Date.now(),
  82. draggable : true,
  83. resizeable : true,
  84. removable : true,
  85. width: 1,
  86. height : 1,
  87. row : 0,
  88. column :0,
  89. options : [],
  90. label : 'Sans titre',
  91. content : "Aucun contenu"
  92. },widgets[k]);
  93. widgetOptions.options.push({icon : 'fa fa-times', class:'widget-option-delete' , label : 'Supprimer' , click : function(element){ object.deleteWidget($(element).closest('.dashboard-widget').attr('data-id')); }});
  94. var widgetElement = $(object.widgetTemplate);
  95. widgetOptions.element = widgetElement;
  96. object.widgets[widgetOptions.id] = widgetOptions;
  97. object.grid.append(widgetElement);
  98. widgetElement.draggable(
  99. {
  100. handle: '.widget-header-title',
  101. containment: object.grid,
  102. "ui-draggable-dragging" : "widget-dragging",
  103. start : function(event){
  104. var element = $(event.currentTarget);
  105. if(!element.hasClass('widget-draggable'))return false;
  106. $('.dashboard-widget').css('z-index','');
  107. element.css('z-index',1000);
  108. }
  109. }
  110. );
  111. widgetElement.find('.dashboard-widget-resize').mousedown(function(){
  112. var element = $(this).closest('.dashboard-widget');
  113. if(!element.hasClass('widget-resizeable'))return;
  114. object.resizing = object.widgets[element.attr('data-id')];
  115. $('.dashboard-placeholder').addClass('bordered');
  116. });
  117. widgetElement.find('.widget-option-delete').click(function(){
  118. object.deleteWidget($(this).closest('.dashboard-widget').attr('data-id'));
  119. });
  120. object.trigger('add',object.widgetToArray(widgetOptions));
  121. }
  122. this.renderContents();
  123. this.renderPositions();
  124. }
  125. //Supprime un widget en fonctiond e son id
  126. deleteWidget(id){
  127. var widget = this.widgets[id];
  128. if(this.trigger('delete',this.widgetToArray(widget))) return;
  129. this.widgets[id].element.remove();
  130. }
  131. widgetToArray(widget){
  132. if(!widget) return {};
  133. return {
  134. id: widget.id,
  135. draggable: widget.draggable,
  136. resizeable: widget.resizeable,
  137. removable: widget.removable,
  138. width: widget.width,
  139. height: widget.height,
  140. row: widget.row,
  141. column: widget.column,
  142. label: widget.label,
  143. content: widget.content,
  144. icon: widget.icon,
  145. headerBackground: widget.headerBackground
  146. };
  147. }
  148. //rafraichis le contenu des widgets en fonction du tableaud e widgets interne
  149. renderContents() {
  150. for(var k in this.widgets){
  151. var widget = this.widgets[k];
  152. if(widget.id) widget.element.attr('data-id',widget.id);
  153. if(widget.label !== null) widget.element.find('.widget-header-title').html(widget.label);
  154. if(widget.icon !== null) widget.element.find('.widget-header-icon i').attr('class',widget.icon);
  155. if(widget.options !== null){
  156. var tpl = '<li class="{{class}}" title="{{label}}"><i class="{{icon}}"></i></li>';
  157. widget.element.find('.widget-header-options').html('');
  158. for(var u in widget.options){
  159. var option = $(Mustache.render(tpl,widget.options[u]));
  160. if(widget.options[u].click){
  161. option.data('click',widget.options[u].click);
  162. option.click(function(){
  163. $(this).data('click')(this);
  164. });
  165. }
  166. widget.element.find('.widget-header-options').append(option);
  167. }
  168. }
  169. if(widget.headerBackground !== null) widget.element.find('.dashboard-widget-header').css('backgroundColor',widget.headerBackground);
  170. widget.element
  171. .toggleClass('widget-draggable',widget.draggable)
  172. .toggleClass('widget-resizeable',widget.resizeable)
  173. .toggleClass('widget-removable',widget.removable);
  174. if(widget.content !== null) widget.element.find('.dashboard-widget-content').html(widget.content);
  175. }
  176. }
  177. //resize / replace les wicgets en fonction de la taille de la fenetre et des cellules de grilles
  178. renderPositions() {
  179. var firstPlaceHolder = this.placeHolders.eq(0);
  180. var placeholderWidth = firstPlaceHolder.outerWidth();
  181. var placeholderHeight = firstPlaceHolder.outerHeight();
  182. for(var k in this.widgets){
  183. var widget = this.widgets[k];
  184. var cell = $('[data-row="'+widget.row+'"][data-column="'+widget.column+'"]').position();
  185. if(!cell) continue;
  186. widget.element.css({
  187. width : ((widget.width * placeholderWidth)-(this.options.placeHolderPadding*2))+'px',
  188. height : ((widget.height * placeholderHeight)-(this.options.placeHolderPadding*2))+'px',
  189. top : (cell.top+this.options.placeHolderPadding)+'px',
  190. left : (cell.left+this.options.placeHolderPadding)+'px'
  191. });
  192. }
  193. }
  194. }