Responsive & Fluid Drag-and-Drop Grid Layout with jQuery - gridstack.js

Responsive & Fluid Drag-and-Drop Grid Layout with jQuery - gridstack.js
File Size: 145 KB
Views Total:
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   

Gridstack.js is a jQuery widget/grid layout plugin inspired by Gridster that allows you to dynamically and responsively rearrange grid items through drag and drop.

More features:

  • Also supports touch events.
  • Resizable grid items.
  • Supports nested grid items.
  • Compatible with Bootstrap 3/4 framework.

View more:

Dependencies:

Basic Usage:

1. Include the required stylesheet in the head section of the document.

<!-- Local -->
<link href="/path/to/gridstack.css" rel="stylesheet" />
<!-- Or From A CDN -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/gridstack.min.css" />

2. Include the jQuery Gridstack.js plugin and other required resources at the end of the document.

<!-- Dependencies -->
<script src="/path/to/cdn/jquery.min.js"></script>
<script src="/path/to/cdn/jquery-ui.min.js"></script>
<script src="/path/to/cdn/jquery.ui.touch-punch.min.js"></script>

<!-- jQuery Gridstack.js -->
<script src="gridstack.all.js"></script>
<!-- Or from a CDN -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gridstack.all.js"></script>
<!-- Polyfill for old IE -->
<script src="gridstack.poly.js"></script>

3. Create a sample draggable grid layout as follows.

  • data-gs-animate: turns animation on (for grid)
  • data-gs-column: amount of columns (for grid)
  • data-gs-max-row: maximum rows amount, defaults to 0 (for grid)
  • data-gs-current-height: current rows amount (for grid)
  • data-gs-id: unique ID (for item)
  • data-gs-x, data-gs-y: element position (for item)
  • data-gs-width, data-gs-height: element size (for item)
  • data-gs-max-width, data-gs-min-width, data-gs-max-height, data-gs-min-height: element constraints (for item)
  • data-gs-no-resize: disable element resizing (for item)
  • data-gs-no-move: disable element moving (for item)
  • data-gs-auto-position: tells to ignore data-gs-x and data-gs-y attributes and to place element to the first available position (for item)
  • data-gs-locked: the widget will be locked. It means another widgets couldn't move it during dragging or resizing. The widget is still can be dragged or resized. You need to add data-gs-no-resize and data-gs-no-move attributes to completely lock the widget (for item)
  • data-gs-resize-handles: resize handles (for item)
<div class="grid-stack" data-gs-width="12">
  <div class="grid-stack-item" data-gs-x="0" data-gs-y="0" data-gs-width="4" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  </div>
  <div class="grid-stack-item" data-gs-x="4" data-gs-y="0" data-gs-width="4" data-gs-height="4">
    <div class="grid-stack-item-content"></div>
  </div>
  <div class="grid-stack-item" data-gs-x="8" data-gs-y="0" data-gs-width="2" data-gs-height="2" data-gs-min-width="2" data-gs-no-resize="yes">
    <div class="grid-stack-item-content"> <span class="fa fa-hand-o-up"></span> Drag me! </div>
  </div>
  <div class="grid-stack-item" data-gs-x="10" data-gs-y="0" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  </div>
  <div class="grid-stack-item" data-gs-x="0" data-gs-y="4" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  </div>
  <div class="grid-stack-item" data-gs-x="2" data-gs-y="4" data-gs-width="2" data-gs-height="4">
    <div class="grid-stack-item-content"></div>
  </div>
  <div class="grid-stack-item" data-gs-x="8" data-gs-y="4" data-gs-width="4" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  </div>
  <div class="grid-stack-item" data-gs-x="0" data-gs-y="6" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  </div>
  <div class="grid-stack-item" data-gs-x="4" data-gs-y="6" data-gs-width="4" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  </div>
  <div class="grid-stack-item" data-gs-x="8" data-gs-y="6" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  </div>
  <div class="grid-stack-item" data-gs-x="10" data-gs-y="6" data-gs-width="2" data-gs-height="2">
    <div class="grid-stack-item-content"></div>
  </div>
</div>

4. Call the plugin and create a responsive & fluid 12 columns grid layout.

$(function () {
  $('.grid-stack').gridstack({
    column: 12
  });
});

