相关文章推荐
爱吹牛的小马驹  ·  border-style - CSS | MDN·  3 月前    · 
直爽的乒乓球  ·  :has() - CSS | MDN·  2 月前    · 
跑龙套的台灯  ·  RecyclerView#smoothScr ...·  1 月前    · 
机灵的香槟  ·  Android RecyclerView ...·  1 月前    · 
行走的消防车  ·  RV 的 scrollToPosition ...·  1 月前    · 
聪明的柚子  ·  HTMLIFrameElement:load ...·  4 月前    · 
八块腹肌的拖把  ·  New Rule for C# and ...·  5 月前    · 
愉快的沙滩裤  ·  北京大学艺术学院·  7 月前    · 
火爆的企鹅  ·  材料观察 | ...·  1 年前    · 
大力的充电器  ·  pd.concat出现unnamed:0 ...·  1 年前    · 

UNPKG

26.1 kB Markdown View Raw
1 gridstack.js
2 ============
4 gridstack.js is a jQuery plugin for widget layout. This is drag-and-drop multi-column grid. It allows you to build
5 draggable responsive bootstrap v3 friendly layouts. It also works great with [ knockout.js ]( http://knockoutjs.com ) and
6 touch devices.
8 Inspired by [ gridster.js ]( http://gridster.net ). Built with love.
10 Join gridstack.js on Slack: https://gridstackjs.troolee.com
12 [ ![Slack Status ]( https://gridstackjs.troolee.com/badge.svg )]( https://gridstackjs.troolee.com )
14 <!-- START doctoc generated TOC please keep comment here to allow auto update -->
15 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
16 **Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
18 - [ Demo ]( #demo )
19 - [ Usage ]( #usage )
20 - [ Requirements ]( #requirements )
21 - [ Basic usage ]( #basic-usage )
22 - [ Options ]( #options )
23 - [ Grid attributes ]( #grid-attributes )
24 - [ Item attributes ]( #item-attributes )
25 - [ Events ]( #events )
26 - [ onchange(items) ]( #onchangeitems )
27 - [ ondragstart(event, ui) ]( #ondragstartevent-ui )
28 - [ ondragstop(event, ui) ]( #ondragstopevent-ui )
29 - [ onresizestart(event, ui) ]( #onresizestartevent-ui )
30 - [ onresizestop(event, ui) ]( #onresizestopevent-ui )
31 - [ disable(event) ]( #disableevent )
32 - [ enable(event) ]( #enableevent )
33 - [ API ]( #api )
34 - [ add_widget(el, x, y, width, height, auto_position) ]( #add_widgetel-x-y-width-height-auto_position )
35 - [ make_widget(el) ]( #make_widgetel )
36 - [ batch_update() ]( #batch_update )
37 - [ cell_height() ]( #cell_height )
38 - [ cell_height(val) ]( #cell_heightval )
39 - [ cell_width() ]( #cell_width )
40 - [ commit() ]( #commit )
41 - [ destroy() ]( #destroy )
42 - [ disable() ]( #disable )
43 - [ enable() ]( #enable )
44 - [ get_cell_from_pixel(position) ]( #get_cell_from_pixelposition )
45 - [ is_area_empty(x, y, width, height) ]( #is_area_emptyx-y-width-height )
46 - [ locked(el, val) ]( #lockedel-val )
47 - [ min_width(el, val) ]( #min_widthel-val )
48 - [ min_height(el, val) ]( #min_heightel-val )
49 - [ movable(el, val) ]( #movableel-val )
50 - [ move(el, x, y) ]( #moveel-x-y )
51 - [ remove_widget(el, detach_node) ]( #remove_widgetel-detach_node )
52 - [ remove_all() ]( #remove_all )
53 - [ resize(el, width, height) ]( #resizeel-width-height )
54 - [ resizable(el, val) ]( #resizableel-val )
55 - [ set_static(static_value) ]( #set_staticstatic_value )
56 - [ update(el, x, y, width, height) ]( #updateel-x-y-width-height )
57 - [ will_it_fit(x, y, width, height, auto_position) ]( #will_it_fitx-y-width-height-auto_position )
58 - [ Utils ]( #utils )
59 - [ GridStackUI.Utils.sort(nodes[, dir[, width ]])](#gridstackuiutilssortnodes-dir-width)
60 - [ Touch devices support ]( #touch-devices-support )
61 - [ Use with knockout.js ]( #use-with-knockoutjs )
62 - [ Use with angular.js ]( #use-with-angularjs )
63 - [ Rails integration ]( #rails-integration )
64 - [ Change grid width ]( #change-grid-width )
65 - [ Extra CSS ]( #extra-css )
66 - [ Different grid widths ]( #different-grid-widths )
67 - [ Save grid to array ]( #save-grid-to-array )
68 - [ Load grid from array ]( #load-grid-from-array )
69 - [ Override resizable/draggable options ]( #override-resizabledraggable-options )
70 - [ IE8 support ]( #ie8-support )
71 - [ Nested grids ]( #nested-grids )
72 - [ Changes ]( #changes )
73 - [ v0.2.4 (2016-02-15) ]( #v024-2016-02-15 )
74 - [ v0.2.3 (2015-06-23) ]( #v023-2015-06-23 )
75 - [ v0.2.2 (2014-12-23) ]( #v022-2014-12-23 )
76 - [ v0.2.1 (2014-12-09) ]( #v021-2014-12-09 )
77 - [ v0.2.0 (2014-11-30) ]( #v020-2014-11-30 )
78 - [ v0.1.0 (2014-11-18) ]( #v010-2014-11-18 )
79 - [ License ]( #license )
81 <!-- END doctoc generated TOC please keep comment here to allow auto update -->
84 Demo
85 ====
87 Please visit http://troolee.github.io/gridstack.js/ for demo.
90 Usage
91 =====
93 ## Requirements
95 * [ lodash.js ]( https://lodash.com ) (>= 3.5.0)
96 * [ jQuery ]( http://jquery.com ) (>= 1.11.0)
97 * [ jQuery UI ]( http://jqueryui.com ) (>= 1.11.0). Minimum required components: Core, Widget, Mouse, Draggable, Resizable
98 * (Optional) [ knockout.js ]( http://knockoutjs.com ) (>= 3.2.0)
99 * (Optional) [ jquery-ui-touch-punch ]( https://github.com/furf/jquery-ui-touch-punch ) for touch-based devices support
101 Note: You can still use [ underscore.js ]( http://underscorejs.org ) (>= 1.7.0) instead of lodash.js
103 ## Basic usage
105 ```html
106 <div class="grid-stack">
107 <div class="grid-stack-item"
108 data-gs-x="0" data-gs-y="0"
109 data-gs-width="4" data-gs-height="2">
110 <div class="grid-stack-item-content"></div>
111 </div>
112 <div class="grid-stack-item"
113 data-gs-x="4" data-gs-y="0"
114 data-gs-width="4" data-gs-height="4">
115 <div class="grid-stack-item-content"></div>
116 </div>
117 </div>
119 <script type="text/javascript">
120 $(function () {
121 var options = {
122 cell_height: 80,
123 vertical_margin: 10
124 };
125 $('.grid-stack').gridstack(options);
126 });
127 </script>
128 ```
130 ## Options
132 - `always_show_resize_handle` - if `true` the resizing handles are shown even if the user is not hovering over the widget
133 (default: `false`)
134 - `animate` - turns animation on (default: `false` )
135 - `auto` - if `false` gridstack will not initialize existing items (default: `true` )
136 - `cell_height` - one cell height (default: `60` )
137 - `draggable` - allows to override jQuery UI draggable options. (default: `{handle: '.grid-stack-item-content', scroll: true, appendTo: 'body'}` )
138 - `handle` - draggable handle selector (default: `'.grid-stack-item-content'` )
139 - `handle_class` - draggable handle class (e.g. `'grid-stack-item-content'` ). If set `handle` is ignored (default: `null` )
140 - `height` - maximum rows amount. Default is `0` which means no maximum rows
141 - `float` - enable floating widgets (default: `false` ) See [ example ]( http://troolee.github.io/gridstack.js/demo/float.html )
142 - `item_class` - widget class (default: `'grid-stack-item'` )
143 - `min_width` - minimal width. If window width is less, grid will be shown in one-column mode. You need also update your css file ( `@media (max-width: 768px) {...}` ) with corresponding value (default: `768` )
144 - `placeholder_class` - class for placeholder (default: `'grid-stack-placeholder'` )
145 - `placeholder_text` - placeholder default content (default: `''` )
146 - `resizable` - allows to override jQuery UI resizable options. (default: `{autoHide: true, handles: 'se'}` )
147 - `static_grid` - makes grid static (default `false` ). If true widgets are not movable/resizable. You don't even need jQueryUI draggable/resizable. A CSS class `grid-stack-static` is also added to the container.
148 - `vertical_margin` - vertical gap size (default: `20` )
149 - `width` - amount of columns (default: `12` )
151 ## Grid attributes
153 - `data-gs-animate` - turns animation on
154 - `data-gs-width` - amount of columns
155 - `data-gs-height` - maximum rows amount. Default is `0` which means no maximum rows.
157 ## Item attributes
159 - `data-gs-x` , `data-gs-y` - element position
160 - `data-gs-width` , `data-gs-height` - element size
161 - `data-gs-max-width` , `data-gs-min-width` , `data-gs-max-height` , `data-gs-min-height` - element constraints
162 - `data-gs-no-resize` - disable element resizing
163 - `data-gs-no-move` - disable element moving
164 - `data-gs-auto-position` - tells to ignore `data-gs-x` and `data-gs-y` attributes and to place element to the first
165 available position
166 - `data-gs-locked` - the widget will be locked. It means another widget wouldn't be able to move it during dragging or resizing.
167 The widget can still be dragged or resized. You need to add `data-gs-no-resize` and `data-gs-no-move` attributes
168 to completely lock the widget.
170 ## Events
172 ### onchange(items)
174 Occurs when adding/removing widgets or existing widgets change their position/size
176 ```javascript
177 var serialize_widget_map = function (items) {
178 console.log(items);
179 };
181 $('.grid-stack').on('change', function (e, items) {
182 serialize_widget_map(items);
183 });
184 ```
186 ### ondragstart(event, ui)
188 ```javascript
189 $('.grid-stack').on('dragstart', function (event, ui) {
190 var grid = this;
191 var element = event.target;
192 });
193 ```
195 ### ondragstop(event, ui)
197 ```javascript
198 $('.grid-stack').on('dragstop', function (event, ui) {
199 var grid = this;
200 var element = event.target;
201 });
202 ```
204 ### onresizestart(event, ui)
206 ```javascript
207 $('.grid-stack').on('resizestart', function (event, ui) {
208 var grid = this;
209 var element = event.target;
210 });
211 ```
213 ### onresizestop(event, ui)
215 ```javascript
216 $('.grid-stack').on('resizestop', function (event, ui) {
217 var grid = this;
218 var element = event.target;
219 });
220 ```
222 ### disable(event)
224 ```javascipt
225 $('.grid-stack').on('disable', function(event) {
226 var grid = event.target;
227 });
228 ```
230 ### enable(event)
232 ```javascipt
233 $('.grid-stack').on('enable', function(event) {
234 var grid = event.target;
235 });
236 ```
238 ## API
240 ### add_widget(el, x, y, width, height, auto_position)
242 Creates new widget and returns it.
244 Parameters:
246 - `el` - widget to add
247 - `x` , `y` , `width` , `height` - widget position/dimensions (Optional)
248 - `auto_position` - if `true` then `x` , `y` parameters will be ignored and widget will be places on the first available
249 position
251 Widget will be always placed even if result height is more than actual grid height. You need to use `will_it_fit` method
252 before calling `add_widget` for additional check.
254 ```javascript
255 $('.grid-stack').gridstack();
257 var grid = $('.grid-stack').data('gridstack');
258 grid.add_widget(el, 0, 0, 3, 2, true);
259 ```
261 ### make_widget(el)
263 If you add elements to your gridstack container by hand, you have to tell gridstack afterwards to make them widgets. If you want gridstack to add the elements for you, use `add_widget` instead.
264 Makes the given element a widget and returns it.
266 Parameters:
268 - `el` - element to convert to a widget
270 ```javascript
271 $('.grid-stack').gridstack();
273 $('.grid-stack').append('<div id="gsi-1" data-gs-x="0" data-gs-y="0" data-gs-width="3" data-gs-height="2" data-gs-auto-position="1"></div>')
274 var grid = $('.grid-stack').data('gridstack');
275 grid.make_widget('gsi-1');
276 ```
278 ### batch_update()
280 Initailizes batch updates. You will see no changes until `commit` method is called.
282 ### cell_height()
284 Gets current cell height.
286 ### cell_height(val)
288 Update current cell height. This method rebuilds an internal CSS stylesheet. Note: You can expect performance issues if
289 call this method too often.
291 ```javascript
292 grid.cell_height(grid.cell_width() * 1.2);
293 ```
295 ### cell_width()
297 Gets current cell width.
299 ### commit()
301 Finishes batch updates. Updates DOM nodes. You must call it after `batch_update` .
303 ### destroy()
305 Destroys a grid instance.
307 ### disable()
309 Disables widgets moving/resizing. This is a shortcut for:
311 ```javascript
312 grid.movable('.grid-stack-item', false);
313 grid.resizable('.grid-stack-item', false);
314 ```
316 ### enable()
318 Enables widgets moving/resizing. This is a shortcut for:
320 ```javascript
321 grid.movable('.grid-stack-item', true);
322 grid.resizable('.grid-stack-item', true);
323 ```
325 ### get_cell_from_pixel(position)
327 Get the position of the cell under a pixel on screen.
329 Parameters :
331 - `position` - the position of the pixel to resolve in absolute coordinates, as an object with `top` and `left` properties
333 Returns an object with properties `x` and `y` i.e. the column and row in the grid.
335 ### is_area_empty(x, y, width, height)
337 Checks if specified area is empty.
339 ### locked(el, val)
341 Locks/unlocks widget.
343 - `el` - widget to modify.
344 - `val` - if `true` widget will be locked.
346 ### min_width(el, val)
348 Set the minWidth for a widget.
350 - `el` - widget to modify.
351 - `val` - A numeric value of the number of columns
353 ### min_height(el, val)
355 Set the minHeight for a widget.
357 - `el` - widget to modify.
358 - `val` - A numeric value of the number of rows
360 ### movable(el, val)
362 Enables/Disables moving.
364 - `el` - widget to modify
365 - `val` - if `true` widget will be draggable.
367 ### move(el, x, y)
369 Changes widget position
371 Parameters:
373 - `el` - widget to move
374 - `x` , `y` - new position. If value is `null` or `undefined` it will be ignored.
376 ### remove_widget(el, detach_node)
378 Removes widget from the grid.
380 Parameters:
382 - `el` - widget to remove.
383 - `detach_node` - if `false` DOM node won't be removed from the tree (Optional. Default `true` ).
385 ### remove_all()
387 Removes all widgets from the grid.
389 ### resize(el, width, height)
391 Changes widget size
393 Parameters:
395 - `el` - widget to resize
396 - `width` , `height` - new dimensions. If value is `null` or `undefined` it will be ignored.
398 ### resizable(el, val)
400 Enables/Disables resizing.
402 - `el` - widget to modify
403 - `val` - if `true` widget will be resizable.
405 ### set_static(static_value)
407 Toggle the grid static state. Also toggle the `grid-stack-static` class.
409 - `static_value` - if `true` the grid become static.
411 ### update(el, x, y, width, height)
413 Parameters:
415 - `el` - widget to move
416 - `x` , `y` - new position. If value is `null` or `undefined` it will be ignored.
417 - `width` , `height` - new dimensions. If value is `null` or `undefined` it will be ignored.
419 Updates widget position/size.
421 ### will_it_fit(x, y, width, height, auto_position)
423 Returns `true` if the `height` of the grid will be less the vertical constraint. Always returns `true` if grid doesn't
424 have `height` constraint.
426 ```javascript
427 if (grid.will_it_fit(new_node.x, new_node.y, new_node.width, new_node.height, true)) {
428 grid.add_widget(new_node.el, new_node.x, new_node.y, new_node.width, new_node.height, true);
429 }
430 else {
431 alert('Not enough free space to place the widget');
432 }
433 ```
436 ## Utils
438 ### GridStackUI.Utils.sort(nodes[, dir[, width]])
440 Sorts array of nodes
442 - `nodes` - array to sort
443 - `dir` - `1` for asc, `-1` for desc (optional)
444 - `width` - width of the grid. If `undefined` the width will be calculated automatically (optional).
446 ## Touch devices support
448 Please use [ jQuery UI Touch Punch ]( https://github.com/furf/jquery-ui-touch-punch ) to make jQuery UI Draggable/Resizable
449 working on touch-based devices.
451 ```html
452 <script src="lodash.min.js"></script>
453 <script src="jquery.min.js"></script>
454 <script src="jquery-ui.min.js"></script>
455 <script src="jquery.ui.touch-punch.min.js"></script>
457 <script src="gridstack.js"></script>
458 ```
460 Also `always_show_resize_handle` option may be useful:
462 ```javascript
463 $(function () {
464 var options = {
465 always_show_resize_handle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
466 };
467 $('.grid-stack').gridstack(options);
468 });
469 ```
471 ## Use with knockout.js
473 ```javascript
474 ko.components.register('dashboard-grid', {
475 viewModel: {
476 createViewModel: function (controller, componentInfo) {
477 var ViewModel = function (controller, componentInfo) {
478 var grid = null;
480 this.widgets = controller.widgets;
482 this.afterAddWidget = function (items) {
483 if (grid == null) {
484 grid = $(componentInfo.element).find('.grid-stack').gridstack({
485 auto: false
486 }).data('gridstack');
487 }
489 var item = _.find(items, function (i) { return i.nodeType == 1 });
490 grid.add_widget(item);
491 ko.utils.domNodeDisposal.addDisposeCallback(item, function () {
492 grid.remove_widget(item);
493 });
494 };
495 };
497 return new ViewModel(controller, componentInfo);
498 }
499 },
500 template:
501 [
502 '<div class="grid-stack" data-bind="foreach: {data: widgets, afterRender: afterAddWidget}">',
503 ' <div class="grid-stack-item" data-bind="attr: {\'data-gs-x\': $data.x, \'data-gs-y\': $data.y, \'data-gs-width\': $data.width, \'data-gs-height\': $data.height, \'data-gs-auto-position\': $data.auto_position}">',
504 ' <div class="grid-stack-item-content">...</div>',
505 ' </div>',
506 '</div> '
507 ].join('')
508 });
510 $(function () {
511 var Controller = function (widgets) {
512 this.widgets = ko.observableArray(widgets);
513 };
515 var widgets = [
516 {x: 0, y: 0, width: 2, height: 2},
517 {x: 2, y: 0, width: 4, height: 2},
518 {x: 6, y: 0, width: 2, height: 4},
519 {x: 1, y: 2, width: 4, height: 2}
520 ];
522 ko.applyBindings(new Controller(widgets));
523 });
524 ```
526 and HTML:
528 ```html
529 <div data-bind="component: {name: 'dashboard-grid', params: $data}"></div>
530 ```
532 See examples: [ example 1 ]( http://troolee.github.io/gridstack.js/demo/knockout.html ), [ example 2 ]( http://troolee.github.io/gridstack.js/demo/knockout2.html ).
534 **Notes:** It's very important to exclude training spaces after widget template:
536 ```
537 template:
538 [
539 '<div class="grid-stack" data-bind="foreach: {data: widgets, afterRender: afterAddWidget}">',
540 ' <div class="grid-stack-item" data-bind="attr: {\'data-gs-x\': $data.x, \'data-gs-y\': $data.y, \'data-gs-width\': $data.width, \'data-gs-height\': $data.height, \'data-gs-auto-position\': $data.auto_position}">',
541 ' ....',
542 ' </div>', // <-- NO SPACE **AFTER** </div>
543 '</div> ' // <-- NO SPACE **BEFORE** </div>
544 ].join('') // <-- JOIN WITH **EMPTY** STRING
545 ```
547 Otherwise `addDisposeCallback` won't work.
550 ## Use with angular.js
552 Please check [ gridstack-angular ]( https://github.com/kdietrich/gridstack-angular )
555 ## Rails integration
557 For rails users, integration of gridstack.js and its dependencies can be done through [ gridstack-js-rails ]( https://github.com/randoum/gridstack-js-rails )
560 ## Change grid width
562 To change grid width (columns count), to addition to `width` option, CSS rules
563 for `.grid-stack-item[data-gs-width="X"]` and `.grid-stack-item[data-gs-x="X"]` have to be changed accordingly.
565 For instance for 3-column grid you need to rewrite CSS to be:
567 ```css
568 .grid-stack-item[data-gs-width="3"] { width: 100% }
569 .grid-stack-item[data-gs-width="2"] { width: 66.66666667% }
570 .grid-stack-item[data-gs-width="1"] { width: 33.33333333% }
572 .grid-stack-item[data-gs-x="2"] { left: 66.66666667% }
573 .grid-stack-item[data-gs-x="1"] { left: 33.33333333% }
574 ```
576 For 4-column grid it should be:
578 ```css
579 .grid-stack-item[data-gs-width="4"] { width: 100% }
580 .grid-stack-item[data-gs-width="3"] { width: 75% }
581 .grid-stack-item[data-gs-width="2"] { width: 50% }
582 .grid-stack-item[data-gs-width="1"] { width: 25% }
584 .grid-stack-item[data-gs-x="3"] { left: 75% }
585 .grid-stack-item[data-gs-x="2"] { left: 50% }
586 .grid-stack-item[data-gs-x="1"] { left: 25% }
587 ```
589 and so on.
591 Here is a SASS code snipped which can make life easier (Thanks to @ascendantofrain, [ #81 ]( https://github.com/troolee/gridstack.js/issues/81 )):
593 ```sass
594 .grid-stack-item {
596 $gridstack-columns: 12;
598 @for $i from 1 through $gridstack-columns {
599 &[data-gs-width='#{$i}'] { width: (100% / $gridstack-columns) * $i; }
600 &[data-gs-x='#{$i}'] { left: (100% / $gridstack-columns) * $i; }
601 &.grid-stack-item[data-gs-min-width='#{$i}'] { min-width: (100% / $gridstack-columns) * $i; }
602 &.grid-stack-item[data-gs-max-width='#{$i}'] { max-width: (100% / $gridstack-columns) * $i; }
603 }
604 }
605 ```
607 Or you can include `gridstack-extra.css` . See below for more details.
609 ## Extra CSS
611 There are few extra CSS batteries in `gridstack-extra.css` ( `gridstack-extra.min.css` ).
613 ### Different grid widths
615 You can use other than 12 grid width:
617 ```html
618 <div class="grid-stack grid-stack-N">...</div>
619 ```
620 ```javascript
621 $('.grid-stack').gridstack({width: N});
622 ```
624 See example: [ 2 grids demo ]( http://troolee.github.io/gridstack.js/demo/two.html )
626 ## Save grid to array
628 Because gridstack doesn't track any kind of user-defined widget id there is no reason to make serialization to be part
629 of gridstack API. To serialize grid you can simply do something like this (let's say you store widget id inside `data-custom-id`
630 attribute):
632 ```javascript
633 var res = _.map($('.grid-stack .grid-stack-item:visible'), function (el) {
634 el = $(el);
635 var node = el.data('_gridstack_node');
636 return {
637 id: el.attr('data-custom-id'),
638 x: node.x,
639 y: node.y,
640 width: node.width,
641 height: node.height
642 };
643 });
644 alert(JSON.stringify(res));
645 ```
647 See example: [ Serialization demo ]( http://troolee.github.io/gridstack.js/demo/serialization.html )
649 You can also use `onchange` event if you need to save only changed widgets right away they have been changed.
651 ## Load grid from array
653 ```javascript
654 var serialization = [
655 {x: 0, y: 0, width: 2, height: 2},
656 {x: 3, y: 1, width: 1, height: 2},
657 {x: 4, y: 1, width: 1, height: 1},
658 {x: 2, y: 3, width: 3, height: 1},
659 {x: 1, y: 4, width: 1, height: 1},
660 {x: 1, y: 3, width: 1, height: 1},
661 {x: 2, y: 4, width: 1, height: 1},
662 {x: 2, y: 5, width: 1, height: 1}
663 ];
665 serialization = GridStackUI.Utils.sort(serialization);
667 var grid = $('.grid-stack').data('gridstack');
668 grid.remove_all();
670 _.each(serialization, function (node) {
671 grid.add_widget($('<div><div class="grid-stack-item-content" /></div>'),
672 node.x, node.y, node.width, node.height);
673 });
674 ```
676 See example: [ Serialization demo ]( http://troolee.github.io/gridstack.js/demo/serialization.html )
678 If you're using knockout there is no need for such method at all.
680 ## Override resizable/draggable options
682 You can override default `resizable` / `draggable` options. For instance to enable other then bottom right resizing handle
683 you can init gridsack like:
685 ```javascript
686 $('.grid-stack').gridstack({
687 resizable: {
688 handles: 'e, se, s, sw, w'
689 }
690 });
691 ```
693 Note: It's not recommended to enable `nw` , `n` , `ne` resizing handles. Their behaviour may be unexpected.
695 ## IE8 support
697 Support of IE8 is quite limited and is not a goal at this time. As far as IE8 doesn't support DOM Level 2 I cannot manipulate with
698 CSS stylesheet dynamically. As a workaround you can do the following:
700 - Create `gridstack-ie8.css` for your configuration (sample for grid with cell height of 60px can be found [ here ]( https://gist.github.com/troolee/6edfea5857f4cd73e6f1 )).
701 - Include this CSS:
703 ```html
704 <!--[if lt IE 9]>
705 <link rel="stylesheet" href="gridstack-ie8.css"/>
706 <![endif]-->
707 ```
709 - You can use this python script to generate such kind of CSS:
711 ```python
712 #!/usr/bin/env python
714 height = 60
715 margin = 20
716 N = 100
718 print '.grid-stack > .grid-stack-item { min-height: %(height)spx }' % {'height': height}
720 for i in range(N):
721 h = height * (i + 1) + margin * i
722 print '.grid-stack > .grid-stack-item[data-gs-height="%(index)s"] { height: %(height)spx }' % {'index': i + 1, 'height': h}
724 for i in range(N):
725 h = height * (i + 1) + margin * i
726 print '.grid-stack > .grid-stack-item[data-gs-min-height="%(index)s"] { min-height: %(height)spx }' % {'index': i + 1, 'height': h}
728 for i in range(N):
729 h = height * (i + 1) + margin * i
730 print '.grid-stack > .grid-stack-item[data-gs-max-height="%(index)s"] { max-height: %(height)spx }' % {'index': i + 1, 'height': h}
732 for i in range(N):
733 h = height * i + margin * i
734 print '.grid-stack > .grid-stack-item[data-gs-y="%(index)s"] { top: %(height)spx }' % {'index': i , 'height': h}
735 ```
737 There are at least two more issues with gridstack in IE8 with jQueryUI resizable (it seems it doesn't work) and
738 droppable. If you have any suggestions about support of IE8 you are welcome here: https://github.com/troolee/gridstack.js/issues/76
741 ## Nested grids
743 Gridstack may be nested. All nested grids have an additional class `grid-stack-nested` which is assigned automatically
744 during initialization.
745 See example: [ Nested grid demo ]( http://troolee.github.io/gridstack.js/demo/nested.html )
748 Changes
749 =======
751 #### v0.2.4 (2016-02-15)
753 - fix closure compiler/linter warnings
754 - add `static_grid` option.
755 - add `min_width` / `min_height` methods (Thanks to @cvillemure)
756 - add `destroy` method (Thanks to @zspitzer)
757 - add `placeholder_text` option (Thanks to @slauyama)
758 - lodash v 4.x support (Thanks to Andy Robbins)
760 #### v0.2.3 (2015-06-23)
762 - gridstack-extra.css
763 - add support of lodash.js
764 - add `is_area_empty` method
765 - nested grids
766 - add `batch_update` / `commit` methods
767 - add `update` method
768 - allow to override `resizable` / `draggable` options
769 - add `disable` / `enable` methods
770 - add `get_cell_from_pixel` (thanks to @juchi)
771 - AMD support
772 - fix nodes sorting
773 - improved touch devices support
774 - add `always_show_resize_handle` option
775 - minor fixes and improvements
777 #### v0.2.2 (2014-12-23)
779 - fix grid initialization
780 - add `cell_height` / `cell_width` API methods
781 - fix boolean attributes (issue #31)
783 #### v0.2.1 (2014-12-09)
785 - add widgets locking (issue #19)
786 - add `will_it_fit` API method
787 - fix auto-positioning (issue #20)
788 - add animation (thanks to @ishields)
789 - fix `y` coordinate calculation when dragging (issue #18)
790 - fix `remove_widget` (issue #16)
791 - minor fixes
794 #### v0.2.0 (2014-11-30)
796 - add `height` option
797 - auto-generate css rules (widgets `height` and `top` )
798 - add `GridStackUI.Utils.sort` utility function
799 - add `remove_all` API method
800 - add `resize` and `move` API methods
801 - add `resizable` and `movable` API methods
802 - add `data-gs-no-move` attribute
803 - add `float` option
804 - fix default css rule for inner content
805 - minor fixes
807 #### v0.1.0 (2014-11-18)
809 Very first version.
812 License
813 =======
815 The MIT License (MIT)
819 Permission is hereby granted, free of charge, to any person obtaining a copy
820 of this software and associated documentation files (the "Software"), to deal
821 in the Software without restriction, including without limitation the rights
822 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
823 copies of the Software, and to permit persons to whom the Software is
824 furnished to do so, subject to the following conditions:
826 The above copyright notice and this permission notice shall be included in all
827 copies or substantial portions of the Software.
829 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
830 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,