Responsive & Fluid Drag-and-Drop Grid Layout with jQuery - gridstack.js
File Size: | 655 KB |
---|---|
Views Total: | 130820 |
Last Update: | |
Publish Date: | |
Official Website: | Go to website |
License: | MIT |
Gridstack.js is a vanilla JavaScript widget/grid layout plugin inspired by Gridster that allows you to dynamically and responsively rearrange grid items through drag and drop.
Note: The library now works as a Vanilla JavaScript plugin. You can also download the jQuery Version here for jQuery projects.
More features:
- Also supports touch events.
- Resizable grid items.
- Supports nested grid items.
- Compatible with Bootstrap framework.
- No jQuery required (v5.1.1+)
View more:
Table Of Contents:
Basic Usage (Vanilla JS Version):
1. Install & Download the package.
# Yarn $ yarn add gridstack # NPM $ npm install gridstack --save
2. Include the necessary JavaScript and CSS files on the page.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gridstack@latest/dist/gridstack.min.css" /> <script src="https://cdn.jsdelivr.net/npm/gridstack@latest/dist/gridstack.all.js"></script>
3. Insert optional grid items to the Grid Stack container and pass the options via data-option
attributes as follows:
<div class="grid-stack"> <div class="grid-stack-item"> <div class="grid-stack-item-content">Item 1</div> </div> <div class="grid-stack-item" data-gs-width="2"> <div class="grid-stack-item-content">Item 2 wider</div> </div> </div>
4. Initialize the plugin and done.
var grid = GridStack.init();
5. All default grid options.
var grid = GridStack.init({ // accept widgets dragged from other grids or from outside // true (uses '.grid-stack-item' class filter) or false // string for explicit class name // function (i: number, element: Element): boolean acceptWidgets: false, // false: the resizing handles are only shown while hovering over a widget // true: the resizing handles are always shown // 'mobile': if running on a mobile device, default to true, else false alwaysShowResizeHandle: 'mobile', // turns animation on animate: false, // amount of columns and rows column: 12, // column options // see below columnOpts: { // wanted width to maintain (+-50%) to dynamically pick a column count columnWidth?: number; // maximum number of columns allowed (default: 12). Note: make sure to have correct CSS to support this. columnMax?: number ; // global re-layout mode when changing columns layout?: ColumnOptions ; // specify if breakpoints are for window size or grid size (default:false = grid) breakpointForWindow?: boolean; // explicit width:column breakpoints instead of automatic 'columnWidth'. // Note: make sure to have correct CSS to support this. breakpoints?: Breakpoint[]; }, row: 0, // max/min number of rows maxRow: 0, minRow: 0, // if you are using a nonce-based Content Security Policy, pass your nonce here and GridStack will add it to the <style> elements it creates nonce: '', // minimal width before grid will be shown in one column mode (default?: 768) */ oneColumnSize: 768, // set to true if you want oneColumnMode to use the DOM order and ignore x,y from normal multi column layouts during sorting. // This enables you to have custom 1 column layout that differ from the rest. (default?: false) oneColumnModeDomSort: false, // 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, // allow for selecting older behavior (adding STYLE element to HEAD element instead of parentNode) styleInHead: false, // an integer (px) // a string (ex: '100px', '10em', '10rem'). Note: % doesn't right - see CellHeight // 0, in which case the library will not generate styles for rows. Everything must be defined in your own CSS files. // auto - height will be calculated for square cells (width / column) and updated live as you resize the window // initial - similar to 'auto' (start at square cells) but stay that size during window resizing. cellHeight: 'auto', // throttle time delay (in ms) used when cellHeight='auto' to improve performance vs usability cellHeightThrottle: 100, // list of children items to create when calling load() or addGrid() // see item options below children: [], // additional class on top of '.grid-stack' (which is required for our CSS) to differentiate this instance. class: '', // Can be: // an integer (px) // a string (ex: '2em', '20px', '2rem') margin: 10, // or marginTop: 10, marginBottom: 10, marginLeft: 10, marginRight: 10 // if false it tells to do not initialize existing items auto: true, // enable floating widgets float: false, // makes grid static staticGrid: false, // false the resizing handles are only shown while hovering over a widget // true the resizing handles are always shown // 'mobile' if running on a mobile device, default to true (since there is no hovering per say), else false. this uses this condition on browser agent check: alwaysShowResizeHandle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) alwaysShowResizeHandle: 'mobile', // allows to owerride jQuery UI draggable options draggable: { handle: '.grid-stack-item-content', scroll: true, appendTo: 'body' }, // lets user drag nested grid items out of a parent or not dragOut: false, // make gridItems size themselves to their content, calling resizeToContent(el) whenever the grid or item is resized sizeToContent: true, // allows to owerride jQuery UI resizable options // handles can be any combo of n,ne,e,se,s,sw,w,nw or all resizable: {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, });
6. All default item options.
var grid = GridStack.init({ children: [ { // element position x:1, y:0, // element size w: 2, h: 4, // min/max width and height maxW: 'none', minW: 'none', maxH: 'none', minH: 'none', // unique ID (number of string) id: 1, // html content content: 'regular item', // enables auto position autoPosition: true, // locks the item locked: false, // enables/disables resizable noResize: false, // enables/disables draggable noMove: false, // items can can have their own custom resize handle resizable: {handles: string}, // boolean | number - make gridItem size itself to the content // calling GridStack.resizeToContent(el) whenever the grid or item is resized. sizeToContent: true, // sub grid subGrid: {children: sub1, class: 'sub1', ...subOptions}, // enables/disables the creation of sub-grids on the fly by dragging items completely over others (nest) vs partially (push) subGridDynamic: true, }, // more items here ] });
7. API methods.
// Initialize let grid = GridStack.init(options, GridStackElement); // Initialize a list of elements (given a selector) and return an array of grids. let grids = GridStack.initAll(options, selector); // Create a grid with the given options let grids = GridStack.addGrid(parent, options); // Setup dragging in from the outside (say toolbar), by specifying the class selection and options let grids = GridStack.setupDragIn(dragIn, dragInOptions); // Specify global custom engine subclass let grids = GridStack..registerEngine(engineClass: typeof GridStackEngine); // Creates a new widget. grid.addWidget(el, { // options x, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id, locked, noResize, noMove, resizeHandles }); // 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(val: number, update = true); // Update current cell height. // grid.cell_height(grid.cell_width() * 1.2); grid.cellHeight(val, noUpdate); // Gets current cell width. grid.cellWidth(); // Set/get the number of columns in the grid // Require gridstack-extra.min.css grid.column(column: number, layout: ColumnOptions = 'moveScale'); // Destroy the instance // removeDOM - if false nodes and grid will not be removed from the DOM grid.destroy([removeDOM]); // Enables/disables the plugin grid.enable(); grid.disable(); // Enables/disables widget moving. grid.enableMove(doEnable); // Enables/disables widget resizing grid.enableResize(doEnable); // Set/get floating widgets // val - boolean to set true/false, else get the current value grid.float(val); // Get current cell height grid.getCellHeight(); // 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); // Returns the number of columns in the grid. grid.getColumn(); // Returns list of GridItem HTML dom elements (excluding temporary placeholder) grid.getGridItems(); // Returns current margin value. grid.getMargin(); // Checks if specified area is empty. grid.isAreaEmpty(x, y, width, height); // Load the widgets from a list grid.load(layout: GridStackWidget[], boolean | ((w: GridStackWidget, add: boolean) => void) = true); // Make new widgets after new items are appended to the grid. grid.makeWidget(el); // Set the top/right/bottom/left margin between grid item and conten grid.margin(value: numberOrString); // Disables / enables widgets moving/resizing. // el - widget to modify // val - if true widget will be draggable. grid.movable(el, val); // Removes widget from the grid. // el - widget to remove. // removeDOM - if false node won't be removed from the DOM (Optional. Default true). // triggerEvent if false (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default true). grid.removeWidget(el, removeDOM = true, triggerEvent = true); // Removes all widgets from the grid. // removeDOM - if false nodes won't be removed from the DOM (Optional. Default true). grid.removeAll(removeDOM = true); // Enables/Disables user resizing of specific grid element. // el - widget to modify // val - if true widget will be resizable. grid.resizable(el, val); // Returns the layout of the grid that can be serialized (list of item non default attributes, not just w,y,x,y but also min/max and id). // saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will be removed. // saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid() to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead. // returns list of widgets or full grid option, including .children list of widgets grid.save(saveContent = true, saveGridOpt = false); // Toggle the grid animation state. // doAnimate - if true the grid will animate. grid.setAnimation(doAnimate); // 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)); // 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);
8. Event handlers.
grid.on('added', function(event, items) { // after new items are added }); grid.on('change', function(event, items) { // fired on change }); grid.on('disable', function(event) { // var grid = event.target; }); grid.on('dragstart', function(event, ui) { // var grid = this; // var element = event.target; }); grid.on('drag', function(event, el) { // fired on resize }); grid.on('dragstop', function(event, ui) { // var grid = this; // var element = event.target; }); grid.on('dropped', function(event, previousWidget, newWidget) { // after dropped }); grid.on('enable', function(event) { // var grid = event.target; }); grid.on('removed', function(event, items) { // after removed }); grid.on('resizestart', function(event, el) { // var grid = this; // var element = event.target; }); grid.on('resize', function(event, el) { // fired on resize }); grid.on('resizestop', function(event, items) { // on stop resizing });
Basic Usage (jQuery Version):
1. Include jQuery library and other required resources in the the document.
- jQuery
- jQuery UI
- jQuery UI Touch Punch: for touch support (OPTIONAL)
- gridstack.poly.js: for IE and older browsers (OPTIONAL)
<!-- Local --> <link href="/path/to/gridstack.css" rel="stylesheet" /> <!-- Or From A CDN --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gridstack@latest/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/gridstack@latest/dist/gridstack.all.js"></script> <!-- Polyfill for old IE --> <script src="gridstack.poly.js"></script>
3. Create a sample draggable grid layout as follows.
gs-animate
: turns animation on (for grid)gs-column
: amount of columns (for grid)gs-max-row
: maximum rows amount, defaults to 0 (for grid)gs-current-height
: current rows amount (for grid)gs-id
: unique ID (for item)gs-x
,data-gs-y
: element position (for item)gs-width
,data-gs-height
: element size (for item)gs-max-width
,gs-min-width
,gs-max-height
,gs-min-height
: element constraints (for item)gs-no-resize
: disable element resizing (for item)gs-no-move
: disable element moving (for item)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)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)gs-resize-handles
: resize handles (for item)gs-static-grid
: whether to make grid static
<div class="grid-stack" data-gs-width="12"> <div class="grid-stack-item" gs-x="0" data-gs-y="0" gs-width="4" gs-height="2"> <div class="grid-stack-item-content"></div> </div> <div class="grid-stack-item" gs-x="4" data-gs-y="0" gs-width="4" gs-height="4"> <div class="grid-stack-item-content"></div> </div> <div class="grid-stack-item" gs-x="8" gs-y="0" gs-width="2" gs-height="2" gs-min-width="2" 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" gs-x="10" gs-y="0" gs-width="2" gs-height="2"> <div class="grid-stack-item-content"></div> </div> <div class="grid-stack-item" gs-x="0" gs-y="4" gs-width="2" gs-height="2"> <div class="grid-stack-item-content"></div> </div> <div class="grid-stack-item" gs-x="2" gs-y="4" gs-width="2" gs-height="4"> <div class="grid-stack-item-content"></div> </div> <div class="grid-stack-item" gs-x="8" gs-y="4" gs-width="4" gs-height="2"> <div class="grid-stack-item-content"></div> </div> <div class="grid-stack-item" gs-x="0" gs-y="6" gs-width="2" gs-height="2"> <div class="grid-stack-item-content"></div> </div> <div class="grid-stack-item" gs-x="4" gs-y="6" gs-width="4" gs-height="2"> <div class="grid-stack-item-content"></div> </div> <div class="grid-stack-item" gs-x="8" gs-y="6" gs-width="2" gs-height="2"> <div class="grid-stack-item-content"></div> </div> <div class="grid-stack-item" gs-x="10" gs-y="6" gs-width="2" 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({ // accept widgets dragged from other grids or from outside // true (uses '.grid-stack-item' class filter) or false // string for explicit class name // function (i: number, element: Element): boolean acceptWidgets: false, // turns animation on animate: false, // amount of columns column: 12, // max/min number of rows maxRow: 0, minRow: 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, // allow for selecting older behavior (adding STYLE element to HEAD element instead of parentNode) styleInHead: false, // one cell height cellHeight: 60, // gap size // e.g. '5px 10px 0 20px' or '5em 10em' margin: 10, // unit verticalMarginUnit: 'px', cellHeightUnit: 'px', // if false it tells to do not initialize existing items auto: true, // minimal width. minWidth: 768, // class set on grid when in one column mode oneColumnModeClass: 'grid-stack-one-column-mode', // set to true if you want oneColumnMode to use the DOM order and ignore x,y from normal multi column layouts during sorting. This enables you to have custom 1 column layout that differ from the rest. oneColumnModeDomSort: false, // 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', containment: null}, // 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. API methods 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. grid.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. // NOTE: Use column() instead in v1.0+ 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]); // Enables/disables the plugin grid.enable(); grid.disable(); // Enables/disables widget moving. includeNewWidgets will force new widgets to be draggable as per doEnable's value by changing the disableDrag grid option. grid.enableMove(doEnable, includeNewWidgets); // Enables/disables widget resizing. includeNewWidgets will force new widgets to be resizable as per doEnable's value by changing the disableResize grid option. grid.enableResize(doEnable, includeNewWidgets);
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 });
Changelog:
v10.3.1 (2024-07-22)
- Bugfixes
v10.3.0 (2024-06-24)
- Bugfixes
v10.2.1 (2024-06-24)
- Bugfixes
v10.2.0 (2024-06-03)
- Bugfixes
- You can now press 'Esc' to cancel a move|resize, 'r' to rotate during a drag. added GridStack.rotate() as well
v10.1.2 (2024-03-31)
- Bugfixes
v10.1.1 (2024-03-04)
- Bugfixes
v10.1.0 (2024-02-05)
- Bugfixes
- Allow cell height in cm and mm units
v10.0.1 (2023-12-11)
- Bugfixes
v10.0.0 (2023-11-21)
- Support much richer responsive behavior with GridStackOptions.columnOpts including any breakpoint width:column pairs, or automatic column sizing.
- disableOneColumnMode, oneColumnSize, oneColumnModeDomSort have been removed
v9.5.1 (2023-11-12)
- bugfixes
v9.5.0 (2023-10-27)
- bugfixes
- add div scale support
v9.4.0 (2023-10-16)
- bugfixes
v9.3.0 (2023-10-01)
- bugfixes
v9.2.2 (2023-09-28)
- bugfixes
v9.2.1 (2023-09-25)
- bugfix
v9.2.0 (2023-09-11)
- bugfix
v9.1.1 (2023-09-07)
- bugfix
v9.1.0 (2023-09-05)
- bugfix
v9.0.2 (2023-08-30)
- update & bugfix
v9.0.1 (2023-08-28)
- update & bugfix
v9.0.0 (2023-08-24)
- added GridStackOptions.fitToContent and GridStackWidget.fitToContent to make gridItems size themselves to their content (no scroll bar), calling GridStack.resizeToContent(el) whenever the grid or item is resized.
- added new 'resizecontent' event, and resizeToContentCB and resizeToContentParent vars.
- fixed inf loop when autoPosition after loading into 1 column, then 2.
v8.4.0 (2023-07-21)
- feat: attribute DDRemoveOpt.decline to deny the removal of a specific class.
- fix: dragging onto trash now calls removeWidget() and therefore GridStack.addRemoveCB (for component cleanup)
- feat: load() support re-order loading without explicit coordinates (autoPosition or missing x,y) uses passed order.
v8.3.0 (2023-06-14)
- column(N, 'list'|'compact'|...) resizing now support reflowing content as list
v8.2.3 (2023-06-12)
- bugfixes
v8.2.1 (2023-05-27)
- fix: make sure removeNode() uses internal _id (unique) and not node itself (since we clone those often)
- fix: after calling addRemoveCB make sure we don't makeWidget() (incorrectly) a second time
- break: GridStackWidget.id is now string only (used to be numberOrString) as it causes usage to have to check and cast
v8.2.0 (2023-05-25)
- feat: makeWidget() now take optional GridStackWidget for sizing
- fix: make sure GridStack.saveCB is call in removeWidget()
- feat: angular wrapper: serialize custom data support, and making sure destroy() is called on ng components
v8.1.2 (2023-05-23)
- module for Angular wrapper
v8.1.1 (2023-05-14)
- bugfix
- also further compressed CSS multi column rules (use .gs-# > .grid-stack-item instead of .grid-stack-# > .grid-stack-item)
v8.1.0 (2023-05-07)
- break: remove GridStackOptions.minWidth obsolete since 5.1, use oneColumnSize instead
- optimize: CSS files now even 25% smaller (after being halfed in 8.0.0) by removing .grid-stack prefix for anything already gs based, and 3 digit rounding.
- fix: setupDragIn() signature tweaks (HTMLElement | Document)
- feat: added GridStackOptions.draggable.cancel for list of selectors that should prevent item dragging
v8.0.0/1 (2023-04-30)
- package is now ES2020 (TS exported files), webpack all.js still umd (better than commonjs for browsers), still have es5/ files unchanged (for now)
- removed gs-min|max_w|h attribute generated in CSS or written out as they are never used for rendering, only for initial load. This reduce our column/row CSS in half!
- removed gs-w='1' and gs-h='1' dom attribute writing since we already have min-width/min-height set, no need to set more attributes.
- remove 'ui-draggable' and 'ui-resizable' since wasn't used in CSS and we have the -disabled version when off (so we can use not(xyz-disabled)).
- add: GridStack.saveCB global callback for each item during save so app can insert any custom data before serializing it. save() can now be passed optional callback
- move: GridStack.addRemoveCB is now global instead of grid option. load() can still be passed different optional callback
- fix: addGrid() to handle passing an existing initialized grid already
- break: GridStackOptions.subGrid -> GridStackOptions.subGridOpts. We now have GridStackWidget.subGridOpts vs GridStackNode.subGrid (subclass) rather than try to merge the two at runtime since very different types...
- tons of improvements for Angular wrapper
v7.3.0 (2023-04-02)
- support nonce for CSP
- support nested grids with Angular component demo
- load() with collision fix
- autoPosition bug loading from DOM
v7.2.3 (2023-02-03)
- add opts.draggable.scroll back to disable scrolling.
- bugfix
v7.2.0 (2023-01-17)
- bugfixes
v7.2.0 (2023-01-08)
- add - init()|initAll() will now load any listed children (what addGrid() already did)
- add - GridStackOptions.addRemoveCB which is use by frameworks (eg Angular) to dynamically create their gridItem components instead of regular div with class
- bugfix
v7.1.2 (2022-12-30)
- add disable/enable are methods now recursive by default
- add better GridStackEventHandlerCallback spelled out types
- bugfix
v7.1.0 (2022-10-24)
- Bugfix
- Add GridStackEngine.findEmptyPosition()
v7.0.1 (2022-10-15)
- Bugfix
v7.0.0 (2022-10-10)
- Create sub-grids on the fly, by dragging items completely over others (nest) vs partially (push) using new flag GridStackOptions.subGridDynamic=true.
- Add - ability to pause drag&drop collision until the user stops moving - see DDDragOpt.pause (used for creating nested grids on the fly based on gesture).
- You can now drag sub-grids into other sub-grids
v6.0.3 (2022-10-09)
- bugfixes
v6.0.2 (2022-09-24)
- bugfixes
v6.0.1 (2022-08-28)
- bugfixes
v6.0.0 (2022-08-22)
- converted previous HTML5 draggable=true based code to simple Mouse Events and Touch mobile support for drag&Drop.
- removed all jquery-ui related code, and D&D plugging as we only support native events now
- alwaysShowResizeHandle now support 'mobile' which is the default, making it much easier
- changed commit() to be batchUpdate(false) to make it easier to turn batch on/off. updated doc. old API remains for now
v5.1.1 (2022-06-17)
- bugfix
v5.1.0 (2022-05-22)
- add GridStack.registerEngine() to let user use their own custom layout engine subclass. Thank you [Thomas] for sponsoring it.
- grid option minWidth is now oneColumnSize to make it clearer, but old field will still work (JS only) for a while
- fixed restore animation when dragging items
- updated jquery-ui to latest v1.13.1
v5.0.0 (2022-01-11)
- add support dragging into and out of nested grids from parents.
- add new column:'auto' option to size nested grids to their parent grid item column count, keeping items the same size inside and outside.
- fix nested.html: dragging between sub-grids show items clipped
- fix dragging between vertical grids causes too much growth, not follow mouse.
- fix no longer force rows for min-height
v4.4.1 (2021-12-25)
- Bugfix
v4.4.0 (2021-12-22)
- add support for IE (new es5 folder)
- bugfix
v4.3.1 (2021-10-19)
- fix prevent swap during resize
- fix save highest resolution in 1 column mode
- fix resize when padding is large vs cellHeight
v4.3.0 (2021-10-16)
- you can now swap items of different width if they are the same row/height
- fix nested grid save inf loop fix
v4.2.7 (2021-09-13)
- Fixed: Enable passing of DragEvent to gridstack dropped event.
- Fixed: Layout incorrectly restored when node has a minimum width.
- Fixed: addGrid() does not recognize rem cellHeightUnit.
v4.2.6 (2021-07-12)
- fixed: removable:true working by itself (without needing acceptWidgets:true)
- fixed: removed drag flicker and scroll issue.
- fixed: save(false) will no longer have .content field (removed existing one if present)
- fixed: save(false, false) now correctly saves nested grids
- fixed: save(false, true) followed by enable() throws error. we now have new Utils.cloneDeep()
v4.2.5 (2021-05-31)
- fix for website with JQ droppable('destroy') giving error
v4.2.4 (2021-05-30)
- fix removable:true working again (broke in 4.x)
- fix staticGrid(false) will now enable drag in behavior (if set)
- fix locked item can be user moved/resized again, just not pushed by other nodes (broke in 1.1.1)
- fix destroy(false) can now re-init properly (doesn't force static grid)
v4.2.3 (2021-05-08)
- Utils.getScrollParent() -> getScrollElement() rename
- fix digression on scrolling in v4.2.1
v4.2.2 (2021-04-24)
- fix mac Safari H5 draggable broken in 4.0.1
- fix mac Safari page scroll fix
v4.2.1 (2021-04-19)
- fixed: JQ nested grid drag fix broken in 4.0.3 (but much older underlying issue)
- fixed: item gs-x:0 not animating fix
- fixed: resize-scroll issue when grid is not at top of page. Thanks @Manfred-on-github
- fixed: fix sizing from top/left sides
v4.2.0 (2021-04-12)
- fixed: scrollbar fix broken in 4.x
- fixed: addWidget() while in 1 column now remembers original wanted width
- added: addWidget() now supports nested grids like init/addGrid() does
v4.1.0 (2021-04-08)
- fixed Can't easily drag widgets below widgets on the bottom border of a grid
- when dragging an item at the bottom below others to make it easier to insert below.
- more fix for drag between 2 grids with row / maxRow broken in 4.x
- fix export symbols .d.ts for gridstack-h5.js | gridstack-jq.js | gridstack-static.js
- fix correct info for using JQ version and ES6 (tested in Angular app)
v4.0.3 (2021-03-29)
- fix load after init() broken in 4.x
- fix drag between 2 grids with row / maxRow broken in 4.x
- fix drag edge case in/out single grid without acceptWidgets fix broken in 4.x
v4.0.2 (2021-03-28)
- fix: {handles:'w/sw'} work again in 4.x
- fix: enableMove(T/F) not working correctly
- fix helper: myFunction now working for H5 case for dragInOptions & setupDragIn()
- fix: prevent addGrid() from creating nested div grid if container already is a '.grid-stack' div
v4.0.1 (2021-03-21)
- fix JQ resize broken
- fix serialization of nested grid
v4.0.0 (2021-03-20)
- add drag | resize events while dragging
- add GridStack.setupDragIn() so user can update external draggable after the grid has been created
- fixed bugs
v3.3.0 (2021-02-03)
- big re-write on how cellHeight() works. you can now call it at any time (not just grid init options) including switching to 'auto' or other modes on the fly.
- fix cellHeight:auto now keeps cell square as window resizes (regressing from 2.x TS conversion). Utils.throttle() works better too (guaranteed to be called last event)
- new cellHeight:initial which makes the cell squares initially, but doesn't change as windows resizes (better performance)
- new grid option cellHeightThrottle (100ms) to control throttle of auto sizing triggers
- fixed: height too small with cellHeight:auto loading in 1 column. Now detect we load at 1 column and size accordingly (default 'auto' could make big 700x700 cells, so explicit px might still be wanted)
- fixed: loading nested into small size and sizing back up
- fixed: nested grid resizing fix
- fixed: H5 resize from left side can move item right
v3.2.0 (2021-01-26)
- fix website & lib works on mobile. We now compile the latest v1.0.8 jquery.ui.touch-punch into the JQ version (only 2k) so mobile devices (android, iphone, ipad, ms surface, etc...) are supported out of the box. HTML5 version will require re-write to plain mousemove & mobile touchmove instead of drag events in a future release.
- small optimizations (create placeholder content on the fly, moved more DD code into draggable class)
v3.1.5 (2021-01-24)
- fix column: N option now sets CSS class
- fix don't allow drop when grid is full
- fix easier to drag out/in from below
- fix cellHeight() not updating CSS correctly
- fix H5 draggable by actual div handle rather than entire item (let content respond to drag as well)
v3.1.4 (2021-01-12)
- fix no-drop cursor on windows when dragging within a default grid (no external drag in)
- fix Safari H5 delay when dropping items
v3.1.3 (2021-01-03)
- bugfixes
v3.1.2 (2020-12-08)
- fix dragging into a fixed row grid works better (check if it will fit, else try to append, else won't insert)
- possible BREAK (unlikely you use engine directly)
- engine constructor takes Options struct rather than spelling arguments (easier to extend/use)
- canBePlacedWithRespectToHeight() -> willItFit() like grid method
- fix maxW does not work as intended with resizable handle "w"
- fix support all options for new dragged in widgets (read all gs-xyz attributes)
- fix dragging any grid item content works
- fix web-component fixes & grid with 0 size initially. (edited)
v3.1.0 (2020-12-05)
- add new addGrid(parent, opts) to create a grid and load children instead of init() + load(), which is used by load() to supports nested grids creation.
- save() will now work on nested grids, recursively saving info. added flag to also allow saving the current grid options + children (needed for nested grids) so you can now call new adddGrid() to re-create everything from JSON.
- fixed: don't call movable()/resizable() on locked items error.
- fixed: force typescript 3.6 as 3.7+ has breaking change forcing apps to be at least 3.7 (we only used one tiny feature in newest TS, not worth the incompatibility).
v3.0.0 (2020-11-30)
- Native HTML5 drag&drop plugin included
- Fix placeholder not having custom GridStackOptions.itemClass. thanks @pablosichert
- Fix dragging between 2 grids and back (regression in 2.0.1)
- Fix load() into 1 column mode doesn't resize back to 12 correctly
- Fix update(el, opts) re-write to take all GridStackWidget options (not just x,y,width,height) and do everything efficiently.
- Hiding locked(), move(), resize(), minWidth(), etc... as they just simply call update() which does all the constrain now as well!
- Del ddPlugin grid option as we only have one drag&drop plugin at runtime, which is defined by the include you use (HTML5 vs jquery vs none)
- Change attribute data-gs-min-width is now gs-min-w. We removed 'data-' from all attributes, and shorten 'width|height' to just 'w|h' to require less typing and more efficient (2k saved in .js alone!)
- Also GridStackWidget used in most API width|height|minWidth|minHeight|maxWidth|maxHeight are now shorter w|h|minW|minH|maxW|maxH
v2.2.0 (2020-11-08)
- add margin option now support multi values CSS format '5px 10px 0 20px' or '5em 10em'
- add data-gs-static-grid attribute
- fix class="ui-draggable-disabled ui-resizable-disabled" have been added back to static grid items, so existing CSS rule to style continue working
- fix getting DOM element by id with number works (api that uses GridStackElement handle more string formats)
- fix setting marginTop (or any 4 sides) to cause resize to break
v2.1.0 (2020-10-29)
- fix grid static: true to no longer add any drag&drop (even disabled) which should speed things up, and setStatic(T/F) will now correctly add it back/delete for items that need it only.
- Also fixed JQ draggable warning if not initialized first
- add addWidget(opt) now handles just passing a GridStackWidget which creates the default divs, simplifying your code. Old API still supported.
- add save(saveContent = true) now lets you optionally save the HTML content in the node property, with load() restoring it
- add GridStackWidget.content now lets you add any HTML content when calling load()/save() or addWidget()
- add ColumnOptions to column(n, options) for multiple re-layout options, including 'none' that will preserve the x and width, until out of bound/overlap
v2.0.2 (2020-10-06)
- fix animate to not re-create CSS style each time (should be faster too) and made it default now since so much nicer. pass {animate: false} grid options if you want instant again
- fix resizable: { handles: ...} forcing alwaysShowResizeHandle behavior
v2.0.1 (2020-09-27)
- lots of bugs fixes
v2.0.0 (2020-09-05)
- re-write to native Typescript, removing all JQuery from main code and API (drag&drop plugin still using jqueryui for now)
- add getGridItems() to return list of HTML grid items
- add {dragIn | dragInOptions} grid attributes to handle external drag&drop items
- add save() and load() to serialize grids from JSON, saving all attributes (not just w,h,x,y)
- add margin to replace verticalMargin which affects both dimensions in code, rather than one in code the other in CSS.
- You can now have perfect square cells (default)
- fix #1299 many columns round-off error
- fix #1102 loose functionality when they are moved to a new grid
- add optional params to removeWidget() to have quiet mode (no callbacks)
v1.2.1 (2020-09-05)
- Enable the UMD behavior for bundlers compatibility
v1.2.0 (2020-05-18)
- fix domAttr is not defined
- adds styleInHead option to allow for selecting older behavior (adding STYLE element to HEAD element instead of parentNode)
- update jquery to v3.5.1
v1.1.2 (2020-05-18)
- fixed: staticGrid no longer disable oneColumnMode
- fixed: options broken with ember hash helper - thanks @btecu
- fixed: don't remove item from another grid
- fixed: init() clones passed options so second doesn't affect first one
- fixed: addWidget() ignores data attributes
v1.1.1 (2020-04-13)
- jQuery was removed from the API and dependencies (initialize differently, and methods take/return GridStack or HTMLElement instead of JQuery).
- Updated Doc accordingly.
v0.6.4 (2020-02-18)
- optimized change callback to save original x,y,w,h values and only call those that changed
- more bugs fixed
This awesome jQuery plugin is developed by gridstack. For more Advanced Usages, please check the demo page or visit the official website.