Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Join us on Slack: https://gridstackjs.troolee.com
- [Requirements](#requirements)
- [API Documentation](#api-documentation)
- [Extend Library](#extend-library)
- [Extend Engine](#extend-engine)
- [Change grid columns](#change-grid-columns)
- [Custom columns CSS](#custom-columns-css)
- [Override resizable/draggable options](#override-resizabledraggable-options)
Expand Down Expand Up @@ -186,6 +187,27 @@ let grid = GridStack.init();
grid.printCount();
```

## Extend Engine

You can now (5.1+) easily create your own layout engine to further customize you usage. Here is a typescript example

```ts
import { GridStack, GridStackEngine, GridStackNod, GridStackMoveOpts } from 'gridstack';

class CustomEngine extends GridStackEngine {

/** refined this to move the node to the given new location */
public moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean {
// keep the same original X and Width and let base do it all...
o.x = node.x;
o.w = node.w;
return super.moveNode(node, o);
}
}

GridStack.registerEngine(CustomEngine); // globally set our custom class
```

## Change grid columns

GridStack makes it very easy if you need [1-12] columns out of the box (default is 12), but you always need **2 things** if you need to customize this:
Expand Down
75 changes: 75 additions & 0 deletions demo/custom-engine.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Custom Engine</title>

<link rel="stylesheet" href="demo.css"/>
<!-- <script src="../dist/gridstack-h5.js"></script> -->
<script src="events.js"></script>
</head>
<body>
<div class="container-fluid">
<h1>Custom Engine</h1>
<p>shows a custom engine subclass in Typescript that only allows objects to move vertically.</p>
<div>
<a class="btn btn-primary" onClick="addNewWidget()" href="#">Add Widget</a>
<a class="btn btn-primary" onclick="toggleFloat()" id="float" href="#">float: true</a>
</div>
<br><br>
<div class="grid-stack"></div>
</div>

<script type="module" > // so we can use import
// get CORS error in Chrome...need to have http://localhost/ URL - see https://stackoverflow.com/questions/50197495/javascript-modules-and-cors
import { GridStack, GridStackEngine } from '../dist/gridstack-h5.js';

/**
* Custom engine class that only allows vertical movement and resizing
*/
class CustomEngine extends GridStackEngine {
/** refined this to move the node to the given new location */
moveNode(node, o) {
// keep the same original X and Width and let base do it all...
o.x = node.x;
o.w = node.w;
return super.moveNode(node, o);
}
}
GridStack.registerEngine(CustomEngine); // globally set our custom class

let count = 0;
let items = [
{x: 0, y: 0},
{x: 1, y: 0},
{x: 1, y: 2, w: 3},
];
items.forEach(n => n.content = String(count++));

let grid = GridStack.init({
float: true,
disableOneColumnMode: true,
cellHeight: 70
}).load(items);
addEvents(grid);

let addNewWidget = function() {
let n = items[count] || {
x: Math.round(12 * Math.random()),
y: Math.round(5 * Math.random()),
w: Math.round(1 + 3 * Math.random()),
h: Math.round(1 + 3 * Math.random())
};
n.content = n.content || String(count++);
grid.addWidget(n);
};

let toggleFloat = function() {
grid.float(! grid.getFloat());
document.querySelector('#float').innerHTML = 'float: ' + grid.getFloat();
};
</script>
</body>
</html>
1 change: 1 addition & 0 deletions doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Change log


## 5.0.0-dev (TBD)
* add `GridStack.registerEngine()` to let user use their own custom layout engine subclass. Thank you [Thomas] for sponsoring it.

## 5.0.0 (2022-01-10)
* add [#992](https://github.com/gridstack/gridstack.js/issues/992) support dragging into and out of nested grids from parents! Thank you [@arclogos132](https://github.com/arclogos132) for sponsoring it.
Expand Down
6 changes: 6 additions & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ gridstack.js API
- [`initAll(options: GridStackOptions = {}, selector = '.grid-stack'): GridStack[]`](#initalloptions-gridstackoptions---selector--grid-stack-gridstack)
- [`addGrid(parent: HTMLElement, opt: GridStackOptions = {}): GridStack `](#addgridparent-htmlelement-opt-gridstackoptions---gridstack-)
- [`setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt)`](#setupdragindragin-string-draginoptions-dddraginopt)
- [`GridStack.registerEngine(engineClass: typeof GridStackEngine)`](#gridstackregisterengineengineclass-typeof-gridstackengine)
- [API](#api)
- [`addWidget(el?: GridStackWidget | GridStackElement, options?: GridStackWidget)`](#addwidgetel-gridstackwidget--gridstackelement-options-gridstackwidget)
- [`batchUpdate()`](#batchupdate)
Expand Down Expand Up @@ -100,6 +101,7 @@ gridstack.js API
* **Note2**: instead of 'clone' you can also pass your own function (get passed the event).
- `draggable` - allows to override draggable options. (default: `{handle: '.grid-stack-item-content', scroll: false, appendTo: 'body', containment: null}`)
- `dragOut` to let user drag nested grid items out of a parent or not (default false) See [example](http://gridstackjs.com/demo/nested.html)
- `engineClass` - the type of engine to create (so you can subclass) default to GridStackEngine
- `float` - enable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html)
- `handle` - draggable handle selector (default: `'.grid-stack-item-content'`)
- `handleClass` - draggable handle class (e.g. `'grid-stack-item-content'`). If set `handle` is ignored (default: `null`)
Expand Down Expand Up @@ -321,6 +323,10 @@ Called during `GridStack.init()` as options, but can also be called directly (la
* @param dragInOptions options - see `DDDragInOpt`. (default: `{revert: 'invalid', handle: '.grid-stack-item-content', scroll: false, appendTo: 'body'}`
but you will probably also want `helper: 'clone'` or your own callback function).


### `GridStack.registerEngine(engineClass: typeof GridStackEngine)`

* call to specify global custom engine subclass - see instead `GridStackOptions.engineClass` if you only need to replace just one instance.
## API

### `addWidget(el?: GridStackWidget | GridStackElement, options?: GridStackWidget)`
Expand Down
8 changes: 1 addition & 7 deletions src/gridstack-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,14 +622,8 @@ export class GridStackEngine {
if (Utils.samePos(node, o)) return false;
let prevPos: GridStackPosition = Utils.copyPos({}, node);

// during while() collisions make sure to check entire row so larger items don't leap frog small ones (push them all down)
let area = nn;
// if (this._useEntireRowArea(node, nn)) {
// area = {x: 0, w: this.column, y: nn.y, h: nn.h};
// }

// check if we will need to fix collision at our new location
let collides = this.collideAll(node, area, o.skip);
let collides = this.collideAll(node, nn, o.skip);
let needToMove = true;
if (collides.length) {
// now check to make sure we actually collided over 50% surface area while dragging
Expand Down
13 changes: 12 additions & 1 deletion src/gridstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ export class GridStack {
return grid;
}

/** call this method to register your engine instead of the default one.
* See instead `GridStackOptions.engineClass` if you only need to
* replace just one instance.
*/
static registerEngine(engineClass: typeof GridStackEngine) {
GridStack.engineClass = engineClass;
}

/** scoping so users can call GridStack.Utils.sort() for example */
public static Utils = Utils;

Expand All @@ -194,6 +202,8 @@ export class GridStack {
/** grid options - public for classes to access, but use methods to modify! */
public opts: GridStackOptions;

protected static engineClass: typeof GridStackEngine;

/** @internal create placeholder DIV as needed */
public get placeholder(): HTMLElement {
if (!this._placeholder) {
Expand Down Expand Up @@ -321,7 +331,8 @@ export class GridStack {

this._setStaticClass();

this.engine = new GridStackEngine({
let engineClass = this.opts.engineClass || GridStack.engineClass || GridStackEngine;
this.engine = new engineClass({
column: this.getColumn(),
float: this.opts.float,
maxRow: this.opts.maxRow,
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { GridStack } from './gridstack';
import { GridStackEngine } from './gridstack-engine';


/** different layout options when changing # of columns,
Expand Down Expand Up @@ -105,6 +106,9 @@ export interface GridStackOptions {
/** let user drag nested grid items out of a parent or not (default false) */
dragOut?: boolean;

/** the type of engine to create (so you can subclass) default to GridStackEngine */
engineClass?: typeof GridStackEngine;

/** enable floating widgets (default?: false) See example (http://gridstack.github.io/gridstack.js/demo/float.html) */
float?: boolean;

Expand Down