Skip to content

Commit aa2e453

Browse files
authored
Merge pull request #1519 from adumesny/develop
dragging into a fixed row grid
2 parents c03aed1 + ed14ed1 commit aa2e453

File tree

7 files changed

+252
-146
lines changed

7 files changed

+252
-146
lines changed

doc/CHANGES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Change log
4545

4646
## 3.1.0-dev
4747

48-
- TBD
48+
- fix [1419](https://github.com/gridstack/gridstack.js/issues/1419) dragging into a fixed row grid works better (check if it will fit, else try to append, else won't insert)
4949

5050
## 3.1.0 (2020-12-4)
5151

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<title>1 row max</title>
8+
9+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
10+
<link rel="stylesheet" href="../../../demo/demo.css"/>
11+
12+
<script src="../../../dist/gridstack-h5.js"></script>
13+
14+
<style type="text/css">
15+
.sidebar {
16+
background: rgba(0, 255, 0, 0.1);
17+
height: 150px;
18+
padding: 25px 0;
19+
text-align: center;
20+
}
21+
.sidebar .grid-stack-item {
22+
width: 120px;
23+
height: 50px;
24+
border: 2px dashed green;
25+
text-align: center;
26+
line-height: 35px;
27+
z-index: 10;
28+
background: rgba(0, 255, 0, 0.1);
29+
cursor: default;
30+
display: inline-block;
31+
}
32+
.sidebar .grid-stack-item .grid-stack-item-content {
33+
background: none;
34+
}
35+
</style>
36+
</head>
37+
<body>
38+
<div class="container-fluid">
39+
<p>1 Row max should prevent dragging from outside to push down, only go to empty slot (until we have push right)</p>
40+
41+
<div class="row">
42+
<div class="col-md-3">
43+
<div class="sidebar">
44+
45+
<div class="grid-stack-item" gs-w="2" gs-h="1">
46+
<div class="grid-stack-item-content">Drag me 2x1</div>
47+
</div>
48+
<div class="grid-stack-item" gs-w="1" gs-h="1">
49+
<div class="grid-stack-item-content">Drag me</div>
50+
</div>
51+
52+
</div>
53+
</div>
54+
<div class="col-md-9">
55+
<div class="grid-stack"></div>
56+
</div>
57+
</div>
58+
</div>
59+
<script src="../../../demo/events.js"></script>
60+
<script type="text/javascript">
61+
let options = {
62+
row: 1,
63+
cellHeight: 120,
64+
dragIn: '.sidebar .grid-stack-item', // class that can be dragged from outside
65+
dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper: 'clone' }, // clone
66+
acceptWidgets: true
67+
};
68+
let grid = GridStack.init(options);
69+
addEvents(grid);
70+
grid.addWidget({x: 0});
71+
</script>
72+
</body>
73+
</html>

spec/gridstack-engine-spec.ts

Lines changed: 68 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { GridStackEngine } from '../src/gridstack-engine';
2+
import { GridStackNode } from '../src/types';
23

