Skip to content

Commit b4ce41c

Browse files
committed
column(n) re-layout options to not scale/move
* fix for #1338 and likely #1332 * add `LayoutOptions` to `column()` for multiple re-layout options, including 'none' that will preserve the x and width, until out of bound/overlap * Possible values: 'moveScale' | 'move' | 'scale' | 'none' * update demos to have dropdown choices, and test cases
1 parent 967faf0 commit b4ce41c

File tree

9 files changed

+81
-33
lines changed

9 files changed

+81
-33
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,12 +344,13 @@ grid.on('added', function(e, items) {/* items contains info */});
344344
var grid = el.gridstack; // where el = document.querySelector('.grid-stack') or other ways...
345345
```
346346
Other changes
347-
```
347+
348+
```js
348349
`GridStackUI` --> `GridStack`
349350
`GridStackUI.GridStackEngine` --> `GridStack.Engine`
350-
`grid.container` (jquery grid wrapper) --> `grid.el` (grid DOM element)
351+
`grid.container` (jquery grid wrapper) --> `grid.el` // (grid DOM element)
351352
`grid.grid` (GridStackEngine) --> `grid.engine`
352-
`grid.setColumn(N)` --> `grid.column(N)` and new `grid.column()` to get value, old API still supported though
353+
`grid.setColumn(N)` --> `grid.column(N)` and `grid.column()` // to get value, old API still supported though
353354
```
354355
355356
Recommend looking at the [many samples](./demo) for more code examples.

demo/column.html

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414
<div class="container-fluid">
1515
<h1>column() grid demo</h1>
1616
<div><span>Number of Columns:</span> <span id="column-text">12</span></div>
17+
<div>
18+
<label>Choose re-layout:</label>
19+
<select onchange="layout = this.value">
20+
<option value="moveScale">move + scale</option>
21+
<option value="move">move</option>
22+
<option value="scale">scale</option>
23+
<option value="none">none</option>
24+
</select>
25+
</div>
1726
<div>
1827
<a onClick="addWidget()" class="btn btn-primary" href="#">Add Widget</a>
1928
<a onClick="setOneColumn(false)" class="btn btn-primary" href="#">1 Column</a>
@@ -33,6 +42,7 @@ <h1>column() grid demo</h1>
3342
<script type="text/javascript">
3443
let grid = GridStack.init({float: true});
3544
let text = document.querySelector('#column-text');
45+
let layout = 'moveScale';
3646

3747
grid.on('added removed change', function(e, items) {
3848
let str = '';
@@ -73,12 +83,12 @@ <h1>column() grid demo</h1>
7383
};
7484

7585
function column(n) {
76-
grid.column(n);
86+
grid.column(n, layout);
7787
text.innerHTML = n;
7888
}
7989
function setOneColumn(dom) {
8090
grid.opts.oneColumnModeDomSort = dom;
81-
grid.column(1);
91+
grid.column(1, layout);
8292
text.innerHTML = dom ? '1 DOM' : '1';
8393
}
8494

demo/responsive.html

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ <h1>Responsive grid demo</h1>
1313
<div>
1414
<span>Number of Columns:</span> <span id="column-text"></span>
1515
</div>
16+
<div>
17+
<label>Choose re-layout:</label>
18+
<select onchange="layout = this.value">
19+
<option value="moveScale">move + scale</option>
20+
<option value="move">move</option>
21+
<option value="scale">scale</option>
22+
<option value="none">none</option>
23+
</select>
24+
</div>
1625
<br/>
1726
<div class="grid-stack">
1827
</div>
@@ -23,23 +32,24 @@ <h1>Responsive grid demo</h1>
2332
disableOneColumnMode: true, // will manually do 1 column
2433
float: true });
2534
let text = document.querySelector('#column-text');
35+
let layout = 'moveScale';
2636

2737
function resizeGrid() {
2838
let width = document.body.clientWidth;
2939
if (width < 700) {
30-
grid.column(1);
40+
grid.column(1, layout);
3141
text.innerHTML = 1;
3242
} else if (width < 850) {
33-
grid.column(3);
43+
grid.column(3, layout);
3444
text.innerHTML = 3;
3545
} else if (width < 950) {
36-
grid.column(6);
46+
grid.column(6, layout);
3747
text.innerHTML = 6;
3848
} else if (width < 1100) {
39-
grid.column(8);
49+
grid.column(8, layout);
4050
text.innerHTML = 8;
4151
} else {
42-
grid.column(12);
52+
grid.column(12, layout);
4353
text.innerHTML = 12;
4454
}
4555
};