5. All possible options and defaults available.

$('.grid-stack').gridstack({

  // turns animation on
  animate: false,

  // amount of columns
  column: 12,

  // max number rows
  maxRow: 0,

  // maximum rows amount
  height: 0, 

  // widget class
  itemClass: 'grid-stack-item',

  // class for placeholder
  placeholderClass: 'grid-stack-placeholder',

  // text for placeholder
  placeholderText: '',

  // draggable handle selector
  handle: '.grid-stack-item-content',

  // class for handle
  handleClass: null,

  // one cell height
  cellHeight: 60,

  // vertical gap size
  verticalMargin: 20,

  // unit
  verticalMarginUnit: 'px',
  cellHeightUnit: 'px',

  // if false it tells to do not initialize existing items
  auto: true,
  
  // minimal width.
  minWidth: 768,

  // enable floating widgets
  float: false,

  // makes grid static
  staticGrid: false,

  // if true the resizing handles are shown even the user is not hovering over the widget
  alwaysShowResizeHandle: false,

  // allows to owerride jQuery UI draggable options
  draggable: {handle: '.grid-stack-item-content', scroll: true, appendTo: 'body'},

  // let user drag nested grid items out of a parent or not
  dragOut: false,

  // allows to owerride jQuery UI resizable options
  resizable: {autoHide: true, handles: 'se'},

  // disallows dragging of widgets
  disableDrag: false

  // disallows resizing of widgets
  disableResize: false,

  // if `true` turns grid to RTL. 
  // Possible values are `true`, `false`, `'auto'`
  rtl: 'auto',

  // if `true` widgets could be removed by dragging outside of the grid
  removable: false,

  // time in milliseconds before widget is being removed while dragging outside of the grid
  removeTimeout: 2000,

  // CSS class when in one column mode
  disableOneColumnMode: 'grid-stack-one-column-mode',

  // class that implement drag'n'drop functionallity for gridstack
  ddPlugin: null

});

6. Public methods.

// Creates a new widget.
grid.addWidget(el, x, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id);

// Initailizes batch updates. 
// You will see no changes until commit method is called.
grid.batchUpdate();

// Relayout grid items to reclaim any empty space.
grid.compact();

// Gets current cell height.
grid.cellHeight();

// Update current cell height.
// grid.cell_height(grid.cell_width() * 1.2);
grid.cellHeight(val, noUpdate);

// Gets current cell width.
grid.cellWidth();

// Returns current vertical margin value.
grid.verticalMargin();

// value - new vertical margin value.
// noUpdate - if true, styles will not be updated.
verticalMargin(value, noUpdate)

// Finishes batch updates. Updates DOM nodes. You must call it after batch_update.
grid.Commit();

// set/get floating widgets
grid.float(val);

// Disables / enables widgets moving/resizing.
grid.movable('.grid-stack-item', false);
grid.resizable('.grid-stack-item', true); 

// Get the position of the cell under a pixel on screen.
// position - the position of the pixel to resolve in absolute coordinates, as an object with top and leftproperties
// useOffset - if true, value will be based on offset vs position (Optional. Default false). Useful when grid is within position: relative element
// Returns an object with properties x and y i.e. the column and row in the grid.
grid.getCellFromPixel(position, useOffset);

// Checks if specified area is empty.
grid.isAreaEmpty(x, y, width, height);

// Locks/unlocks widget.
// el - widget to modify.
// val - if true widget will be locked.
grid.locked(el, val);

// Make new widgets after new items are appended to the grid.
grid.makeWidget(el);

// Set the minWidth/maxWidth for a widget.
grid.minWidth(el, val);
grid.maxWidth(el, val);

// Set the minHeight/maxWidth for a widget.
grid.minHeight(el, val);
grid.maxHeight(el, val);

// Removes widget from the grid.
// detachNode - if false node won't be removed from the DOM
grid.removeWidget(el, detachNode);

// Removes all widgets from the grid.
// detachNode - if false node won't be removed from the DOM
grid.removeAll(detachNode);

// Changes widget size
grid.resize(el, width, height);

// Changes widget position
grid.move(el, x, y);

// Enables/Disables resizing.
grid.resizable(el, val);

// Enables/Disables moving.
grid.movable(el, val);