34
describe('gridstack engine', function() {
45
'use strict';
5-
let engine;
6+
let engine: GridStackEngine;
67
// old hacky JS code that's not happy in TS. just cast to `any` and skip warnings
78
let e: any = GridStackEngine;
89
let w: any = window;
910

1011
let findNode = function(engine, id) {
11-
return engine.nodes.find(function(i) { return i._id === id; });
12+
return engine.nodes.find(function(i) { return i.id === id; });
1213
};
1314

1415
it('should exist setup function.', function() {
@@ -19,24 +20,24 @@ describe('gridstack engine', function() {
1920
describe('test constructor', function() {
2021

2122
it('should be setup properly', function() {
22-
engine = new GridStackEngine(12);
23+
engine = new GridStackEngine();
2324
expect(engine.column).toEqual(12);
2425
expect(engine.float).toEqual(false);
25-
expect(engine.maxRow).toEqual(0);
26+
expect(engine.maxRow).toEqual(undefined);
2627
expect(engine.nodes).toEqual([]);
27-
expect(engine.onchange).toEqual(undefined);
28+
expect(engine.onChange).toEqual(undefined);
2829
expect(engine.batchMode).toEqual(undefined);
2930
});
3031

3132
it('should set params correctly.', function() {
3233
let fkt = function() { };
3334
let arr: any = [1,2,3];
34-
engine = new GridStackEngine(1, fkt, true, 2, arr);
35+
engine = new GridStackEngine({column: 1, onChange:fkt, float:true, maxRow:2, nodes:arr});
3536
expect(engine.column).toEqual(1);
3637
expect(engine.float).toBe(true);
3738
expect(engine.maxRow).toEqual(2);
3839
expect(engine.nodes).toEqual(arr);
39-
expect(engine.onchange).toEqual(fkt);
40+
expect(engine.onChange).toEqual(fkt);
4041
expect(engine.batchMode).toEqual(undefined);
4142
});
4243
});
@@ -54,21 +55,21 @@ describe('gridstack engine', function() {
5455
describe('test prepareNode', function() {
5556

5657
beforeAll(function() {
57-
engine = new GridStackEngine(12);
58+
engine = new GridStackEngine();
5859
});
5960
it('should prepare a node', function() {
60-
expect(engine.prepareNode({}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
61-
expect(engine.prepareNode({x: 10}, false)).toEqual(jasmine.objectContaining({x: 10, y: 0, h: 1}));
62-
expect(engine.prepareNode({x: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
63-
expect(engine.prepareNode({y: 10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 10, h: 1}));
64-
expect(engine.prepareNode({y: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
61+
expect(engine.prepareNode({}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
62+
expect(engine.prepareNode({x: 10}, false)).toEqual(jasmine.objectContaining({x: 10, y: 0, h: 1}));
63+
expect(engine.prepareNode({x: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
64+
expect(engine.prepareNode({y: 10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 10, h: 1}));
65+
expect(engine.prepareNode({y: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
6566
expect(engine.prepareNode({w: 3}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, w: 3, h: 1}));
6667
expect(engine.prepareNode({w: 100}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, w: 12, h: 1}));
67-
expect(engine.prepareNode({w: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
68-
expect(engine.prepareNode({w: -190}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
69-
expect(engine.prepareNode({h: 3}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 3}));
70-
expect(engine.prepareNode({h: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
71-
expect(engine.prepareNode({h: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
68+
expect(engine.prepareNode({w: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
69+
expect(engine.prepareNode({w: -190}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
70+
expect(engine.prepareNode({h: 3}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 3}));
71+
expect(engine.prepareNode({h: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
72+
expect(engine.prepareNode({h: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
7273
expect(engine.prepareNode({x: 4, w: 10}, false)).toEqual(jasmine.objectContaining({x: 2, y: 0, w: 10, h: 1}));
7374
expect(engine.prepareNode({x: 4, w: 10}, true)).toEqual(jasmine.objectContaining({x: 4, y: 0, w: 8, h: 1}));
7475
});
@@ -123,7 +124,7 @@ describe('gridstack engine', function() {
123124
describe('test isAreaEmpty', function() {
124125

125126
beforeAll(function() {
126-
engine = new GridStackEngine(12, null, true);
127+
engine = new GridStackEngine({float:true});
127128
engine.nodes = [
128129
engine.prepareNode({x: 3, y: 2, w: 3, h: 2})
129130
];
@@ -143,11 +144,11 @@ describe('gridstack engine', function() {
143144
describe('test cleanNodes/getDirtyNodes', function() {
144145

145146
beforeAll(function() {
146-
engine = new GridStackEngine(12, null, true);
147+
engine = new GridStackEngine({float:true});
147148
engine.nodes = [
148-
engine.prepareNode({x: 0, y: 0, idx: 1, _dirty: true}),
149-
engine.prepareNode({x: 3, y: 2, w: 3, h: 2, idx: 2, _dirty: true}),
150-
engine.prepareNode({x: 3, y: 7, w: 3, h: 2, idx: 3})
149+
engine.prepareNode({x: 0, y: 0, id: 1, _dirty: true}),
150+
engine.prepareNode({x: 3, y: 2, w: 3, h: 2, id: 2, _dirty: true}),
151+
engine.prepareNode({x: 3, y: 7, w: 3, h: 2, id: 3})
151152
];
152153
});
153154

@@ -158,8 +159,8 @@ describe('gridstack engine', function() {
158159
it('should return all dirty nodes', function() {
159160
let nodes = engine.getDirtyNodes();
160161
expect(nodes.length).toEqual(2);
161-
expect(nodes[0].idx).toEqual(1);
162-
expect(nodes[1].idx).toEqual(2);
162+
expect(nodes[0].id).toEqual(1);
163+
expect(nodes[1].id).toEqual(2);
163164
});
164165

165166
it('should\'n clean nodes if batchMode true', function() {
@@ -176,7 +177,7 @@ describe('gridstack engine', function() {
176177

177178
describe('test batchUpdate/commit', function() {
178179
beforeAll(function() {
179-
engine = new GridStackEngine(12);
180+
engine = new GridStackEngine();
180181
});
181182

182183
it('should work on not float grids', function() {
@@ -205,7 +206,7 @@ describe('gridstack engine', function() {
205206
describe('test batchUpdate/commit', function() {
206207

207208
beforeAll(function() {
208-
engine = new GridStackEngine(12, null, true);
209+
engine = new GridStackEngine({float:true});
209210
});
210211

211212
it('should work on float grids', function() {
@@ -227,31 +228,31 @@ describe('gridstack engine', function() {
227228
callback: function() {}
228229
};
229230
spyOn(spy, 'callback');
230-
engine = new GridStackEngine(12, spy.callback, true);
231+
engine = new GridStackEngine({float:true, onChange: spy.callback});
231232
engine.nodes = [
232-
engine.prepareNode({x: 0, y: 0, idx: 1, _dirty: true}),
233-
engine.prepareNode({x: 3, y: 2, w: 3, h: 2, idx: 2, _dirty: true}),
234-
engine.prepareNode({x: 3, y: 7, w: 3, h: 2, idx: 3})
233+
engine.prepareNode({x: 0, y: 0, id: 1, _dirty: true}),
234+
engine.prepareNode({x: 3, y: 2, w: 3, h: 2, id: 2, _dirty: true}),
235+
engine.prepareNode({x: 3, y: 7, w: 3, h: 2, id: 3})
235236
];
236237
});
237238

238239
it('should\'n be called if batchMode true', function() {
239240
engine.batchMode = true;
240-
engine._notify();
241+
(engine as any)._notify();
241242
expect(spy.callback).not.toHaveBeenCalled();
242243
});
243244

244245
it('should by called with dirty nodes', function() {
245-
engine._notify();
246+
(engine as any)._notify();
246247
expect(spy.callback).toHaveBeenCalledWith([
247248
engine.nodes[0],
248249
engine.nodes[1]
249250
], true);
250251
});
251252

252253
it('should by called with extra passed node to be removed', function() {
253-
let n1 = {idx: -1};
254-
engine._notify(n1);
254+
let n1 = {id: -1};
255+
(engine as any)._notify(n1);
255256
expect(spy.callback).toHaveBeenCalledWith([
256257
n1,
257258
engine.nodes[0],
@@ -260,8 +261,8 @@ describe('gridstack engine', function() {
260261
});
261262

262263
it('should by called with extra passed node to be removed and should maintain false parameter', function() {
263-
let n1 = {idx: -1};
264-
engine._notify(n1, false);
264+
let n1 = {id: -1};
265+
(engine as any)._notify(n1, false);
265266
expect(spy.callback).toHaveBeenCalledWith([
266267
n1,
267268
engine.nodes[0],
@@ -273,62 +274,62 @@ describe('gridstack engine', function() {
273274
describe('test _packNodes', function() {
274275
describe('using not float mode', function() {
275276
beforeEach(function() {
276-
engine = new GridStackEngine(12, null, false);
277+
engine = new GridStackEngine({float:false});
277278
});
278279

279280
it('shouldn\'t pack one node with y coord eq 0', function() {
280281
engine.nodes = [
281-
{x: 0, y: 0, w:1, h:1,_id: 1},
282+
{x: 0, y: 0, w:1, h:1, id: 1},
282283
];
283-
engine._packNodes();
284-
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
284+
(engine as any)._packNodes();
285+
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 0, h: 1}));
285286
expect(findNode(engine, 1)._dirty).toBeFalsy();
286287
});
287288

288289
it('should pack one node correctly', function() {
289290
engine.nodes = [
290-
{x: 0, y: 1, w:1, h:1,_id: 1},
291+
{x: 0, y: 1, w:1, h:1, id: 1},
291292
];
292-
engine._packNodes();
293-
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 0, _dirty: true}));
293+
(engine as any)._packNodes();
294+
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 0, _dirty: true}));
294295
});
295296

296297
it('should pack nodes correctly', function() {
297298
engine.nodes = [
298-
{x: 0, y: 1, w:1, h:1,_id: 1},
299-
{x: 0, y: 5, w:1, h:1,_id: 2},
299+
{x: 0, y: 1, w:1, h:1, id: 1},
300+
{x: 0, y: 5, w:1, h:1, id: 2},
300301
];
301-
engine._packNodes();
302-
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 0, _dirty: true}));
303-
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 0, y: 1, _dirty: true}));
302+
(engine as any)._packNodes();
303+
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 0, _dirty: true}));
304+
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 0, y: 1, _dirty: true}));
304305
});
305306

306307
it('should pack nodes correctly', function() {
307308
engine.nodes = [
308-
{x: 0, y: 5, w:1, h:1,_id: 1},
309-
{x: 0, y: 1, w:1, h:1,_id: 2},
309+
{x: 0, y: 5, w:1, h:1, id: 1},
310+
{x: 0, y: 1, w:1, h:1, id: 2},
310311
];
311-
engine._packNodes();
312-
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 0, y: 0, _dirty: true}));
313-
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, _dirty: true}));
312+
(engine as any)._packNodes();
313+
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 0, y: 0, _dirty: true}));
314+
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, _dirty: true}));
314315
});
315316

316317
it('should respect locked nodes', function() {
317318
engine.nodes = [
318-
{x: 0, y: 1, w:1, h:1,_id: 1, locked: true},
319-
{x: 0, y: 5, w:1, h:1,_id: 2},
319+
{x: 0, y: 1, w:1, h:1, id: 1, locked: true},
320+
{x: 0, y: 5, w:1, h:1, id: 2},
320321
];
321-
engine._packNodes();
322-
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, h: 1}));
322+
(engine as any)._packNodes();
323+
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, h: 1}));
323324
expect(findNode(engine, 1)._dirty).toBeFalsy();
324-
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 0, y: 2, _dirty: true}));
325+
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 0, y: 2, _dirty: true}));
325326
});
326327
});
327328
});
328329

329330
describe('test isNodeChangedPosition', function() {
330331
beforeAll(function() {
331-
engine = new GridStackEngine(12);
332+
engine = new GridStackEngine();
332333
});
333334
it('should return true for changed x', function() {
334335
let widget = { x: 1, y: 2, w: 3, h: 4 };
@@ -354,19 +355,19 @@ describe('gridstack engine', function() {
354355

355356
describe('test locked widget', function() {
356357
beforeAll(function() {
357-
engine = new GridStackEngine(12);
358+
engine = new GridStackEngine();
358359
});
359360
it('should add widgets around locked one', function() {
360-
let nodes = [
361-
{x: 0, y: 1, w: 12, h: 1, locked: 'yes', noMove: true, noResize: true, _id: 1},
362-
{x: 1, y: 0, w: 2, h: 3, _id: 2}
361+
let nodes: GridStackNode[] = [
362+
{x: 0, y: 1, w: 12, h: 1, locked: true, noMove: true, noResize: true, id: 1},
363+
{x: 1, y: 0, w: 2, h: 3, id: 2}
363364
];
364365
// add locked item
365366
engine.addNode(nodes[0])
366-
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, w: 12, h: 1, locked: 'yes'}));
367+
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, w: 12, h: 1, locked: true}));
367368
engine.addNode(nodes[1])
368369
// add item that moves past locked one
369-
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, w: 12, h: 1, locked: 'yes'}));
370+
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, w: 12, h: 1, locked: true}));
370371
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 1, y: 2}));
371372
// prevents moving locked item
372373
let node1 = findNode(engine, 1);
@@ -382,7 +383,7 @@ describe('gridstack engine', function() {
382383

383384
describe('test compact', function() {
384385
beforeAll(function() {
385-
engine = new GridStackEngine(12);
386+
engine = new GridStackEngine();
386387
});
387388
it('do nothing', function() {
388389
engine.compact();

0 commit comments

Comments
 (0)