doc/CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Also fixed JQ draggable warning if not initialized first [858](https://github.co
4646
- add `addWidget(opt)` now handles just passing a `GridStackWidget` which creates the default divs, simplifying your code. Old API still supported.
4747
- add `save(saveContent = true)` now lets you optionally save the HTML content in the node property, with load() restoring it [1418](https://github.com/gridstack/gridstack.js/issues/1418)
4848
- add `GridStackWidget.content` now lets you add any HTML content when calling `load()/save()` or `addWidget()` [1418](https://github.com/gridstack/gridstack.js/issues/1418)
49+
- add `LayoutOptions` to `column()` for multiple re-layout options, including 'none' that will preserve the x and width, until out of bound/overlap [1338](https://github.com/gridstack/gridstack.js/issues/1338)
4950

5051
## 2.0.2 (2020-10-05)
5152

doc/README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ gridstack.js API
2121
- [resizestart(event, el)](#resizestartevent-el)
2222
- [resizestop(event, el)](#resizestopevent-el)
2323
- [API](#api)
24-
- [addWidget(el, [options])](#addwidgetel-options)
24+
- [addWidget(el?: GridStackWidget | GridStackElement, options?: GridStackWidget)](#addwidgetel-gridstackwidget--gridstackelement-options-gridstackwidget)
2525
- [batchUpdate()](#batchupdate)
2626
- [compact()](#compact)
2727
- [cellHeight(val: number, update = true)](#cellheightval-number-update--true)
2828
- [cellWidth()](#cellwidth)
2929
- [commit()](#commit)
30-
- [column(column, doNotPropagate)](#columncolumn-donotpropagate)
30+
- [column(column: number, layout: LayoutOptions = 'moveScale')](#columncolumn-number-layout-layoutoptions--movescale)
3131
- [destroy([removeDOM])](#destroyremovedom)
3232
- [disable()](#disable)
3333
- [enable()](#enable)
@@ -53,7 +53,7 @@ gridstack.js API
5353
- [removeAll(removeDOM = true)](#removeallremovedom--true)
5454
- [resize(el, width, height)](#resizeel-width-height)
5555
- [resizable(el, val)](#resizableel-val)
56-
- [save(): GridStackWidget[]](#save-gridstackwidget)
56+
- [save(saveContent = true): GridStackWidget[]](#savesavecontent--true-gridstackwidget)
5757
- [setAnimation(doAnimate)](#setanimationdoanimate)
5858
- [setStatic(staticValue)](#setstaticstaticvalue)
5959
- [update(el, x, y, width, height)](#updateel-x-y-width-height)
@@ -298,15 +298,17 @@ Gets current cell width (grid width / # of columns).
298298

299299
Ends batch updates. Updates DOM nodes. You must call it after `batchUpdate()`.
300300

301-
### column(column, doNotPropagate)
301+
### column(column: number, layout: LayoutOptions = 'moveScale')
302302

303303
set/get the number of columns in the grid. Will update existing widgets to conform to new number of columns,
304304
as well as cache the original layout so you can revert back to previous positions without loss.
305305
Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],
306306
else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)
307307

308308
- `column` - Integer > 0 (default 12), if missing it will return the current count instead.
309-
- `doNotPropagate` - if true existing widgets will not be updated during a set.
309+
- `layout` - specify the type of re-layout that will happen (position, size, etc...).
310+
Note: items will never be outside of the current column boundaries. default ('moveScale'). Ignored for 1 column.
311+
Possible values: 'moveScale' | 'move' | 'scale' | 'none'
310312

311313
### destroy([removeDOM])
312314

spec/gridstack-spec.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,7 @@ describe('gridstack', function() {
252252
};
253253
let grid = GridStack.init(options);
254254
let items = $('.grid-stack-item');
255-
grid.column(10, false);
256-
expect(grid.getColumn()).toBe(10);
257-
for (let j = 0; j < items.length; j++) {
258-
expect(parseInt($(items[j]).attr('data-gs-y'), 10)).toBe(0);
259-
}
260-
grid.column(9, true);
255+
grid.column(9);
261256
expect(grid.getColumn()).toBe(9);
262257
for (let j = 0; j < items.length; j++) {
263258
expect(parseInt($(items[j]).attr('data-gs-y'), 10)).toBe(0);
@@ -268,7 +263,28 @@ describe('gridstack', function() {
268263
expect(parseInt($(items[j]).attr('data-gs-y'), 10)).toBe(0);
269264
}
270265
});
271-
it('should change column number and relayout items', function() {
266+
it('no sizing, no moving', function() {
267+
let grid = GridStack.init({column: 12});
268+
let items = $('.grid-stack-item');
269+
grid.column(8, 'none');
270+
expect(grid.getColumn()).toBe(8);
271+
for (let j = 0; j < items.length; j++) {
272+
expect(parseInt($(items[j]).attr('data-gs-width'), 10)).toBe(4);
273+
expect(parseInt($(items[j]).attr('data-gs-y'), 10)).toBe(0);
274+
}
275+
});
276+
it('no sizing, but moving down', function() {
277+
let grid = GridStack.init({column: 12});
278+
let items = $('.grid-stack-item');
279+
grid.column(7, 'none');
280+
expect(grid.getColumn()).toBe(7);
281+
for (let j = 0; j < items.length; j++) {
282+
expect(parseInt($(items[j]).attr('data-gs-width'), 10)).toBe(4);
283+
}
284+
expect(parseInt($(items[0]).attr('data-gs-y'), 10)).toBe(0);
285+
expect(parseInt($(items[1]).attr('data-gs-y'), 10)).toBe(2);
286+
});
287+
it('should change column number and re-layout items', function() {
272288
let options = {
273289
column: 12,
274290
float: true

src/gridstack-engine.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import { Utils, obsolete } from './utils';
10-
import { GridStackNode, GridStackWidget } from './types';
10+
import { GridStackNode, LayoutOptions } from './types';
1111

1212
export type onChangeCB = (nodes: GridStackNode[], removeDOM?: boolean) => void;
1313

@@ -534,8 +534,10 @@ export class GridStackEngine {
534534
* @param oldColumn previous number of columns
535535
* @param column new column number
536536
* @param nodes different sorted list (ex: DOM order) instead of current list
537+
* @param layout specify the type of re-layout that will happen (position, size, etc...).
538+
* Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column
537539
*/
538-
public updateNodeWidths(oldColumn: number, column: number, nodes: GridStackNode[]): GridStackEngine {
540+
public updateNodeWidths(oldColumn: number, column: number, nodes: GridStackNode[], layout: LayoutOptions = 'moveScale'): GridStackEngine {
539541
if (!this.nodes.length || oldColumn === column) { return this }
540542

541543
// cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data
@@ -594,10 +596,13 @@ export class GridStackEngine {
594596
});
595597
// ...and add any extra non-cached ones
596598
let ratio = column / oldColumn;
599+
let move = layout === 'move' || layout === 'moveScale';
600+
let scale = layout === 'scale' || layout === 'moveScale';
597601
nodes.forEach(node => {
598602
if (!node) return this;
599-
node.x = (column === 1 ? 0 : Math.round(node.x * ratio));
600-
node.width = ((column === 1 || oldColumn === 1) ? 1 : (Math.round(node.width * ratio) || 1));
603+
node.x = (column === 1 ? 0 : (move ? Math.round(node.x * ratio) : Math.min(node.x, column - 1)));
604+
node.width = ((column === 1 || oldColumn === 1) ? 1 :
605+
scale ? (Math.round(node.width * ratio) || 1) : (Math.min(node.width, column)));
601606
newNodes.push(node);
602607
});
603608

src/gridstack.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import { GridStackEngine } from './gridstack-engine';
1010
import { obsoleteOpts, obsoleteOptsDel, obsoleteAttr, obsolete, Utils } from './utils';
11-
import { GridItemHTMLElement, GridStackWidget, GridStackNode, GridStackOptions, numberOrString } from './types';
11+
import { GridItemHTMLElement, GridStackWidget, GridStackNode, GridStackOptions, numberOrString, LayoutOptions } from './types';
1212
import { GridStackDD } from './gridstack-dd';
1313

1414
// export all dependent file as well to make it easier for users to just import the main file
@@ -510,12 +510,13 @@ export class GridStack {
510510
/**
511511
* set the number of columns in the grid. Will update existing widgets to conform to new number of columns,
512512
* as well as cache the original layout so you can revert back to previous positions without loss.
513-
* Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [1-11],
513+
* Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],
514514
* else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)
515515
* @param column - Integer > 0 (default 12).
516-
* @param doNotPropagate if true existing widgets will not be updated (optional)
516+
* @param layout specify the type of re-layout that will happen (position, size, etc...).
517+
* Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column
517518
*/
518-
public column(column: number, doNotPropagate?: boolean): GridStack {
519+
public column(column: number, layout: LayoutOptions = 'moveScale'): GridStack {
519520
if (this.opts.column === column) { return this; }
520521
let oldColumn = this.opts.column;
521522

@@ -531,8 +532,6 @@ export class GridStack {
531532
this.el.classList.add('grid-stack-' + column);
532533
this.opts.column = this.engine.column = column;
533534

534-
if (doNotPropagate === true) { return this; }
535-
536535
// update the items now - see if the dom order nodes should be passed instead (else default to current list)
537536
let domNodes: GridStackNode[] = undefined; // explicitly leave not defined
538537
if (column === 1 && this.opts.oneColumnModeDomSort) {
@@ -542,7 +541,7 @@ export class GridStack {
542541
});
543542
if (!domNodes.length) { domNodes = undefined; }
544543
}
545-
this.engine.updateNodeWidths(oldColumn, column, domNodes);
544+
this.engine.updateNodeWidths(oldColumn, column, domNodes, layout);
546545

547546
// and trigger our event last...
548547
this._triggerChangeEvent(true); // skip layout update

src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
import { GridStack } from './gridstack';
1010
import { GridStackDD } from './gridstack-dd';
1111

12+
13+
/** different layout options when changing # of columns and other re-layouts */
14+
export type LayoutOptions = 'moveScale' | 'move' | 'scale' | 'none';
15+
1216
export type numberOrString = number | string;
1317
export interface GridItemHTMLElement extends HTMLElement {
1418
/** pointer to grid node instance */

0 commit comments

Comments
 (0)