dashboard.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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 : 'fas fa-ellipsis-v', class:'widget-option-configure' , label : 'Configurer' , click : function(element){ object.configureWidget($(element).closest('.dashboard-widget').attr('data-id')); }});
  102. 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')); }});
  103. var widgetElement = $(object.widgetTemplate);
  104. widgetOptions.element = widgetElement;
  105. object.widgets[widgetOptions.id] = widgetOptions;
  106. object.grid.append(widgetElement);
  107. widgetElement.draggable(
  108. {
  109. handle: '.widget-header-title',
  110. containment: object.grid,
  111. "ui-draggable-dragging" : "widget-dragging",
  112. start : function(event){
  113. var element = $(event.currentTarget);
  114. if(!element.hasClass('widget-draggable'))return false;
  115. $('.dashboard-widget').css('z-index','');
  116. element.css('z-index',1000);
  117. }
  118. }
  119. );
  120. widgetElement.find('.dashboard-widget-resize').mousedown(function(){
  121. var element = $(this).closest('.dashboard-widget');
  122. if(!element.hasClass('widget-resizeable'))return;
  123. object.resizing = object.widgets[element.attr('data-id')];
  124. $('.dashboard-placeholder').addClass('bordered');
  125. });
  126. widgetElement.find('.widget-option-delete').click(function(){
  127. object.deleteWidget($(this).closest('.dashboard-widget').attr('data-id'));
  128. });
  129. object.trigger('add',object.widgetToArray(widgetOptions));
  130. }
  131. this.renderContents();
  132. this.renderPositions();
  133. }
  134. //Supprime un widget en fonctiond e son id
  135. deleteWidget(id){
  136. var widget = this.widgets[id];
  137. if(this.trigger('delete',this.widgetToArray(widget))) return;
  138. this.widgets[id].element.remove();
  139. }
  140. configureWidget(id){
  141. $('#dashboardModal').modal('show');
  142. this.trigger('configure',id);
  143. }
  144. widgetToArray(widget){
  145. if(!widget) return {};
  146. return {
  147. id: widget.id,
  148. draggable: widget.draggable,
  149. resizeable: widget.resizeable,
  150. removable: widget.removable,
  151. width: widget.width,
  152. height: widget.height,
  153. row: widget.row,
  154. column: widget.column,
  155. label: widget.label,
  156. content: widget.content,
  157. icon: widget.icon,
  158. headerBackground: widget.headerBackground
  159. };
  160. }
  161. //rafraichis le contenu des widgets en fonction du tableaud e widgets interne
  162. renderContents() {
  163. for(var k in this.widgets){
  164. var widget = this.widgets[k];
  165. if(widget.id) widget.element.attr('data-id',widget.id);
  166. if(widget.label !== null) widget.element.find('.widget-header-title').html(widget.label);
  167. if(widget.icon !== null) widget.element.find('.widget-header-icon i').attr('class',widget.icon);
  168. if(widget.options !== null){
  169. var tpl = '<li class="{{class}}" title="{{label}}"><i class="{{icon}}"></i></li>';
  170. widget.element.find('.widget-header-options').html('');
  171. for(var u in widget.options){
  172. var option = $(Mustache.render(tpl,widget.options[u]));
  173. if(widget.options[u].click){
  174. option.data('click',widget.options[u].click);
  175. option.click(function(){
  176. $(this).data('click')(this);
  177. });
  178. }
  179. widget.element.find('.widget-header-options').append(option);
  180. }
  181. }
  182. if(widget.headerBackground !== null) widget.element.find('.dashboard-widget-header').css('backgroundColor',widget.headerBackground);
  183. widget.element
  184. .toggleClass('widget-draggable',widget.draggable)
  185. .toggleClass('widget-resizeable',widget.resizeable)
  186. .toggleClass('widget-removable',widget.removable);
  187. if(widget.content !== null) widget.element.find('.dashboard-widget-content').html(widget.content);
  188. }
  189. }
  190. //resize / replace les wicgets en fonction de la taille de la fenetre et des cellules de grilles
  191. renderPositions() {
  192. var firstPlaceHolder = this.placeHolders.eq(0);
  193. var placeholderWidth = firstPlaceHolder.outerWidth();
  194. var placeholderHeight = firstPlaceHolder.outerHeight();
  195. for(var k in this.widgets){
  196. var widget = this.widgets[k];
  197. var cell = $('[data-row="'+widget.row+'"][data-column="'+widget.column+'"]').position();
  198. if(!cell) continue;
  199. widget.element.css({
  200. width : ((widget.width * placeholderWidth)-(this.options.placeHolderPadding*2))+'px',
  201. height : ((widget.height * placeholderHeight)-(this.options.placeHolderPadding*2))+'px',
  202. top : (cell.top+this.options.placeHolderPadding)+'px',
  203. left : (cell.left+this.options.placeHolderPadding)+'px'
  204. });
  205. }
  206. }
  207. }