dashboard.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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"><i class="fa fa-plus placeholder-add"></i></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. $('.dashboard-placeholder').click(function(){
  62. var placeholder = $(this);
  63. object.trigger('placeholder-click',{
  64. element : placeholder,
  65. row: placeholder.attr('data-row'),
  66. column: placeholder.attr('data-column')
  67. });
  68. });
  69. }
  70. on(event,callback){
  71. if(!this.triggers[event]) this.triggers[event] = [];
  72. this.triggers[event].push(callback);
  73. return this;
  74. }
  75. trigger(event,data){
  76. if(!this.triggers[event]) return;
  77. if(!data) data = {};
  78. var abort = false;
  79. for(var k in this.triggers[event]){
  80. if(this.triggers[event][k](data) === true) abort = true;
  81. }
  82. return abort;
  83. }
  84. //Ajoute un ou plusieurs widgets
  85. addWidgets(widgets){
  86. var object = this;
  87. for(var k in widgets){
  88. var widgetOptions = $.extend({
  89. id : Math.floor(Math.random() * 100)+Date.now(),
  90. draggable : true,
  91. resizeable : true,
  92. removable : true,
  93. width: 1,
  94. height : 1,
  95. row : 0,
  96. column :0,
  97. options : [],
  98. label : 'Sans titre',
  99. content : "Aucun contenu"
  100. },widgets[k]);
  101. 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')); }});
  102. var widgetElement = $(object.widgetTemplate);
  103. widgetOptions.element = widgetElement;
  104. object.widgets[widgetOptions.id] = widgetOptions;
  105. object.grid.append(widgetElement);
  106. widgetElement.draggable(
  107. {
  108. handle: '.widget-header-title',
  109. containment: object.grid,
  110. "ui-draggable-dragging" : "widget-dragging",
  111. start : function(event){
  112. var element = $(event.currentTarget);
  113. if(!element.hasClass('widget-draggable'))return false;
  114. $('.dashboard-widget').css('z-index','');
  115. element.css('z-index',1000);
  116. }
  117. }
  118. );
  119. widgetElement.find('.dashboard-widget-resize').mousedown(function(){
  120. var element = $(this).closest('.dashboard-widget');
  121. if(!element.hasClass('widget-resizeable'))return;
  122. object.resizing = object.widgets[element.attr('data-id')];
  123. $('.dashboard-placeholder').addClass('bordered');
  124. });
  125. widgetElement.find('.widget-option-delete').click(function(){
  126. object.deleteWidget($(this).closest('.dashboard-widget').attr('data-id'));
  127. });
  128. object.trigger('add',object.widgetToArray(widgetOptions));
  129. }
  130. this.renderContents();
  131. this.renderPositions();
  132. }
  133. //Supprime un widget en fonctiond e son id
  134. deleteWidget(id){
  135. var widget = this.widgets[id];
  136. if(this.trigger('delete',this.widgetToArray(widget))) return;
  137. this.widgets[id].element.remove();
  138. }
  139. widgetToArray(widget){
  140. if(!widget) return {};
  141. return {
  142. id: widget.id,
  143. draggable: widget.draggable,
  144. resizeable: widget.resizeable,
  145. removable: widget.removable,
  146. width: widget.width,
  147. height: widget.height,
  148. row: widget.row,
  149. column: widget.column,
  150. label: widget.label,
  151. content: widget.content,
  152. icon: widget.icon,
  153. headerBackground: widget.headerBackground
  154. };
  155. }
  156. //rafraichis le contenu des widgets en fonction du tableaud e widgets interne
  157. renderContents() {
  158. for(var k in this.widgets){
  159. var widget = this.widgets[k];
  160. if(widget.id) widget.element.attr('data-id',widget.id);
  161. if(widget.label !== null) widget.element.find('.widget-header-title').html(widget.label);
  162. if(widget.icon !== null) widget.element.find('.widget-header-icon i').attr('class',widget.icon);
  163. if(widget.options !== null){
  164. var tpl = '<li class="{{class}}" title="{{label}}"><i class="{{icon}}"></i></li>';
  165. widget.element.find('.widget-header-options').html('');
  166. for(var u in widget.options){
  167. var option = $(Mustache.render(tpl,widget.options[u]));
  168. if(widget.options[u].click){
  169. option.data('click',widget.options[u].click);
  170. option.click(function(){
  171. $(this).data('click')(this);
  172. });
  173. }
  174. widget.element.find('.widget-header-options').append(option);
  175. }
  176. }
  177. if(widget.headerBackground !== null) widget.element.find('.dashboard-widget-header').css('backgroundColor',widget.headerBackground);
  178. widget.element
  179. .toggleClass('widget-draggable',widget.draggable)
  180. .toggleClass('widget-resizeable',widget.resizeable)
  181. .toggleClass('widget-removable',widget.removable);
  182. if(widget.content !== null) widget.element.find('.dashboard-widget-content').html(widget.content);
  183. }
  184. }
  185. //resize / replace les wicgets en fonction de la taille de la fenetre et des cellules de grilles
  186. renderPositions() {
  187. var firstPlaceHolder = this.placeHolders.eq(0);
  188. var placeholderWidth = firstPlaceHolder.outerWidth();
  189. var placeholderHeight = firstPlaceHolder.outerHeight();
  190. for(var k in this.widgets){
  191. var widget = this.widgets[k];
  192. var cell = $('[data-row="'+widget.row+'"][data-column="'+widget.column+'"]').position();
  193. if(!cell) continue;
  194. widget.element.css({
  195. width : ((widget.width * placeholderWidth)-(this.options.placeHolderPadding*2))+'px',
  196. height : ((widget.height * placeholderHeight)-(this.options.placeHolderPadding*2))+'px',
  197. top : (cell.top+this.options.placeHolderPadding)+'px',
  198. left : (cell.left+this.options.placeHolderPadding)+'px'
  199. });
  200. }
  201. }
  202. }