![]() |
Drag and Drop Grid Responsive & Fluid Layout with jQuery |
Gridstack.js is a Gridster-inspired JavaScript fluid layout widget/grid layout widget plugin that allows you to dynamically and responsively rearrange grid items via drag and drop styling on a seamless page layout.
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 3/4 framework.
- No jQuery required (v2.0.0+)
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/dist/gridstack.min.css" /> <script src="https://cdn.jsdelivr.net/npm/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, // turns animation on animate: false, // amount of columns and rows column: 12, row: 0, // max/min number of rows maxRow: 0, minRow: 0, // 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: 60, // 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: '', // cell height unit cellHeightUnit: 'px', // margin margin: 10, marginUnit: 'px', // or marginTop: 10, marginBottom: 10, marginLeft: 10, marginRight: 10 // 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, // 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' }, // specify the class of items that can be dragged into the grid dragIn: false, dragInOptions : { helper: 'clone', handle: '.grid-stack-item-content', appendTo: 'body' }, // the type of engine to create (so you can subclass) engineClass: 'GridStackEngine', // 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, removableOptions: { accept: 'grid-stack-item' }, // time in milliseconds before widget is being removed while dragging outside of the grid removeTimeout: 2000, // disables the oneColumnMode when the grid width is less than minW disableOneColumnMode: 'false', });
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}, // 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/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/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 });
Live Demo
See the Pen Untitled by Plugin JS (@teguhsigit) on CodePen.
File Info
- File Name :
- gridstack.js-master.zip
- Size :
- 312.82KB
- Site Download :
- Github.com
- Official Website:
- Go to website
- License:
- MIT