// Updates widget position/size.
grid.update(el, x, y, width, height);

// Returns true if the height of the grid will be less the vertical constraint. Always returns true if grid doesn't have height constraint.
grid.willItFit(x, y, width, height, autoPosition);

// Toggle the grid animation state.
// doAnimate - if true the grid will animate.
grid.setAnimation(doAnimate);

// Modify number of columns in the grid
// doNotPropagate - if true existing widgets will not be updated.
grid.setColumn(column, doNotPropagate);

// Update widget position/size.
grid.setStatic(staticValue);

// Toggle the grid static state
// staticValue - if true the grid becomes static.
grid.update(el, x, y, width, height));

// Destroy the instance
// detachGrid - if false nodes and grid will not be removed from the DOM
grid.destroy([detachGrid]);

7. Event listeners available.

$('.grid-stack').on('added', function(event, items) {
  // after new items are added
});

$('.grid-stack').on('change', function(event, items) {
  // fired on change
});

$('.grid-stack').on('disable', function(event) {
  // var grid = event.target;
});

$('.grid-stack').on('dragstart', function(event, ui) {
  // var grid = this;
  // var element = event.target;
});

$('.grid-stack').on('dragstop',  function(event, ui) {
  // var grid = this;
  // var element = event.target;
});

$('.grid-stack').on('dropped',  function(event, previousWidget, newWidget) {
  // after dropped
});

$('.grid-stack').on('enable',  function(event) {
  // var grid = event.target;
});

$('.grid-stack').on('removed',  function(event, items) {
  // after removed
});

$('.grid-stack').on('resizestart',  function(event, ui) {
  // var grid = this;
  // var element = event.target;
});

$('.grid-stack').on('gsresizestop',  function(event, items) {
  // on stop resizing
});

8. Please check out doc/README.md for more information about gridstack.js API.

Changelog:

v0.6.0 (2019-12-25)

  • add float(val) to set/get the grid float mode, which will relayout 
  • add compact() to reclaim any empty space and relayout grid items
  • add options.dragOut to let user drag nested grid items out of a parent or not (default false) and jQuery UI draggable.containment can now be specified in options. You can now drag&drop between 2 nested grids
  • Allow percentage as a valid unit for height
  • fixed callbacks to get either added, removed, change or combination if adding a node require also to change its (x,y) for example. Also you can now call batchUpdate() before calling a bunch of addWidget() and get a single event callback (more efficient)
  • removeAll() is now much faster (no relayout) and calls removed event just once with a list
  • setColumn() complete re-write and is no longer "Experimental". We now do a reasonable job at sizing/position the widgets (especially 1 column) and also now cache each column layout so you can go back to say 12 column and not loose original layout
  • fix bug where addWidget(el) (no data) would not render item at correct location, and overlap item at (0,0)
  • you can now pre-define size of dragable elements from a sidebar using standard data-gs-width and data-gs-height

v0.5.4 (2019-11-28)

  • no code change, just packing issues

v0.5.4 (2019-11-27)

  • fix for griditems with x=0 placement wrong order
  • fix cellHeight(val) not working due to style change 
  • add gridstack.poly.js for IE and older browsers, removed core-js lib from samples (<1k vs 85k), and all IE8 mentions
  • add jquery-ui.js (and min.js) as minimal subset we need (55k vs 248k), which is now part of gridstack.all.js. Include individual parts if you need your own lib instead of all.js
  • changed jquery dependency to lowest we can use (>=1.8)

2019-11-22

  • Doc updated

2018-05-11

  • Update dependencies, remove .bithoundrc (bithound is closing), update syntax for sortBy

2018-05-05

  • Temporary bugfix

v1.0.0 (2017-09-12)

  • Build last few merges, fix indentation, allow the maximum height to be the style `min-height` / `cellHeight` in cases where that is larger than the biggest cell y + cell height.
  • "trashzone" improvement
  • Fix build by breaking line before 120 characters.

