mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
new methods, fixes and improvements:
- new disable, enable methods - don't generate duplicated stylesheets for the same origin config - new configuration option called avoid_overlapped_widgets. Avoid that widgets loaded from the DOM can be overlapped. It is helpful if the positions were bad stored in the database or if there was any conflict. - Removed jquery ui dependencie. - Fix to prevent widgets go out of the grid. - New methods to get all widgets from a column or row. - generate_stylesheets method now supports namespaces to generate multiple stylesheets based on a parent class.
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
min_cols: 1,
|
min_cols: 1,
|
||||||
min_rows: 10,
|
min_rows: 10,
|
||||||
autogenerate_stylesheet: true,
|
autogenerate_stylesheet: true,
|
||||||
|
avoid_overlapped_widgets: true,
|
||||||
serialize_params: function($w, wgd) {
|
serialize_params: function($w, wgd) {
|
||||||
return {
|
return {
|
||||||
col: wgd.col,
|
col: wgd.col,
|
||||||
@@ -23,47 +24,9 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
collision: {},
|
collision: {},
|
||||||
draggable: {}
|
draggable: {
|
||||||
};
|
distance: 4
|
||||||
|
}
|
||||||
|
|
||||||
/* Debounce and throttle functions taken from underscore.js */
|
|
||||||
var debounce = function(func, wait, immediate) {
|
|
||||||
var timeout;
|
|
||||||
return function() {
|
|
||||||
var context = this, args = arguments;
|
|
||||||
var later = function() {
|
|
||||||
timeout = null;
|
|
||||||
if (!immediate) func.apply(context, args);
|
|
||||||
};
|
|
||||||
if (immediate && !timeout) func.apply(context, args);
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(later, wait);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var throttle = function(func, wait) {
|
|
||||||
var context, args, timeout, throttling, more, result;
|
|
||||||
var whenDone = debounce(
|
|
||||||
function(){ more = throttling = false; }, wait, true);
|
|
||||||
return function() {
|
|
||||||
context = this; args = arguments;
|
|
||||||
var later = function() {
|
|
||||||
timeout = null;
|
|
||||||
if (more) func.apply(context, args);
|
|
||||||
whenDone();
|
|
||||||
};
|
|
||||||
if (!timeout) timeout = setTimeout(later, wait);
|
|
||||||
if (throttling) {
|
|
||||||
more = true;
|
|
||||||
} else {
|
|
||||||
result = func.apply(context, args);
|
|
||||||
}
|
|
||||||
whenDone();
|
|
||||||
throttling = true;
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -123,6 +86,8 @@
|
|||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Gridster.generated_stylesheets = [];
|
||||||
|
|
||||||
var fn = Gridster.prototype;
|
var fn = Gridster.prototype;
|
||||||
|
|
||||||
fn.init = function() {
|
fn.init = function() {
|
||||||
@@ -137,6 +102,30 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable dragging.
|
||||||
|
*
|
||||||
|
* @method enable
|
||||||
|
* @return {Class} Returns the instance of the Gridster Class.
|
||||||
|
*/
|
||||||
|
fn.disable = function(){
|
||||||
|
this.drag_api.disable();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable dragging.
|
||||||
|
*
|
||||||
|
* @method enable
|
||||||
|
* @return {Class} Returns the instance of the Gridster Class.
|
||||||
|
*/
|
||||||
|
fn.enable = function(){
|
||||||
|
this.drag_api.enable();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new widget to the grid.
|
* Add a new widget to the grid.
|
||||||
*
|
*
|
||||||
@@ -144,7 +133,7 @@
|
|||||||
* @param {String} html The string representing the HTML of the widget.
|
* @param {String} html The string representing the HTML of the widget.
|
||||||
* @param {Number} size_x The nº of rows the widget occupies horizontally.
|
* @param {Number} size_x The nº of rows the widget occupies horizontally.
|
||||||
* @param {Number} size_y The nº of columns the widget occupies vertically.
|
* @param {Number} size_y The nº of columns the widget occupies vertically.
|
||||||
* @return {HTMLElement} Returns the jQuery wrapped HTMLElement representing
|
* @return {HTMLElement} Returns the jQuery wrapped HTMLElement representing.
|
||||||
* the widget that was just created.
|
* the widget that was just created.
|
||||||
*/
|
*/
|
||||||
fn.add_widget = function(html, size_x, size_y) {
|
fn.add_widget = function(html, size_x, size_y) {
|
||||||
@@ -161,12 +150,9 @@
|
|||||||
|
|
||||||
this.register_widget($w);
|
this.register_widget($w);
|
||||||
|
|
||||||
this.$widgets.draggable('destroy');
|
|
||||||
this.draggable();
|
|
||||||
|
|
||||||
this.set_dom_grid_height();
|
this.set_dom_grid_height();
|
||||||
|
|
||||||
$w.fadeIn();
|
return $w.fadeIn();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -284,7 +270,8 @@
|
|||||||
* @return {Array} Returns the instance of the Gridster class.
|
* @return {Array} Returns the instance of the Gridster class.
|
||||||
*/
|
*/
|
||||||
fn.register_widget = function($el) {
|
fn.register_widget = function($el) {
|
||||||
var widget_grid_data = {
|
|
||||||
|
var wgd = {
|
||||||
'col': parseInt($el.attr('data-col'), 10),
|
'col': parseInt($el.attr('data-col'), 10),
|
||||||
'row': parseInt($el.attr('data-row'), 10),
|
'row': parseInt($el.attr('data-row'), 10),
|
||||||
'size_x': parseInt($el.attr('data-sizex'), 10),
|
'size_x': parseInt($el.attr('data-sizex'), 10),
|
||||||
@@ -292,13 +279,27 @@
|
|||||||
'el': $el
|
'el': $el
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (this.options.avoid_overlapped_widgets &&
|
||||||
|
!this.can_move_to(
|
||||||
|
{ size_x: wgd.size_x, size_y: wgd.size_y }, wgd.col, wgd.row)
|
||||||
|
) {
|
||||||
|
wgd = this.next_position(wgd.size_x, wgd.size_y);
|
||||||
|
wgd.el = $el;
|
||||||
|
$el.attr({
|
||||||
|
'data-col': wgd.col,
|
||||||
|
'data-row': wgd.row,
|
||||||
|
'data-sizex': wgd.size_x,
|
||||||
|
'data-sizey': wgd.size_y
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// attach Coord object to player data-coord attribute
|
// attach Coord object to player data-coord attribute
|
||||||
$el.data('coords', $el.coords());
|
$el.data('coords', $el.coords());
|
||||||
|
|
||||||
// Extend Coord object with grid position info
|
// Extend Coord object with grid position info
|
||||||
$el.data('coords').grid = widget_grid_data;
|
$el.data('coords').grid = wgd;
|
||||||
|
|
||||||
this.add_to_gridmap(widget_grid_data, $el);
|
this.add_to_gridmap(wgd, $el);
|
||||||
this.widgets.push($el);
|
this.widgets.push($el);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@@ -369,8 +370,10 @@
|
|||||||
fn.draggable = function() {
|
fn.draggable = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var draggable_options = $.extend(true, {}, this.options.draggable, {
|
var draggable_options = $.extend(true, {}, this.options.draggable, {
|
||||||
// containment : this.$wrapper,
|
offset_left: this.options.widget_margins[0],
|
||||||
|
items: '.gs_w',
|
||||||
start: function(event, ui) {
|
start: function(event, ui) {
|
||||||
|
self.$widgets.filter('.player-revert').removeClass('player-revert');
|
||||||
self.$player = $(this);
|
self.$player = $(this);
|
||||||
self.$helper = self.options.draggable.helper === 'clone' ?
|
self.$helper = self.options.draggable.helper === 'clone' ?
|
||||||
$(ui.helper) : self.$player;
|
$(ui.helper) : self.$player;
|
||||||
@@ -380,16 +383,16 @@
|
|||||||
self.$el.trigger('gridster:dragstart');
|
self.$el.trigger('gridster:dragstart');
|
||||||
},
|
},
|
||||||
stop: function(event, ui) {
|
stop: function(event, ui) {
|
||||||
self.on_stop_drag.call(self, ui);
|
self.on_stop_drag.call(self, event, ui);
|
||||||
self.$el.trigger('gridster:dragstop');
|
self.$el.trigger('gridster:dragstop');
|
||||||
},
|
},
|
||||||
drag: throttle(function(event, ui) {
|
drag: function(event, ui) {
|
||||||
self.on_drag.call(self, event, ui);
|
self.on_drag.call(self, event, ui);
|
||||||
self.$el.trigger('gridster:drag');
|
self.$el.trigger('gridster:drag');
|
||||||
}, 100, true)
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$widgets.draggable(draggable_options);
|
this.drag_api = this.$el.draggable(draggable_options).data('draggable');
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -403,8 +406,10 @@
|
|||||||
* See http://jqueryui.com/demos/draggable/ for more info.
|
* See http://jqueryui.com/demos/draggable/ for more info.
|
||||||
*/
|
*/
|
||||||
fn.on_start_drag = function(event, ui) {
|
fn.on_start_drag = function(event, ui) {
|
||||||
|
|
||||||
|
this.$helper.add(this.$player).add(this.$wrapper).addClass('dragging');
|
||||||
|
|
||||||
this.$player.addClass('player');
|
this.$player.addClass('player');
|
||||||
this.$wrapper.addClass('dragging');
|
|
||||||
this.player_grid_data = this.$player.coords().grid;
|
this.player_grid_data = this.$player.coords().grid;
|
||||||
this.placeholder_grid_data = $.extend({}, this.player_grid_data);
|
this.placeholder_grid_data = $.extend({}, this.player_grid_data);
|
||||||
|
|
||||||
@@ -423,8 +428,9 @@
|
|||||||
this.last_cols = [];
|
this.last_cols = [];
|
||||||
this.last_rows = [];
|
this.last_rows = [];
|
||||||
|
|
||||||
|
|
||||||
// see jquery.collision.js
|
// see jquery.collision.js
|
||||||
this.drag_api = this.$helper.collision(
|
this.collision_api = this.$helper.collision(
|
||||||
colliders, this.options.collision);
|
colliders, this.options.collision);
|
||||||
|
|
||||||
this.$preview_holder = $('<li />', {
|
this.$preview_holder = $('<li />', {
|
||||||
@@ -452,7 +458,11 @@
|
|||||||
* See http://jqueryui.com/demos/draggable/ for more info.
|
* See http://jqueryui.com/demos/draggable/ for more info.
|
||||||
*/
|
*/
|
||||||
fn.on_drag = function(event, ui) {
|
fn.on_drag = function(event, ui) {
|
||||||
this.colliders_data = this.drag_api.get_closest_colliders();
|
var abs_offset = {
|
||||||
|
left: ui.position.left + this.baseX,
|
||||||
|
top: ui.position.top + this.baseY
|
||||||
|
}
|
||||||
|
this.colliders_data = this.collision_api.get_closest_colliders(abs_offset);
|
||||||
|
|
||||||
this.on_overlapped_column_change(
|
this.on_overlapped_column_change(
|
||||||
this.on_start_overlapping_column,
|
this.on_start_overlapping_column,
|
||||||
@@ -485,8 +495,11 @@
|
|||||||
* See http://jqueryui.com/demos/draggable/ for more info.
|
* See http://jqueryui.com/demos/draggable/ for more info.
|
||||||
*/
|
*/
|
||||||
fn.on_stop_drag = function(event, ui) {
|
fn.on_stop_drag = function(event, ui) {
|
||||||
this.$wrapper.removeClass('dragging');
|
this.$helper.add(this.$player).add(this.$wrapper).removeClass('dragging');
|
||||||
this.colliders_data = this.drag_api.get_closest_colliders();
|
|
||||||
|
ui.position.left = ui.position.left + this.baseX;
|
||||||
|
ui.position.top = ui.position.top + this.baseY;
|
||||||
|
this.colliders_data = this.collision_api.get_closest_colliders(ui.position);
|
||||||
|
|
||||||
this.on_overlapped_column_change(
|
this.on_overlapped_column_change(
|
||||||
this.on_start_overlapping_column,
|
this.on_start_overlapping_column,
|
||||||
@@ -498,13 +511,14 @@
|
|||||||
this.on_stop_overlapping_row
|
this.on_stop_overlapping_row
|
||||||
);
|
);
|
||||||
|
|
||||||
this.$player.add(this.$helper).attr({
|
this.$player
|
||||||
|
.addClass('player-revert').removeClass('player').attr({
|
||||||
'data-col': this.placeholder_grid_data.col,
|
'data-col': this.placeholder_grid_data.col,
|
||||||
'data-row': this.placeholder_grid_data.row
|
'data-row': this.placeholder_grid_data.row
|
||||||
}).css({
|
}).css({
|
||||||
'left': '',
|
'left': '',
|
||||||
'top': ''
|
'top': ''
|
||||||
}).removeClass('player');
|
});
|
||||||
|
|
||||||
this.$changed = this.$changed.add(this.$player);
|
this.$changed = this.$changed.add(this.$player);
|
||||||
|
|
||||||
@@ -998,12 +1012,21 @@
|
|||||||
size_y: phgd.size_y,
|
size_y: phgd.size_y,
|
||||||
size_x: phgd.size_x
|
size_x: phgd.size_x
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Prevents widgets go out of the grid
|
||||||
|
var right_col = (col + phgd.size_x - 1);
|
||||||
|
if (right_col > this.cols) {
|
||||||
|
col = col - (right_col - col);
|
||||||
|
};
|
||||||
|
|
||||||
var moved_down = this.placeholder_grid_data.row < row;
|
var moved_down = this.placeholder_grid_data.row < row;
|
||||||
var changed_column = this.placeholder_grid_data.col !== col;
|
var changed_column = this.placeholder_grid_data.col !== col;
|
||||||
|
|
||||||
this.placeholder_grid_data.col = col;
|
this.placeholder_grid_data.col = col;
|
||||||
this.placeholder_grid_data.row = row;
|
this.placeholder_grid_data.row = row;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.cells_occupied_by_placeholder = this.get_cells_occupied(
|
this.cells_occupied_by_placeholder = this.get_cells_occupied(
|
||||||
this.placeholder_grid_data);
|
this.placeholder_grid_data);
|
||||||
|
|
||||||
@@ -1624,6 +1647,12 @@
|
|||||||
};
|
};
|
||||||
var result = true;
|
var result = true;
|
||||||
|
|
||||||
|
//Prevents widgets go out of the grid
|
||||||
|
var right_col = col + widget_grid_data.size_x - 1;
|
||||||
|
if (right_col > this.cols) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
this.for_each_cell_occupied(future_wd, function(tcol, trow){
|
this.for_each_cell_occupied(future_wd, function(tcol, trow){
|
||||||
var $tw = this.is_widget(tcol, trow);
|
var $tw = this.is_widget(tcol, trow);
|
||||||
if ($tw && (!widget_grid_data.el || $tw.is($w))) {
|
if ($tw && (!widget_grid_data.el || $tw.is($w))) {
|
||||||
@@ -1868,6 +1897,33 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn.get_widgets_from = function(col, row) {
|
||||||
|
var ga = this.gridmap;
|
||||||
|
var $widgets = $();
|
||||||
|
|
||||||
|
if (col) {
|
||||||
|
$widgets = $widgets.add(
|
||||||
|
this.$widgets.filter(function(){
|
||||||
|
var tcol = $(this).attr('data-col');
|
||||||
|
return (tcol == col || tcol > col);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (row) {
|
||||||
|
$widgets = $widgets.add(
|
||||||
|
this.$widgets.filter(function(){
|
||||||
|
var trow = $(this).attr('data-row');
|
||||||
|
return (trow == row || trow > row);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return $widgets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current height of the parent grid.
|
* Set the current height of the parent grid.
|
||||||
*
|
*
|
||||||
@@ -1890,7 +1946,7 @@
|
|||||||
* @param {Number} cols Number of rows.
|
* @param {Number} cols Number of rows.
|
||||||
* @return {Object} Returns the instance of the Gridster class.
|
* @return {Object} Returns the instance of the Gridster class.
|
||||||
*/
|
*/
|
||||||
fn.generate_stylesheet = function(rows, cols) {
|
fn.generate_stylesheet = function(opts) {
|
||||||
var styles = '';
|
var styles = '';
|
||||||
var extra_cells = 10;
|
var extra_cells = 10;
|
||||||
var max_size_y = 6;
|
var max_size_y = 6;
|
||||||
@@ -1898,28 +1954,47 @@
|
|||||||
var i;
|
var i;
|
||||||
var rules;
|
var rules;
|
||||||
|
|
||||||
|
opts || (opts = {});
|
||||||
|
opts.cols || (opts.cols = this.cols);
|
||||||
|
opts.rows || (opts.rows = this.rows);
|
||||||
|
opts.namespace || (opts.namespace = '');
|
||||||
|
opts.widget_base_dimensions || (opts.widget_base_dimensions = this.options.widget_base_dimensions);
|
||||||
|
opts.widget_margins || (opts.widget_margins = this.options.widget_margins);
|
||||||
|
|
||||||
|
opts.min_widget_width = (opts.widget_margins[0] * 2) + opts.widget_base_dimensions[0];
|
||||||
|
opts.min_widget_height = (opts.widget_margins[1] * 2) + opts.widget_base_dimensions[1];
|
||||||
|
|
||||||
|
var serialized_opts = $.param(opts);
|
||||||
|
// don't duplicate stylesheets for the same configuration
|
||||||
|
if ($.inArray(serialized_opts, Gridster.generated_stylesheets) >= 0) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gridster.generated_stylesheets.push(serialized_opts);
|
||||||
|
|
||||||
/* generate CSS styles for cols */
|
/* generate CSS styles for cols */
|
||||||
for (i = cols + extra_cells; i >= 0; i--) {
|
for (i = opts.cols + extra_cells; i >= 0; i--) {
|
||||||
styles += '[data-col="'+ (i + 1) +'"] { left: ' +
|
styles += opts.namespace + ' [data-col="'+ (i + 1) +'"] { left: ' +
|
||||||
(i * this.min_widget_width) +
|
((i * opts.widget_base_dimensions[0]) + (i *opts.widget_margins[0] ) + ((i+1) * opts.widget_margins[0])) +
|
||||||
'px;} ';
|
'px;} ';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate CSS styles for rows */
|
/* generate CSS styles for rows */
|
||||||
for (i = rows + extra_cells; i >= 0; i--) {
|
for (i = opts.rows + extra_cells; i >= 0; i--) {
|
||||||
styles += '[data-row="' + (i + 1) + '"] { top: ' +
|
styles += opts.namespace + ' [data-row="' + (i + 1) + '"] { top: ' +
|
||||||
(i * this.min_widget_height) + 'px;} ';
|
((i * opts.widget_base_dimensions[1]) + (i * opts.widget_margins[1]) + ((i+1) * opts.widget_margins[1]) ) +
|
||||||
|
'px;} ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (var y = 1; y < max_size_y; y++) {
|
for (var y = 1; y < max_size_y; y++) {
|
||||||
styles += '[data-sizey="' + (y) + '"] { height: ' +
|
styles += opts.namespace + ' [data-sizey="' + (y) + '"] { height: ' +
|
||||||
(y * this.options.widget_base_dimensions[1] + (y-1)*(this.options.widget_margins[1]*2)) + 'px;}';
|
(y * opts.widget_base_dimensions[1] + (y-1)*(opts.widget_margins[1]*2)) + 'px;}';
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var x = 1; x < max_size_x; x++) {
|
for (var x = 1; x < max_size_x; x++) {
|
||||||
styles += '[data-sizex="' + (x) + '"] { width: ' +
|
styles += opts.namespace + ' [data-sizex="' + (x) + '"] { width: ' +
|
||||||
(x * this.options.widget_base_dimensions[0] + (x-1)*(this.options.widget_margins[0]*2)) + 'px;}';
|
(x * opts.widget_base_dimensions[0] + (x-1)*(opts.widget_margins[0]*2)) + 'px;}';
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.add_style_tag(styles);
|
return this.add_style_tag(styles);
|
||||||
@@ -2050,19 +2125,19 @@
|
|||||||
var min_cols = Math.max.apply(null, actual_cols);
|
var min_cols = Math.max.apply(null, actual_cols);
|
||||||
var min_rows = Math.max.apply(null, actual_rows);
|
var min_rows = Math.max.apply(null, actual_rows);
|
||||||
|
|
||||||
cols = Math.max(min_cols, cols, this.options.min_cols);
|
this.cols = Math.max(min_cols, cols, this.options.min_cols);
|
||||||
rows = Math.max(min_rows, rows, this.options.min_rows);
|
this.rows = Math.max(min_rows, rows, this.options.min_rows);
|
||||||
|
|
||||||
this.baseX = ($(window).width() - aw) / 2;
|
this.baseX = ($(window).width() - aw) / 2;
|
||||||
this.baseY = this.$wrapper.offset().top;
|
this.baseY = this.$wrapper.offset().top;
|
||||||
|
|
||||||
if (this.options.autogenerate_stylesheet) {
|
if (this.options.autogenerate_stylesheet) {
|
||||||
this.generate_stylesheet(rows, cols);
|
this.generate_stylesheet();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* more faux rows that needed are created so that there are cells
|
/* more faux rows that needed are created so that there are cells
|
||||||
* where drag beyond the limits */
|
* where drag beyond the limits */
|
||||||
return this.generate_faux_grid(rows, cols);
|
return this.generate_faux_grid(this.rows, this.cols);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user