dashing-rails 2.4.3 → 2.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile +7 -0
- data/app/views/dashing/widgets/graph.html +1 -1
- data/dashing.gemspec +0 -4
- data/lib/dashing/version.rb +1 -1
- data/vendor/assets/javascripts/dashing/dashing-src.coffee +7 -2
- data/vendor/assets/javascripts/dashing/index.js +1 -1
- data/vendor/assets/javascripts/dashing/jquery.gridster.js +1572 -475
- data/vendor/assets/javascripts/dashing/rickshaw-1.5.1.min.js +3 -0
- data/vendor/assets/stylesheets/dashing/dashing-src.scss +2 -2
- data/vendor/assets/stylesheets/dashing/jquery.gridster.css +75 -11
- metadata +26 -81
- data/vendor/assets/javascripts/dashing/rickshaw-1.4.3.min.js +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9333080f44e686f2ea430c16aacc839617384755
|
4
|
+
data.tar.gz: 1d876a9d631409fa33832e201a783310268a0839
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 518e8283c53c5e76b702073b062b7aceba01ada5634a9416b4711975f7804b102e15749663ca1132a086ee5317bffaf9c3a550734ad4b6c8721c69e6b1d32999
|
7
|
+
data.tar.gz: 10a8eb97f7a805f1a5f3108c96fe5631a7ad088c653fa96c2ce6d424b2b46eb896a55a2581647affd92362aeae22580c83ea436e3b98c0d825d6bb2bbb3aeeca
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 2.4.4
|
2
|
+
|
3
|
+
* Upgrade jquery.gridster to 0.5.6
|
4
|
+
* Upgrade Rickshaw to 1.5.1
|
5
|
+
* Cherry pick https://github.com/Shopify/dashing/pull/438
|
6
|
+
* Cherry pick https://github.com/Shopify/dashing/pull/521
|
7
|
+
|
1
8
|
## 2.4.3
|
2
9
|
|
3
10
|
* Fix bugs in `2.4.2` related to upgrades on graph widget without upgrading dashing-src and downgrading batman.js
|
data/Gemfile
CHANGED
data/dashing.gemspec
CHANGED
@@ -24,10 +24,6 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_dependency 'redis', '~> 3.2'
|
25
25
|
spec.add_dependency 'connection_pool', '~> 2.1'
|
26
26
|
|
27
|
-
spec.add_development_dependency 'rspec-rails', '~> 2.14'
|
28
27
|
spec.add_development_dependency 'pry-rails'
|
29
28
|
spec.add_development_dependency 'better_errors'
|
30
|
-
spec.add_development_dependency 'coveralls'
|
31
|
-
spec.add_development_dependency 'simplecov'
|
32
|
-
spec.add_development_dependency 'generator_spec'
|
33
29
|
end
|
data/lib/dashing/version.rb
CHANGED
@@ -37,7 +37,6 @@ class Dashing.Widget extends Batman.View
|
|
37
37
|
@mixin($(@node).data())
|
38
38
|
Dashing.widgets[@id] ||= []
|
39
39
|
Dashing.widgets[@id].push(@)
|
40
|
-
@mixin(Dashing.lastEvents[@id]) # in case the events from the server came before the widget was rendered
|
41
40
|
|
42
41
|
type = Batman.Filters.dashize(@view)
|
43
42
|
$(@node).addClass("widget widget-#{type} #{@id}")
|
@@ -52,6 +51,12 @@ class Dashing.Widget extends Batman.View
|
|
52
51
|
@::on 'ready', ->
|
53
52
|
Dashing.Widget.fire 'ready'
|
54
53
|
|
54
|
+
# In case the events from the server came before the widget was rendered
|
55
|
+
lastData = Dashing.lastEvents[@id]
|
56
|
+
if lastData
|
57
|
+
@mixin(lastData)
|
58
|
+
@onData(lastData)
|
59
|
+
|
55
60
|
receiveData: (data) =>
|
56
61
|
@mixin(data)
|
57
62
|
@onData(data)
|
@@ -106,8 +111,8 @@ source.addEventListener 'message', (e) ->
|
|
106
111
|
if lastEvents[data.id]?.updatedAt != data.updatedAt
|
107
112
|
if Dashing.debugMode
|
108
113
|
console.log("Received data for #{data.id}", data)
|
114
|
+
lastEvents[data.id] = data
|
109
115
|
if widgets[data.id]?.length > 0
|
110
|
-
lastEvents[data.id] = data
|
111
116
|
for widget in widgets[data.id]
|
112
117
|
widget.receiveData(data)
|
113
118
|
|
@@ -1,8 +1,16 @@
|
|
1
|
-
/*! gridster.js - v0.
|
1
|
+
/*! gridster.js - v0.5.6 - 2014-09-25
|
2
2
|
* http://gridster.net/
|
3
|
-
* Copyright (c)
|
3
|
+
* Copyright (c) 2014 ducksboard; Licensed MIT */
|
4
4
|
|
5
|
-
;(function(
|
5
|
+
;(function(root, factory) {
|
6
|
+
|
7
|
+
if (typeof define === 'function' && define.amd) {
|
8
|
+
define('gridster-coords', ['jquery'], factory);
|
9
|
+
} else {
|
10
|
+
root.GridsterCoords = factory(root.$ || root.jQuery);
|
11
|
+
}
|
12
|
+
|
13
|
+
}(this, function($) {
|
6
14
|
/**
|
7
15
|
* Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height)
|
8
16
|
* to simulate DOM elements on the screen.
|
@@ -55,6 +63,9 @@
|
|
55
63
|
|
56
64
|
var d = this.data;
|
57
65
|
|
66
|
+
typeof d.left === 'undefined' && (d.left = d.x1);
|
67
|
+
typeof d.top === 'undefined' && (d.top = d.y1);
|
68
|
+
|
58
69
|
this.coords.x1 = d.left;
|
59
70
|
this.coords.y1 = d.top;
|
60
71
|
this.coords.x2 = d.left + d.width;
|
@@ -89,6 +100,10 @@
|
|
89
100
|
return this.coords;
|
90
101
|
};
|
91
102
|
|
103
|
+
fn.destroy = function() {
|
104
|
+
this.el.removeData('coords');
|
105
|
+
delete this.el;
|
106
|
+
};
|
92
107
|
|
93
108
|
//jQuery adapter
|
94
109
|
$.fn.coords = function() {
|
@@ -101,12 +116,24 @@
|
|
101
116
|
return ins;
|
102
117
|
};
|
103
118
|
|
104
|
-
|
119
|
+
return Coords;
|
120
|
+
|
121
|
+
}));
|
122
|
+
|
123
|
+
;(function(root, factory) {
|
124
|
+
|
125
|
+
if (typeof define === 'function' && define.amd) {
|
126
|
+
define('gridster-collision', ['jquery', 'gridster-coords'], factory);
|
127
|
+
} else {
|
128
|
+
root.GridsterCollision = factory(root.$ || root.jQuery,
|
129
|
+
root.GridsterCoords);
|
130
|
+
}
|
105
131
|
|
106
|
-
|
132
|
+
}(this, function($, Coords) {
|
107
133
|
|
108
134
|
var defaults = {
|
109
|
-
colliders_context: document.body
|
135
|
+
colliders_context: document.body,
|
136
|
+
overlapping_region: 'C'
|
110
137
|
// ,on_overlap: function(collider_data){},
|
111
138
|
// on_overlap_start : function(collider_data){},
|
112
139
|
// on_overlap_stop : function(collider_data){}
|
@@ -124,6 +151,9 @@
|
|
124
151
|
* of HTMLElements or an Array of Coords instances.
|
125
152
|
* @param {Object} [options] An Object with all options you want to
|
126
153
|
* overwrite:
|
154
|
+
* @param {String} [options.overlapping_region] Determines when collision
|
155
|
+
* is valid, depending on the overlapped area. Values can be: 'N', 'S',
|
156
|
+
* 'W', 'E', 'C' or 'all'. Default is 'C'.
|
127
157
|
* @param {Function} [options.on_overlap_start] Executes a function the first
|
128
158
|
* time each `collider ` is overlapped.
|
129
159
|
* @param {Function} [options.on_overlap_stop] Executes a function when a
|
@@ -138,16 +168,12 @@
|
|
138
168
|
this.$element = el;
|
139
169
|
this.last_colliders = [];
|
140
170
|
this.last_colliders_coords = [];
|
141
|
-
|
142
|
-
this.$colliders = $(colliders,
|
143
|
-
this.options.colliders_context).not(this.$element);
|
144
|
-
}else{
|
145
|
-
this.colliders = $(colliders);
|
146
|
-
}
|
171
|
+
this.set_colliders(colliders);
|
147
172
|
|
148
173
|
this.init();
|
149
174
|
}
|
150
175
|
|
176
|
+
Collision.defaults = defaults;
|
151
177
|
|
152
178
|
var fn = Collision.prototype;
|
153
179
|
|
@@ -228,6 +254,7 @@
|
|
228
254
|
|
229
255
|
fn.find_collisions = function(player_data_coords){
|
230
256
|
var self = this;
|
257
|
+
var overlapping_region = this.options.overlapping_region;
|
231
258
|
var colliders_coords = [];
|
232
259
|
var colliders_data = [];
|
233
260
|
var $colliders = (this.colliders || this.$colliders);
|
@@ -251,7 +278,8 @@
|
|
251
278
|
player_coords, collider_coords);
|
252
279
|
|
253
280
|
//todo: make this an option
|
254
|
-
if (region === '
|
281
|
+
if (region === overlapping_region || overlapping_region === 'all') {
|
282
|
+
|
255
283
|
var area_coords = self.calculate_overlapped_area_coords(
|
256
284
|
player_coords, collider_coords);
|
257
285
|
var area = self.calculate_overlapped_area(area_coords);
|
@@ -274,7 +302,7 @@
|
|
274
302
|
|
275
303
|
if (self.options.on_overlap_stop || self.options.on_overlap_start) {
|
276
304
|
this.manage_colliders_start_stop(colliders_coords,
|
277
|
-
self.options.
|
305
|
+
self.options.on_overlap_start, self.options.on_overlap_stop);
|
278
306
|
}
|
279
307
|
|
280
308
|
this.last_colliders_coords = colliders_coords;
|
@@ -285,12 +313,8 @@
|
|
285
313
|
|
286
314
|
fn.get_closest_colliders = function(player_data_coords){
|
287
315
|
var colliders = this.find_collisions(player_data_coords);
|
288
|
-
var min_area = 100;
|
289
|
-
colliders.sort(function(a, b){
|
290
|
-
if (a.area <= min_area) {
|
291
|
-
return 1;
|
292
|
-
}
|
293
316
|
|
317
|
+
colliders.sort(function(a, b) {
|
294
318
|
/* if colliders are being overlapped by the "C" (center) region,
|
295
319
|
* we have to set a lower index in the array to which they are placed
|
296
320
|
* above in the grid. */
|
@@ -302,7 +326,7 @@
|
|
302
326
|
}
|
303
327
|
}
|
304
328
|
|
305
|
-
if (a.area < b.area){
|
329
|
+
if (a.area < b.area) {
|
306
330
|
return 1;
|
307
331
|
}
|
308
332
|
|
@@ -312,16 +336,59 @@
|
|
312
336
|
};
|
313
337
|
|
314
338
|
|
339
|
+
fn.set_colliders = function(colliders) {
|
340
|
+
if (typeof colliders === 'string' || colliders instanceof $) {
|
341
|
+
this.$colliders = $(colliders,
|
342
|
+
this.options.colliders_context).not(this.$element);
|
343
|
+
}else{
|
344
|
+
this.colliders = $(colliders);
|
345
|
+
}
|
346
|
+
};
|
347
|
+
|
348
|
+
|
315
349
|
//jQuery adapter
|
316
350
|
$.fn.collision = function(collider, options) {
|
317
351
|
return new Collision( this, collider, options );
|
318
352
|
};
|
319
353
|
|
354
|
+
return Collision;
|
320
355
|
|
321
|
-
}
|
356
|
+
}));
|
322
357
|
|
323
358
|
;(function(window, undefined) {
|
324
|
-
|
359
|
+
|
360
|
+
/* Delay, debounce and throttle functions taken from underscore.js
|
361
|
+
*
|
362
|
+
* Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and
|
363
|
+
* Investigative Reporters & Editors
|
364
|
+
*
|
365
|
+
* Permission is hereby granted, free of charge, to any person
|
366
|
+
* obtaining a copy of this software and associated documentation
|
367
|
+
* files (the "Software"), to deal in the Software without
|
368
|
+
* restriction, including without limitation the rights to use,
|
369
|
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
370
|
+
* copies of the Software, and to permit persons to whom the
|
371
|
+
* Software is furnished to do so, subject to the following
|
372
|
+
* conditions:
|
373
|
+
*
|
374
|
+
* The above copyright notice and this permission notice shall be
|
375
|
+
* included in all copies or substantial portions of the Software.
|
376
|
+
*
|
377
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
378
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
379
|
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
380
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
381
|
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
382
|
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
383
|
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
384
|
+
* OTHER DEALINGS IN THE SOFTWARE.
|
385
|
+
*/
|
386
|
+
|
387
|
+
window.delay = function(func, wait) {
|
388
|
+
var args = Array.prototype.slice.call(arguments, 2);
|
389
|
+
return setTimeout(function(){ return func.apply(null, args); }, wait);
|
390
|
+
};
|
391
|
+
|
325
392
|
window.debounce = function(func, wait, immediate) {
|
326
393
|
var timeout;
|
327
394
|
return function() {
|
@@ -336,7 +403,6 @@
|
|
336
403
|
};
|
337
404
|
};
|
338
405
|
|
339
|
-
|
340
406
|
window.throttle = function(func, wait) {
|
341
407
|
var context, args, timeout, throttling, more, result;
|
342
408
|
var whenDone = debounce(
|
@@ -362,27 +428,46 @@
|
|
362
428
|
|
363
429
|
})(window);
|
364
430
|
|
365
|
-
;(function(
|
431
|
+
;(function(root, factory) {
|
432
|
+
|
433
|
+
if (typeof define === 'function' && define.amd) {
|
434
|
+
define('gridster-draggable', ['jquery'], factory);
|
435
|
+
} else {
|
436
|
+
root.GridsterDraggable = factory(root.$ || root.jQuery);
|
437
|
+
}
|
438
|
+
|
439
|
+
}(this, function($) {
|
366
440
|
|
367
441
|
var defaults = {
|
368
|
-
items: '
|
442
|
+
items: 'li',
|
369
443
|
distance: 1,
|
370
444
|
limit: true,
|
371
445
|
offset_left: 0,
|
372
|
-
autoscroll: true
|
373
|
-
|
374
|
-
|
375
|
-
//
|
446
|
+
autoscroll: true,
|
447
|
+
ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'], // or function
|
448
|
+
handle: null,
|
449
|
+
container_width: 0, // 0 == auto
|
450
|
+
move_element: true,
|
451
|
+
helper: false, // or 'clone'
|
452
|
+
remove_helper: true
|
453
|
+
// drag: function(e) {},
|
454
|
+
// start : function(e, ui) {},
|
455
|
+
// stop : function(e) {}
|
376
456
|
};
|
377
457
|
|
378
458
|
var $window = $(window);
|
459
|
+
var dir_map = { x : 'left', y : 'top' };
|
379
460
|
var isTouch = !!('ontouchstart' in window);
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
end: isTouch ? 'touchend' : 'mouseup.draggable'
|
461
|
+
|
462
|
+
var capitalize = function(str) {
|
463
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
384
464
|
};
|
385
465
|
|
466
|
+
var idCounter = 0;
|
467
|
+
var uniqId = function() {
|
468
|
+
return ++idCounter + '';
|
469
|
+
}
|
470
|
+
|
386
471
|
/**
|
387
472
|
* Basic drag implementation for DOM elements inside a container.
|
388
473
|
* Provide start/stop/drag callbacks.
|
@@ -399,6 +484,9 @@
|
|
399
484
|
* the mouse must move before dragging should start.
|
400
485
|
* @param {Boolean} [options.limit] Constrains dragging to the width of
|
401
486
|
* the container
|
487
|
+
* @param {Object|Function} [options.ignore_dragging] Array of node names
|
488
|
+
* that sould not trigger dragging, by default is `['INPUT', 'TEXTAREA',
|
489
|
+
* 'SELECT', 'BUTTON']`. If a function is used return true to ignore dragging.
|
402
490
|
* @param {offset_left} [options.offset_left] Offset added to the item
|
403
491
|
* that is being dragged.
|
404
492
|
* @param {Number} [options.drag] Executes a callback when the mouse is
|
@@ -411,25 +499,57 @@
|
|
411
499
|
*/
|
412
500
|
function Draggable(el, options) {
|
413
501
|
this.options = $.extend({}, defaults, options);
|
414
|
-
this.$
|
502
|
+
this.$document = $(document);
|
415
503
|
this.$container = $(el);
|
416
504
|
this.$dragitems = $(this.options.items, this.$container);
|
417
505
|
this.is_dragging = false;
|
418
506
|
this.player_min_left = 0 + this.options.offset_left;
|
507
|
+
this.id = uniqId();
|
508
|
+
this.ns = '.gridster-draggable-' + this.id;
|
419
509
|
this.init();
|
420
510
|
}
|
421
511
|
|
512
|
+
Draggable.defaults = defaults;
|
513
|
+
|
422
514
|
var fn = Draggable.prototype;
|
423
515
|
|
424
516
|
fn.init = function() {
|
425
|
-
this.
|
426
|
-
this
|
427
|
-
this.
|
517
|
+
var pos = this.$container.css('position');
|
518
|
+
this.calculate_dimensions();
|
519
|
+
this.$container.css('position', pos === 'static' ? 'relative' : pos);
|
520
|
+
this.disabled = false;
|
521
|
+
this.events();
|
522
|
+
|
523
|
+
$(window).bind(this.nsEvent('resize'),
|
524
|
+
throttle($.proxy(this.calculate_dimensions, this), 200));
|
525
|
+
};
|
428
526
|
|
429
|
-
|
430
|
-
|
527
|
+
fn.nsEvent = function(ev) {
|
528
|
+
return (ev || '') + this.ns;
|
431
529
|
};
|
432
530
|
|
531
|
+
fn.events = function() {
|
532
|
+
this.pointer_events = {
|
533
|
+
start: this.nsEvent('touchstart') + ' ' + this.nsEvent('mousedown'),
|
534
|
+
move: this.nsEvent('touchmove') + ' ' + this.nsEvent('mousemove'),
|
535
|
+
end: this.nsEvent('touchend') + ' ' + this.nsEvent('mouseup'),
|
536
|
+
};
|
537
|
+
|
538
|
+
this.$container.on(this.nsEvent('selectstart'),
|
539
|
+
$.proxy(this.on_select_start, this));
|
540
|
+
|
541
|
+
this.$container.on(this.pointer_events.start, this.options.items,
|
542
|
+
$.proxy(this.drag_handler, this));
|
543
|
+
|
544
|
+
this.$document.on(this.pointer_events.end, $.proxy(function(e) {
|
545
|
+
this.is_dragging = false;
|
546
|
+
if (this.disabled) { return; }
|
547
|
+
this.$document.off(this.pointer_events.move);
|
548
|
+
if (this.drag_start) {
|
549
|
+
this.on_dragstop(e);
|
550
|
+
}
|
551
|
+
}, this));
|
552
|
+
};
|
433
553
|
|
434
554
|
fn.get_actual_pos = function($el) {
|
435
555
|
var pos = $el.position();
|
@@ -438,10 +558,10 @@
|
|
438
558
|
|
439
559
|
|
440
560
|
fn.get_mouse_pos = function(e) {
|
441
|
-
if (
|
561
|
+
if (e.originalEvent && e.originalEvent.touches) {
|
442
562
|
var oe = e.originalEvent;
|
443
563
|
e = oe.touches.length ? oe.touches[0] : oe.changedTouches[0];
|
444
|
-
}
|
564
|
+
}
|
445
565
|
|
446
566
|
return {
|
447
567
|
left: e.clientX,
|
@@ -457,77 +577,119 @@
|
|
457
577
|
mouse_actual_pos.left - this.mouse_init_pos.left);
|
458
578
|
var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top);
|
459
579
|
|
460
|
-
var left = Math.round(this.el_init_offset.left +
|
461
|
-
|
462
|
-
|
580
|
+
var left = Math.round(this.el_init_offset.left +
|
581
|
+
diff_x - this.baseX + $(window).scrollLeft() - this.win_offset_x);
|
582
|
+
var top = Math.round(this.el_init_offset.top +
|
583
|
+
diff_y - this.baseY + $(window).scrollTop() - this.win_offset_y);
|
463
584
|
|
464
585
|
if (this.options.limit) {
|
465
586
|
if (left > this.player_max_left) {
|
466
587
|
left = this.player_max_left;
|
467
|
-
}else if(left < this.player_min_left) {
|
588
|
+
} else if(left < this.player_min_left) {
|
468
589
|
left = this.player_min_left;
|
469
590
|
}
|
470
591
|
}
|
471
592
|
|
472
593
|
return {
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
594
|
+
position: {
|
595
|
+
left: left,
|
596
|
+
top: top
|
597
|
+
},
|
598
|
+
pointer: {
|
599
|
+
left: mouse_actual_pos.left,
|
600
|
+
top: mouse_actual_pos.top,
|
601
|
+
diff_left: diff_x + ($(window).scrollLeft() - this.win_offset_x),
|
602
|
+
diff_top: diff_y + ($(window).scrollTop() - this.win_offset_y)
|
603
|
+
}
|
477
604
|
};
|
478
605
|
};
|
479
606
|
|
480
607
|
|
481
|
-
fn.
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
608
|
+
fn.get_drag_data = function(e) {
|
609
|
+
var offset = this.get_offset(e);
|
610
|
+
offset.$player = this.$player;
|
611
|
+
offset.$helper = this.helper ? this.$helper : this.$player;
|
612
|
+
|
613
|
+
return offset;
|
614
|
+
};
|
615
|
+
|
616
|
+
|
617
|
+
fn.set_limits = function(container_width) {
|
618
|
+
container_width || (container_width = this.$container.width());
|
619
|
+
this.player_max_left = (container_width - this.player_width +
|
620
|
+
- this.options.offset_left);
|
621
|
+
|
622
|
+
this.options.container_width = container_width;
|
623
|
+
|
624
|
+
return this;
|
625
|
+
};
|
626
|
+
|
627
|
+
|
628
|
+
fn.scroll_in = function(axis, data) {
|
629
|
+
var dir_prop = dir_map[axis];
|
630
|
+
|
631
|
+
var area_size = 50;
|
632
|
+
var scroll_inc = 30;
|
633
|
+
|
634
|
+
var is_x = axis === 'x';
|
635
|
+
var window_size = is_x ? this.window_width : this.window_height;
|
636
|
+
var doc_size = is_x ? $(document).width() : $(document).height();
|
637
|
+
var player_size = is_x ? this.$player.width() : this.$player.height();
|
487
638
|
|
488
|
-
var
|
489
|
-
var
|
639
|
+
var next_scroll;
|
640
|
+
var scroll_offset = $window['scroll' + capitalize(dir_prop)]();
|
641
|
+
var min_window_pos = scroll_offset;
|
642
|
+
var max_window_pos = min_window_pos + window_size;
|
490
643
|
|
491
|
-
var
|
492
|
-
var
|
644
|
+
var mouse_next_zone = max_window_pos - area_size; // down/right
|
645
|
+
var mouse_prev_zone = min_window_pos + area_size; // up/left
|
493
646
|
|
494
|
-
var
|
495
|
-
this.player_height);
|
647
|
+
var abs_mouse_pos = min_window_pos + data.pointer[dir_prop];
|
496
648
|
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
649
|
+
var max_player_pos = (doc_size - window_size + player_size);
|
650
|
+
|
651
|
+
if (abs_mouse_pos >= mouse_next_zone) {
|
652
|
+
next_scroll = scroll_offset + scroll_inc;
|
653
|
+
if (next_scroll < max_player_pos) {
|
654
|
+
$window['scroll' + capitalize(dir_prop)](next_scroll);
|
655
|
+
this['scroll_offset_' + axis] += scroll_inc;
|
502
656
|
}
|
503
|
-
}
|
657
|
+
}
|
504
658
|
|
505
|
-
if (
|
506
|
-
|
507
|
-
if (
|
508
|
-
$window
|
509
|
-
this
|
659
|
+
if (abs_mouse_pos <= mouse_prev_zone) {
|
660
|
+
next_scroll = scroll_offset - scroll_inc;
|
661
|
+
if (next_scroll > 0) {
|
662
|
+
$window['scroll' + capitalize(dir_prop)](next_scroll);
|
663
|
+
this['scroll_offset_' + axis] -= scroll_inc;
|
510
664
|
}
|
511
|
-
}
|
512
|
-
|
665
|
+
}
|
666
|
+
|
667
|
+
return this;
|
668
|
+
};
|
669
|
+
|
670
|
+
|
671
|
+
fn.manage_scroll = function(data) {
|
672
|
+
this.scroll_in('x', data);
|
673
|
+
this.scroll_in('y', data);
|
674
|
+
};
|
513
675
|
|
514
676
|
|
515
|
-
fn.
|
677
|
+
fn.calculate_dimensions = function(e) {
|
516
678
|
this.window_height = $window.height();
|
517
|
-
|
679
|
+
this.window_width = $window.width();
|
680
|
+
};
|
518
681
|
|
519
682
|
|
520
683
|
fn.drag_handler = function(e) {
|
521
684
|
var node = e.target.nodeName;
|
522
|
-
|
523
|
-
if (e.which !== 1 && !isTouch) {
|
685
|
+
// skip if drag is disabled, or click was not done with the mouse primary button
|
686
|
+
if (this.disabled || e.which !== 1 && !isTouch) {
|
524
687
|
return;
|
525
688
|
}
|
526
689
|
|
527
|
-
if (
|
528
|
-
node === 'BUTTON') {
|
690
|
+
if (this.ignore_drag(e)) {
|
529
691
|
return;
|
530
|
-
}
|
692
|
+
}
|
531
693
|
|
532
694
|
var self = this;
|
533
695
|
var first = true;
|
@@ -537,7 +699,7 @@
|
|
537
699
|
this.mouse_init_pos = this.get_mouse_pos(e);
|
538
700
|
this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top;
|
539
701
|
|
540
|
-
this.$
|
702
|
+
this.$document.on(this.pointer_events.move, function(mme) {
|
541
703
|
var mouse_actual_pos = self.get_mouse_pos(mme);
|
542
704
|
var diff_x = Math.abs(
|
543
705
|
mouse_actual_pos.left - self.mouse_init_pos.left);
|
@@ -545,7 +707,7 @@
|
|
545
707
|
mouse_actual_pos.top - self.mouse_init_pos.top);
|
546
708
|
if (!(diff_x > self.options.distance ||
|
547
709
|
diff_y > self.options.distance)
|
548
|
-
|
710
|
+
) {
|
549
711
|
return false;
|
550
712
|
}
|
551
713
|
|
@@ -555,90 +717,87 @@
|
|
555
717
|
return false;
|
556
718
|
}
|
557
719
|
|
558
|
-
if (self.is_dragging
|
720
|
+
if (self.is_dragging === true) {
|
559
721
|
self.on_dragmove.call(self, mme);
|
560
722
|
}
|
561
723
|
|
562
724
|
return false;
|
563
725
|
});
|
564
726
|
|
565
|
-
return false;
|
727
|
+
if (!isTouch) { return false; }
|
566
728
|
};
|
567
729
|
|
568
730
|
|
569
731
|
fn.on_dragstart = function(e) {
|
570
732
|
e.preventDefault();
|
571
|
-
|
572
|
-
this.is_dragging
|
733
|
+
|
734
|
+
if (this.is_dragging) { return this; }
|
735
|
+
|
736
|
+
this.drag_start = this.is_dragging = true;
|
573
737
|
var offset = this.$container.offset();
|
574
738
|
this.baseX = Math.round(offset.left);
|
575
739
|
this.baseY = Math.round(offset.top);
|
576
|
-
this.
|
740
|
+
this.initial_container_width = this.options.container_width || this.$container.width();
|
577
741
|
|
578
742
|
if (this.options.helper === 'clone') {
|
579
743
|
this.$helper = this.$player.clone()
|
580
744
|
.appendTo(this.$container).addClass('helper');
|
581
745
|
this.helper = true;
|
582
|
-
}else{
|
746
|
+
} else {
|
583
747
|
this.helper = false;
|
584
748
|
}
|
585
|
-
|
749
|
+
|
750
|
+
this.win_offset_y = $(window).scrollTop();
|
751
|
+
this.win_offset_x = $(window).scrollLeft();
|
752
|
+
this.scroll_offset_y = 0;
|
753
|
+
this.scroll_offset_x = 0;
|
586
754
|
this.el_init_offset = this.$player.offset();
|
587
755
|
this.player_width = this.$player.width();
|
588
756
|
this.player_height = this.$player.height();
|
589
|
-
|
590
|
-
|
757
|
+
|
758
|
+
this.set_limits(this.options.container_width);
|
591
759
|
|
592
760
|
if (this.options.start) {
|
593
|
-
this.options.start.call(this.$player, e,
|
594
|
-
helper: this.helper ? this.$helper : this.$player
|
595
|
-
});
|
761
|
+
this.options.start.call(this.$player, e, this.get_drag_data(e));
|
596
762
|
}
|
597
763
|
return false;
|
598
764
|
};
|
599
765
|
|
600
766
|
|
601
767
|
fn.on_dragmove = function(e) {
|
602
|
-
var
|
768
|
+
var data = this.get_drag_data(e);
|
603
769
|
|
604
|
-
this.options.autoscroll && this.manage_scroll(
|
770
|
+
this.options.autoscroll && this.manage_scroll(data);
|
605
771
|
|
606
|
-
(this.
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
772
|
+
if (this.options.move_element) {
|
773
|
+
(this.helper ? this.$helper : this.$player).css({
|
774
|
+
'position': 'absolute',
|
775
|
+
'left' : data.position.left,
|
776
|
+
'top' : data.position.top
|
777
|
+
});
|
778
|
+
}
|
611
779
|
|
612
|
-
var
|
613
|
-
|
614
|
-
'left': offset.left,
|
615
|
-
'top': offset.top
|
616
|
-
}
|
617
|
-
};
|
780
|
+
var last_position = this.last_position || data.position;
|
781
|
+
data.prev_position = last_position;
|
618
782
|
|
619
783
|
if (this.options.drag) {
|
620
|
-
this.options.drag.call(this.$player, e,
|
784
|
+
this.options.drag.call(this.$player, e, data);
|
621
785
|
}
|
786
|
+
|
787
|
+
this.last_position = data.position;
|
622
788
|
return false;
|
623
789
|
};
|
624
790
|
|
625
791
|
|
626
792
|
fn.on_dragstop = function(e) {
|
627
|
-
var
|
793
|
+
var data = this.get_drag_data(e);
|
628
794
|
this.drag_start = false;
|
629
795
|
|
630
|
-
var ui = {
|
631
|
-
'position': {
|
632
|
-
'left': offset.left,
|
633
|
-
'top': offset.top
|
634
|
-
}
|
635
|
-
};
|
636
|
-
|
637
796
|
if (this.options.stop) {
|
638
|
-
this.options.stop.call(this.$player, e,
|
797
|
+
this.options.stop.call(this.$player, e, data);
|
639
798
|
}
|
640
799
|
|
641
|
-
if (this.helper) {
|
800
|
+
if (this.helper && this.options.remove_helper) {
|
642
801
|
this.$helper.remove();
|
643
802
|
}
|
644
803
|
|
@@ -646,78 +805,104 @@
|
|
646
805
|
};
|
647
806
|
|
648
807
|
fn.on_select_start = function(e) {
|
649
|
-
return
|
650
|
-
}
|
651
|
-
|
808
|
+
if (this.disabled) { return; }
|
652
809
|
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
this.$container.on(pointer_events.start, this.options.items, $.proxy(
|
657
|
-
this.drag_handler, this));
|
810
|
+
if (this.ignore_drag(e)) {
|
811
|
+
return;
|
812
|
+
}
|
658
813
|
|
659
|
-
|
660
|
-
this.is_dragging = false;
|
661
|
-
this.$body.off(pointer_events.move);
|
662
|
-
if (this.drag_start) {
|
663
|
-
this.on_dragstop(e);
|
664
|
-
}
|
665
|
-
}, this));
|
814
|
+
return false;
|
666
815
|
};
|
667
816
|
|
668
|
-
|
669
|
-
|
670
|
-
this.$container.off(pointer_events.start);
|
671
|
-
this.$body.off(pointer_events.end);
|
672
|
-
this.$container.off('selectstart', this.on_select_start);
|
817
|
+
fn.enable = function() {
|
818
|
+
this.disabled = false;
|
673
819
|
};
|
674
820
|
|
821
|
+
fn.disable = function() {
|
822
|
+
this.disabled = true;
|
823
|
+
};
|
675
824
|
|
676
|
-
fn.destroy = function(){
|
825
|
+
fn.destroy = function() {
|
677
826
|
this.disable();
|
827
|
+
|
828
|
+
this.$container.off(this.ns);
|
829
|
+
this.$document.off(this.ns);
|
830
|
+
$(window).off(this.ns);
|
831
|
+
|
678
832
|
$.removeData(this.$container, 'drag');
|
679
833
|
};
|
680
834
|
|
835
|
+
fn.ignore_drag = function(event) {
|
836
|
+
if (this.options.handle) {
|
837
|
+
return !$(event.target).is(this.options.handle);
|
838
|
+
}
|
839
|
+
|
840
|
+
if ($.isFunction(this.options.ignore_dragging)) {
|
841
|
+
return this.options.ignore_dragging(event);
|
842
|
+
}
|
843
|
+
|
844
|
+
return $(event.target).is(this.options.ignore_dragging.join(', '));
|
845
|
+
};
|
681
846
|
|
682
847
|
//jQuery adapter
|
683
848
|
$.fn.drag = function ( options ) {
|
684
|
-
return this
|
685
|
-
if (!$.data(this, 'drag')) {
|
686
|
-
$.data(this, 'drag', new Draggable( this, options ));
|
687
|
-
}
|
688
|
-
});
|
849
|
+
return new Draggable(this, options);
|
689
850
|
};
|
690
851
|
|
852
|
+
return Draggable;
|
853
|
+
|
854
|
+
}));
|
855
|
+
|
856
|
+
;(function(root, factory) {
|
691
857
|
|
692
|
-
|
858
|
+
if (typeof define === 'function' && define.amd) {
|
859
|
+
define(['jquery', 'gridster-draggable', 'gridster-collision'], factory);
|
860
|
+
} else {
|
861
|
+
root.Gridster = factory(root.$ || root.jQuery, root.GridsterDraggable,
|
862
|
+
root.GridsterCollision);
|
863
|
+
}
|
693
864
|
|
694
|
-
|
865
|
+
}(this, function($, Draggable, Collision) {
|
695
866
|
|
696
867
|
var defaults = {
|
697
|
-
|
868
|
+
namespace: '',
|
869
|
+
widget_selector: 'li',
|
698
870
|
widget_margins: [10, 10],
|
699
871
|
widget_base_dimensions: [400, 225],
|
700
872
|
extra_rows: 0,
|
701
873
|
extra_cols: 0,
|
702
874
|
min_cols: 1,
|
875
|
+
max_cols: Infinity,
|
703
876
|
min_rows: 15,
|
704
|
-
max_size_x:
|
705
|
-
|
877
|
+
max_size_x: false,
|
878
|
+
autogrow_cols: false,
|
706
879
|
autogenerate_stylesheet: true,
|
707
880
|
avoid_overlapped_widgets: true,
|
881
|
+
auto_init: true,
|
708
882
|
serialize_params: function($w, wgd) {
|
709
883
|
return {
|
710
884
|
col: wgd.col,
|
711
|
-
row: wgd.row
|
885
|
+
row: wgd.row,
|
886
|
+
size_x: wgd.size_x,
|
887
|
+
size_y: wgd.size_y
|
712
888
|
};
|
713
889
|
},
|
714
890
|
collision: {},
|
715
891
|
draggable: {
|
716
|
-
|
892
|
+
items: '.gs-w',
|
893
|
+
distance: 4,
|
894
|
+
ignore_dragging: Draggable.defaults.ignore_dragging.slice(0)
|
895
|
+
},
|
896
|
+
resize: {
|
897
|
+
enabled: false,
|
898
|
+
axes: ['both'],
|
899
|
+
handle_append_to: '',
|
900
|
+
handle_class: 'gs-resize-handle',
|
901
|
+
max_size: [Infinity, Infinity],
|
902
|
+
min_size: [1, 1]
|
717
903
|
}
|
718
904
|
};
|
719
905
|
|
720
|
-
|
721
906
|
/**
|
722
907
|
* @class Gridster
|
723
908
|
* @uses Draggable
|
@@ -739,11 +924,11 @@
|
|
739
924
|
* @param {Number} [options.extra_rows] Add more rows in addition to
|
740
925
|
* those that have been calculated.
|
741
926
|
* @param {Number} [options.min_cols] The minimum required columns.
|
927
|
+
* @param {Number} [options.max_cols] The maximum columns possible (set to null
|
928
|
+
* for no maximum).
|
742
929
|
* @param {Number} [options.min_rows] The minimum required rows.
|
743
930
|
* @param {Number} [options.max_size_x] The maximum number of columns
|
744
931
|
* that a widget can span.
|
745
|
-
* @param {Number} [options.max_size_y] The maximum number of rows
|
746
|
-
* that a widget can span.
|
747
932
|
* @param {Boolean} [options.autogenerate_stylesheet] If true, all the
|
748
933
|
* CSS required to position all widgets in their respective columns
|
749
934
|
* and rows will be generated automatically and injected to the
|
@@ -753,6 +938,8 @@
|
|
753
938
|
* @param {Boolean} [options.avoid_overlapped_widgets] Avoid that widgets loaded
|
754
939
|
* from the DOM can be overlapped. It is helpful if the positions were
|
755
940
|
* bad stored in the database or if there was any conflict.
|
941
|
+
* @param {Boolean} [options.auto_init] Automatically call gridster init
|
942
|
+
* method or not when the plugin is instantiated.
|
756
943
|
* @param {Function} [options.serialize_params] Return the data you want
|
757
944
|
* for each widget in the serialization. Two arguments are passed:
|
758
945
|
* `$w`: the jQuery wrapped HTMLElement, and `wgd`: the grid
|
@@ -763,37 +950,158 @@
|
|
763
950
|
* @param {Object} [options.draggable] An Object with all options for
|
764
951
|
* Draggable class you want to overwrite. See Draggable docs for more
|
765
952
|
* info.
|
953
|
+
* @param {Object|Function} [options.draggable.ignore_dragging] Note that
|
954
|
+
* if you use a Function, and resize is enabled, you should ignore the
|
955
|
+
* resize handlers manually (options.resize.handle_class).
|
956
|
+
* @param {Object} [options.resize] An Object with resize config options.
|
957
|
+
* @param {Boolean} [options.resize.enabled] Set to true to enable
|
958
|
+
* resizing.
|
959
|
+
* @param {Array} [options.resize.axes] Axes in which widgets can be
|
960
|
+
* resized. Possible values: ['x', 'y', 'both'].
|
961
|
+
* @param {String} [options.resize.handle_append_to] Set a valid CSS
|
962
|
+
* selector to append resize handles to.
|
963
|
+
* @param {String} [options.resize.handle_class] CSS class name used
|
964
|
+
* by resize handles.
|
965
|
+
* @param {Array} [options.resize.max_size] Limit widget dimensions
|
966
|
+
* when resizing. Array values should be integers:
|
967
|
+
* `[max_cols_occupied, max_rows_occupied]`
|
968
|
+
* @param {Array} [options.resize.min_size] Limit widget dimensions
|
969
|
+
* when resizing. Array values should be integers:
|
970
|
+
* `[min_cols_occupied, min_rows_occupied]`
|
971
|
+
* @param {Function} [options.resize.start] Function executed
|
972
|
+
* when resizing starts.
|
973
|
+
* @param {Function} [otions.resize.resize] Function executed
|
974
|
+
* during the resizing.
|
975
|
+
* @param {Function} [options.resize.stop] Function executed
|
976
|
+
* when resizing stops.
|
766
977
|
*
|
767
978
|
* @constructor
|
768
979
|
*/
|
769
980
|
function Gridster(el, options) {
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
this.options.
|
779
|
-
|
780
|
-
this.options.
|
781
|
-
|
981
|
+
this.options = $.extend(true, {}, defaults, options);
|
982
|
+
this.$el = $(el);
|
983
|
+
this.$wrapper = this.$el.parent();
|
984
|
+
this.$widgets = this.$el.children(
|
985
|
+
this.options.widget_selector).addClass('gs-w');
|
986
|
+
this.widgets = [];
|
987
|
+
this.$changed = $([]);
|
988
|
+
this.wrapper_width = this.$wrapper.width();
|
989
|
+
this.min_widget_width = (this.options.widget_margins[0] * 2) +
|
990
|
+
this.options.widget_base_dimensions[0];
|
991
|
+
this.min_widget_height = (this.options.widget_margins[1] * 2) +
|
992
|
+
this.options.widget_base_dimensions[1];
|
993
|
+
|
994
|
+
this.generated_stylesheets = [];
|
995
|
+
this.$style_tags = $([]);
|
996
|
+
|
997
|
+
this.options.auto_init && this.init();
|
782
998
|
}
|
783
999
|
|
1000
|
+
Gridster.defaults = defaults;
|
784
1001
|
Gridster.generated_stylesheets = [];
|
785
1002
|
|
1003
|
+
|
1004
|
+
/**
|
1005
|
+
* Sorts an Array of grid coords objects (representing the grid coords of
|
1006
|
+
* each widget) in ascending way.
|
1007
|
+
*
|
1008
|
+
* @method sort_by_row_asc
|
1009
|
+
* @param {Array} widgets Array of grid coords objects
|
1010
|
+
* @return {Array} Returns the array sorted.
|
1011
|
+
*/
|
1012
|
+
Gridster.sort_by_row_asc = function(widgets) {
|
1013
|
+
widgets = widgets.sort(function(a, b) {
|
1014
|
+
if (!a.row) {
|
1015
|
+
a = $(a).coords().grid;
|
1016
|
+
b = $(b).coords().grid;
|
1017
|
+
}
|
1018
|
+
|
1019
|
+
if (a.row > b.row) {
|
1020
|
+
return 1;
|
1021
|
+
}
|
1022
|
+
return -1;
|
1023
|
+
});
|
1024
|
+
|
1025
|
+
return widgets;
|
1026
|
+
};
|
1027
|
+
|
1028
|
+
|
1029
|
+
/**
|
1030
|
+
* Sorts an Array of grid coords objects (representing the grid coords of
|
1031
|
+
* each widget) placing first the empty cells upper left.
|
1032
|
+
*
|
1033
|
+
* @method sort_by_row_and_col_asc
|
1034
|
+
* @param {Array} widgets Array of grid coords objects
|
1035
|
+
* @return {Array} Returns the array sorted.
|
1036
|
+
*/
|
1037
|
+
Gridster.sort_by_row_and_col_asc = function(widgets) {
|
1038
|
+
widgets = widgets.sort(function(a, b) {
|
1039
|
+
if (a.row > b.row || a.row === b.row && a.col > b.col) {
|
1040
|
+
return 1;
|
1041
|
+
}
|
1042
|
+
return -1;
|
1043
|
+
});
|
1044
|
+
|
1045
|
+
return widgets;
|
1046
|
+
};
|
1047
|
+
|
1048
|
+
|
1049
|
+
/**
|
1050
|
+
* Sorts an Array of grid coords objects by column (representing the grid
|
1051
|
+
* coords of each widget) in ascending way.
|
1052
|
+
*
|
1053
|
+
* @method sort_by_col_asc
|
1054
|
+
* @param {Array} widgets Array of grid coords objects
|
1055
|
+
* @return {Array} Returns the array sorted.
|
1056
|
+
*/
|
1057
|
+
Gridster.sort_by_col_asc = function(widgets) {
|
1058
|
+
widgets = widgets.sort(function(a, b) {
|
1059
|
+
if (a.col > b.col) {
|
1060
|
+
return 1;
|
1061
|
+
}
|
1062
|
+
return -1;
|
1063
|
+
});
|
1064
|
+
|
1065
|
+
return widgets;
|
1066
|
+
};
|
1067
|
+
|
1068
|
+
|
1069
|
+
/**
|
1070
|
+
* Sorts an Array of grid coords objects (representing the grid coords of
|
1071
|
+
* each widget) in descending way.
|
1072
|
+
*
|
1073
|
+
* @method sort_by_row_desc
|
1074
|
+
* @param {Array} widgets Array of grid coords objects
|
1075
|
+
* @return {Array} Returns the array sorted.
|
1076
|
+
*/
|
1077
|
+
Gridster.sort_by_row_desc = function(widgets) {
|
1078
|
+
widgets = widgets.sort(function(a, b) {
|
1079
|
+
if (a.row + a.size_y < b.row + b.size_y) {
|
1080
|
+
return 1;
|
1081
|
+
}
|
1082
|
+
return -1;
|
1083
|
+
});
|
1084
|
+
return widgets;
|
1085
|
+
};
|
1086
|
+
|
1087
|
+
|
1088
|
+
|
1089
|
+
/** Instance Methods **/
|
1090
|
+
|
786
1091
|
var fn = Gridster.prototype;
|
787
1092
|
|
788
1093
|
fn.init = function() {
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
1094
|
+
this.options.resize.enabled && this.setup_resize();
|
1095
|
+
this.generate_grid_and_stylesheet();
|
1096
|
+
this.get_widgets_from_DOM();
|
1097
|
+
this.set_dom_grid_height();
|
1098
|
+
this.set_dom_grid_width();
|
1099
|
+
this.$wrapper.addClass('ready');
|
1100
|
+
this.draggable();
|
1101
|
+
this.options.resize.enabled && this.resizable();
|
794
1102
|
|
795
|
-
|
796
|
-
|
1103
|
+
$(window).bind('resize.gridster', throttle(
|
1104
|
+
$.proxy(this.recalculate_faux_grid, this), 200));
|
797
1105
|
};
|
798
1106
|
|
799
1107
|
|
@@ -822,54 +1130,410 @@
|
|
822
1130
|
};
|
823
1131
|
|
824
1132
|
|
1133
|
+
|
1134
|
+
/**
|
1135
|
+
* Disables drag-and-drop widget resizing.
|
1136
|
+
*
|
1137
|
+
* @method disable
|
1138
|
+
* @return {Class} Returns instance of gridster Class.
|
1139
|
+
*/
|
1140
|
+
fn.disable_resize = function() {
|
1141
|
+
this.$el.addClass('gs-resize-disabled');
|
1142
|
+
this.resize_api.disable();
|
1143
|
+
return this;
|
1144
|
+
};
|
1145
|
+
|
1146
|
+
|
1147
|
+
/**
|
1148
|
+
* Enables drag-and-drop widget resizing.
|
1149
|
+
*
|
1150
|
+
* @method enable
|
1151
|
+
* @return {Class} Returns instance of gridster Class.
|
1152
|
+
*/
|
1153
|
+
fn.enable_resize = function() {
|
1154
|
+
this.$el.removeClass('gs-resize-disabled');
|
1155
|
+
this.resize_api.enable();
|
1156
|
+
return this;
|
1157
|
+
};
|
1158
|
+
|
1159
|
+
|
825
1160
|
/**
|
826
1161
|
* Add a new widget to the grid.
|
827
1162
|
*
|
828
1163
|
* @method add_widget
|
829
|
-
* @param {String} html The string representing the HTML of the widget
|
830
|
-
*
|
831
|
-
* @param {Number}
|
1164
|
+
* @param {String|HTMLElement} html The string representing the HTML of the widget
|
1165
|
+
* or the HTMLElement.
|
1166
|
+
* @param {Number} [size_x] The nº of rows the widget occupies horizontally.
|
1167
|
+
* @param {Number} [size_y] The nº of columns the widget occupies vertically.
|
1168
|
+
* @param {Number} [col] The column the widget should start in.
|
1169
|
+
* @param {Number} [row] The row the widget should start in.
|
1170
|
+
* @param {Array} [max_size] max_size Maximun size (in units) for width and height.
|
1171
|
+
* @param {Array} [min_size] min_size Minimum size (in units) for width and height.
|
832
1172
|
* @return {HTMLElement} Returns the jQuery wrapped HTMLElement representing.
|
833
1173
|
* the widget that was just created.
|
834
1174
|
*/
|
835
|
-
fn.add_widget = function(html, size_x, size_y) {
|
836
|
-
var
|
1175
|
+
fn.add_widget = function(html, size_x, size_y, col, row, max_size, min_size) {
|
1176
|
+
var pos;
|
1177
|
+
size_x || (size_x = 1);
|
1178
|
+
size_y || (size_y = 1);
|
1179
|
+
|
1180
|
+
if (!col & !row) {
|
1181
|
+
pos = this.next_position(size_x, size_y);
|
1182
|
+
} else {
|
1183
|
+
pos = {
|
1184
|
+
col: col,
|
1185
|
+
row: row,
|
1186
|
+
size_x: size_x,
|
1187
|
+
size_y: size_y
|
1188
|
+
};
|
1189
|
+
|
1190
|
+
this.empty_cells(col, row, size_x, size_y);
|
1191
|
+
}
|
837
1192
|
|
838
1193
|
var $w = $(html).attr({
|
839
|
-
'data-col':
|
840
|
-
'data-row':
|
841
|
-
'data-sizex' :
|
842
|
-
'data-sizey' :
|
843
|
-
}).addClass('
|
1194
|
+
'data-col': pos.col,
|
1195
|
+
'data-row': pos.row,
|
1196
|
+
'data-sizex' : size_x,
|
1197
|
+
'data-sizey' : size_y
|
1198
|
+
}).addClass('gs-w').appendTo(this.$el).hide();
|
844
1199
|
|
845
1200
|
this.$widgets = this.$widgets.add($w);
|
846
1201
|
|
847
1202
|
this.register_widget($w);
|
848
1203
|
|
1204
|
+
this.add_faux_rows(pos.size_y);
|
1205
|
+
//this.add_faux_cols(pos.size_x);
|
1206
|
+
|
1207
|
+
if (max_size) {
|
1208
|
+
this.set_widget_max_size($w, max_size);
|
1209
|
+
}
|
1210
|
+
|
1211
|
+
if (min_size) {
|
1212
|
+
this.set_widget_min_size($w, min_size);
|
1213
|
+
}
|
1214
|
+
|
1215
|
+
this.set_dom_grid_width();
|
849
1216
|
this.set_dom_grid_height();
|
850
1217
|
|
1218
|
+
this.drag_api.set_limits(this.cols * this.min_widget_width);
|
1219
|
+
|
851
1220
|
return $w.fadeIn();
|
852
1221
|
};
|
853
1222
|
|
854
1223
|
|
855
1224
|
/**
|
856
|
-
*
|
1225
|
+
* Change widget size limits.
|
857
1226
|
*
|
858
|
-
* @method
|
859
|
-
* @param {Number}
|
860
|
-
*
|
861
|
-
* @
|
862
|
-
*
|
1227
|
+
* @method set_widget_min_size
|
1228
|
+
* @param {HTMLElement|Number} $widget The jQuery wrapped HTMLElement
|
1229
|
+
* representing the widget or an index representing the desired widget.
|
1230
|
+
* @param {Array} min_size Minimum size (in units) for width and height.
|
1231
|
+
* @return {HTMLElement} Returns instance of gridster Class.
|
863
1232
|
*/
|
864
|
-
fn.
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
1233
|
+
fn.set_widget_min_size = function($widget, min_size) {
|
1234
|
+
$widget = typeof $widget === 'number' ?
|
1235
|
+
this.$widgets.eq($widget) : $widget;
|
1236
|
+
|
1237
|
+
if (!$widget.length) { return this; }
|
1238
|
+
|
1239
|
+
var wgd = $widget.data('coords').grid;
|
1240
|
+
wgd.min_size_x = min_size[0];
|
1241
|
+
wgd.min_size_y = min_size[1];
|
1242
|
+
|
1243
|
+
return this;
|
1244
|
+
};
|
1245
|
+
|
1246
|
+
|
1247
|
+
/**
|
1248
|
+
* Change widget size limits.
|
1249
|
+
*
|
1250
|
+
* @method set_widget_max_size
|
1251
|
+
* @param {HTMLElement|Number} $widget The jQuery wrapped HTMLElement
|
1252
|
+
* representing the widget or an index representing the desired widget.
|
1253
|
+
* @param {Array} max_size Maximun size (in units) for width and height.
|
1254
|
+
* @return {HTMLElement} Returns instance of gridster Class.
|
1255
|
+
*/
|
1256
|
+
fn.set_widget_max_size = function($widget, max_size) {
|
1257
|
+
$widget = typeof $widget === 'number' ?
|
1258
|
+
this.$widgets.eq($widget) : $widget;
|
1259
|
+
|
1260
|
+
if (!$widget.length) { return this; }
|
1261
|
+
|
1262
|
+
var wgd = $widget.data('coords').grid;
|
1263
|
+
wgd.max_size_x = max_size[0];
|
1264
|
+
wgd.max_size_y = max_size[1];
|
1265
|
+
|
1266
|
+
return this;
|
1267
|
+
};
|
1268
|
+
|
1269
|
+
|
1270
|
+
/**
|
1271
|
+
* Append the resize handle into a widget.
|
1272
|
+
*
|
1273
|
+
* @method add_resize_handle
|
1274
|
+
* @param {HTMLElement} $widget The jQuery wrapped HTMLElement
|
1275
|
+
* representing the widget.
|
1276
|
+
* @return {HTMLElement} Returns instance of gridster Class.
|
1277
|
+
*/
|
1278
|
+
fn.add_resize_handle = function($w) {
|
1279
|
+
var append_to = this.options.resize.handle_append_to;
|
1280
|
+
$(this.resize_handle_tpl).appendTo( append_to ? $(append_to, $w) : $w);
|
1281
|
+
|
1282
|
+
return this;
|
1283
|
+
};
|
1284
|
+
|
1285
|
+
|
1286
|
+
/**
|
1287
|
+
* Change the size of a widget. Width is limited to the current grid width.
|
1288
|
+
*
|
1289
|
+
* @method resize_widget
|
1290
|
+
* @param {HTMLElement} $widget The jQuery wrapped HTMLElement
|
1291
|
+
* representing the widget.
|
1292
|
+
* @param {Number} size_x The number of columns that will occupy the widget.
|
1293
|
+
* By default <code>size_x</code> is limited to the space available from
|
1294
|
+
* the column where the widget begins, until the last column to the right.
|
1295
|
+
* @param {Number} size_y The number of rows that will occupy the widget.
|
1296
|
+
* @param {Function} [callback] Function executed when the widget is removed.
|
1297
|
+
* @return {HTMLElement} Returns $widget.
|
1298
|
+
*/
|
1299
|
+
fn.resize_widget = function($widget, size_x, size_y, callback) {
|
1300
|
+
var wgd = $widget.coords().grid;
|
1301
|
+
var col = wgd.col;
|
1302
|
+
var max_cols = this.options.max_cols;
|
1303
|
+
var old_size_y = wgd.size_y;
|
1304
|
+
var old_col = wgd.col;
|
1305
|
+
var new_col = old_col;
|
1306
|
+
|
1307
|
+
size_x || (size_x = wgd.size_x);
|
1308
|
+
size_y || (size_y = wgd.size_y);
|
1309
|
+
|
1310
|
+
if (max_cols !== Infinity) {
|
1311
|
+
size_x = Math.min(size_x, max_cols - col + 1);
|
1312
|
+
}
|
1313
|
+
|
1314
|
+
if (size_y > old_size_y) {
|
1315
|
+
this.add_faux_rows(Math.max(size_y - old_size_y, 0));
|
1316
|
+
}
|
1317
|
+
|
1318
|
+
var player_rcol = (col + size_x - 1);
|
1319
|
+
if (player_rcol > this.cols) {
|
1320
|
+
this.add_faux_cols(player_rcol - this.cols);
|
1321
|
+
}
|
1322
|
+
|
1323
|
+
var new_grid_data = {
|
1324
|
+
col: new_col,
|
1325
|
+
row: wgd.row,
|
1326
|
+
size_x: size_x,
|
1327
|
+
size_y: size_y
|
1328
|
+
};
|
1329
|
+
|
1330
|
+
this.mutate_widget_in_gridmap($widget, wgd, new_grid_data);
|
1331
|
+
|
1332
|
+
this.set_dom_grid_height();
|
1333
|
+
this.set_dom_grid_width();
|
1334
|
+
|
1335
|
+
if (callback) {
|
1336
|
+
callback.call(this, new_grid_data.size_x, new_grid_data.size_y);
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
return $widget;
|
1340
|
+
};
|
1341
|
+
|
1342
|
+
|
1343
|
+
/**
|
1344
|
+
* Mutate widget dimensions and position in the grid map.
|
1345
|
+
*
|
1346
|
+
* @method mutate_widget_in_gridmap
|
1347
|
+
* @param {HTMLElement} $widget The jQuery wrapped HTMLElement
|
1348
|
+
* representing the widget to mutate.
|
1349
|
+
* @param {Object} wgd Current widget grid data (col, row, size_x, size_y).
|
1350
|
+
* @param {Object} new_wgd New widget grid data.
|
1351
|
+
* @return {HTMLElement} Returns instance of gridster Class.
|
1352
|
+
*/
|
1353
|
+
fn.mutate_widget_in_gridmap = function($widget, wgd, new_wgd) {
|
1354
|
+
var old_size_x = wgd.size_x;
|
1355
|
+
var old_size_y = wgd.size_y;
|
1356
|
+
|
1357
|
+
var old_cells_occupied = this.get_cells_occupied(wgd);
|
1358
|
+
var new_cells_occupied = this.get_cells_occupied(new_wgd);
|
1359
|
+
|
1360
|
+
var empty_cols = [];
|
1361
|
+
$.each(old_cells_occupied.cols, function(i, col) {
|
1362
|
+
if ($.inArray(col, new_cells_occupied.cols) === -1) {
|
1363
|
+
empty_cols.push(col);
|
1364
|
+
}
|
1365
|
+
});
|
1366
|
+
|
1367
|
+
var occupied_cols = [];
|
1368
|
+
$.each(new_cells_occupied.cols, function(i, col) {
|
1369
|
+
if ($.inArray(col, old_cells_occupied.cols) === -1) {
|
1370
|
+
occupied_cols.push(col);
|
1371
|
+
}
|
1372
|
+
});
|
1373
|
+
|
1374
|
+
var empty_rows = [];
|
1375
|
+
$.each(old_cells_occupied.rows, function(i, row) {
|
1376
|
+
if ($.inArray(row, new_cells_occupied.rows) === -1) {
|
1377
|
+
empty_rows.push(row);
|
1378
|
+
}
|
1379
|
+
});
|
1380
|
+
|
1381
|
+
var occupied_rows = [];
|
1382
|
+
$.each(new_cells_occupied.rows, function(i, row) {
|
1383
|
+
if ($.inArray(row, old_cells_occupied.rows) === -1) {
|
1384
|
+
occupied_rows.push(row);
|
1385
|
+
}
|
1386
|
+
});
|
1387
|
+
|
1388
|
+
this.remove_from_gridmap(wgd);
|
1389
|
+
|
1390
|
+
if (occupied_cols.length) {
|
1391
|
+
var cols_to_empty = [
|
1392
|
+
new_wgd.col, new_wgd.row, new_wgd.size_x, Math.min(old_size_y, new_wgd.size_y), $widget
|
1393
|
+
];
|
1394
|
+
this.empty_cells.apply(this, cols_to_empty);
|
1395
|
+
}
|
1396
|
+
|
1397
|
+
if (occupied_rows.length) {
|
1398
|
+
var rows_to_empty = [new_wgd.col, new_wgd.row, new_wgd.size_x, new_wgd.size_y, $widget];
|
1399
|
+
this.empty_cells.apply(this, rows_to_empty);
|
1400
|
+
}
|
1401
|
+
|
1402
|
+
// not the same that wgd = new_wgd;
|
1403
|
+
wgd.col = new_wgd.col;
|
1404
|
+
wgd.row = new_wgd.row;
|
1405
|
+
wgd.size_x = new_wgd.size_x;
|
1406
|
+
wgd.size_y = new_wgd.size_y;
|
1407
|
+
|
1408
|
+
this.add_to_gridmap(new_wgd, $widget);
|
1409
|
+
|
1410
|
+
$widget.removeClass('player-revert');
|
1411
|
+
|
1412
|
+
//update coords instance attributes
|
1413
|
+
$widget.data('coords').update({
|
1414
|
+
width: (new_wgd.size_x * this.options.widget_base_dimensions[0] +
|
1415
|
+
((new_wgd.size_x - 1) * this.options.widget_margins[0]) * 2),
|
1416
|
+
height: (new_wgd.size_y * this.options.widget_base_dimensions[1] +
|
1417
|
+
((new_wgd.size_y - 1) * this.options.widget_margins[1]) * 2)
|
1418
|
+
});
|
1419
|
+
|
1420
|
+
$widget.attr({
|
1421
|
+
'data-col': new_wgd.col,
|
1422
|
+
'data-row': new_wgd.row,
|
1423
|
+
'data-sizex': new_wgd.size_x,
|
1424
|
+
'data-sizey': new_wgd.size_y
|
1425
|
+
});
|
1426
|
+
|
1427
|
+
if (empty_cols.length) {
|
1428
|
+
var cols_to_remove_holes = [
|
1429
|
+
empty_cols[0], new_wgd.row,
|
1430
|
+
empty_cols.length,
|
1431
|
+
Math.min(old_size_y, new_wgd.size_y),
|
1432
|
+
$widget
|
1433
|
+
];
|
1434
|
+
|
1435
|
+
this.remove_empty_cells.apply(this, cols_to_remove_holes);
|
1436
|
+
}
|
1437
|
+
|
1438
|
+
if (empty_rows.length) {
|
1439
|
+
var rows_to_remove_holes = [
|
1440
|
+
new_wgd.col, new_wgd.row, new_wgd.size_x, new_wgd.size_y, $widget
|
1441
|
+
];
|
1442
|
+
this.remove_empty_cells.apply(this, rows_to_remove_holes);
|
1443
|
+
}
|
1444
|
+
|
1445
|
+
this.move_widget_up($widget);
|
1446
|
+
|
1447
|
+
return this;
|
1448
|
+
};
|
1449
|
+
|
1450
|
+
|
1451
|
+
/**
|
1452
|
+
* Move down widgets in cells represented by the arguments col, row, size_x,
|
1453
|
+
* size_y
|
1454
|
+
*
|
1455
|
+
* @method empty_cells
|
1456
|
+
* @param {Number} col The column where the group of cells begin.
|
1457
|
+
* @param {Number} row The row where the group of cells begin.
|
1458
|
+
* @param {Number} size_x The number of columns that the group of cells
|
1459
|
+
* occupy.
|
1460
|
+
* @param {Number} size_y The number of rows that the group of cells
|
1461
|
+
* occupy.
|
1462
|
+
* @param {HTMLElement} $exclude Exclude widgets from being moved.
|
1463
|
+
* @return {Class} Returns the instance of the Gridster Class.
|
1464
|
+
*/
|
1465
|
+
fn.empty_cells = function(col, row, size_x, size_y, $exclude) {
|
1466
|
+
var $nexts = this.widgets_below({
|
1467
|
+
col: col,
|
1468
|
+
row: row - size_y,
|
1469
|
+
size_x: size_x,
|
1470
|
+
size_y: size_y
|
1471
|
+
});
|
1472
|
+
|
1473
|
+
$nexts.not($exclude).each($.proxy(function(i, w) {
|
1474
|
+
var wgd = $(w).coords().grid;
|
1475
|
+
if ( !(wgd.row <= (row + size_y - 1))) { return; }
|
1476
|
+
var diff = (row + size_y) - wgd.row;
|
1477
|
+
this.move_widget_down($(w), diff);
|
1478
|
+
}, this));
|
1479
|
+
|
1480
|
+
this.set_dom_grid_height();
|
1481
|
+
|
1482
|
+
return this;
|
1483
|
+
};
|
1484
|
+
|
1485
|
+
|
1486
|
+
/**
|
1487
|
+
* Move up widgets below cells represented by the arguments col, row, size_x,
|
1488
|
+
* size_y.
|
1489
|
+
*
|
1490
|
+
* @method remove_empty_cells
|
1491
|
+
* @param {Number} col The column where the group of cells begin.
|
1492
|
+
* @param {Number} row The row where the group of cells begin.
|
1493
|
+
* @param {Number} size_x The number of columns that the group of cells
|
1494
|
+
* occupy.
|
1495
|
+
* @param {Number} size_y The number of rows that the group of cells
|
1496
|
+
* occupy.
|
1497
|
+
* @param {HTMLElement} exclude Exclude widgets from being moved.
|
1498
|
+
* @return {Class} Returns the instance of the Gridster Class.
|
1499
|
+
*/
|
1500
|
+
fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) {
|
1501
|
+
var $nexts = this.widgets_below({
|
1502
|
+
col: col,
|
1503
|
+
row: row,
|
1504
|
+
size_x: size_x,
|
1505
|
+
size_y: size_y
|
1506
|
+
});
|
1507
|
+
|
1508
|
+
$nexts.not(exclude).each($.proxy(function(i, widget) {
|
1509
|
+
this.move_widget_up( $(widget), size_y );
|
1510
|
+
}, this));
|
1511
|
+
|
1512
|
+
this.set_dom_grid_height();
|
1513
|
+
|
1514
|
+
return this;
|
1515
|
+
};
|
1516
|
+
|
1517
|
+
|
1518
|
+
/**
|
1519
|
+
* Get the most left column below to add a new widget.
|
1520
|
+
*
|
1521
|
+
* @method next_position
|
1522
|
+
* @param {Number} size_x The nº of rows the widget occupies horizontally.
|
1523
|
+
* @param {Number} size_y The nº of columns the widget occupies vertically.
|
1524
|
+
* @return {Object} Returns a grid coords object representing the future
|
1525
|
+
* widget coords.
|
1526
|
+
*/
|
1527
|
+
fn.next_position = function(size_x, size_y) {
|
1528
|
+
size_x || (size_x = 1);
|
1529
|
+
size_y || (size_y = 1);
|
1530
|
+
var ga = this.gridmap;
|
1531
|
+
var cols_l = ga.length;
|
1532
|
+
var valid_pos = [];
|
1533
|
+
var rows_l;
|
870
1534
|
|
871
1535
|
for (var c = 1; c < cols_l; c++) {
|
872
|
-
|
1536
|
+
rows_l = ga[c].length;
|
873
1537
|
for (var r = 1; r <= rows_l; r++) {
|
874
1538
|
var can_move_to = this.can_move_to({
|
875
1539
|
size_x: size_x,
|
@@ -888,7 +1552,7 @@
|
|
888
1552
|
}
|
889
1553
|
|
890
1554
|
if (valid_pos.length) {
|
891
|
-
return
|
1555
|
+
return Gridster.sort_by_row_and_col_asc(valid_pos)[0];
|
892
1556
|
}
|
893
1557
|
return false;
|
894
1558
|
};
|
@@ -899,12 +1563,21 @@
|
|
899
1563
|
*
|
900
1564
|
* @method remove_widget
|
901
1565
|
* @param {HTMLElement} el The jQuery wrapped HTMLElement you want to remove.
|
1566
|
+
* @param {Boolean|Function} silent If true, widgets below the removed one
|
1567
|
+
* will not move up. If a Function is passed it will be used as callback.
|
1568
|
+
* @param {Function} callback Function executed when the widget is removed.
|
902
1569
|
* @return {Class} Returns the instance of the Gridster Class.
|
903
1570
|
*/
|
904
|
-
fn.remove_widget = function(el, callback) {
|
905
|
-
var $el = el instanceof
|
1571
|
+
fn.remove_widget = function(el, silent, callback) {
|
1572
|
+
var $el = el instanceof $ ? el : $(el);
|
906
1573
|
var wgd = $el.coords().grid;
|
907
1574
|
|
1575
|
+
// if silent is a function assume it's a callback
|
1576
|
+
if ($.isFunction(silent)) {
|
1577
|
+
callback = silent;
|
1578
|
+
silent = false;
|
1579
|
+
}
|
1580
|
+
|
908
1581
|
this.cells_occupied_by_placeholder = {};
|
909
1582
|
this.$widgets = this.$widgets.not($el);
|
910
1583
|
|
@@ -915,9 +1588,11 @@
|
|
915
1588
|
$el.fadeOut($.proxy(function() {
|
916
1589
|
$el.remove();
|
917
1590
|
|
918
|
-
|
919
|
-
|
920
|
-
|
1591
|
+
if (!silent) {
|
1592
|
+
$nexts.each($.proxy(function(i, widget) {
|
1593
|
+
this.move_widget_up( $(widget), wgd.size_y );
|
1594
|
+
}, this));
|
1595
|
+
}
|
921
1596
|
|
922
1597
|
this.set_dom_grid_height();
|
923
1598
|
|
@@ -925,6 +1600,24 @@
|
|
925
1600
|
callback.call(this, el);
|
926
1601
|
}
|
927
1602
|
}, this));
|
1603
|
+
|
1604
|
+
return this;
|
1605
|
+
};
|
1606
|
+
|
1607
|
+
|
1608
|
+
/**
|
1609
|
+
* Remove all widgets from the grid.
|
1610
|
+
*
|
1611
|
+
* @method remove_all_widgets
|
1612
|
+
* @param {Function} callback Function executed for each widget removed.
|
1613
|
+
* @return {Class} Returns the instance of the Gridster Class.
|
1614
|
+
*/
|
1615
|
+
fn.remove_all_widgets = function(callback) {
|
1616
|
+
this.$widgets.each($.proxy(function(i, el){
|
1617
|
+
this.remove_widget(el, true, callback);
|
1618
|
+
}, this));
|
1619
|
+
|
1620
|
+
return this;
|
928
1621
|
};
|
929
1622
|
|
930
1623
|
|
@@ -940,13 +1633,11 @@
|
|
940
1633
|
*/
|
941
1634
|
fn.serialize = function($widgets) {
|
942
1635
|
$widgets || ($widgets = this.$widgets);
|
943
|
-
var result = [];
|
944
|
-
$widgets.each($.proxy(function(i, widget) {
|
945
|
-
result.push(this.options.serialize_params(
|
946
|
-
$(widget), $(widget).coords().grid ) );
|
947
|
-
}, this));
|
948
1636
|
|
949
|
-
return
|
1637
|
+
return $widgets.map($.proxy(function(i, widget) {
|
1638
|
+
var $w = $(widget);
|
1639
|
+
return this.options.serialize_params($w, $w.coords().grid);
|
1640
|
+
}, this)).get();
|
950
1641
|
};
|
951
1642
|
|
952
1643
|
|
@@ -964,45 +1655,74 @@
|
|
964
1655
|
|
965
1656
|
|
966
1657
|
/**
|
967
|
-
*
|
1658
|
+
* Convert widgets from DOM elements to "widget grid data" Objects.
|
1659
|
+
*
|
1660
|
+
* @method dom_to_coords
|
1661
|
+
* @param {HTMLElement} $widget The widget to be converted.
|
1662
|
+
*/
|
1663
|
+
fn.dom_to_coords = function($widget) {
|
1664
|
+
return {
|
1665
|
+
'col': parseInt($widget.attr('data-col'), 10),
|
1666
|
+
'row': parseInt($widget.attr('data-row'), 10),
|
1667
|
+
'size_x': parseInt($widget.attr('data-sizex'), 10) || 1,
|
1668
|
+
'size_y': parseInt($widget.attr('data-sizey'), 10) || 1,
|
1669
|
+
'max_size_x': parseInt($widget.attr('data-max-sizex'), 10) || false,
|
1670
|
+
'max_size_y': parseInt($widget.attr('data-max-sizey'), 10) || false,
|
1671
|
+
'min_size_x': parseInt($widget.attr('data-min-sizex'), 10) || false,
|
1672
|
+
'min_size_y': parseInt($widget.attr('data-min-sizey'), 10) || false,
|
1673
|
+
'el': $widget
|
1674
|
+
};
|
1675
|
+
};
|
1676
|
+
|
1677
|
+
|
1678
|
+
/**
|
1679
|
+
* Creates the grid coords object representing the widget an add it to the
|
968
1680
|
* mapped array of positions.
|
969
1681
|
*
|
970
1682
|
* @method register_widget
|
971
|
-
* @
|
1683
|
+
* @param {HTMLElement|Object} $el jQuery wrapped HTMLElement representing
|
1684
|
+
* the widget, or an "widget grid data" Object with (col, row, el ...).
|
1685
|
+
* @return {Boolean} Returns true if the widget final position is different
|
1686
|
+
* than the original.
|
972
1687
|
*/
|
973
1688
|
fn.register_widget = function($el) {
|
1689
|
+
var isDOM = $el instanceof jQuery;
|
1690
|
+
var wgd = isDOM ? this.dom_to_coords($el) : $el;
|
1691
|
+
var posChanged = false;
|
1692
|
+
isDOM || ($el = wgd.el);
|
974
1693
|
|
975
|
-
var
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
}
|
1694
|
+
var empty_upper_row = this.can_go_widget_up(wgd);
|
1695
|
+
if (empty_upper_row) {
|
1696
|
+
wgd.row = empty_upper_row;
|
1697
|
+
$el.attr('data-row', empty_upper_row);
|
1698
|
+
this.$el.trigger('gridster:positionchanged', [wgd]);
|
1699
|
+
posChanged = true;
|
1700
|
+
}
|
982
1701
|
|
983
1702
|
if (this.options.avoid_overlapped_widgets &&
|
984
1703
|
!this.can_move_to(
|
985
1704
|
{size_x: wgd.size_x, size_y: wgd.size_y}, wgd.col, wgd.row)
|
986
1705
|
) {
|
987
|
-
wgd
|
988
|
-
wgd.el = $el;
|
1706
|
+
$.extend(wgd, this.next_position(wgd.size_x, wgd.size_y));
|
989
1707
|
$el.attr({
|
990
1708
|
'data-col': wgd.col,
|
991
1709
|
'data-row': wgd.row,
|
992
1710
|
'data-sizex': wgd.size_x,
|
993
1711
|
'data-sizey': wgd.size_y
|
994
1712
|
});
|
1713
|
+
posChanged = true;
|
995
1714
|
}
|
996
1715
|
|
997
1716
|
// attach Coord object to player data-coord attribute
|
998
1717
|
$el.data('coords', $el.coords());
|
999
|
-
|
1000
1718
|
// Extend Coord object with grid position info
|
1001
1719
|
$el.data('coords').grid = wgd;
|
1002
1720
|
|
1003
1721
|
this.add_to_gridmap(wgd, $el);
|
1004
|
-
|
1005
|
-
|
1722
|
+
|
1723
|
+
this.options.resize.enabled && this.add_resize_handle($el);
|
1724
|
+
|
1725
|
+
return posChanged;
|
1006
1726
|
};
|
1007
1727
|
|
1008
1728
|
|
@@ -1073,14 +1793,16 @@
|
|
1073
1793
|
var self = this;
|
1074
1794
|
var draggable_options = $.extend(true, {}, this.options.draggable, {
|
1075
1795
|
offset_left: this.options.widget_margins[0],
|
1076
|
-
|
1796
|
+
offset_top: this.options.widget_margins[1],
|
1797
|
+
container_width: this.cols * this.min_widget_width,
|
1798
|
+
limit: true,
|
1077
1799
|
start: function(event, ui) {
|
1078
1800
|
self.$widgets.filter('.player-revert')
|
1079
1801
|
.removeClass('player-revert');
|
1080
1802
|
|
1081
1803
|
self.$player = $(this);
|
1082
|
-
self.$helper =
|
1083
|
-
|
1804
|
+
self.$helper = $(ui.$helper);
|
1805
|
+
|
1084
1806
|
self.helper = !self.$helper.is(self.$player);
|
1085
1807
|
|
1086
1808
|
self.on_start_drag.call(self, event, ui);
|
@@ -1096,7 +1818,59 @@
|
|
1096
1818
|
}, 60)
|
1097
1819
|
});
|
1098
1820
|
|
1099
|
-
this.drag_api = this.$el.drag(draggable_options)
|
1821
|
+
this.drag_api = this.$el.drag(draggable_options);
|
1822
|
+
return this;
|
1823
|
+
};
|
1824
|
+
|
1825
|
+
|
1826
|
+
/**
|
1827
|
+
* Bind resize events to get resize working.
|
1828
|
+
*
|
1829
|
+
* @method resizable
|
1830
|
+
* @return {Class} Returns instance of gridster Class.
|
1831
|
+
*/
|
1832
|
+
fn.resizable = function() {
|
1833
|
+
this.resize_api = this.$el.drag({
|
1834
|
+
items: '.' + this.options.resize.handle_class,
|
1835
|
+
offset_left: this.options.widget_margins[0],
|
1836
|
+
container_width: this.container_width,
|
1837
|
+
move_element: false,
|
1838
|
+
resize: true,
|
1839
|
+
limit: this.options.autogrow_cols ? false : true,
|
1840
|
+
start: $.proxy(this.on_start_resize, this),
|
1841
|
+
stop: $.proxy(function(event, ui) {
|
1842
|
+
delay($.proxy(function() {
|
1843
|
+
this.on_stop_resize(event, ui);
|
1844
|
+
}, this), 120);
|
1845
|
+
}, this),
|
1846
|
+
drag: throttle($.proxy(this.on_resize, this), 60)
|
1847
|
+
});
|
1848
|
+
|
1849
|
+
return this;
|
1850
|
+
};
|
1851
|
+
|
1852
|
+
|
1853
|
+
/**
|
1854
|
+
* Setup things required for resizing. Like build templates for drag handles.
|
1855
|
+
*
|
1856
|
+
* @method setup_resize
|
1857
|
+
* @return {Class} Returns instance of gridster Class.
|
1858
|
+
*/
|
1859
|
+
fn.setup_resize = function() {
|
1860
|
+
this.resize_handle_class = this.options.resize.handle_class;
|
1861
|
+
var axes = this.options.resize.axes;
|
1862
|
+
var handle_tpl = '<span class="' + this.resize_handle_class + ' ' +
|
1863
|
+
this.resize_handle_class + '-{type}" />';
|
1864
|
+
|
1865
|
+
this.resize_handle_tpl = $.map(axes, function(type) {
|
1866
|
+
return handle_tpl.replace('{type}', type);
|
1867
|
+
}).join('');
|
1868
|
+
|
1869
|
+
if ($.isArray(this.options.draggable.ignore_dragging)) {
|
1870
|
+
this.options.draggable.ignore_dragging.push(
|
1871
|
+
'.' + this.resize_handle_class);
|
1872
|
+
}
|
1873
|
+
|
1100
1874
|
return this;
|
1101
1875
|
};
|
1102
1876
|
|
@@ -1105,20 +1879,29 @@
|
|
1105
1879
|
* This function is executed when the player begins to be dragged.
|
1106
1880
|
*
|
1107
1881
|
* @method on_start_drag
|
1108
|
-
* @param {Event} The original browser event
|
1109
|
-
* @param {Object} A prepared ui object
|
1882
|
+
* @param {Event} event The original browser event
|
1883
|
+
* @param {Object} ui A prepared ui object with useful drag-related data
|
1110
1884
|
*/
|
1111
1885
|
fn.on_start_drag = function(event, ui) {
|
1112
|
-
|
1113
1886
|
this.$helper.add(this.$player).add(this.$wrapper).addClass('dragging');
|
1114
1887
|
|
1888
|
+
this.highest_col = this.get_highest_occupied_cell().col;
|
1889
|
+
|
1115
1890
|
this.$player.addClass('player');
|
1116
1891
|
this.player_grid_data = this.$player.coords().grid;
|
1117
1892
|
this.placeholder_grid_data = $.extend({}, this.player_grid_data);
|
1118
1893
|
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1894
|
+
this.set_dom_grid_height(this.$el.height() +
|
1895
|
+
(this.player_grid_data.size_y * this.min_widget_height));
|
1896
|
+
|
1897
|
+
this.set_dom_grid_width(this.cols);
|
1898
|
+
|
1899
|
+
var pgd_sizex = this.player_grid_data.size_x;
|
1900
|
+
var cols_diff = this.cols - this.highest_col;
|
1901
|
+
|
1902
|
+
if (this.options.autogrow_cols && cols_diff <= pgd_sizex) {
|
1903
|
+
this.add_faux_cols(Math.min(pgd_sizex - cols_diff, 1));
|
1904
|
+
}
|
1122
1905
|
|
1123
1906
|
var colliders = this.faux_grid;
|
1124
1907
|
var coords = this.$player.data('coords').coords;
|
@@ -1131,12 +1914,11 @@
|
|
1131
1914
|
this.last_cols = [];
|
1132
1915
|
this.last_rows = [];
|
1133
1916
|
|
1134
|
-
|
1135
1917
|
// see jquery.collision.js
|
1136
1918
|
this.collision_api = this.$helper.collision(
|
1137
1919
|
colliders, this.options.collision);
|
1138
1920
|
|
1139
|
-
this.$preview_holder = $('<
|
1921
|
+
this.$preview_holder = $('<' + this.$player.get(0).tagName + ' />', {
|
1140
1922
|
'class': 'preview-holder',
|
1141
1923
|
'data-row': this.$player.attr('data-row'),
|
1142
1924
|
'data-col': this.$player.attr('data-col'),
|
@@ -1156,32 +1938,44 @@
|
|
1156
1938
|
* This function is executed when the player is being dragged.
|
1157
1939
|
*
|
1158
1940
|
* @method on_drag
|
1159
|
-
* @param {Event} The original browser event
|
1160
|
-
* @param {Object} A prepared ui object
|
1941
|
+
* @param {Event} event The original browser event
|
1942
|
+
* @param {Object} ui A prepared ui object with useful drag-related data
|
1161
1943
|
*/
|
1162
1944
|
fn.on_drag = function(event, ui) {
|
1163
1945
|
//break if dragstop has been fired
|
1164
1946
|
if (this.$player === null) {
|
1165
1947
|
return false;
|
1166
|
-
}
|
1948
|
+
}
|
1167
1949
|
|
1168
1950
|
var abs_offset = {
|
1169
1951
|
left: ui.position.left + this.baseX,
|
1170
1952
|
top: ui.position.top + this.baseY
|
1171
1953
|
};
|
1172
1954
|
|
1955
|
+
// auto grow cols
|
1956
|
+
if (this.options.autogrow_cols) {
|
1957
|
+
var prcol = this.placeholder_grid_data.col +
|
1958
|
+
this.placeholder_grid_data.size_x - 1;
|
1959
|
+
|
1960
|
+
// "- 1" due to adding at least 1 column in on_start_drag
|
1961
|
+
if (prcol >= this.cols - 1 && this.options.max_cols >= this.cols + 1) {
|
1962
|
+
this.add_faux_cols(1);
|
1963
|
+
this.set_dom_grid_width(this.cols + 1);
|
1964
|
+
this.drag_api.set_limits(this.container_width);
|
1965
|
+
}
|
1966
|
+
|
1967
|
+
this.collision_api.set_colliders(this.faux_grid);
|
1968
|
+
}
|
1969
|
+
|
1173
1970
|
this.colliders_data = this.collision_api.get_closest_colliders(
|
1174
1971
|
abs_offset);
|
1175
1972
|
|
1176
1973
|
this.on_overlapped_column_change(
|
1177
|
-
this.on_start_overlapping_column,
|
1178
|
-
this.on_stop_overlapping_column
|
1179
|
-
);
|
1974
|
+
this.on_start_overlapping_column, this.on_stop_overlapping_column);
|
1180
1975
|
|
1181
1976
|
this.on_overlapped_row_change(
|
1182
|
-
this.on_start_overlapping_row,
|
1183
|
-
|
1184
|
-
);
|
1977
|
+
this.on_start_overlapping_row, this.on_stop_overlapping_row);
|
1978
|
+
|
1185
1979
|
|
1186
1980
|
if (this.helper && this.$player) {
|
1187
1981
|
this.$player.css({
|
@@ -1195,12 +1989,13 @@
|
|
1195
1989
|
}
|
1196
1990
|
};
|
1197
1991
|
|
1992
|
+
|
1198
1993
|
/**
|
1199
1994
|
* This function is executed when the player stops being dragged.
|
1200
1995
|
*
|
1201
1996
|
* @method on_stop_drag
|
1202
|
-
* @param {Event} The original browser event
|
1203
|
-
* @param {Object} A prepared ui object
|
1997
|
+
* @param {Event} event The original browser event
|
1998
|
+
* @param {Object} ui A prepared ui object with useful drag-related data
|
1204
1999
|
*/
|
1205
2000
|
fn.on_stop_drag = function(event, ui) {
|
1206
2001
|
this.$helper.add(this.$player).add(this.$wrapper)
|
@@ -1208,7 +2003,8 @@
|
|
1208
2003
|
|
1209
2004
|
ui.position.left = ui.position.left + this.baseX;
|
1210
2005
|
ui.position.top = ui.position.top + this.baseY;
|
1211
|
-
this.colliders_data = this.collision_api.get_closest_colliders(
|
2006
|
+
this.colliders_data = this.collision_api.get_closest_colliders(
|
2007
|
+
ui.position);
|
1212
2008
|
|
1213
2009
|
this.on_overlapped_column_change(
|
1214
2010
|
this.on_start_overlapping_column,
|
@@ -1229,24 +2025,233 @@
|
|
1229
2025
|
'top': ''
|
1230
2026
|
});
|
1231
2027
|
|
1232
|
-
this.$changed = this.$changed.add(this.$player);
|
2028
|
+
this.$changed = this.$changed.add(this.$player);
|
2029
|
+
|
2030
|
+
this.cells_occupied_by_player = this.get_cells_occupied(
|
2031
|
+
this.placeholder_grid_data);
|
2032
|
+
this.set_cells_player_occupies(
|
2033
|
+
this.placeholder_grid_data.col, this.placeholder_grid_data.row);
|
2034
|
+
|
2035
|
+
this.$player.coords().grid.row = this.placeholder_grid_data.row;
|
2036
|
+
this.$player.coords().grid.col = this.placeholder_grid_data.col;
|
2037
|
+
|
2038
|
+
if (this.options.draggable.stop) {
|
2039
|
+
this.options.draggable.stop.call(this, event, ui);
|
2040
|
+
}
|
2041
|
+
|
2042
|
+
this.$preview_holder.remove();
|
2043
|
+
|
2044
|
+
this.$player = null;
|
2045
|
+
this.$helper = null;
|
2046
|
+
this.placeholder_grid_data = {};
|
2047
|
+
this.player_grid_data = {};
|
2048
|
+
this.cells_occupied_by_placeholder = {};
|
2049
|
+
this.cells_occupied_by_player = {};
|
2050
|
+
|
2051
|
+
this.set_dom_grid_height();
|
2052
|
+
this.set_dom_grid_width();
|
2053
|
+
|
2054
|
+
if (this.options.autogrow_cols) {
|
2055
|
+
this.drag_api.set_limits(this.cols * this.min_widget_width);
|
2056
|
+
}
|
2057
|
+
};
|
2058
|
+
|
2059
|
+
|
2060
|
+
/**
|
2061
|
+
* This function is executed every time a widget starts to be resized.
|
2062
|
+
*
|
2063
|
+
* @method on_start_resize
|
2064
|
+
* @param {Event} event The original browser event
|
2065
|
+
* @param {Object} ui A prepared ui object with useful drag-related data
|
2066
|
+
*/
|
2067
|
+
fn.on_start_resize = function(event, ui) {
|
2068
|
+
this.$resized_widget = ui.$player.closest('.gs-w');
|
2069
|
+
this.resize_coords = this.$resized_widget.coords();
|
2070
|
+
this.resize_wgd = this.resize_coords.grid;
|
2071
|
+
this.resize_initial_width = this.resize_coords.coords.width;
|
2072
|
+
this.resize_initial_height = this.resize_coords.coords.height;
|
2073
|
+
this.resize_initial_sizex = this.resize_coords.grid.size_x;
|
2074
|
+
this.resize_initial_sizey = this.resize_coords.grid.size_y;
|
2075
|
+
this.resize_initial_col = this.resize_coords.grid.col;
|
2076
|
+
this.resize_last_sizex = this.resize_initial_sizex;
|
2077
|
+
this.resize_last_sizey = this.resize_initial_sizey;
|
2078
|
+
|
2079
|
+
this.resize_max_size_x = Math.min(this.resize_wgd.max_size_x ||
|
2080
|
+
this.options.resize.max_size[0],
|
2081
|
+
this.options.max_cols - this.resize_initial_col + 1);
|
2082
|
+
this.resize_max_size_y = this.resize_wgd.max_size_y ||
|
2083
|
+
this.options.resize.max_size[1];
|
2084
|
+
|
2085
|
+
this.resize_min_size_x = (this.resize_wgd.min_size_x ||
|
2086
|
+
this.options.resize.min_size[0] || 1);
|
2087
|
+
this.resize_min_size_y = (this.resize_wgd.min_size_y ||
|
2088
|
+
this.options.resize.min_size[1] || 1);
|
2089
|
+
|
2090
|
+
this.resize_initial_last_col = this.get_highest_occupied_cell().col;
|
2091
|
+
|
2092
|
+
this.set_dom_grid_width(this.cols);
|
2093
|
+
|
2094
|
+
this.resize_dir = {
|
2095
|
+
right: ui.$player.is('.' + this.resize_handle_class + '-x'),
|
2096
|
+
bottom: ui.$player.is('.' + this.resize_handle_class + '-y')
|
2097
|
+
};
|
2098
|
+
|
2099
|
+
this.$resized_widget.css({
|
2100
|
+
'min-width': this.options.widget_base_dimensions[0],
|
2101
|
+
'min-height': this.options.widget_base_dimensions[1]
|
2102
|
+
});
|
2103
|
+
|
2104
|
+
var nodeName = this.$resized_widget.get(0).tagName;
|
2105
|
+
this.$resize_preview_holder = $('<' + nodeName + ' />', {
|
2106
|
+
'class': 'preview-holder resize-preview-holder',
|
2107
|
+
'data-row': this.$resized_widget.attr('data-row'),
|
2108
|
+
'data-col': this.$resized_widget.attr('data-col'),
|
2109
|
+
'css': {
|
2110
|
+
'width': this.resize_initial_width,
|
2111
|
+
'height': this.resize_initial_height
|
2112
|
+
}
|
2113
|
+
}).appendTo(this.$el);
|
2114
|
+
|
2115
|
+
this.$resized_widget.addClass('resizing');
|
2116
|
+
|
2117
|
+
if (this.options.resize.start) {
|
2118
|
+
this.options.resize.start.call(this, event, ui, this.$resized_widget);
|
2119
|
+
}
|
2120
|
+
|
2121
|
+
this.$el.trigger('gridster:resizestart');
|
2122
|
+
};
|
2123
|
+
|
2124
|
+
|
2125
|
+
/**
|
2126
|
+
* This function is executed every time a widget stops being resized.
|
2127
|
+
*
|
2128
|
+
* @method on_stop_resize
|
2129
|
+
* @param {Event} event The original browser event
|
2130
|
+
* @param {Object} ui A prepared ui object with useful drag-related data
|
2131
|
+
*/
|
2132
|
+
fn.on_stop_resize = function(event, ui) {
|
2133
|
+
this.$resized_widget
|
2134
|
+
.removeClass('resizing')
|
2135
|
+
.css({
|
2136
|
+
'width': '',
|
2137
|
+
'height': ''
|
2138
|
+
});
|
2139
|
+
|
2140
|
+
delay($.proxy(function() {
|
2141
|
+
this.$resize_preview_holder
|
2142
|
+
.remove()
|
2143
|
+
.css({
|
2144
|
+
'min-width': '',
|
2145
|
+
'min-height': ''
|
2146
|
+
});
|
2147
|
+
|
2148
|
+
if (this.options.resize.stop) {
|
2149
|
+
this.options.resize.stop.call(this, event, ui, this.$resized_widget);
|
2150
|
+
}
|
2151
|
+
|
2152
|
+
this.$el.trigger('gridster:resizestop');
|
2153
|
+
}, this), 300);
|
2154
|
+
|
2155
|
+
this.set_dom_grid_width();
|
2156
|
+
|
2157
|
+
if (this.options.autogrow_cols) {
|
2158
|
+
this.drag_api.set_limits(this.cols * this.min_widget_width);
|
2159
|
+
}
|
2160
|
+
};
|
2161
|
+
|
2162
|
+
|
2163
|
+
/**
|
2164
|
+
* This function is executed when a widget is being resized.
|
2165
|
+
*
|
2166
|
+
* @method on_resize
|
2167
|
+
* @param {Event} event The original browser event
|
2168
|
+
* @param {Object} ui A prepared ui object with useful drag-related data
|
2169
|
+
*/
|
2170
|
+
fn.on_resize = function(event, ui) {
|
2171
|
+
var rel_x = (ui.pointer.diff_left);
|
2172
|
+
var rel_y = (ui.pointer.diff_top);
|
2173
|
+
var wbd_x = this.options.widget_base_dimensions[0];
|
2174
|
+
var wbd_y = this.options.widget_base_dimensions[1];
|
2175
|
+
var margin_x = this.options.widget_margins[0];
|
2176
|
+
var margin_y = this.options.widget_margins[1];
|
2177
|
+
var max_size_x = this.resize_max_size_x;
|
2178
|
+
var min_size_x = this.resize_min_size_x;
|
2179
|
+
var max_size_y = this.resize_max_size_y;
|
2180
|
+
var min_size_y = this.resize_min_size_y;
|
2181
|
+
var autogrow = this.options.autogrow_cols;
|
2182
|
+
var width;
|
2183
|
+
var max_width = Infinity;
|
2184
|
+
var max_height = Infinity;
|
2185
|
+
|
2186
|
+
var inc_units_x = Math.ceil((rel_x / (wbd_x + margin_x * 2)) - 0.2);
|
2187
|
+
var inc_units_y = Math.ceil((rel_y / (wbd_y + margin_y * 2)) - 0.2);
|
2188
|
+
|
2189
|
+
var size_x = Math.max(1, this.resize_initial_sizex + inc_units_x);
|
2190
|
+
var size_y = Math.max(1, this.resize_initial_sizey + inc_units_y);
|
2191
|
+
|
2192
|
+
var max_cols = (this.container_width / this.min_widget_width) -
|
2193
|
+
this.resize_initial_col + 1;
|
2194
|
+
var limit_width = ((max_cols * this.min_widget_width) - margin_x * 2);
|
2195
|
+
|
2196
|
+
size_x = Math.max(Math.min(size_x, max_size_x), min_size_x);
|
2197
|
+
size_x = Math.min(max_cols, size_x);
|
2198
|
+
width = (max_size_x * wbd_x) + ((size_x - 1) * margin_x * 2);
|
2199
|
+
max_width = Math.min(width, limit_width);
|
2200
|
+
min_width = (min_size_x * wbd_x) + ((size_x - 1) * margin_x * 2);
|
2201
|
+
|
2202
|
+
size_y = Math.max(Math.min(size_y, max_size_y), min_size_y);
|
2203
|
+
max_height = (max_size_y * wbd_y) + ((size_y - 1) * margin_y * 2);
|
2204
|
+
min_height = (min_size_y * wbd_y) + ((size_y - 1) * margin_y * 2);
|
2205
|
+
|
2206
|
+
if (this.resize_dir.right) {
|
2207
|
+
size_y = this.resize_initial_sizey;
|
2208
|
+
} else if (this.resize_dir.bottom) {
|
2209
|
+
size_x = this.resize_initial_sizex;
|
2210
|
+
}
|
2211
|
+
|
2212
|
+
if (autogrow) {
|
2213
|
+
var last_widget_col = this.resize_initial_col + size_x - 1;
|
2214
|
+
if (autogrow && this.resize_initial_last_col <= last_widget_col) {
|
2215
|
+
this.set_dom_grid_width(Math.max(last_widget_col + 1, this.cols));
|
2216
|
+
|
2217
|
+
if (this.cols < last_widget_col) {
|
2218
|
+
this.add_faux_cols(last_widget_col - this.cols);
|
2219
|
+
}
|
2220
|
+
}
|
2221
|
+
}
|
2222
|
+
|
2223
|
+
var css_props = {};
|
2224
|
+
!this.resize_dir.bottom && (css_props.width = Math.max(Math.min(
|
2225
|
+
this.resize_initial_width + rel_x, max_width), min_width));
|
2226
|
+
!this.resize_dir.right && (css_props.height = Math.max(Math.min(
|
2227
|
+
this.resize_initial_height + rel_y, max_height), min_height));
|
2228
|
+
|
2229
|
+
this.$resized_widget.css(css_props);
|
1233
2230
|
|
1234
|
-
|
1235
|
-
this.
|
1236
|
-
this.set_cells_player_occupies(
|
1237
|
-
this.placeholder_grid_data.col, this.placeholder_grid_data.row);
|
2231
|
+
if (size_x !== this.resize_last_sizex ||
|
2232
|
+
size_y !== this.resize_last_sizey) {
|
1238
2233
|
|
1239
|
-
|
1240
|
-
|
2234
|
+
this.resize_widget(this.$resized_widget, size_x, size_y);
|
2235
|
+
this.set_dom_grid_width(this.cols);
|
1241
2236
|
|
1242
|
-
|
1243
|
-
|
2237
|
+
this.$resize_preview_holder.css({
|
2238
|
+
'width': '',
|
2239
|
+
'height': ''
|
2240
|
+
}).attr({
|
2241
|
+
'data-row': this.$resized_widget.attr('data-row'),
|
2242
|
+
'data-sizex': size_x,
|
2243
|
+
'data-sizey': size_y
|
2244
|
+
});
|
1244
2245
|
}
|
1245
2246
|
|
1246
|
-
this
|
1247
|
-
|
2247
|
+
if (this.options.resize.resize) {
|
2248
|
+
this.options.resize.resize.call(this, event, ui, this.$resized_widget);
|
2249
|
+
}
|
1248
2250
|
|
1249
|
-
this.
|
2251
|
+
this.$el.trigger('gridster:resize');
|
2252
|
+
|
2253
|
+
this.resize_last_sizex = size_x;
|
2254
|
+
this.resize_last_sizey = size_y;
|
1250
2255
|
};
|
1251
2256
|
|
1252
2257
|
|
@@ -1263,7 +2268,7 @@
|
|
1263
2268
|
*/
|
1264
2269
|
fn.on_overlapped_column_change = function(start_callback, stop_callback) {
|
1265
2270
|
if (!this.colliders_data.length) {
|
1266
|
-
return;
|
2271
|
+
return this;
|
1267
2272
|
}
|
1268
2273
|
var cols = this.get_targeted_columns(
|
1269
2274
|
this.colliders_data[0].el.data.col);
|
@@ -1296,14 +2301,14 @@
|
|
1296
2301
|
*
|
1297
2302
|
* @param {Function} start_callback Function executed when a new row begins
|
1298
2303
|
* to be overlapped. The row is passed as first argument.
|
1299
|
-
* @param {Function}
|
2304
|
+
* @param {Function} end_callback Function executed when a row stops being
|
1300
2305
|
* overlapped. The row is passed as first argument.
|
1301
2306
|
* @method on_overlapped_row_change
|
1302
2307
|
* @return {Class} Returns the instance of the Gridster Class.
|
1303
2308
|
*/
|
1304
2309
|
fn.on_overlapped_row_change = function(start_callback, end_callback) {
|
1305
2310
|
if (!this.colliders_data.length) {
|
1306
|
-
return;
|
2311
|
+
return this;
|
1307
2312
|
}
|
1308
2313
|
var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row);
|
1309
2314
|
var last_n_rows = this.last_rows.length;
|
@@ -1329,18 +2334,18 @@
|
|
1329
2334
|
/**
|
1330
2335
|
* Sets the current position of the player
|
1331
2336
|
*
|
1332
|
-
* @param {
|
1333
|
-
*
|
1334
|
-
* @param {
|
1335
|
-
* overlapped. The row is passed as first argument.
|
2337
|
+
* @param {Number} col
|
2338
|
+
* @param {Number} row
|
2339
|
+
* @param {Boolean} no_player
|
1336
2340
|
* @method set_player
|
1337
|
-
* @return {
|
2341
|
+
* @return {object}
|
1338
2342
|
*/
|
1339
|
-
fn.set_player = function(col, row) {
|
1340
|
-
this.empty_cells_player_occupies();
|
1341
|
-
|
2343
|
+
fn.set_player = function(col, row, no_player) {
|
1342
2344
|
var self = this;
|
1343
|
-
|
2345
|
+
if (!no_player) {
|
2346
|
+
this.empty_cells_player_occupies();
|
2347
|
+
}
|
2348
|
+
var cell = !no_player ? self.colliders_data[0].el.data : {col: col};
|
1344
2349
|
var to_col = cell.col;
|
1345
2350
|
var to_row = row || cell.row;
|
1346
2351
|
|
@@ -1384,9 +2389,9 @@
|
|
1384
2389
|
* a upper row and which not.
|
1385
2390
|
*
|
1386
2391
|
* @method widgets_contraints
|
1387
|
-
* @param {
|
2392
|
+
* @param {jQuery} $widgets A jQuery wrapped collection of
|
1388
2393
|
* HTMLElements.
|
1389
|
-
* @return {
|
2394
|
+
* @return {object} Returns a literal Object with two keys: `can_go_up` &
|
1390
2395
|
* `can_not_go_up`. Each contains a set of HTMLElements.
|
1391
2396
|
*/
|
1392
2397
|
fn.widgets_constraints = function($widgets) {
|
@@ -1401,7 +2406,7 @@
|
|
1401
2406
|
if (this.can_go_widget_up(wgd)) {
|
1402
2407
|
$widgets_can_go_up = $widgets_can_go_up.add($w);
|
1403
2408
|
wgd_can_go_up.push(wgd);
|
1404
|
-
}else{
|
2409
|
+
} else {
|
1405
2410
|
wgd_can_not_go_up.push(wgd);
|
1406
2411
|
}
|
1407
2412
|
}, this));
|
@@ -1409,97 +2414,18 @@
|
|
1409
2414
|
$widgets_can_not_go_up = $widgets.not($widgets_can_go_up);
|
1410
2415
|
|
1411
2416
|
return {
|
1412
|
-
can_go_up:
|
1413
|
-
can_not_go_up:
|
2417
|
+
can_go_up: Gridster.sort_by_row_asc(wgd_can_go_up),
|
2418
|
+
can_not_go_up: Gridster.sort_by_row_desc(wgd_can_not_go_up)
|
1414
2419
|
};
|
1415
2420
|
};
|
1416
2421
|
|
1417
2422
|
|
1418
|
-
/**
|
1419
|
-
* Sorts an Array of grid coords objects (representing the grid coords of
|
1420
|
-
* each widget) in ascending way.
|
1421
|
-
*
|
1422
|
-
* @method sort_by_row_asc
|
1423
|
-
* @param {Array} widgets Array of grid coords objects
|
1424
|
-
* @return {Array} Returns the array sorted.
|
1425
|
-
*/
|
1426
|
-
fn.sort_by_row_asc = function(widgets) {
|
1427
|
-
widgets = widgets.sort(function(a, b) {
|
1428
|
-
if (a.row > b.row) {
|
1429
|
-
return 1;
|
1430
|
-
}
|
1431
|
-
return -1;
|
1432
|
-
});
|
1433
|
-
|
1434
|
-
return widgets;
|
1435
|
-
};
|
1436
|
-
|
1437
|
-
|
1438
|
-
/**
|
1439
|
-
* Sorts an Array of grid coords objects (representing the grid coords of
|
1440
|
-
* each widget) placing first the empty cells upper left.
|
1441
|
-
*
|
1442
|
-
* @method sort_by_row_and_col_asc
|
1443
|
-
* @param {Array} widgets Array of grid coords objects
|
1444
|
-
* @return {Array} Returns the array sorted.
|
1445
|
-
*/
|
1446
|
-
fn.sort_by_row_and_col_asc = function(widgets) {
|
1447
|
-
widgets = widgets.sort(function(a, b) {
|
1448
|
-
if (a.row > b.row || a.row == b.row && a.col > b.col) {
|
1449
|
-
return 1;
|
1450
|
-
}
|
1451
|
-
return -1;
|
1452
|
-
});
|
1453
|
-
|
1454
|
-
return widgets;
|
1455
|
-
};
|
1456
|
-
|
1457
|
-
|
1458
|
-
/**
|
1459
|
-
* Sorts an Array of grid coords objects by column (representing the grid
|
1460
|
-
* coords of each widget) in ascending way.
|
1461
|
-
*
|
1462
|
-
* @method sort_by_col_asc
|
1463
|
-
* @param {Array} widgets Array of grid coords objects
|
1464
|
-
* @return {Array} Returns the array sorted.
|
1465
|
-
*/
|
1466
|
-
fn.sort_by_col_asc = function(widgets) {
|
1467
|
-
widgets = widgets.sort(function(a, b) {
|
1468
|
-
if (a.col > b.col) {
|
1469
|
-
return 1;
|
1470
|
-
}
|
1471
|
-
return -1;
|
1472
|
-
});
|
1473
|
-
|
1474
|
-
return widgets;
|
1475
|
-
};
|
1476
|
-
|
1477
|
-
|
1478
|
-
/**
|
1479
|
-
* Sorts an Array of grid coords objects (representing the grid coords of
|
1480
|
-
* each widget) in descending way.
|
1481
|
-
*
|
1482
|
-
* @method sort_by_row_desc
|
1483
|
-
* @param {Array} widgets Array of grid coords objects
|
1484
|
-
* @return {Array} Returns the array sorted.
|
1485
|
-
*/
|
1486
|
-
fn.sort_by_row_desc = function(widgets) {
|
1487
|
-
widgets = widgets.sort(function(a, b) {
|
1488
|
-
if (a.row + a.size_y < b.row + b.size_y) {
|
1489
|
-
return 1;
|
1490
|
-
}
|
1491
|
-
return -1;
|
1492
|
-
});
|
1493
|
-
return widgets;
|
1494
|
-
};
|
1495
|
-
|
1496
|
-
|
1497
2423
|
/**
|
1498
2424
|
* Sorts an Array of grid coords objects (representing the grid coords of
|
1499
2425
|
* each widget) in descending way.
|
1500
2426
|
*
|
1501
2427
|
* @method manage_movements
|
1502
|
-
* @param {
|
2428
|
+
* @param {jQuery} $widgets A jQuery collection of HTMLElements
|
1503
2429
|
* representing the widgets you want to move.
|
1504
2430
|
* @param {Number} to_col The column to which we want to move the widgets.
|
1505
2431
|
* @param {Number} to_row The row to which we want to move the widgets.
|
@@ -1607,13 +2533,15 @@
|
|
1607
2533
|
* @return {Boolean} Returns true or false.
|
1608
2534
|
*/
|
1609
2535
|
fn.is_empty = function(col, row) {
|
1610
|
-
if (typeof this.gridmap[col] !== 'undefined'
|
1611
|
-
typeof this.gridmap[col][row] !== 'undefined' &&
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
2536
|
+
if (typeof this.gridmap[col] !== 'undefined') {
|
2537
|
+
if(typeof this.gridmap[col][row] !== 'undefined' &&
|
2538
|
+
this.gridmap[col][row] === false
|
2539
|
+
) {
|
2540
|
+
return true;
|
2541
|
+
}
|
2542
|
+
return false;
|
1615
2543
|
}
|
1616
|
-
return
|
2544
|
+
return true;
|
1617
2545
|
};
|
1618
2546
|
|
1619
2547
|
|
@@ -1680,13 +2608,14 @@
|
|
1680
2608
|
|
1681
2609
|
|
1682
2610
|
/**
|
1683
|
-
* Get widgets overlapping with the player
|
2611
|
+
* Get widgets overlapping with the player or with the object passed
|
2612
|
+
* representing the grid cells.
|
1684
2613
|
*
|
1685
2614
|
* @method get_widgets_under_player
|
1686
2615
|
* @return {HTMLElement} Returns a jQuery collection of HTMLElements
|
1687
2616
|
*/
|
1688
|
-
fn.get_widgets_under_player = function() {
|
1689
|
-
|
2617
|
+
fn.get_widgets_under_player = function(cells) {
|
2618
|
+
cells || (cells = this.cells_occupied_by_player || {cols: [], rows: []});
|
1690
2619
|
var $widgets = $([]);
|
1691
2620
|
|
1692
2621
|
$.each(cells.cols, $.proxy(function(i, col) {
|
@@ -1720,7 +2649,7 @@
|
|
1720
2649
|
size_x: phgd.size_x
|
1721
2650
|
});
|
1722
2651
|
|
1723
|
-
//Prevents widgets go out of the grid
|
2652
|
+
// Prevents widgets go out of the grid
|
1724
2653
|
var right_col = (col + phgd.size_x - 1);
|
1725
2654
|
if (right_col > this.cols) {
|
1726
2655
|
col = col - (right_col - col);
|
@@ -1747,6 +2676,17 @@
|
|
1747
2676
|
}, this));
|
1748
2677
|
}
|
1749
2678
|
|
2679
|
+
var $widgets_under_ph = this.get_widgets_under_player(
|
2680
|
+
this.cells_occupied_by_placeholder);
|
2681
|
+
|
2682
|
+
if ($widgets_under_ph.length) {
|
2683
|
+
$widgets_under_ph.each($.proxy(function(i, widget) {
|
2684
|
+
var $w = $(widget);
|
2685
|
+
this.move_widget_down(
|
2686
|
+
$w, row + phgd.size_y - $w.data('coords').grid.row);
|
2687
|
+
}, this));
|
2688
|
+
}
|
2689
|
+
|
1750
2690
|
};
|
1751
2691
|
|
1752
2692
|
|
@@ -1780,7 +2720,7 @@
|
|
1780
2720
|
) {
|
1781
2721
|
upper_rows[tcol].push(r);
|
1782
2722
|
min_row = r < min_row ? r : min_row;
|
1783
|
-
}else{
|
2723
|
+
} else {
|
1784
2724
|
break;
|
1785
2725
|
}
|
1786
2726
|
}
|
@@ -1790,7 +2730,9 @@
|
|
1790
2730
|
return true; //break
|
1791
2731
|
}
|
1792
2732
|
|
1793
|
-
upper_rows[tcol].sort()
|
2733
|
+
upper_rows[tcol].sort(function(a, b) {
|
2734
|
+
return a - b;
|
2735
|
+
});
|
1794
2736
|
});
|
1795
2737
|
|
1796
2738
|
if (!result) { return false; }
|
@@ -1814,33 +2756,26 @@
|
|
1814
2756
|
var upper_rows = [];
|
1815
2757
|
var min_row = 10000;
|
1816
2758
|
|
1817
|
-
|
1818
|
-
(widget_grid_data.col + widget_grid_data.size_y - 1) >
|
1819
|
-
(this.player_grid_data.col + this.player_grid_data.size_y - 1)
|
1820
|
-
) {
|
1821
|
-
return false;
|
1822
|
-
};
|
1823
|
-
|
1824
|
-
/* generate an array with columns as index and array with upper rows
|
2759
|
+
/* generate an array with columns as index and array with topmost rows
|
1825
2760
|
* empty as value */
|
1826
2761
|
this.for_each_column_occupied(widget_grid_data, function(tcol) {
|
1827
2762
|
var grid_col = this.gridmap[tcol];
|
1828
2763
|
upper_rows[tcol] = [];
|
1829
2764
|
|
1830
2765
|
var r = p_bottom_row + 1;
|
1831
|
-
|
2766
|
+
// iterate over each row
|
1832
2767
|
while (--r > 0) {
|
1833
2768
|
if (this.is_widget(tcol, r) && !this.is_player_in(tcol, r)) {
|
1834
2769
|
if (!grid_col[r].is(widget_grid_data.el)) {
|
1835
2770
|
break;
|
1836
|
-
}
|
2771
|
+
}
|
1837
2772
|
}
|
1838
2773
|
|
1839
2774
|
if (!this.is_player(tcol, r) &&
|
1840
2775
|
!this.is_placeholder_in(tcol, r) &&
|
1841
2776
|
!this.is_player_in(tcol, r)) {
|
1842
2777
|
upper_rows[tcol].push(r);
|
1843
|
-
}
|
2778
|
+
}
|
1844
2779
|
|
1845
2780
|
if (r < min_row) {
|
1846
2781
|
min_row = r;
|
@@ -1852,7 +2787,9 @@
|
|
1852
2787
|
return true; //break
|
1853
2788
|
}
|
1854
2789
|
|
1855
|
-
upper_rows[tcol].sort()
|
2790
|
+
upper_rows[tcol].sort(function(a, b) {
|
2791
|
+
return a - b;
|
2792
|
+
});
|
1856
2793
|
});
|
1857
2794
|
|
1858
2795
|
if (!result) { return false; }
|
@@ -1902,7 +2839,7 @@
|
|
1902
2839
|
if (valid_rows[0] !== p_top_row) {
|
1903
2840
|
new_row = valid_rows[0] || false;
|
1904
2841
|
}
|
1905
|
-
}else{
|
2842
|
+
} else {
|
1906
2843
|
if (valid_rows[0] !== p_top_row) {
|
1907
2844
|
new_row = this.get_consecutive_numbers_index(
|
1908
2845
|
valid_rows, size_y);
|
@@ -1926,7 +2863,7 @@
|
|
1926
2863
|
break;
|
1927
2864
|
}
|
1928
2865
|
first = false;
|
1929
|
-
}else{
|
2866
|
+
} else {
|
1930
2867
|
result = [];
|
1931
2868
|
first = true;
|
1932
2869
|
}
|
@@ -1942,7 +2879,7 @@
|
|
1942
2879
|
* Get widgets overlapping with the player.
|
1943
2880
|
*
|
1944
2881
|
* @method get_widgets_overlapped
|
1945
|
-
* @return {
|
2882
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
1946
2883
|
*/
|
1947
2884
|
fn.get_widgets_overlapped = function() {
|
1948
2885
|
var $w;
|
@@ -1956,7 +2893,6 @@
|
|
1956
2893
|
// if there is a widget in the player position
|
1957
2894
|
if (!this.gridmap[col]) { return true; } //next iteration
|
1958
2895
|
var $w = this.gridmap[col][row];
|
1959
|
-
|
1960
2896
|
if (this.is_occupied(col, row) && !this.is_player($w) &&
|
1961
2897
|
$.inArray($w, used) === -1
|
1962
2898
|
) {
|
@@ -1976,7 +2912,7 @@
|
|
1976
2912
|
*
|
1977
2913
|
* @method on_start_overlapping_column
|
1978
2914
|
* @param {Number} col The collided column.
|
1979
|
-
* @return {
|
2915
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
1980
2916
|
*/
|
1981
2917
|
fn.on_start_overlapping_column = function(col) {
|
1982
2918
|
this.set_player(col, false);
|
@@ -1987,8 +2923,8 @@
|
|
1987
2923
|
* A callback executed when the player begins to collide with a row.
|
1988
2924
|
*
|
1989
2925
|
* @method on_start_overlapping_row
|
1990
|
-
* @param {Number}
|
1991
|
-
* @return {
|
2926
|
+
* @param {Number} row The collided row.
|
2927
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
1992
2928
|
*/
|
1993
2929
|
fn.on_start_overlapping_row = function(row) {
|
1994
2930
|
this.set_player(false, row);
|
@@ -2000,7 +2936,7 @@
|
|
2000
2936
|
*
|
2001
2937
|
* @method on_stop_overlapping_column
|
2002
2938
|
* @param {Number} col The collided row.
|
2003
|
-
* @return {
|
2939
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
2004
2940
|
*/
|
2005
2941
|
fn.on_stop_overlapping_column = function(col) {
|
2006
2942
|
this.set_player(col, false);
|
@@ -2018,7 +2954,7 @@
|
|
2018
2954
|
*
|
2019
2955
|
* @method on_stop_overlapping_row
|
2020
2956
|
* @param {Number} row The collided row.
|
2021
|
-
* @return {
|
2957
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
2022
2958
|
*/
|
2023
2959
|
fn.on_stop_overlapping_row = function(row) {
|
2024
2960
|
this.set_player(false, row);
|
@@ -2128,16 +3064,20 @@
|
|
2128
3064
|
* Move down the specified widget and all below it.
|
2129
3065
|
*
|
2130
3066
|
* @method move_widget_down
|
2131
|
-
* @param {
|
3067
|
+
* @param {jQuery} $widget The jQuery object representing the widget
|
2132
3068
|
* you want to move.
|
2133
|
-
* @param {Number} The number of cells that the widget has to move.
|
3069
|
+
* @param {Number} y_units The number of cells that the widget has to move.
|
2134
3070
|
* @return {Class} Returns the instance of the Gridster Class.
|
2135
3071
|
*/
|
2136
3072
|
fn.move_widget_down = function($widget, y_units) {
|
2137
|
-
var el_grid_data
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
3073
|
+
var el_grid_data, actual_row, moved, y_diff;
|
3074
|
+
|
3075
|
+
if (y_units <= 0) { return false; }
|
3076
|
+
|
3077
|
+
el_grid_data = $widget.coords().grid;
|
3078
|
+
actual_row = el_grid_data.row;
|
3079
|
+
moved = [];
|
3080
|
+
y_diff = y_units;
|
2141
3081
|
|
2142
3082
|
if (!$widget) { return false; }
|
2143
3083
|
|
@@ -2201,7 +3141,7 @@
|
|
2201
3141
|
!this.is_placeholder_in(tcol, r)
|
2202
3142
|
) {
|
2203
3143
|
urc[tcol].push(r);
|
2204
|
-
}else{
|
3144
|
+
} else {
|
2205
3145
|
break;
|
2206
3146
|
}
|
2207
3147
|
}
|
@@ -2266,7 +3206,7 @@
|
|
2266
3206
|
*
|
2267
3207
|
* @method widgets_below
|
2268
3208
|
* @param {HTMLElement} $el The jQuery wrapped HTMLElement.
|
2269
|
-
* @return {
|
3209
|
+
* @return {jQuery} A jQuery collection of HTMLElements.
|
2270
3210
|
*/
|
2271
3211
|
fn.widgets_below = function($el) {
|
2272
3212
|
var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid;
|
@@ -2276,17 +3216,15 @@
|
|
2276
3216
|
var $nexts = $([]);
|
2277
3217
|
|
2278
3218
|
this.for_each_column_occupied(el_grid_data, function(col) {
|
2279
|
-
self.for_each_widget_below(col, next_row,
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2283
|
-
|
2284
|
-
|
2285
|
-
}
|
2286
|
-
});
|
3219
|
+
self.for_each_widget_below(col, next_row, function(tcol, trow) {
|
3220
|
+
if (!self.is_player(this) && $.inArray(this, $nexts) === -1) {
|
3221
|
+
$nexts = $nexts.add(this);
|
3222
|
+
return true; // break
|
3223
|
+
}
|
3224
|
+
});
|
2287
3225
|
});
|
2288
3226
|
|
2289
|
-
return
|
3227
|
+
return Gridster.sort_by_row_asc($nexts);
|
2290
3228
|
};
|
2291
3229
|
|
2292
3230
|
|
@@ -2331,6 +3269,7 @@
|
|
2331
3269
|
|
2332
3270
|
this.for_each_column_occupied(el_grid_data, function(col) {
|
2333
3271
|
var $w = this.is_widget(col, prev_row);
|
3272
|
+
|
2334
3273
|
if (this.is_occupied(col, prev_row) ||
|
2335
3274
|
this.is_player(col, prev_row) ||
|
2336
3275
|
this.is_placeholder_in(col, prev_row) ||
|
@@ -2345,7 +3284,6 @@
|
|
2345
3284
|
};
|
2346
3285
|
|
2347
3286
|
|
2348
|
-
|
2349
3287
|
/**
|
2350
3288
|
* Check if it's possible to move a widget to a specific col/row. It takes
|
2351
3289
|
* into account the dimensions (`size_y` and `size_x` attrs. of the grid
|
@@ -2356,9 +3294,10 @@
|
|
2356
3294
|
* the widget.
|
2357
3295
|
* @param {Object} col The col to check.
|
2358
3296
|
* @param {Object} row The row to check.
|
3297
|
+
* @param {Number} [max_row] The max row allowed.
|
2359
3298
|
* @return {Boolean} Returns true if all cells are empty, else return false.
|
2360
3299
|
*/
|
2361
|
-
fn.can_move_to = function(widget_grid_data, col, row) {
|
3300
|
+
fn.can_move_to = function(widget_grid_data, col, row, max_row) {
|
2362
3301
|
var ga = this.gridmap;
|
2363
3302
|
var $w = widget_grid_data.el;
|
2364
3303
|
var future_wd = {
|
@@ -2373,7 +3312,11 @@
|
|
2373
3312
|
var right_col = col + widget_grid_data.size_x - 1;
|
2374
3313
|
if (right_col > this.cols) {
|
2375
3314
|
return false;
|
2376
|
-
}
|
3315
|
+
}
|
3316
|
+
|
3317
|
+
if (max_row && max_row < row + widget_grid_data.size_y - 1) {
|
3318
|
+
return false;
|
3319
|
+
}
|
2377
3320
|
|
2378
3321
|
this.for_each_cell_occupied(future_wd, function(tcol, trow) {
|
2379
3322
|
var $tw = this.is_widget(tcol, trow);
|
@@ -2432,7 +3375,7 @@
|
|
2432
3375
|
fn.get_cells_occupied = function(el_grid_data) {
|
2433
3376
|
var cells = { cols: [], rows: []};
|
2434
3377
|
var i;
|
2435
|
-
if (arguments[1] instanceof
|
3378
|
+
if (arguments[1] instanceof $) {
|
2436
3379
|
el_grid_data = arguments[1].coords().grid;
|
2437
3380
|
}
|
2438
3381
|
|
@@ -2516,7 +3459,7 @@
|
|
2516
3459
|
|
2517
3460
|
var cr, max;
|
2518
3461
|
var action = type + '/' + direction;
|
2519
|
-
if (arguments[2] instanceof
|
3462
|
+
if (arguments[2] instanceof $) {
|
2520
3463
|
var el_grid_data = arguments[2].coords().grid;
|
2521
3464
|
col = el_grid_data.col;
|
2522
3465
|
row = el_grid_data.row;
|
@@ -2600,26 +3543,23 @@
|
|
2600
3543
|
fn.get_highest_occupied_cell = function() {
|
2601
3544
|
var r;
|
2602
3545
|
var gm = this.gridmap;
|
2603
|
-
var
|
3546
|
+
var rl = gm[1].length;
|
3547
|
+
var rows = [], cols = [];
|
2604
3548
|
var row_in_col = [];
|
2605
3549
|
for (var c = gm.length - 1; c >= 1; c--) {
|
2606
|
-
for (r =
|
3550
|
+
for (r = rl - 1; r >= 1; r--) {
|
2607
3551
|
if (this.is_widget(c, r)) {
|
2608
3552
|
rows.push(r);
|
2609
|
-
|
3553
|
+
cols.push(c);
|
2610
3554
|
break;
|
2611
3555
|
}
|
2612
3556
|
}
|
2613
3557
|
}
|
2614
3558
|
|
2615
|
-
|
2616
|
-
|
2617
|
-
|
2618
|
-
col: row_in_col[highest_row],
|
2619
|
-
row: highest_row
|
3559
|
+
return {
|
3560
|
+
col: Math.max.apply(Math, cols),
|
3561
|
+
row: Math.max.apply(Math, rows)
|
2620
3562
|
};
|
2621
|
-
|
2622
|
-
return this.highest_occupied_cell;
|
2623
3563
|
};
|
2624
3564
|
|
2625
3565
|
|
@@ -2646,7 +3586,7 @@
|
|
2646
3586
|
}
|
2647
3587
|
|
2648
3588
|
return $widgets;
|
2649
|
-
}
|
3589
|
+
};
|
2650
3590
|
|
2651
3591
|
|
2652
3592
|
/**
|
@@ -2655,9 +3595,34 @@
|
|
2655
3595
|
* @method set_dom_grid_height
|
2656
3596
|
* @return {Object} Returns the instance of the Gridster class.
|
2657
3597
|
*/
|
2658
|
-
fn.set_dom_grid_height = function() {
|
2659
|
-
|
2660
|
-
|
3598
|
+
fn.set_dom_grid_height = function(height) {
|
3599
|
+
if (typeof height === 'undefined') {
|
3600
|
+
var r = this.get_highest_occupied_cell().row;
|
3601
|
+
height = r * this.min_widget_height;
|
3602
|
+
}
|
3603
|
+
|
3604
|
+
this.container_height = height;
|
3605
|
+
this.$el.css('height', this.container_height);
|
3606
|
+
return this;
|
3607
|
+
};
|
3608
|
+
|
3609
|
+
/**
|
3610
|
+
* Set the current width of the parent grid.
|
3611
|
+
*
|
3612
|
+
* @method set_dom_grid_width
|
3613
|
+
* @return {Object} Returns the instance of the Gridster class.
|
3614
|
+
*/
|
3615
|
+
fn.set_dom_grid_width = function(cols) {
|
3616
|
+
if (typeof cols === 'undefined') {
|
3617
|
+
cols = this.get_highest_occupied_cell().col;
|
3618
|
+
}
|
3619
|
+
|
3620
|
+
var max_cols = (this.options.autogrow_cols ? this.options.max_cols :
|
3621
|
+
this.cols);
|
3622
|
+
|
3623
|
+
cols = Math.min(max_cols, Math.max(cols, this.options.min_cols));
|
3624
|
+
this.container_width = cols * this.min_widget_width;
|
3625
|
+
this.$el.css('width', this.container_width);
|
2661
3626
|
return this;
|
2662
3627
|
};
|
2663
3628
|
|
@@ -2672,16 +3637,16 @@
|
|
2672
3637
|
*/
|
2673
3638
|
fn.generate_stylesheet = function(opts) {
|
2674
3639
|
var styles = '';
|
2675
|
-
var
|
2676
|
-
var
|
2677
|
-
var
|
3640
|
+
var max_size_x = this.options.max_size_x || this.cols;
|
3641
|
+
var max_rows = 0;
|
3642
|
+
var max_cols = 0;
|
2678
3643
|
var i;
|
2679
3644
|
var rules;
|
2680
3645
|
|
2681
3646
|
opts || (opts = {});
|
2682
3647
|
opts.cols || (opts.cols = this.cols);
|
2683
3648
|
opts.rows || (opts.rows = this.rows);
|
2684
|
-
opts.namespace || (opts.namespace =
|
3649
|
+
opts.namespace || (opts.namespace = this.options.namespace);
|
2685
3650
|
opts.widget_base_dimensions ||
|
2686
3651
|
(opts.widget_base_dimensions = this.options.widget_base_dimensions);
|
2687
3652
|
opts.widget_margins ||
|
@@ -2691,42 +3656,45 @@
|
|
2691
3656
|
opts.min_widget_height = (opts.widget_margins[1] * 2) +
|
2692
3657
|
opts.widget_base_dimensions[1];
|
2693
3658
|
|
2694
|
-
var serialized_opts = $.param(opts);
|
2695
3659
|
// don't duplicate stylesheets for the same configuration
|
3660
|
+
var serialized_opts = $.param(opts);
|
2696
3661
|
if ($.inArray(serialized_opts, Gridster.generated_stylesheets) >= 0) {
|
2697
3662
|
return false;
|
2698
3663
|
}
|
2699
3664
|
|
3665
|
+
this.generated_stylesheets.push(serialized_opts);
|
2700
3666
|
Gridster.generated_stylesheets.push(serialized_opts);
|
2701
3667
|
|
2702
3668
|
/* generate CSS styles for cols */
|
2703
|
-
for (i = opts.cols
|
3669
|
+
for (i = opts.cols; i >= 0; i--) {
|
2704
3670
|
styles += (opts.namespace + ' [data-col="'+ (i + 1) + '"] { left:' +
|
2705
3671
|
((i * opts.widget_base_dimensions[0]) +
|
2706
3672
|
(i * opts.widget_margins[0]) +
|
2707
|
-
((i + 1) * opts.widget_margins[0])) + 'px;}
|
3673
|
+
((i + 1) * opts.widget_margins[0])) + 'px; }\n');
|
2708
3674
|
}
|
2709
3675
|
|
2710
3676
|
/* generate CSS styles for rows */
|
2711
|
-
for (i = opts.rows
|
3677
|
+
for (i = opts.rows; i >= 0; i--) {
|
2712
3678
|
styles += (opts.namespace + ' [data-row="' + (i + 1) + '"] { top:' +
|
2713
3679
|
((i * opts.widget_base_dimensions[1]) +
|
2714
3680
|
(i * opts.widget_margins[1]) +
|
2715
|
-
((i + 1) * opts.widget_margins[1]) ) + 'px;}
|
3681
|
+
((i + 1) * opts.widget_margins[1]) ) + 'px; }\n');
|
2716
3682
|
}
|
2717
3683
|
|
2718
|
-
for (var y = 1; y <=
|
3684
|
+
for (var y = 1; y <= opts.rows; y++) {
|
2719
3685
|
styles += (opts.namespace + ' [data-sizey="' + y + '"] { height:' +
|
2720
3686
|
(y * opts.widget_base_dimensions[1] +
|
2721
|
-
(y - 1) * (opts.widget_margins[1] * 2)) + 'px;}');
|
3687
|
+
(y - 1) * (opts.widget_margins[1] * 2)) + 'px; }\n');
|
2722
3688
|
}
|
2723
3689
|
|
2724
3690
|
for (var x = 1; x <= max_size_x; x++) {
|
2725
3691
|
styles += (opts.namespace + ' [data-sizex="' + x + '"] { width:' +
|
2726
3692
|
(x * opts.widget_base_dimensions[0] +
|
2727
|
-
(x - 1) * (opts.widget_margins[0] * 2)) + 'px;}');
|
3693
|
+
(x - 1) * (opts.widget_margins[0] * 2)) + 'px; }\n');
|
2728
3694
|
}
|
2729
3695
|
|
3696
|
+
this.remove_style_tags();
|
3697
|
+
|
2730
3698
|
return this.add_style_tag(styles);
|
2731
3699
|
};
|
2732
3700
|
|
@@ -2739,18 +3707,39 @@
|
|
2739
3707
|
* @return {Object} Returns the instance of the Gridster class.
|
2740
3708
|
*/
|
2741
3709
|
fn.add_style_tag = function(css) {
|
2742
|
-
|
2743
|
-
|
3710
|
+
var d = document;
|
3711
|
+
var tag = d.createElement('style');
|
3712
|
+
|
3713
|
+
d.getElementsByTagName('head')[0].appendChild(tag);
|
3714
|
+
tag.setAttribute('type', 'text/css');
|
3715
|
+
|
3716
|
+
if (tag.styleSheet) {
|
3717
|
+
tag.styleSheet.cssText = css;
|
3718
|
+
} else {
|
3719
|
+
tag.appendChild(document.createTextNode(css));
|
3720
|
+
}
|
3721
|
+
|
3722
|
+
this.$style_tags = this.$style_tags.add(tag);
|
3723
|
+
|
3724
|
+
return this;
|
3725
|
+
};
|
3726
|
+
|
2744
3727
|
|
2745
|
-
|
2746
|
-
|
3728
|
+
/**
|
3729
|
+
* Remove the style tag with the associated id from the head of the document
|
3730
|
+
*
|
3731
|
+
* @method remove_style_tag
|
3732
|
+
* @return {Object} Returns the instance of the Gridster class.
|
3733
|
+
*/
|
3734
|
+
fn.remove_style_tags = function() {
|
3735
|
+
var all_styles = Gridster.generated_stylesheets;
|
3736
|
+
var ins_styles = this.generated_stylesheets;
|
2747
3737
|
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
return this;
|
3738
|
+
this.$style_tags.remove();
|
3739
|
+
|
3740
|
+
Gridster.generated_stylesheets = $.map(all_styles, function(s) {
|
3741
|
+
if ($.inArray(s, ins_styles) === -1) { return s; }
|
3742
|
+
});
|
2754
3743
|
};
|
2755
3744
|
|
2756
3745
|
|
@@ -2771,7 +3760,23 @@
|
|
2771
3760
|
for (col = cols; col > 0; col--) {
|
2772
3761
|
this.gridmap[col] = [];
|
2773
3762
|
for (row = rows; row > 0; row--) {
|
2774
|
-
|
3763
|
+
this.add_faux_cell(row, col);
|
3764
|
+
}
|
3765
|
+
}
|
3766
|
+
return this;
|
3767
|
+
};
|
3768
|
+
|
3769
|
+
|
3770
|
+
/**
|
3771
|
+
* Add cell to the faux grid.
|
3772
|
+
*
|
3773
|
+
* @method add_faux_cell
|
3774
|
+
* @param {Number} row The row for the new faux cell.
|
3775
|
+
* @param {Number} col The col for the new faux cell.
|
3776
|
+
* @return {Object} Returns the instance of the Gridster class.
|
3777
|
+
*/
|
3778
|
+
fn.add_faux_cell = function(row, col) {
|
3779
|
+
var coords = $({
|
2775
3780
|
left: this.baseX + ((col - 1) * this.min_widget_width),
|
2776
3781
|
top: this.baseY + (row -1) * this.min_widget_height,
|
2777
3782
|
width: this.min_widget_width,
|
@@ -2782,10 +3787,67 @@
|
|
2782
3787
|
original_row: row
|
2783
3788
|
}).coords();
|
2784
3789
|
|
2785
|
-
|
2786
|
-
|
3790
|
+
if (!$.isArray(this.gridmap[col])) {
|
3791
|
+
this.gridmap[col] = [];
|
3792
|
+
}
|
3793
|
+
|
3794
|
+
this.gridmap[col][row] = false;
|
3795
|
+
this.faux_grid.push(coords);
|
3796
|
+
|
3797
|
+
return this;
|
3798
|
+
};
|
3799
|
+
|
3800
|
+
|
3801
|
+
/**
|
3802
|
+
* Add rows to the faux grid.
|
3803
|
+
*
|
3804
|
+
* @method add_faux_rows
|
3805
|
+
* @param {Number} rows The number of rows you want to add to the faux grid.
|
3806
|
+
* @return {Object} Returns the instance of the Gridster class.
|
3807
|
+
*/
|
3808
|
+
fn.add_faux_rows = function(rows) {
|
3809
|
+
var actual_rows = this.rows;
|
3810
|
+
var max_rows = actual_rows + (rows || 1);
|
3811
|
+
|
3812
|
+
for (var r = max_rows; r > actual_rows; r--) {
|
3813
|
+
for (var c = this.cols; c >= 1; c--) {
|
3814
|
+
this.add_faux_cell(r, c);
|
3815
|
+
}
|
3816
|
+
}
|
3817
|
+
|
3818
|
+
this.rows = max_rows;
|
3819
|
+
|
3820
|
+
if (this.options.autogenerate_stylesheet) {
|
3821
|
+
this.generate_stylesheet();
|
3822
|
+
}
|
3823
|
+
|
3824
|
+
return this;
|
3825
|
+
};
|
3826
|
+
|
3827
|
+
/**
|
3828
|
+
* Add cols to the faux grid.
|
3829
|
+
*
|
3830
|
+
* @method add_faux_cols
|
3831
|
+
* @param {Number} cols The number of cols you want to add to the faux grid.
|
3832
|
+
* @return {Object} Returns the instance of the Gridster class.
|
3833
|
+
*/
|
3834
|
+
fn.add_faux_cols = function(cols) {
|
3835
|
+
var actual_cols = this.cols;
|
3836
|
+
var max_cols = actual_cols + (cols || 1);
|
3837
|
+
max_cols = Math.min(max_cols, this.options.max_cols);
|
3838
|
+
|
3839
|
+
for (var c = actual_cols + 1; c <= max_cols; c++) {
|
3840
|
+
for (var r = this.rows; r >= 1; r--) {
|
3841
|
+
this.add_faux_cell(r, c);
|
2787
3842
|
}
|
2788
3843
|
}
|
3844
|
+
|
3845
|
+
this.cols = max_cols;
|
3846
|
+
|
3847
|
+
if (this.options.autogenerate_stylesheet) {
|
3848
|
+
this.generate_stylesheet();
|
3849
|
+
}
|
3850
|
+
|
2789
3851
|
return this;
|
2790
3852
|
};
|
2791
3853
|
|
@@ -2807,7 +3869,6 @@
|
|
2807
3869
|
left: this.baseX + (coords.data.col -1) * this.min_widget_width,
|
2808
3870
|
top: this.baseY + (coords.data.row -1) * this.min_widget_height
|
2809
3871
|
});
|
2810
|
-
|
2811
3872
|
}, this));
|
2812
3873
|
|
2813
3874
|
return this;
|
@@ -2821,9 +3882,21 @@
|
|
2821
3882
|
* @return {Object} Returns the instance of the Gridster class.
|
2822
3883
|
*/
|
2823
3884
|
fn.get_widgets_from_DOM = function() {
|
2824
|
-
this.$widgets.
|
2825
|
-
|
3885
|
+
var widgets_coords = this.$widgets.map($.proxy(function(i, widget) {
|
3886
|
+
var $w = $(widget);
|
3887
|
+
return this.dom_to_coords($w);
|
2826
3888
|
}, this));
|
3889
|
+
|
3890
|
+
widgets_coords = Gridster.sort_by_row_and_col_asc(widgets_coords);
|
3891
|
+
|
3892
|
+
var changes = $(widgets_coords).map($.proxy(function(i, wgd) {
|
3893
|
+
return this.register_widget(wgd) || null;
|
3894
|
+
}, this));
|
3895
|
+
|
3896
|
+
if (changes.length) {
|
3897
|
+
this.$el.trigger('gridster:positionschanged');
|
3898
|
+
}
|
3899
|
+
|
2827
3900
|
return this;
|
2828
3901
|
};
|
2829
3902
|
|
@@ -2837,32 +3910,33 @@
|
|
2837
3910
|
*/
|
2838
3911
|
fn.generate_grid_and_stylesheet = function() {
|
2839
3912
|
var aw = this.$wrapper.width();
|
2840
|
-
var
|
3913
|
+
var max_cols = this.options.max_cols;
|
2841
3914
|
|
2842
3915
|
var cols = Math.floor(aw / this.min_widget_width) +
|
2843
3916
|
this.options.extra_cols;
|
2844
|
-
var rows = Math.floor(ah / this.min_widget_height) +
|
2845
|
-
this.options.extra_rows;
|
2846
3917
|
|
2847
3918
|
var actual_cols = this.$widgets.map(function() {
|
2848
3919
|
return $(this).attr('data-col');
|
2849
|
-
});
|
2850
|
-
actual_cols = Array.prototype.slice.call(actual_cols, 0);
|
2851
|
-
//needed to pass tests with phantomjs
|
2852
|
-
actual_cols.length || (actual_cols = [0]);
|
3920
|
+
}).get();
|
2853
3921
|
|
2854
|
-
var actual_rows = this.$widgets.map(function() {
|
2855
|
-
return $(this).attr('data-row');
|
2856
|
-
});
|
2857
|
-
actual_rows = Array.prototype.slice.call(actual_rows, 0);
|
2858
3922
|
//needed to pass tests with phantomjs
|
2859
|
-
|
3923
|
+
actual_cols.length || (actual_cols = [0]);
|
2860
3924
|
|
2861
3925
|
var min_cols = Math.max.apply(Math, actual_cols);
|
2862
|
-
var min_rows = Math.max.apply(Math, actual_rows);
|
2863
3926
|
|
2864
3927
|
this.cols = Math.max(min_cols, cols, this.options.min_cols);
|
2865
|
-
|
3928
|
+
|
3929
|
+
if (max_cols !== Infinity && max_cols >= min_cols && max_cols < this.cols) {
|
3930
|
+
this.cols = max_cols;
|
3931
|
+
}
|
3932
|
+
|
3933
|
+
// get all rows that could be occupied by the current widgets
|
3934
|
+
var max_rows = this.options.extra_rows;
|
3935
|
+
this.$widgets.each(function(i, w) {
|
3936
|
+
max_rows += (+$(w).attr('data-sizey'));
|
3937
|
+
});
|
3938
|
+
|
3939
|
+
this.rows = Math.max(max_rows, this.options.min_rows);
|
2866
3940
|
|
2867
3941
|
this.baseX = ($(window).width() - aw) / 2;
|
2868
3942
|
this.baseY = this.$wrapper.offset().top;
|
@@ -2871,20 +3945,43 @@
|
|
2871
3945
|
this.generate_stylesheet();
|
2872
3946
|
}
|
2873
3947
|
|
2874
|
-
/* more faux rows that needed are created so that there are cells
|
2875
|
-
* where drag beyond the limits */
|
2876
3948
|
return this.generate_faux_grid(this.rows, this.cols);
|
2877
3949
|
};
|
2878
3950
|
|
3951
|
+
/**
|
3952
|
+
* Destroy this gridster by removing any sign of its presence, making it easy to avoid memory leaks
|
3953
|
+
*
|
3954
|
+
* @method destroy
|
3955
|
+
* @param {Boolean} remove If true, remove gridster from DOM.
|
3956
|
+
* @return {Object} Returns the instance of the Gridster class.
|
3957
|
+
*/
|
3958
|
+
fn.destroy = function(remove) {
|
3959
|
+
this.$el.removeData('gridster');
|
3960
|
+
|
3961
|
+
// remove bound callback on window resize
|
3962
|
+
$(window).unbind('.gridster');
|
3963
|
+
|
3964
|
+
if (this.drag_api) {
|
3965
|
+
this.drag_api.destroy();
|
3966
|
+
}
|
3967
|
+
|
3968
|
+
this.remove_style_tags();
|
3969
|
+
|
3970
|
+
remove && this.$el.remove();
|
3971
|
+
|
3972
|
+
return this;
|
3973
|
+
};
|
3974
|
+
|
2879
3975
|
|
2880
3976
|
//jQuery adapter
|
2881
3977
|
$.fn.gridster = function(options) {
|
2882
|
-
|
2883
|
-
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
3978
|
+
return this.each(function() {
|
3979
|
+
if (! $(this).data('gridster')) {
|
3980
|
+
$(this).data('gridster', new Gridster( this, options ));
|
3981
|
+
}
|
3982
|
+
});
|
2887
3983
|
};
|
2888
3984
|
|
3985
|
+
return Gridster;
|
2889
3986
|
|
2890
|
-
}
|
3987
|
+
}));
|