v0.3.0 (2017-04-22)

  • remove placeholder when dragging widget below grid (already worked when dragging left, above, and to the right of grid).
  • prevent extra checks for removing widget when dragging off grid.
  • trigger added when a widget is added via dropping from one grid to another.
  • trigger removed when a widget is removed via dropping from one grid to another.
  • trigger removed when a widget is removed via dropping on a removable zone.
  • trigger custom event for resizestop called gsresizestop.
  • prevent dragging/resizing in oneColumnMode.
  • add oneColumnModeClass option to grid.
  • remove 768px CSS styles, moved to grid-stack-one-column-mode class.
  • add max-width override on grid-stck-one-column-mode.
  • add internal functionisNodeChangedPosition, minor optimization to move/drag.
  • drag'n'drop plugin system. Move jQuery UI dependencies to separate plugin file.

v0.2.6 (2016-08-17)

  • update requirements to the latest versions
  • fix jQuery size()
  • Fixed setStatic not working
  • fix cellWidth method

v0.2.5 (2016-03-03)

  • update names to respect js naming convention.
  • cellHeight and verticalMargin can now be string (e.g. '3em', '20px').
  • add maxWidth/maxHeight methods.
  • add enableMove/enableResize methods.
  • fix window resize issue.
  • add options disableDrag and disableResize.
  • fix batchUpdate/commit 
  • remove dependency of FontAwesome
  • RTL support
  • 'auto' value for cellHeight option
  • fix setStatic method
  • add setAnimation method to API
  • add setGridWidth method
  • add removable/removeTimeout
  • add detachGrid parameter to destroy method
  • add useOffset parameter to getCellFromPixel method
  • add minWidth, maxWidth, minHeight, maxHeight, id parameters to addWidget
  • add added and removed events for when a widget is added or removed, respectively

2016-02-14

  • Include resizable, draggable opts in all listeners for resizable, draggable, respectively. Fixes issue particularly when passing handle to draggable - was listening to everything on el rather than this.opts.draggable.handle.

2016-02-11

  • Adding make_widget functionality

2016-02-09

  • Fixed: Grid ID and Extra CSS use same prefix

2015-09-22

  • fix handle option

2015-09-10

  • Make sure not to include placeholders when calling prepare element.

2015-07-23

  • Trigger change event for add/remove

2015-07-22

  • Add destroy method.

2015-07-21

  • Add a API to set minWidth and minHeight to a node

2015-07-17

  • add 'static_grid' option

2015-06-25

  • fix closure compiler/linter warnings

2015-06-20

  • extra CSS

2015-06-19

  • do not fire onchange event with empty array

2015-05-15

  • fix ‘w’ resize

2015-03-13

  • fix floating mode

2015-03-11

  • lodash.js support

2015-03-10

  • improve memory usage
  • added more demos.

2015-03-09

  • fix styles initialization
  • add `detach_node` param to `remove_widget`

2015-03-06

  • remove default value for max height

2015-03-04

  • improve default resizable options

2015-03-02

  • avoid runtime error in IE8

2015-02-28

  • improve stylesheet creation
  • resizable/draggable options

2015-02-27

  • fix IE9 resize handle issue

2015-02-18

  • add disable/enable methods

2015-02-14

  • respect max/min constrains when resize widgets

2015-01-29

  • add get_cell_from_pixel
  • AMD support
  • fix nodes sorting
  • improved touch devices support
  • add always_show_resize_handle option

2015-01-20

  • added knockout.js support
  • added AMD support

2015-01-09

  • improve touch support

2014-12-20

  • Fixed: Dragging widgets around can still cause unexpected changes in other widgets

2014-12-12

  • add cell_width/cell_height

2014-12-08

  • minify css
  • Animates grid-stack container itself.

2014-12-06

  • fix widgets packing in float mode
  • fix locked for not floating grid.

2014-12-05

  • set animation after grid initialization

2014-12-02

  • improve 'y' calc when dragging

2014-11-29

  • add height option

2014-11-27

  • fix css rules generation

2014-11-26

  • auto-generate css rules for width and y

2014-11-24

  • add remove_all method

2014-11-21

  • add movable/resizable API methods

2014-11-21

  • add data-gs-no-move attribute to disable drag'n drop on specified elements.

2014-11-20

  • add float option

2014-11-17

  • added one-column mode for small devices

2014-11-14

  • added auto positioning

2014-11-12

  • update container height after add/remove

This awesome jQuery plugin is developed by gridstack. For more Advanced Usages, please check the demo page or visit the official website.