Compare commits

...

329 commits

Author SHA1 Message Date
Pavel Reznikov c1c4ff8e92 build js 2016-10-03 13:44:18 -07:00
Pavel Reznikov ff547b5ba0 Merge pull request #535 from troolee/releases
Releases
2016-10-03 13:42:17 -07:00
Pavel Reznikov b0e68cafca Merge pull request #534 from troolee/revert-532-patch-1
Revert "fixed ie8 not support"
2016-10-03 13:40:58 -07:00
Pavel Reznikov 9007eeafe7 Revert "fixed ie8 not support" 2016-10-03 13:39:39 -07:00
Pavel Reznikov 6d5f189613 Merge pull request #531 from madeITBelgium/patch-1
Delete not needed </script> tag
2016-10-03 13:35:04 -07:00
Pavel Reznikov 016c1610bc Merge pull request #532 from lpyt/patch-1
fixed ie8 not support
2016-10-03 13:34:40 -07:00
lpyt bd8bbfff2a fixed ie8 not support 2016-09-29 12:57:41 +08:00
Made I.T 4383fc846d Delete not needed </script> tag 2016-09-28 14:55:15 +02:00
radiolips 2f2c6bbaf4 Merge pull request #518 from radiolips/bugfix/actually-optimize-drag-resize
Bugfix/actually optimize drag resize
2016-08-21 10:40:30 -04:00
Dylan Weiss 5cf92a3c62 Only run checks for drag and resize if x, y, width, or height have changed at least one cell width/height. 2016-08-21 10:33:24 -04:00
Dylan Weiss 215a6f16a2 Merge commit '8a554b37c5dea0036d695596ef68985120d9b83d' 2016-08-20 18:18:34 -04:00
Pavel Reznikov 8a554b37c5 typo 2016-08-20 14:02:58 -07:00
Pavel Reznikov 8dc5916896 update install instructions 2016-08-20 13:45:17 -07:00
Pavel Reznikov 79d9b423ce fix dist 2016-08-20 13:44:01 -07:00
Pavel Reznikov 0102470f65 update install instruction 2016-08-20 13:43:50 -07:00
Pavel Reznikov 6ebd7a2005 0.2.7-dev -> 0.3.0-dev 2016-08-20 13:33:40 -07:00
Pavel Reznikov ca95e7ba49 update requirements section 2016-08-20 13:32:51 -07:00
Pavel Reznikov 6e4c6d2645 change log 2016-08-20 13:22:30 -07:00
Pavel Reznikov a749a930c0 Merge branch 'feature/dd-plugins' 2016-08-20 13:03:57 -07:00
Pavel Reznikov 999020bcff fix amd 2016-08-20 12:57:37 -07:00
Pavel Reznikov 5bc7d51959 build js 2016-08-20 12:48:10 -07:00
Pavel Reznikov 6ca195271f migrating to 0.2.7 notes 2016-08-20 12:48:02 -07:00
Pavel Reznikov 46b857a443 copy 2016-08-20 12:47:47 -07:00
d 6122ca4d27 Merge commit '67dc2dd85ce42746dbe22f988bd9ca3aae945501' 2016-08-19 10:08:09 -04:00
Pavel Reznikov e9460847ce update docs 2016-08-18 21:56:32 -07:00
Pavel Reznikov 56d9ec325d build js 2016-08-18 21:44:07 -07:00
Pavel Reznikov bc4d07687a update demo 2016-08-18 21:44:01 -07:00
Pavel Reznikov 625a8378b4 update tests 2016-08-18 21:43:55 -07:00
Pavel Reznikov a9a332cd8f update gruntfile/karma 2016-08-18 21:43:48 -07:00
Pavel Reznikov 3f193dbb3a move jQueryUI plugin to separate file 2016-08-18 21:43:28 -07:00
Pavel Reznikov 7cb3da3878 fix direct resizable calling 2016-08-18 21:42:59 -07:00
Pavel Reznikov 6d8ce2299c dd plugin registration 2016-08-18 21:01:23 -07:00
Pavel Reznikov eeff06dbe8 incapsulate drag/drop into plugin 2016-08-18 20:51:41 -07:00
Pavel Reznikov 0b3b47cefe merge with master 2016-08-18 20:10:50 -07:00
radiolips 67dc2dd85c Merge pull request #514 from radiolips/feature/isNodeChangedPosition
Feature/is node changed position
2016-08-18 16:26:00 -04:00
d 64ea5c4cf6 Add isNodeChangedPosition. 2016-08-18 16:19:48 -04:00
Pavel Reznikov 78f00738ab fix lint errors 2016-08-17 23:36:05 -07:00
Pavel Reznikov 30b096d5f9 dd plugin draft 2016-08-17 23:29:59 -07:00
Dylan Weiss 01a27c6ed9 Merge commit 'f1cdbe27c991b6eb96305df106d439ef0b322699' 2016-08-17 20:02:16 -04:00
radiolips f1cdbe27c9 Merge pull request #512 from radiolips/bugfix/462
Bugfix/462
2016-08-17 19:45:58 -04:00
Dylan Weiss af0f2d235b Fix #462 and remove 768px CSS limitation. 2016-08-17 19:09:02 -04:00
Dylan Weiss 76164595fe Merge commit 'f8b56af17bbc466cbf85efb281812296242c8cd5' 2016-08-17 15:55:52 -04:00
Pavel Reznikov f8b56af17b Update README.md 2016-08-17 12:50:34 -07:00
Pavel Reznikov d3db46a3a5 Update README.md 2016-08-17 12:48:22 -07:00
Pavel Reznikov a219accfa3 update cdn 2016-08-17 11:46:57 -07:00
Dylan Weiss 075c06f38e Merge commit '39ffe9ca3dcf394035c763138ee29683622c014c' 2016-08-17 13:37:54 -04:00
Pavel Reznikov 39ffe9ca3d copyrights 2016-08-17 09:43:21 -07:00
Pavel Reznikov eebc0b15a6 0.2.7-dev 2016-08-17 09:39:52 -07:00
Pavel Reznikov 5c605e48b7 update copyrights 2016-08-17 09:39:36 -07:00
Pavel Reznikov 28ed6fa374 fix version in packages 2016-08-17 09:27:15 -07:00
Pavel Reznikov a064a2ee6b readme 2016-08-17 09:22:42 -07:00
Pavel Reznikov 3928d05109 v0.2.6 2016-08-17 09:22:12 -07:00
radiolips 0d7c8edc92 Merge pull request #510 from radiolips/bugfix/505
Bugfix/505
2016-08-17 11:53:52 -04:00
Dylan Weiss 4ae4540bba README, dist. 2016-08-17 11:47:38 -04:00
Dylan Weiss 12605cceeb Don't mutate this.opts.draggable or this.opts.resizable when using _.extend. Fixes #505. 2016-08-17 11:45:52 -04:00
Dylan Weiss 8f072be871 Merge branch 'master' into bugfix/505 2016-08-17 11:44:46 -04:00
Dylan Weiss 75e936314b Merge commit '9c0bcd74e70aa1b5c8f97e32ca76cfad1a4a4466' 2016-08-17 11:44:29 -04:00
Dylan Weiss 5c4e44ef23 Merge commit '9c0bcd74e70aa1b5c8f97e32ca76cfad1a4a4466' into bugfix/505 2016-08-17 11:44:17 -04:00
radiolips 9c0bcd74e7 Merge pull request #509 from radiolips/bugfix/422
Bugfix/422
2016-08-17 11:08:35 -04:00
Dylan Weiss 042ba6a887 Merge branch 'master' into bugfix/422
# Conflicts:
#	README.md
#	dist/gridstack.js
#	dist/gridstack.min.js
#	dist/gridstack.min.map
#	src/gridstack.js
2016-08-17 10:55:22 -04:00
Dylan Weiss ceaffa8f54 Merge commit '723cb235b97f782f9c42fbb05d70ed3c3492e442' 2016-08-17 10:54:13 -04:00
radiolips 723cb235b9 Merge pull request #508 from radiolips/prep-for-026-release
Prep for 026 release
2016-08-17 10:49:39 -04:00
Dylan Weiss 137fe18995 Update readme and code for final 0.2.6. 2016-08-17 10:40:02 -04:00
Dylan Weiss ceef60d356 Fix #422, update to 0.2.7-dev. 2016-08-17 10:36:51 -04:00
Dylan Weiss 07ff68010e Merge commit 'fcd23271948583082959ade315653d3476112bd2' 2016-08-17 08:37:55 -04:00
Pavel Reznikov fcd2327194 readme 2016-08-16 22:06:05 -07:00
Pavel Reznikov 703c52dc59 Merge pull request #506 from troolee/fix/460
fix #460: fix cellWidth method
2016-08-16 22:03:26 -07:00
Pavel Reznikov d47ad9cd21 fix cellWidth test 2016-08-16 21:56:52 -07:00
Pavel Reznikov 11b6292d31 fix #460: fix cellWidth method 2016-08-16 21:43:28 -07:00
radiolips b09ae61fe2 Merge pull request #503 from radiolips/bugfix/481
Bugfix/481
2016-08-16 15:44:06 -04:00
d 696b0f7ca8 Fix #481. 2016-08-16 15:36:22 -04:00
d 56801119c2 Merge commit 'a04a2477439c520ad74bcfe3a7bf502b98df3f89' 2016-08-16 15:19:03 -04:00
radiolips a04a247743 Merge pull request #502 from radiolips/bugfix/notify-fix
Bugfix/notify fix - #411
2016-08-16 15:08:37 -04:00
d 34213e6fe9 411 and 141. Same thing, right? Womp. 2016-08-16 15:00:19 -04:00
d dbe642f294 Add fixes to readme. 2016-08-16 14:56:09 -04:00
d 491388379c Include built files. 2016-08-16 14:38:13 -04:00
d 0c424c2637 Always call notify when removing a widget. Only remove the actual element if detachNode is not false. Update tests to reflect these changes. 2016-08-16 14:36:02 -04:00
d c0704f18d4 Merge commit '1079cd4c1c1619d262a7d319925614d423dbed75' 2016-08-16 13:48:36 -04:00
radiolips 1079cd4c1c Merge pull request #501 from nikcub/nikcub-grunt-cli-requirement
Add grunt-cli as dev dependancy
2016-08-15 10:28:48 -04:00
radiolips 5498ce2bae Merge pull request #500 from nikcub/nikcub-droppable-requirement
Add jQuery UI droppable as requirement
2016-08-15 09:11:13 -04:00
Nik Cubrilovic 669c6747f2 Add grunt-cli as dev dependancy 2016-08-15 23:01:37 +10:00
Nik Cubrilovic cb7e0bdeb4 Add jQuery UI Droppable as module requirement - dist files 2016-08-15 22:57:17 +10:00
Nik Cubrilovic 7f1d362a29 Add jQuery UI Droppable as module requirement 2016-08-15 22:57:04 +10:00
Dylan Weiss 62f07b2da1 Merge commit '2de0c4ee00b1b3bd696dac7091a9c9c444337218' 2016-08-13 11:34:48 -04:00
Pavel Reznikov 2de0c4ee00 Merge pull request #497 from redstubble/master
Add https to CDN's with only network-path references.
2016-08-11 22:29:20 -07:00
John Williams 020523855e Add https to CDN's with only network-path references. 2016-08-12 13:21:00 +12:00
radiolips 9cc4396f2e Merge pull request #496 from radiolips/feature/update-jquery-ui-amd
Feature/update jquery ui amd
2016-08-11 16:46:18 -04:00
d d909458602 Add built files. 2016-08-11 16:36:50 -04:00
d 8f69732dda Update jquery-ui AMD requirements. 2016-08-11 16:35:44 -04:00
d d3b77baf8c Merge commit 'f29236a78fa14795745d36efcb79ee20e02e947b' 2016-08-10 12:45:43 -04:00
Pavel Reznikov f29236a78f Merge pull request #493 from troolee/troolee
Troolee
2016-08-09 19:52:37 -07:00
Pavel Reznikov 6579b4c93d dev dep 2016-08-09 19:49:05 -07:00
Pavel Reznikov 8c240d1e83 dev dep 2016-08-09 19:43:50 -07:00
Pavel Reznikov cabb0b886a update travis 2016-08-09 19:30:37 -07:00
Pavel Reznikov 8ea6b706ba update dev dependencies 2016-08-09 19:30:10 -07:00
Pavel Reznikov 47fbdd1ff3 Merge pull request #492 from troolee/develop
0.2.6-dev
2016-08-09 18:59:22 -07:00
Pavel Reznikov 9a9e8ece7e build js 2016-08-09 18:54:46 -07:00
Pavel Reznikov d7a4171b54 fix ident 2016-08-09 18:54:39 -07:00
Pavel Reznikov 4c3abe8e63 fix jquery size() 2016-08-09 18:54:26 -07:00
Pavel Reznikov fb157a3dd2 update requirements 2016-08-09 18:53:51 -07:00
Pavel Reznikov 0336d2401e starting 0.2.6-dev 2016-08-09 18:53:32 -07:00
Pavel Reznikov f0c76130e7 gridster link 2016-08-06 22:54:41 -07:00
Dylan Weiss 9fecc0dcb5 Merge branch 'bugfix/jquery-ui-update' 2016-07-19 18:04:58 -04:00
Dylan Weiss 69ebbdbae5 Fix silly jQuery-ui updates (get rid of core and add /widgets to the widget calls. 2016-07-19 18:04:45 -04:00
Dylan Weiss c9971a69a4 Merge commit '99653bded3afc20d67660bb98c76cf5e0e70139d' 2016-07-19 18:00:39 -04:00
Pavel Reznikov 99653bded3 Update README.md
fix #430
2016-04-22 16:15:15 -07:00
Pavel Reznikov acaec8d429 close #426 2016-04-22 15:46:14 -07:00
Pavel Reznikov 35b9c6a6c2 Merge pull request #431 from rharriso/master
Remove requirement for jQueryUI when grid is static
2016-04-21 15:12:37 -07:00
Ross Harrison 4399e1a455 clean and build 2016-04-21 11:45:59 -04:00
Ross Harrison 94b249c77d don't trigger drag events without jquery ui 2016-04-21 11:45:25 -04:00
Ross Harrison 0a5d67cfc8 clean and build 2016-04-21 11:16:20 -04:00
Ross Harrison f20fb331c9 static grid removes jquery ui requirement 2016-04-21 11:12:24 -04:00
Ross Harrison cad14ab88e actually build 2016-04-21 11:11:58 -04:00
Pavel Reznikov 61ed99ab5c build js 2016-04-08 09:20:50 -07:00
Pavel Reznikov 0c409773a7 Merge pull request #420 from Julienng/master
Fire resize event for gridstack node when changing view
2016-04-08 09:20:27 -07:00
julien cavaleiro cc9271bcb5 Missing semicolon 2016-04-08 11:49:11 +02:00
julien cavaleiro 08f8b1d118 every node of gridstack should trigger resize when gridstack pass from desktop to mobile view. 2016-04-08 11:36:38 +02:00
julien cavaleiro 2c71ce639c every node of gridstack should trigger resize when gridstack pass from desktop to mobile view. 2016-04-08 11:22:56 +02:00
Pavel Reznikov f04965a78e Merge pull request #407 from illusionalsagacity/master
fix: SVG resizable icons not showing in Internet Explorer.
2016-03-30 23:21:16 -07:00
illusionalsagacity 90838740b0 fix: SVG resizable icons not showing in Internet Explorer.
IE9+ does not like the UTF8 encoding specifier.
2016-03-30 10:41:14 -04:00
Pavel Reznikov 7b1f147283 update dev dependencies 2016-03-09 13:08:47 -08:00
Pavel Reznikov 0c0b7793dd Update index.html 2016-03-09 10:08:19 -08:00
Pavel Reznikov fa9736ee84 Update README.md 2016-03-09 10:07:37 -08:00
Pavel Reznikov 0318e3a922 update readme 2016-03-06 12:11:41 -08:00
Pavel Reznikov 2f29a71c8f Merge branch 'master' of https://github.com/troolee/gridstack.js 2016-03-06 12:10:44 -08:00
Pavel Reznikov d06834c5cc add faq 2016-03-06 12:09:51 -08:00
Pavel Reznikov 01c7607d0b Update README.md 2016-03-02 21:58:48 -08:00
Pavel Reznikov 8a419fbda7 Merge pull request #380 from troolee/release/0.2.5
v0.2.5
2016-03-02 20:41:35 -08:00
Pavel Reznikov c93ff95c03 v0.2.5 2016-03-02 19:58:52 -08:00
d 19a52197c2 Commas are overrated. 2016-03-02 08:53:09 -05:00
d a3babd353c This should work better. 2016-03-02 08:49:41 -05:00
d 376a5f2945 Adding bithoundrc. 2016-03-02 08:44:29 -05:00
d 61fc120b11 Merge commit '93bedb4404597ab74426141aa3aec27ef6134dd1' 2016-03-02 08:03:21 -05:00
Pavel Reznikov 93bedb4404 Merge pull request #378 from troolee/tests/grid-height
Tests/grid height
2016-03-02 01:15:34 -08:00
Pavel Reznikov 373c1eab14 build dist 2016-03-02 01:09:21 -08:00
Pavel Reznikov 92d7e51d68 fix #373 2016-03-02 01:09:10 -08:00
Pavel Reznikov e4fecff7f7 error with setup height 2016-03-02 01:07:03 -08:00
Pavel Reznikov 208a8baf64 Merge pull request #377 from troolee/tests/end-to-end
move webdriver-manager start to grunt
2016-03-01 23:42:54 -08:00
Pavel Reznikov e2b88ec0d9 move webdriver-manager start to grunt 2016-03-01 23:32:10 -08:00
Pavel Reznikov de83c6230b Merge pull request #376 from troolee/tests/end-to-end
e2e tests
2016-03-01 23:21:59 -08:00
Pavel Reznikov 4862a61af3 protractor e2e test 2016-03-01 23:16:40 -08:00
d 205df5ded4 Merge commit '3d19aede54055b00c3fe8c7b8affd8b7c9ab1fbe' 2016-03-01 15:22:32 -05:00
radiolips 3d19aede54 Merge pull request #375 from radiolips/tests/frontend-1
Tests/frontend 1
2016-03-01 15:21:05 -05:00
d 398dccb7a9 Add default values for verticalMarginUnit and cellHeightUnit, update readme to have verticalMargin info, and several more unit tests. 2016-03-01 15:15:32 -05:00
Pavel Reznikov 1dd2420207 Update README.md 2016-03-01 11:26:28 -08:00
d 3d0c8baefe Merge branch 'master' into tests/frontend-1 2016-03-01 13:07:21 -05:00
d 620d190ba9 Merge commit '7f0d4921a5c39a7673b31071fffd3aa4f8d2035c' 2016-03-01 13:07:00 -05:00
radiolips 7f0d4921a5 Merge pull request #374 from radiolips/tests/frontend-1
Tests/frontend 1
2016-03-01 11:28:37 -05:00
d f29a34aaea Merge branch 'tests/frontend-1' of https://github.com/radiolips/gridstack.js into tests/frontend-1 2016-03-01 11:22:55 -05:00
Pavel Reznikov 0273bb66d8 Update dist. (+14 squashed commits)
Squashed commits:
[50607a9] build dist
[ff0c00b] Allow negative numbers to be passed to parseHeight function test case fix
[3ecc1ca] Allow negative numbers to be passed to parseHeight function test case
[d20f670] Allow negative numbers to be passed to parseHeight function fix
[0816163] Allow negative numbers to be passed to parseHeight function
[aa18c63] rebuild dist
[601b5d5] setGridWidth api documentation udpdate
[c309856] Add a parameter to setGridWidth method to allow not to propagate resizing to widgets.
[ea442d1] drag between grids
[50ce614] jqueryui + requirejs note
[3d8a8e1] drag between grids demo
[446dade] drag from sidebar/between grids
[e31d50e] check if element setup before detach
[67274f8] trash zone is accepting only widgets
2016-03-01 11:22:39 -05:00
d c14473fab1 Update dist. 2016-03-01 11:20:03 -05:00
d 6cd56abe11 Merge branch 'master' into tests/frontend-1 2016-03-01 11:15:26 -05:00
d 2ddd6d5adb Merge commit '50607a9797d98ce856ec8c4ee1e140928a88cf3a' 2016-03-01 11:14:54 -05:00
d 0b944927ab More tests (including all obsolete options), clean up unnecessary code. 2016-03-01 11:14:26 -05:00
Pavel Reznikov 50607a9797 build dist 2016-03-01 00:00:01 -08:00
Pavel Reznikov 156b8e40cb Merge pull request #370 from krema/master
Allow negative numbers to be passed to parseHeight function
2016-02-29 23:59:28 -08:00
André Kremser ff0c00bc34 Allow negative numbers to be passed to parseHeight function test case fix 2016-02-29 23:56:17 -08:00
André Kremser 3ecc1caab9 Allow negative numbers to be passed to parseHeight function test case 2016-02-29 23:53:59 -08:00
Pavel Reznikov aa18c6332e rebuild dist 2016-02-29 23:49:34 -08:00
Pavel Reznikov b3d5be137c Merge pull request #371 from pmoradei/setgridsize_propagate
Add a parameter to setGridWidth method to allow not to propagate resi…
2016-02-29 23:49:11 -08:00
pmoradei 601b5d54a3 setGridWidth api documentation udpdate 2016-03-01 08:42:22 +01:00
Pavel Reznikov 65d5110349 Merge pull request #372 from troolee/features/add-from-sidebar
Features/add from sidebar
2016-02-29 23:24:00 -08:00
Pavel Reznikov ea442d1936 drag between grids 2016-02-29 23:10:23 -08:00
Pavel Reznikov d010ddd93e Merge branch 'master' into features/add-from-sidebar 2016-02-29 22:06:53 -08:00
Pavel Reznikov 50ce614128 jqueryui + requirejs note 2016-02-29 22:05:28 -08:00
pmoradei c309856f8d Add a parameter to setGridWidth method to allow not to propagate resizing to widgets. 2016-02-29 19:52:46 +01:00
Pavel Reznikov 3d8a8e1e42 drag between grids demo 2016-02-28 22:08:33 -08:00
Pavel Reznikov 446dade5d0 drag from sidebar/between grids 2016-02-28 22:08:05 -08:00
André Kremser d20f6703c6 Allow negative numbers to be passed to parseHeight function fix 2016-02-28 15:55:45 -08:00
André Kremser 0816163693 Allow negative numbers to be passed to parseHeight function 2016-02-28 11:26:17 -08:00
Pavel Reznikov e31d50eedc check if element setup before detach 2016-02-27 18:47:24 -08:00
Pavel Reznikov 67274f873c trash zone is accepting only widgets 2016-02-27 18:46:41 -08:00
radiolips ba1ee253bb Merge pull request #364 from radiolips/tests/frontend-1
Fix _is_one_column_mode -> _isOneColumnMode and add in obsolete unit …
2016-02-25 16:52:19 -05:00
d eedf6d5716 Fix _is_one_column_mode -> _isOneColumnMode and add in obsolete unit checks for all gs, non-GSEngine code. 2016-02-25 16:48:57 -05:00
radiolips 6aae19b80d Merge pull request #363 from radiolips/tests/frontend-1
Tests/frontend 1
2016-02-25 15:55:53 -05:00
d 51d7a20116 Comments left in. Whoops. 2016-02-25 15:49:41 -05:00
d b9c916554e Added parseInt(x, 10) to cellWidth and added some unit tests. 2016-02-25 15:48:25 -05:00
d 4af1f27447 Merge commit 'f96dae55f32612344896a3b52318fa451bd69b83' 2016-02-24 13:29:13 -05:00
radiolips f96dae55f3 Merge pull request #361 from radiolips/bugfix/detach-grid-2
Bugfix/detach grid 2
2016-02-24 13:23:39 -05:00
d d521ef5330 Bit safer. 2016-02-24 13:22:36 -05:00
d 19f41a72a8 Fix one bug and another pops up. This fixes issue where passing detachNode=false to removeWidget would still cause it to be removed from the DOM. 2016-02-24 13:20:04 -05:00
d 1c040b7e0b Merge commit 'bc6222771710a1820e304ff9635664df448d939b' 2016-02-24 12:45:38 -05:00
radiolips bc62227717 Merge pull request #360 from radiolips/bugfix/detach-grid
Bugfix/detach grid
2016-02-24 11:12:38 -05:00
d 735ffa2129 Fixes bug when calling destroy with detachGrid=false. Thanks @jhpedemonte. 2016-02-24 11:05:54 -05:00
d e1602ed658 Merge commit '8faecc91769cd43431524065ea35bac10ee33cb5' 2016-02-24 07:50:28 -05:00
Pavel Reznikov 8faecc9176 tests 2016-02-23 22:00:07 -08:00
Pavel Reznikov a053998899 Merge branch 'master' of https://github.com/troolee/gridstack.js 2016-02-23 21:44:36 -08:00
Pavel Reznikov e1d8c736b8 tests 2016-02-23 21:44:27 -08:00
Pavel Reznikov f447890421 Update README.md 2016-02-23 20:25:28 -08:00
Pavel Reznikov 3e78afceb5 update two grids demo 2016-02-23 20:13:19 -08:00
Pavel Reznikov 9d12e25a02 improve removable behaviour 2016-02-23 20:13:11 -08:00
Dylan Weiss 68ebd3e5a5 Merge commit 'a51a802268fe34d1a5d5331c3d0cb5e68bc76632' 2016-02-23 21:28:19 -05:00
radiolips a51a802268 Merge pull request #358 from radiolips/demo/anijs
Demo/anijs
2016-02-23 21:21:10 -05:00
Dylan Weiss 5a427dd6bd Merge commit 'cac983e2affd6efd7470d43593f243fbe99199be' into demo/anijs 2016-02-23 21:16:36 -05:00
Dylan Weiss b44308b4ed Animate widgets. Just for troolee. 2016-02-23 21:16:12 -05:00
Pavel Reznikov cac983e2af build js 2016-02-23 15:01:53 -08:00
Dylan Weiss b41dfe062c Merge commit '91757911fa3e19bd52e96d4d49d34f8d8dc2bf2e' 2016-02-23 17:50:37 -05:00
radiolips 91757911fa Merge pull request #357 from radiolips/demo/anijs
Demo/anijs
2016-02-23 17:48:51 -05:00
Dylan Weiss ab6df29429 Add AniJS demo. 2016-02-23 17:47:11 -05:00
d 32dcc4725c Merge commit 'e34407d40c151e00e5127c642c6793bbed325889' 2016-02-23 12:50:19 -05:00
radiolips e34407d40c Merge pull request #355 from radiolips/feature/54/add-remove-events
Feature/54/add remove events
2016-02-23 11:52:41 -05:00
d 2abfbb37bf #54 - Added added and removed events. 2016-02-23 11:46:24 -05:00
Dylan Weiss 3f374257f2 Merge commit 'a33f046fa6b05ad2e42f4b3eaf2d0921504f2b4b' 2016-02-23 05:34:55 -05:00
Pavel Reznikov a33f046fa6 fix in isAreaEmpty and _notify 2016-02-22 22:48:20 -08:00
Pavel Reznikov 00d780adfa GridStackEngine testing 2016-02-22 22:47:43 -08:00
Pavel Reznikov 6cd5084a23 fix isAreaEmpty 2016-02-22 22:21:13 -08:00
Pavel Reznikov eca0e9f9bd team 2016-02-22 21:41:06 -08:00
Pavel Reznikov 88e3c1d8e5 dependencies and badges 2016-02-22 21:40:58 -08:00
Pavel Reznikov 85740de2e0 build dist 2016-02-22 21:40:36 -08:00
Pavel Reznikov 54b2b9105e GridstackEngine tests 2016-02-22 21:09:57 -08:00
Pavel Reznikov fba9bd52db remove tests from jscs 2016-02-22 20:50:17 -08:00
Pavel Reznikov 9c01f02f1a build dist 2016-02-22 20:44:07 -08:00
Pavel Reznikov 907464c891 tests 2016-02-22 20:43:51 -08:00
Pavel Reznikov 707916d6da fix parseHeight 2016-02-22 20:43:44 -08:00
Pavel Reznikov 23cd18804a remove unused code 2016-02-22 20:43:29 -08:00
Pavel Reznikov cddbf077be cover Utils.isIntercepted 2016-02-22 18:59:32 -08:00
Dylan Weiss 9e8d5c3203 Merge commit '9168a7fc518b7baea5b5c0c0a701d239ce8cbf2b' 2016-02-22 18:08:28 -05:00
Pavel Reznikov 9168a7fc51 remove unnecessary deps 2016-02-22 13:48:23 -08:00
d 41f1b5c42a Merge commit '2247a361c29df03b137b5bdd7b94a646a6db04d8' 2016-02-22 16:24:44 -05:00
Pavel Reznikov 2247a361c2 coverall 2016-02-22 13:04:34 -08:00
Pavel Reznikov d915030cd6 trying to setup coveralls 2016-02-22 12:52:09 -08:00
Kevin Dietrich 8a7bbd76c7 Merge pull request #351 from kdietrich/travis
Travis
2016-02-22 20:43:23 +01:00
Kevin Dietrich 464a8e8982 Added travis 2016-02-22 20:39:22 +01:00
Pavel Reznikov 698fce3ac4 Update README.md 2016-02-22 10:48:00 -08:00
d f990b71464 Merge commit 'fcae35661fc549c831d1b596272f35aead0c618c' 2016-02-22 13:44:09 -05:00
Pavel Reznikov fcae35661f Update README.md 2016-02-22 10:34:35 -08:00
Kevin Dietrich 42bb51b876 Merge remote-tracking branch 'troolee/master' 2016-02-22 19:19:12 +01:00
Kevin Dietrich acdd8b9100 Merge pull request #350 from kdietrich/tests
Fixed missing comma
2016-02-22 19:17:11 +01:00
Kevin Dietrich 98d1e301f0 Fixed missing comma 2016-02-22 19:16:25 +01:00
Pavel Reznikov 9d269e18f2 Merge pull request #349 from kdietrich/tests
Unit Tests
2016-02-22 10:13:40 -08:00
Kevin Dietrich 934863e285 Merge remote-tracking branch 'troolee/master' into tests
# Conflicts:
#	package.json
2016-02-22 19:09:50 +01:00
Kevin Dietrich 1c4738084a Added first tests 2016-02-22 19:06:54 +01:00
d 78058d9cbe Merge commit 'c02c2a36d18333a20081235aeba7b38ae91a3b39' 2016-02-22 12:41:06 -05:00
radiolips c02c2a36d1 Merge pull request #348 from radiolips/feature/188/addWidget-params
Feature/188/add widget params
2016-02-22 12:22:45 -05:00
d 5f5a83d01b Added several optional parameters to addWidget: minWidth, maxWidth, minHeight, maxHeight, and id. 2016-02-22 12:21:32 -05:00
d 43c400db8c Merge commit 'ae95373f794fb8977d95e7e8715f1c59ba141bc3' 2016-02-22 10:59:27 -05:00
radiolips ae95373f79 Merge pull request #347 from radiolips/feature/237/get-cell-from-position-param
Feature/237/get cell from position param
2016-02-22 10:59:09 -05:00
d 78803147c6 #237 Add optional useOffset parameter to getCellFromPixel. 2016-02-22 10:56:49 -05:00
d 1039368121 Merge commit 'b67ac87f7dd9cd35be939ddd43e71e15d0e7fa98' 2016-02-22 09:42:36 -05:00
radiolips b67ac87f7d Merge pull request #346 from radiolips/feature/216/destroy-param
Feature/216/destroy param
2016-02-22 09:34:14 -05:00
d de26b00f85 #216 Add detachGrid parameter to destroy. Updated docs for remove and removeAll param. 2016-02-22 09:33:09 -05:00
d d1c90cf3d7 Merge commit '9d80ede0b90840f5ad3b06a30f9f0d2cc66a2891' 2016-02-22 08:57:58 -05:00
Pavel Reznikov 9d80ede0b9 build dist 2016-02-21 20:50:09 -08:00
Pavel Reznikov 1c67f7d6d7 Merge branch 'master' of https://github.com/troolee/gridstack.js 2016-02-21 20:49:41 -08:00
Pavel Reznikov 2075d2556b add removable option 2016-02-21 20:49:18 -08:00
Pavel Reznikov a5d06d2b1f css fix: hide resize handle during dragging 2016-02-21 20:44:00 -08:00
radiolips 4feab20cdf Merge pull request #344 from radiolips/demo/responsive
Demo/responsive
2016-02-21 20:44:45 -05:00
Dylan Weiss 6954d2c9b7 Remove FontAwesome from demos. Add responsive demo. 2016-02-21 20:43:52 -05:00
Pavel Reznikov d3dcb6b61b demo index 2016-02-21 03:23:33 -08:00
Pavel Reznikov 715d972a4f update jscsrc 2016-02-21 00:49:55 -08:00
Dylan Weiss ba086c7c0a Merge commit 'ab9b8eb78c329798cf79397ec685f23b4483053d' 2016-02-20 11:55:07 -05:00
radiolips ab9b8eb78c Merge pull request #342 from radiolips/feature/227/Change-grid-columns
Feature/227/change grid columns
2016-02-20 11:42:21 -05:00
Dylan Weiss 9b455d6018 #227 Add setGridWidth(gridWidth) method. Attempts to intelligently change existing widgets' x-coordinate and width to map to new width. 2016-02-20 11:37:34 -05:00
Dylan Weiss 308a33bb45 Merge commit 'af1729497132ad4d9fca8c5944e473d058d71787' 2016-02-20 09:59:01 -05:00
radiolips af17294971 Merge pull request #341 from radiolips/feature/114/Update-api-doc
Typo.
2016-02-20 09:57:10 -05:00
Dylan Weiss 4b7cc8d24b Typo. 2016-02-20 09:56:03 -05:00
radiolips 07fd836de6 Merge pull request #340 from radiolips/feature/114/Update-api-doc
#114 Add setAnimate(doAnimate) to API docs.
2016-02-20 09:53:15 -05:00
Dylan Weiss c185a7a093 Add grunt-jscs to package.json dev dependencies, update doctoc. 2016-02-20 09:49:27 -05:00
Dylan Weiss 72432d0fa8 #114 Add setAnimate(doAnimate) to API docs. 2016-02-20 09:42:18 -05:00
Pavel Reznikov c34777b2a0 hack for meteor support 2016-02-20 01:14:04 -08:00
Pavel Reznikov ce2cd06c01 update .jscsrc 2016-02-20 01:13:44 -08:00
Pavel Reznikov 3a5c675e6f ‘auto’ value for cellHeight 2016-02-20 00:55:33 -08:00
Pavel Reznikov c4f30b3df1 update README.md 2016-02-20 00:21:27 -08:00
Pavel Reznikov ce47d340d2 typo 2016-02-20 00:20:50 -08:00
Pavel Reznikov 049ef64c51 update README.md 2016-02-20 00:13:19 -08:00
Pavel Reznikov 495918f9c7 build dist 2016-02-20 00:11:17 -08:00
Pavel Reznikov e09b0c9a30 rtl demo 2016-02-20 00:11:12 -08:00
Pavel Reznikov 4b13d407b0 rtl support 2016-02-20 00:11:06 -08:00
Pavel Reznikov 76f90a21f3 clean scss 2016-02-20 00:07:54 -08:00
Pavel Reznikov 9b531d0571 update grunt 2016-02-19 23:49:19 -08:00
Pavel Reznikov cea9174bd3 move parseHeight to Utils 2016-02-19 23:37:25 -08:00
Pavel Reznikov 632c3e14c2 Update README.md 2016-02-19 23:32:16 -08:00
Pavel Reznikov 781776e408 remove dependency from FontAwesome 2016-02-19 23:23:27 -08:00
Pavel Reznikov 2e4964d675 grunt watch 2016-02-19 23:23:20 -08:00
Pavel Reznikov 15192f33bd exclude demo files from jscs 2016-02-19 23:20:30 -08:00
Pavel Reznikov 100860d262 move API doc from readme 2016-02-19 19:45:51 -08:00
Pavel Reznikov 7c586417fb fix #267 2016-02-19 18:17:46 -08:00
Pavel Reznikov c43a12ac06 code style 2016-02-19 16:45:30 -08:00
Pavel Reznikov 47218bd7a6 fix jshit warnings 2016-02-19 14:31:24 -08:00
Pavel Reznikov e52d16defa add jshint to grunt tasks 2016-02-19 14:31:06 -08:00
Kevin Dietrich d3d00d563f Set engine for testing purposes 2016-02-19 19:59:58 +01:00
Kevin Dietrich 504b0ad4ac Added coverage 2016-02-19 19:58:32 +01:00
Pavel Reznikov b8bd181970 Viewport Size fix 2016-02-19 09:33:29 -08:00
radiolips f5311ec8d0 Merge pull request #337 from radiolips/bugfix/331/keep-disabled
Update changes section of readme.
2016-02-19 11:27:43 -05:00
d 56b4c7f12c Update changes section of readme. 2016-02-19 11:26:33 -05:00
Kevin Dietrich b9b52603e8 Setup unit tests 2016-02-19 17:23:22 +01:00
radiolips eca0ce7335 Merge pull request #336 from radiolips/bugfix/331/keep-disabled
Bugfix/331/keep disabled
2016-02-19 11:23:20 -05:00
Kevin Dietrich 0202fa9257 Updated .gitignore 2016-02-19 17:23:10 +01:00
d ff15070de0 Fix #331. Add options to disable move and resize independently without impacting jquery-ui options. Update enableMove and enableResize methods to update these options on-the-fly. 2016-02-19 11:18:09 -05:00
d bb0ce8fab1 Merge commit '47817a3489b063c1e3d92b9b36a7b731dab899a3' 2016-02-19 09:48:37 -05:00
radiolips 47817a3489 Merge pull request #334 from radiolips/bugfix/staticGrid
Bugfix/static grid
2016-02-18 20:20:14 -05:00
d 03ca75717c Merge branch 'master' into bugfix/staticGrid
# Conflicts:
#	dist/gridstack.min.map
2016-02-18 16:52:57 -05:00
d 1364e180e1 Merge commit 'a830cc51d0bdce57c331655caaac6a1ff8ab74c3' 2016-02-18 16:49:44 -05:00
d ca800454f1 #220. Add enableMove and enableResize. Fix staticGrid. 2016-02-18 16:48:16 -05:00
Pavel Reznikov a830cc51d0 build js 2016-02-18 09:51:30 -08:00
Pavel Reznikov 6e0aab4780 Revert "Viewport Size" 2016-02-18 09:49:33 -08:00
Stuardo -StR- Rodríguez b979982cc5 Viewport
- do not parseInt but parseFloat
2016-02-18 11:33:49 -05:00
Kevin Dietrich ed8a673022 Merge remote-tracking branch 'troolee/master' 2016-02-18 17:18:43 +01:00
Stuardo -StR- Rodríguez 71c15ee64c Merge pull request #1 from str/str-viewport-size
Viewport Size
2016-02-18 11:16:42 -05:00
Stuardo -StR- Rodríguez 331eef1f57 Viewport Size
Allow viewport height units. Allow to use float as size.
example:  1.5em;  33vh;
2016-02-18 11:15:58 -05:00
d 9c51fa040f Merge commit 'a4540dc118a1ba14d06513b652e0a566a431e3a5' 2016-02-18 10:23:44 -05:00
Pavel Reznikov a4540dc118 Update README.md 2016-02-17 22:30:54 -08:00
Pavel Reznikov fe865db460 remove knockout.js from requirements 2016-02-17 19:23:49 -08:00
Pavel Reznikov 02f0eba64d add maxWidth/maxHeight 2016-02-17 19:03:21 -08:00
Pavel Reznikov 29857f4131 update doc to be all functions in alphabetical order 2016-02-17 18:50:59 -08:00
Pavel Reznikov 45d39a0b3a Merge branch 'radiolips-style' 2016-02-17 18:48:26 -08:00
Pavel Reznikov 1527485f75 update demo 2016-02-17 18:48:03 -08:00
Pavel Reznikov 31c3eb494e update DOC 2016-02-17 18:41:10 -08:00
Pavel Reznikov f163d40e7f build js 2016-02-17 18:40:57 -08:00
Pavel Reznikov e146e0d943 replace tab with spaces 2016-02-17 18:40:47 -08:00
Pavel Reznikov a654096a39 remove static from serialization demo grid 2016-02-17 18:35:37 -08:00
d f9aafafb8f Merge branch 'master' into style
# Conflicts:
#	src/gridstack.js
2016-02-17 16:10:25 -05:00
d ab08669965 Merge commit '12e3d5f8ec347cfab7c0e0a15ef530a8251cc12a' 2016-02-17 16:08:15 -05:00
d 7bcbeba849 Added previous PR. 2016-02-17 16:07:40 -05:00
d 64de4684e3 Added obsoletion code for deprecated methods and options. Added jscs settings and ensured code passed. Ensured code passed jshint. 2016-02-17 15:46:48 -05:00
Pavel Reznikov 12e3d5f8ec Update README.md 2016-02-16 19:31:42 -08:00
Pavel Reznikov 2bb81a7085 update docs 2016-02-16 15:46:42 -08:00
Pavel Reznikov b968bb3501 last pr credenrials 2016-02-16 15:40:23 -08:00
Pavel Reznikov cc284c735f update docs 2016-02-16 15:38:53 -08:00
Pavel Reznikov 1cce0bd9f6 Merge pull request #325 from jlowcs/height_units
Add handling of em/rem/px units for cell_height and vertical_margin
2016-02-16 15:36:37 -08:00
Dylan Weiss e9bc1bb3ad Merge commit '707ab11f54f702cdce0e4a54d63007ce4620f15e' 2016-02-16 09:53:28 -05:00
Pavel Reznikov 707ab11f54 add install notes 2016-02-15 23:12:06 -08:00
Kevin Dietrich 0be3e4d1df Modified changes in README.md 2016-02-15 22:51:36 +01:00
Kevin Dietrich 1e75be19ed Preserve license comments in dist 2016-02-15 20:37:07 +01:00
Kevin Dietrich f4e8b9e03e Development of 0.2.5 started 2016-02-15 20:31:19 +01:00
Jerome Louis f34e93baac increased readability 2016-02-15 11:32:39 +01:00
Jerome Louis ef9328fdab Add handling of em/rem/px units for cell_height and vertical_margin, as well as no height option/full CSS heights 2016-02-15 10:43:21 +01:00
Dylan Weiss 48ad1afd3b Merge branch 'bugfix/listeners' 2016-02-13 20:51:16 -05:00
Dylan Weiss 6433bfb9fc Merge branch 'bugfix/listeners' 2016-02-13 17:26:35 -05:00
39 changed files with 5974 additions and 1465 deletions

15
.bithoundrc Normal file
View file

@ -0,0 +1,15 @@
{
"ignore": [
"dist/**",
"**/node_modules/**",
"**/bower_components/**",
"**/demo/**",
"**/coverage/**"
],
"test": [
"**/spec/**"
],
"critics": {
"lint": "jshint"
}
}

3
.gitignore vendored
View file

@ -1 +1,4 @@
node_modules
bower_components
coverage
*.log

19
.jscsrc Normal file
View file

@ -0,0 +1,19 @@
{
"preset": "node-style-guide",
"validateIndentation": 4,
"maximumLineLength": 120,
"jsDoc": {
"checkAnnotations": {
"preset": "jsdoc3",
"extra": {
"preserve": true
}
}
},
"requireCamelCaseOrUpperCaseIdentifiers": true,
"validateLineBreaks": false,
"requireTrailingComma": false,
"disallowTrailingWhitespace": true,
"requireCapitalizedComments": false,
"excludeFiles": ["dist/*.js", "demo/*", "spec/*"]
}

31
.travis.yml Normal file
View file

@ -0,0 +1,31 @@
language: node_js
node_js:
- 5.7.0
env:
- CXX=g++-4.8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
before_install:
- npm install -g protractor
install:
- npm install -g npm@2
- npm install -g grunt-cli
- npm install -g bower
- bower install
- npm install
- ./node_modules/protractor/bin/webdriver-manager update --standalone
before_script:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
script:
- npm run build
- npm test
- grunt e2e-test
notifications:
slack:
secure: iGLGsYyVIyKVpVVCskGh/zc6Pkqe0D7jpUtbywSbnq6l5seE6bvBVqm0F2FSCIN+AIC+qal2mPEWysDVsLACm5tTEeA8NfL8dmCrAKbiFbi+gHl4mnHHCHl7ii/7UkoIIXNc5UXbgMSXRS5l8UcsSDlN8VxC5zWstbJvjeYIvbA=

90
Gruntfile.js Executable file → Normal file
View file

@ -1,9 +1,16 @@
module.exports = function (grunt) {
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-doctoc');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-jscs');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-protractor-runner');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-protractor-webdriver');
grunt.initConfig({
sass: {
@ -30,7 +37,8 @@ module.exports = function (grunt) {
copy: {
dist: {
files: {
'dist/gridstack.js': ['src/gridstack.js']
'dist/gridstack.js': ['src/gridstack.js'],
'dist/gridstack.jQueryUI.js': ['src/gridstack.jQueryUI.js'],
}
}
},
@ -38,11 +46,14 @@ module.exports = function (grunt) {
uglify: {
options: {
sourceMap: true,
sourceMapName: 'dist/gridstack.min.map'
sourceMapName: 'dist/gridstack.min.map',
preserveComments: 'some'
},
dist: {
files: {
'dist/gridstack.min.js': ['src/gridstack.js']
'dist/gridstack.min.js': ['src/gridstack.js'],
'dist/gridstack.jQueryUI.min.js': ['src/gridstack.jQueryUI.js'],
'dist/gridstack.all.js': ['src/gridstack.js', 'src/gridstack.jQueryUI.js']
}
}
},
@ -52,10 +63,77 @@ module.exports = function (grunt) {
removeAd: false
},
readme: {
target: "./README.md"
options: {
target: './README.md'
}
},
doc: {
options: {
target: './doc/README.md'
}
},
faq: {
options: {
target: './doc/FAQ.md'
}
},
},
jshint: {
all: ['src/*.js']
},
jscs: {
all: ['*.js', 'src/*.js', ],
},
watch: {
scripts: {
files: ['src/*.js'],
tasks: ['uglify', 'copy'],
options: {
},
},
styles: {
files: ['src/*.scss'],
tasks: ['sass', 'cssmin'],
options: {
},
},
docs: {
files: ['README.md', 'doc/README.md', 'doc/FAQ.md'],
tasks: ['doctoc'],
options: {
},
},
},
protractor: {
options: {
configFile: 'protractor.conf.js',
},
all: {}
},
connect: {
all: {
options: {
port: 8080,
hostname: 'localhost',
base: '.',
},
},
},
protractor_webdriver: {
all: {
options: {
command: 'webdriver-manager start',
}
}
}
});
grunt.registerTask('default', ['sass', 'cssmin', 'copy', 'uglify', 'doctoc']);
grunt.registerTask('default', ['sass', 'cssmin', 'jshint', 'jscs', 'copy', 'uglify', 'doctoc']);
grunt.registerTask('e2e-test', ['connect', 'protractor_webdriver', 'protractor']);
};

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2016 Pavel Reznikov
Copyright (c) 2014-2016 Pavel Reznikov, Dylan Weiss
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

523
README.md
View file

@ -1,11 +1,16 @@
gridstack.js
============
gridstack.js is a jQuery plugin for widget layout. This is drag-and-drop multi-column grid. It allows you to build
draggable responsive bootstrap v3 friendly layouts. It also works great with [knockout.js](http://knockoutjs.com) and
touch devices.
[![Build Status](https://travis-ci.org/troolee/gridstack.js.svg?branch=master)](https://travis-ci.org/troolee/gridstack.js)
[![Coverage Status](https://coveralls.io/repos/github/troolee/gridstack.js/badge.svg?branch=master)](https://coveralls.io/github/troolee/gridstack.js?branch=master)
[![Dependency Status](https://david-dm.org/troolee/gridstack.js.svg)](https://david-dm.org/troolee/gridstack.js)
[![devDependency Status](https://david-dm.org/troolee/gridstack.js/dev-status.svg)](https://david-dm.org/troolee/gridstack.js#info=devDependencies)
[![Stories in Ready](https://badge.waffle.io/troolee/gridstack.js.png?label=ready&title=Ready)](http://waffle.io/troolee/gridstack.js)
Inspired by [gridster.js](http://gridster.net). Built with love.
gridstack.js is a jQuery plugin for widget layout. This is drag-and-drop multi-column grid. It allows you to build
draggable responsive bootstrap v3 friendly layouts. It also works great with [knockout.js](http://knockoutjs.com), [angular.js](https://angularjs.org) and touch devices.
Inspired by [gridster.js](https://github.com/ducksboard/gridster.js). Built with love.
Join gridstack.js on Slack: https://gridstackjs.troolee.com
@ -18,45 +23,13 @@ Join gridstack.js on Slack: https://gridstackjs.troolee.com
- [Demo](#demo)
- [Usage](#usage)
- [Requirements](#requirements)
- [Using gridstack.js with jQuery UI](#using-gridstackjs-with-jquery-ui)
- [Install](#install)
- [Basic usage](#basic-usage)
- [Options](#options)
- [Grid attributes](#grid-attributes)
- [Item attributes](#item-attributes)
- [Events](#events)
- [onchange(items)](#onchangeitems)
- [ondragstart(event, ui)](#ondragstartevent-ui)
- [ondragstop(event, ui)](#ondragstopevent-ui)
- [onresizestart(event, ui)](#onresizestartevent-ui)
- [onresizestop(event, ui)](#onresizestopevent-ui)
- [disable(event)](#disableevent)
- [enable(event)](#enableevent)
- [API](#api)
- [add_widget(el, x, y, width, height, auto_position)](#add_widgetel-x-y-width-height-auto_position)
- [make_widget(el)](#make_widgetel)
- [batch_update()](#batch_update)
- [cell_height()](#cell_height)
- [cell_height(val)](#cell_heightval)
- [cell_width()](#cell_width)
- [commit()](#commit)
- [destroy()](#destroy)
- [disable()](#disable)
- [enable()](#enable)
- [get_cell_from_pixel(position)](#get_cell_from_pixelposition)
- [is_area_empty(x, y, width, height)](#is_area_emptyx-y-width-height)
- [locked(el, val)](#lockedel-val)
- [min_width(el, val)](#min_widthel-val)
- [min_height(el, val)](#min_heightel-val)
- [movable(el, val)](#movableel-val)
- [move(el, x, y)](#moveel-x-y)
- [remove_widget(el, detach_node)](#remove_widgetel-detach_node)
- [remove_all()](#remove_all)
- [resize(el, width, height)](#resizeel-width-height)
- [resizable(el, val)](#resizableel-val)
- [set_static(static_value)](#set_staticstatic_value)
- [update(el, x, y, width, height)](#updateel-x-y-width-height)
- [will_it_fit(x, y, width, height, auto_position)](#will_it_fitx-y-width-height-auto_position)
- [Utils](#utils)
- [GridStackUI.Utils.sort(nodes[, dir[, width]])](#gridstackuiutilssortnodes-dir-width)
- [Migrating to v0.3.0](#migrating-to-v030)
- [Migrating to v0.2.5](#migrating-to-v025)
- [API Documentation](#api-documentation)
- [Questions and Answers](#questions-and-answers)
- [Touch devices support](#touch-devices-support)
- [Use with knockout.js](#use-with-knockoutjs)
- [Use with angular.js](#use-with-angularjs)
@ -68,8 +41,15 @@ Join gridstack.js on Slack: https://gridstackjs.troolee.com
- [Load grid from array](#load-grid-from-array)
- [Override resizable/draggable options](#override-resizabledraggable-options)
- [IE8 support](#ie8-support)
- [Use with require.js](#use-with-requirejs)
- [Nested grids](#nested-grids)
- [Resizing active grid](#resizing-active-grid)
- [Using AniJS](#using-anijs)
- [The Team](#the-team)
- [Changes](#changes)
- [v0.3.0-dev (Development Version)](#v030-dev-development-version)
- [v0.2.6 (2016-08-17)](#v026-2016-08-17)
- [v0.2.5 (2016-03-02)](#v025-2016-03-02)
- [v0.2.4 (2016-02-15)](#v024-2016-02-15)
- [v0.2.3 (2015-06-23)](#v023-2015-06-23)
- [v0.2.2 (2014-12-23)](#v022-2014-12-23)
@ -84,7 +64,7 @@ Join gridstack.js on Slack: https://gridstackjs.troolee.com
Demo
====
Please visit http://troolee.github.io/gridstack.js/ for demo.
Please visit http://troolee.github.io/gridstack.js/ for demo. Or check out [these example](http://troolee.github.io/gridstack.js/demo/).
Usage
@ -92,14 +72,47 @@ Usage
## Requirements
* [lodash.js](https://lodash.com) (>= 3.5.0)
* [jQuery](http://jquery.com) (>= 1.11.0)
* [jQuery UI](http://jqueryui.com) (>= 1.11.0). Minimum required components: Core, Widget, Mouse, Draggable, Resizable
* (Optional) [knockout.js](http://knockoutjs.com) (>= 3.2.0)
* (Optional) [jquery-ui-touch-punch](https://github.com/furf/jquery-ui-touch-punch) for touch-based devices support
* [lodash.js](https://lodash.com) (>= 3.5.0, full build)
* [jQuery](http://jquery.com) (>= 3.1.0)
Note: You can still use [underscore.js](http://underscorejs.org) (>= 1.7.0) instead of lodash.js
#### Using gridstack.js with jQuery UI
* [jQuery UI](http://jqueryui.com) (>= 1.12.0). Minimum required components: Core, Widget, Mouse, Draggable, Resizable
* (Optional) [jquery-ui-touch-punch](https://github.com/furf/jquery-ui-touch-punch) for touch-based devices support
## Install
```html
<link rel="stylesheet" href="gridstack.css" />
<script src="gridstack.js"></script>
<script src="gridstack.jQueryUI.js"></script>
```
* Using CDN:
```html
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.2.6/gridstack.min.css" />
<script type="text/javascript" src='//cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.2.6/gridstack.min.js'></script>
```
* Using bower:
```bash
$ bower install gridstack
```
* Using npm:
[![NPM version](https://img.shields.io/npm/v/gridstack.svg)](https://www.npmjs.com/package/gridstack)
```bash
$ npm install gridstack
```
You can download files from `dist` directory as well.
## Basic usage
```html
@ -119,329 +132,49 @@ Note: You can still use [underscore.js](http://underscorejs.org) (>= 1.7.0) inst
<script type="text/javascript">
$(function () {
var options = {
cell_height: 80,
vertical_margin: 10
cellHeight: 80,
verticalMargin: 10
};
$('.grid-stack').gridstack(options);
});
</script>
```
## Options
## Migrating to v0.3.0
- `always_show_resize_handle` - if `true` the resizing handles are shown even if the user is not hovering over the widget
(default: `false`)
- `animate` - turns animation on (default: `false`)
- `auto` - if `false` gridstack will not initialize existing items (default: `true`)
- `cell_height` - one cell height (default: `60`)
- `draggable` - allows to override jQuery UI draggable options. (default: `{handle: '.grid-stack-item-content', scroll: true, appendTo: 'body'}`)
- `handle` - draggable handle selector (default: `'.grid-stack-item-content'`)
- `handle_class` - draggable handle class (e.g. `'grid-stack-item-content'`). If set `handle` is ignored (default: `null`)
- `height` - maximum rows amount. Default is `0` which means no maximum rows
- `float` - enable floating widgets (default: `false`) See [example](http://troolee.github.io/gridstack.js/demo/float.html)
- `item_class` - widget class (default: `'grid-stack-item'`)
- `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`)
- `placeholder_class` - class for placeholder (default: `'grid-stack-placeholder'`)
- `placeholder_text` - placeholder default content (default: `''`)
- `resizable` - allows to override jQuery UI resizable options. (default: `{autoHide: true, handles: 'se'}`)
- `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.
- `vertical_margin` - vertical gap size (default: `20`)
- `width` - amount of columns (default: `12`)
As of v0.3.0, gridstack introduces a new plugin system. The drag'n'drop functionality has been modified to take advantage of this system. Because of this, and to avoid dependency on core code from jQuery UI, the plugin was functionality was moved to a separate file.
## Grid attributes
To ensure gridstack continues to work, either include the additional `gridstack.jQueryUI.js` file into your HTML or use `gridstack.all.js`:
- `data-gs-animate` - turns animation on
- `data-gs-width` - amount of columns
- `data-gs-height` - maximum rows amount. Default is `0` which means no maximum rows.
## Item attributes
- `data-gs-x`, `data-gs-y` - element position
- `data-gs-width`, `data-gs-height` - element size
- `data-gs-max-width`, `data-gs-min-width`, `data-gs-max-height`, `data-gs-min-height` - element constraints
- `data-gs-no-resize` - disable element resizing
- `data-gs-no-move` - disable element moving
- `data-gs-auto-position` - tells to ignore `data-gs-x` and `data-gs-y` attributes and to place element to the first
available position
- `data-gs-locked` - the widget will be locked. It means another widget wouldn't be able to move it during dragging or resizing.
The widget can still be dragged or resized. You need to add `data-gs-no-resize` and `data-gs-no-move` attributes
to completely lock the widget.
## Events
### onchange(items)
Occurs when adding/removing widgets or existing widgets change their position/size
```javascript
var serialize_widget_map = function (items) {
console.log(items);
};
$('.grid-stack').on('change', function (e, items) {
serialize_widget_map(items);
});
```html
<script src="gridstack.js"></script>
<script src="gridstack.jQueryUI.js"></script>
```
### ondragstart(event, ui)
or
```javascript
$('.grid-stack').on('dragstart', function (event, ui) {
var grid = this;
var element = event.target;
});
```html
<script src="gridstack.all.js"></script>
```
### ondragstop(event, ui)
We're working on implementing support for other drag'n'drop libraries through the new plugin system.
```javascript
$('.grid-stack').on('dragstop', function (event, ui) {
var grid = this;
var element = event.target;
});
```
## Migrating to v0.2.5
### onresizestart(event, ui)
As of v0.2.5 all methods and parameters are in camel case to respect [JavaScript Style Guide and Coding Conventions](http://www.w3schools.com/js/js_conventions.asp).
All old methods and parameters are marked as deprecated and still available but a warning will be displayed in js console. They will be available until v1.0
when they will be completely removed.
```javascript
$('.grid-stack').on('resizestart', function (event, ui) {
var grid = this;
var element = event.target;
});
```
## API Documentation
### onresizestop(event, ui)
Please check out `doc/README.md` for more information about gridstack.js API.
```javascript
$('.grid-stack').on('resizestop', function (event, ui) {
var grid = this;
var element = event.target;
});
```
## Questions and Answers
### disable(event)
Please feel free to as a questions here in issues, using [Stackoverflow](http://stackoverflow.com/search?q=gridstack) or [Slack chat](https://gridstackjs.troolee.com).
We will glad to answer and help you as soon as we can.
```javascipt
$('.grid-stack').on('disable', function(event) {
var grid = event.target;
});
```
### enable(event)
```javascipt
$('.grid-stack').on('enable', function(event) {
var grid = event.target;
});
```
## API
### add_widget(el, x, y, width, height, auto_position)
Creates new widget and returns it.
Parameters:
- `el` - widget to add
- `x`, `y`, `width`, `height` - widget position/dimensions (Optional)
- `auto_position` - if `true` then `x`, `y` parameters will be ignored and widget will be places on the first available
position
Widget will be always placed even if result height is more than actual grid height. You need to use `will_it_fit` method
before calling `add_widget` for additional check.
```javascript
$('.grid-stack').gridstack();
var grid = $('.grid-stack').data('gridstack');
grid.add_widget(el, 0, 0, 3, 2, true);
```
### make_widget(el)
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.
Makes the given element a widget and returns it.
Parameters:
- `el` - element to convert to a widget
```javascript
$('.grid-stack').gridstack();
$('.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>')
var grid = $('.grid-stack').data('gridstack');
grid.make_widget('gsi-1');
```
### batch_update()
Initailizes batch updates. You will see no changes until `commit` method is called.
### cell_height()
Gets current cell height.
### cell_height(val)
Update current cell height. This method rebuilds an internal CSS stylesheet. Note: You can expect performance issues if
call this method too often.
```javascript
grid.cell_height(grid.cell_width() * 1.2);
```
### cell_width()
Gets current cell width.
### commit()
Finishes batch updates. Updates DOM nodes. You must call it after `batch_update`.
### destroy()
Destroys a grid instance.
### disable()
Disables widgets moving/resizing. This is a shortcut for:
```javascript
grid.movable('.grid-stack-item', false);
grid.resizable('.grid-stack-item', false);
```
### enable()
Enables widgets moving/resizing. This is a shortcut for:
```javascript
grid.movable('.grid-stack-item', true);
grid.resizable('.grid-stack-item', true);
```
### get_cell_from_pixel(position)
Get the position of the cell under a pixel on screen.
Parameters :
- `position` - the position of the pixel to resolve in absolute coordinates, as an object with `top` and `left`properties
Returns an object with properties `x` and `y` i.e. the column and row in the grid.
### is_area_empty(x, y, width, height)
Checks if specified area is empty.
### locked(el, val)
Locks/unlocks widget.
- `el` - widget to modify.
- `val` - if `true` widget will be locked.
### min_width(el, val)
Set the minWidth for a widget.
- `el` - widget to modify.
- `val` - A numeric value of the number of columns
### min_height(el, val)
Set the minHeight for a widget.
- `el` - widget to modify.
- `val` - A numeric value of the number of rows
### movable(el, val)
Enables/Disables moving.
- `el` - widget to modify
- `val` - if `true` widget will be draggable.
### move(el, x, y)
Changes widget position
Parameters:
- `el` - widget to move
- `x`, `y` - new position. If value is `null` or `undefined` it will be ignored.
### remove_widget(el, detach_node)
Removes widget from the grid.
Parameters:
- `el` - widget to remove.
- `detach_node` - if `false` DOM node won't be removed from the tree (Optional. Default `true`).
### remove_all()
Removes all widgets from the grid.
### resize(el, width, height)
Changes widget size
Parameters:
- `el` - widget to resize
- `width`, `height` - new dimensions. If value is `null` or `undefined` it will be ignored.
### resizable(el, val)
Enables/Disables resizing.
- `el` - widget to modify
- `val` - if `true` widget will be resizable.
### set_static(static_value)
Toggle the grid static state. Also toggle the `grid-stack-static` class.
- `static_value` - if `true` the grid become static.
### update(el, x, y, width, height)
Parameters:
- `el` - widget to move
- `x`, `y` - new position. If value is `null` or `undefined` it will be ignored.
- `width`, `height` - new dimensions. If value is `null` or `undefined` it will be ignored.
Updates widget position/size.
### will_it_fit(x, y, width, height, auto_position)
Returns `true` if the `height` of the grid will be less the vertical constraint. Always returns `true` if grid doesn't
have `height` constraint.
```javascript
if (grid.will_it_fit(new_node.x, new_node.y, new_node.width, new_node.height, true)) {
grid.add_widget(new_node.el, new_node.x, new_node.y, new_node.width, new_node.height, true);
}
else {
alert('Not enough free space to place the widget');
}
```
## Utils
### GridStackUI.Utils.sort(nodes[, dir[, width]])
Sorts array of nodes
- `nodes` - array to sort
- `dir` - `1` for asc, `-1` for desc (optional)
- `width` - width of the grid. If `undefined` the width will be calculated automatically (optional).
Also please check our FAQ `doc/FAQ.md` before asking in case the answer is already there.
## Touch devices support
@ -457,17 +190,19 @@ working on touch-based devices.
<script src="gridstack.js"></script>
```
Also `always_show_resize_handle` option may be useful:
Also `alwaysShowResizeHandle` option may be useful:
```javascript
$(function () {
var options = {
always_show_resize_handle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
alwaysShowResizeHandle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
};
$('.grid-stack').gridstack(options);
});
```
If you're still experiencing issues on touch devices please check [#444](https://github.com/troolee/gridstack.js/issues/444)
## Use with knockout.js
```javascript
@ -487,9 +222,9 @@ ko.components.register('dashboard-grid', {
}
var item = _.find(items, function (i) { return i.nodeType == 1 });
grid.add_widget(item);
grid.addWidget(item);
ko.utils.domNodeDisposal.addDisposeCallback(item, function () {
grid.remove_widget(item);
grid.removeWidget(item);
});
};
};
@ -500,7 +235,7 @@ ko.components.register('dashboard-grid', {
template:
[
'<div class="grid-stack" data-bind="foreach: {data: widgets, afterRender: afterAddWidget}">',
' <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}">',
' <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.autoPosition}">',
' <div class="grid-stack-item-content">...</div>',
' </div>',
'</div> '
@ -533,11 +268,11 @@ See examples: [example 1](http://troolee.github.io/gridstack.js/demo/knockout.ht
**Notes:** It's very important to exclude training spaces after widget template:
```
```javascript
template:
[
'<div class="grid-stack" data-bind="foreach: {data: widgets, afterRender: afterAddWidget}">',
' <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}">',
' <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.autoPosition}">',
' ....',
' </div>', // <-- NO SPACE **AFTER** </div>
'</div> ' // <-- NO SPACE **BEFORE** </div>
@ -665,10 +400,10 @@ var serialization = [
serialization = GridStackUI.Utils.sort(serialization);
var grid = $('.grid-stack').data('gridstack');
grid.remove_all();
grid.removeAll();
_.each(serialization, function (node) {
grid.add_widget($('<div><div class="grid-stack-item-content" /></div>'),
grid.addWidget($('<div><div class="grid-stack-item-content" /></div>'),
node.x, node.y, node.width, node.height);
});
```
@ -737,6 +472,12 @@ for i in range(N):
There are at least two more issues with gridstack in IE8 with jQueryUI resizable (it seems it doesn't work) and
droppable. If you have any suggestions about support of IE8 you are welcome here: https://github.com/troolee/gridstack.js/issues/76
## Use with require.js
If you're using require.js and a single file jQueryUI please check out this
[Stackoverflow question](http://stackoverflow.com/questions/35582945/redundant-dependencies-with-requirejs) to get it
working properly.
## Nested grids
@ -745,9 +486,67 @@ during initialization.
See example: [Nested grid demo](http://troolee.github.io/gridstack.js/demo/nested.html)
## Resizing active grid
Resizing on-the-fly is possible, though experimental. This may be used to make gridstack responsive. gridstack will change the total number of columns and will attempt to update the width and x values of each widget to be more logical.
See example: [Responsive grid demo](http://troolee.github.io/gridstack.js/demo/responsive.html)
## Using AniJS
Using AniJS with gridstack is a breeze. In the following example, a listener is added that gets triggered by a widget being added.
See widgets wiggle! [AniJS demo](http://troolee.github.io/gridstack.js/demo/anijs.html)
The Team
========
gridstack.js is currently maintained by [Pavel Reznikov](https://github.com/troolee), [Dylan Weiss](https://github.com/radiolips)
and [Kevin Dietrich](https://github.com/kdietrich). And we appreciate [all contributors](https://github.com/troolee/gridstack.js/graphs/contributors)
for help.
Changes
=======
#### v0.3.0-dev (Development Version)
- 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 ([#462](https://github.com/troolee/gridstack.js/issues/462)).
- add internal function`isNodeChangedPosition`, 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 of jQuery (v3.1.0+) and jquery-ui (v1.12.0+).
- fix jQuery `size()` ([#486](https://github.com/troolee/gridstack.js/issues/486)).
- update `destroy([detachGrid])` call ([#422](https://github.com/troolee/gridstack.js/issues/422)).
- don't mutate options when calling `draggable` and `resizable`. ([#505](https://github.com/troolee/gridstack.js/issues/505)).
- update _notify to allow detach ([#411](https://github.com/troolee/gridstack.js/issues/411)).
- fix code that checks for jquery-ui ([#481](https://github.com/troolee/gridstack.js/issues/481)).
- fix `cellWidth` calculation on empty grid
#### v0.2.5 (2016-03-02)
- update names to respect js naming convention.
- `cellHeight` and `verticalMargin` can now be string (e.g. '3em', '20px') (Thanks to @jlowcs).
- add `maxWidth`/`maxHeight` methods.
- add `enableMove`/`enableResize` methods.
- fix window resize issue #331.
- add options `disableDrag` and `disableResize`.
- fix `batchUpdate`/`commit` (Thank to @radiolips)
- remove dependency of FontAwesome
- RTL support
- `'auto'` value for `cellHeight` option
- fix `setStatic` method
- add `setAnimation` method to API
- add `setGridWidth` method ([#227](https://github.com/troolee/gridstack.js/issues/227))
- add `removable`/`removeTimeout` *(experimental)*
- add `detachGrid` parameter to `destroy` method ([#216](https://github.com/troolee/gridstack.js/issues/216)) (thanks @jhpedemonte)
- add `useOffset` parameter to `getCellFromPixel` method ([#237](https://github.com/troolee/gridstack.js/issues/237))
- add `minWidth`, `maxWidth`, `minHeight`, `maxHeight`, `id` parameters to `addWidget` ([#188](https://github.com/troolee/gridstack.js/issues/188))
- add `added` and `removed` events for when a widget is added or removed, respectively. ([#54](https://github.com/troolee/gridstack.js/issues/54))
- add `acceptWidgets` parameter. Widgets can now be draggable between grids or from outside *(experimental)*
#### v0.2.4 (2016-02-15)
- fix closure compiler/linter warnings
@ -755,7 +554,9 @@ Changes
- add `min_width`/`min_height` methods (Thanks to @cvillemure)
- add `destroy` method (Thanks to @zspitzer)
- add `placeholder_text` option (Thanks to @slauyama)
- lodash v 4.x support (Thanks to Andy Robbins)
- add `handle_class` option.
- add `make_widget` method.
- lodash v 4.x support (Thanks to @andrewr88)
#### v0.2.3 (2015-06-23)
@ -814,7 +615,7 @@ License
The MIT License (MIT)
Copyright (c) 2014-2016 Pavel Reznikov
Copyright (c) 2014-2016 Pavel Reznikov, Dylan Weiss
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -1,6 +1,6 @@
{
"name": "gridstack",
"version": "0.2.4",
"version": "0.3.0-dev",
"homepage": "https://github.com/troolee/gridstack.js",
"authors": [
"Pavel Reznikov <pashka.reznikov@gmail.com>"
@ -14,9 +14,9 @@
"amd"
],
"dependencies": {
"lodash": ">= 3.5.0",
"jquery": ">= 1.11.0",
"jquery-ui": ">= 1.11.0"
"lodash": ">= 4.14.2",
"jquery": ">= 3.1.0",
"jquery-ui": ">= 1.12.0"
},
"keywords": [
"gridstack",

89
demo/anijs.html Normal file
View file

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AniJS demo</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="../dist/gridstack.css"/>
<link rel="stylesheet" href="https://anijs.github.io/lib/anicollection/anicollection.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="../dist/gridstack.js"></script>
<script src="../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
.grid-stack {
background: lightgoldenrodyellow;
}
.grid-stack-item-content {
color: #2c3e50;
text-align: center;
background-color: #18bc9c;
}
</style>
</head>
<body>
<div class="container-fluid">
<h1>AniJS demo</h1>
<div>
<a class="btn btn-default" id="add-widget" href="#">Add Widget</a>
</div>
<div>
<h4>Widget added</h4>
</div>
<br/>
<div class="grid-stack">
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/AniJS/0.9.3/anijs.js"></script>
<script type="text/javascript">
$(function () {
$('.grid-stack').gridstack();
var self = this;
this.grid = $('.grid-stack').data('gridstack');
$('.grid-stack').on('added', function(event, items) {
// add anijs data to gridstack item
for (var i = 0; i < items.length; i++) {
$(items[i].el[0]).attr('data-anijs', 'if: added, do: swing animated, after: $removeAnimations, on: $gridstack');
}
AniJS.run();
self.gridstackNotifier = AniJS.getNotifier('gridstack');
// fire added event!
self.gridstackNotifier.dispatchEvent('added');
});
$('#add-widget').click(function() {
addNewWidget();
});
function addNewWidget() {
var grid = $('.grid-stack').data('gridstack');
grid.addWidget($('<div><div class="grid-stack-item-content"></div></div>'), 0, 0, Math.floor(1 + 3 * Math.random()), Math.floor(1 + 3 * Math.random()), true);
}
var animationHelper = AniJS.getHelper();
//Defining removeAnimations to remove existing animations
animationHelper.removeAnimations = function(e, animationContext){
$('.grid-stack-item').attr('data-anijs', '');
};
});
</script>
</body>
</html>

View file

@ -10,15 +10,15 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Float grid demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="../dist/gridstack.js"></script>
<script src="../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
.grid-stack {
@ -68,18 +68,19 @@
this.grid = $('.grid-stack').data('gridstack');
this.add_new_widget = function () {
this.addNewWidget = function () {
var node = this.items.pop() || {
x: 12 * Math.random(),
y: 5 * Math.random(),
width: 1 + 3 * Math.random(),
height: 1 + 3 * Math.random()
};
this.grid.add_widget($('<div><div class="grid-stack-item-content" /><div/>'),
this.grid.addWidget($('<div><div class="grid-stack-item-content" /><div/>'),
node.x, node.y, node.width, node.height);
return false;
}.bind(this);
$('#add-new-widget').click(this.add_new_widget);
$('#add-new-widget').click(this.addNewWidget);
};
});
</script>

20
demo/index.html Normal file
View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
<body>
<ul>
<li><a href="float.html">Float grid demo</a></li>
<li><a href="knockout.html">Knockout.js demo</a></li>
<li><a href="knockout2.html">Knockout.js demo (2)</a></li>
<li><a href="nested.html">Nested grids demo</a></li>
<li><a href="rtl.html">RTL demo</a></li>
<li><a href="serialization.html">Serialization demo</a></li>
<li><a href="two.html">Two grids demo</a></li>
<li><a href="responsive.html">Resize grid (responsive) demo</a></li>
<li><a href="anijs.html">AniJS demo</a></li>
</ul>
</body>
</html>

View file

@ -10,16 +10,16 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Knockout.js demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="../dist/gridstack.js"></script>
<script src="../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
.grid-stack {
@ -38,7 +38,7 @@
<h1>knockout.js Demo</h1>
<div>
<button data-bind="click: add_new_widget">Add new widget</button>
<button data-bind="click: addNewWidget">Add new widget</button>
</div>
<br>
@ -64,9 +64,9 @@
}
var item = _.find(items, function (i) { return i.nodeType == 1 });
grid.add_widget(item);
grid.addWidget(item);
ko.utils.domNodeDisposal.addDisposeCallback(item, function () {
grid.remove_widget(item);
grid.removeWidget(item);
});
};
};
@ -78,7 +78,7 @@
[
'<div class="grid-stack" data-bind="foreach: {data: widgets, afterRender: afterAddWidget}">',
' <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}">',
' <div class="grid-stack-item-content"><button data-bind="click: $root.delete_widget">Delete me</button></div>',
' <div class="grid-stack-item-content"><button data-bind="click: $root.deleteWidget">Delete me</button></div>',
' </div>',
'</div> '
].join('')
@ -90,7 +90,7 @@
this.widgets = ko.observableArray(widgets);
this.add_new_widget = function () {
this.addNewWidget = function () {
this.widgets.push({
x: 0,
y: 0,
@ -98,10 +98,12 @@
height: Math.floor(1 + 3 * Math.random()),
auto_position: true
});
return false;
};
this.delete_widget = function (item) {
this.deleteWidget = function (item) {
self.widgets.remove(item);
return false;
};
};

View file

@ -10,16 +10,16 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Knockout.js demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="../dist/gridstack.js"></script>
<script src="../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
.grid-stack {
@ -38,7 +38,7 @@
<h1>knockout.js Demo</h1>
<div>
<button data-bind="click: add_new_widget">Add new widget</button>
<button data-bind="click: addNewWidget">Add new widget</button>
</div>
<br>
@ -64,9 +64,9 @@
}
var item = _.find(items, function (i) { return i.nodeType == 1 });
grid.add_widget(item);
grid.addWidget(item);
ko.utils.domNodeDisposal.addDisposeCallback(item, function () {
grid.remove_widget(item);
grid.removeWidget(item);
});
};
};
@ -83,7 +83,7 @@
this.widgets = ko.observableArray(widgets);
this.add_new_widget = function () {
this.addNewWidget = function () {
this.widgets.push({
x: 0,
y: 0,
@ -91,10 +91,12 @@
height: Math.floor(1 + 3 * Math.random()),
auto_position: true
});
return false;
};
this.delete_widget = function (item) {
this.deleteWidget = function (item) {
self.widgets.remove(item);
return false;
};
};
@ -113,7 +115,7 @@
<template id="gridstack-template">
<div class="grid-stack" data-bind="foreach: {data: widgets, afterRender: afterAddWidget}">
<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}">
<div class="grid-stack-item-content"><button data-bind="click: $root.delete_widget">Delete me</button></div>
<div class="grid-stack-item-content"><button data-bind="click: $root.deleteWidget">Delete me</button></div>
</div></div><!-- <---- NO SPACE BETWEEN THESE CLOSING TAGS -->
</template>
</body>

View file

@ -10,15 +10,15 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Nested grids demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="../dist/gridstack.js"></script>
<script src="../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
.grid-stack {

122
demo/responsive.html Normal file
View file

@ -0,0 +1,122 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Responsive grid demo</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/gridstack.css"/>
<link rel="stylesheet" href="../dist/gridstack-extra.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="../dist/gridstack.js"></script>
<script src="../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
.grid-stack {
background: lightgoldenrodyellow;
}
.grid-stack-item-content {
color: #2c3e50;
text-align: center;
background-color: #18bc9c;
}
</style>
</head>
<body>
<div class="device-xs visible-xs"></div>
<div class="device-sm visible-sm"></div>
<div class="device-md visible-md"></div>
<div class="device-lg visible-lg"></div>
<div class="device-xl visible-xl"></div>
<div class="container-fluid">
<h1>Responsive grid demo</h1>
<div>
<span>Number of Columns:</span> <span id="grid-size"></span>
</div>
<br/>
<div class="grid-stack">
</div>
</div>
<script type="text/javascript">
$(function () {
// thanks to http://stackoverflow.com/a/22885503
var waitForFinalEvent=function(){var b={};return function(c,d,a){a||(a="I am a banana!");b[a]&&clearTimeout(b[a]);b[a]=setTimeout(c,d)}}();
var fullDateString = new Date();
function isBreakpoint(alias) {
return $('.device-' + alias).is(':visible');
}
var options = {
float: false
};
$('.grid-stack').gridstack(options);
function resizeGrid() {
var grid = $('.grid-stack').data('gridstack');
if (isBreakpoint('xs')) {
$('#grid-size').text('One column mode');
} else if (isBreakpoint('sm')) {
grid.setGridWidth(3);
$('#grid-size').text(3);
} else if (isBreakpoint('md')) {
grid.setGridWidth(6);
$('#grid-size').text(6);
} else if (isBreakpoint('lg')) {
grid.setGridWidth(12);
$('#grid-size').text(12);
}
};
$(window).resize(function () {
waitForFinalEvent(function() {
resizeGrid();
}, 300, fullDateString.getTime());
});
new function () {
this.serializedData = [
{x: 0, y: 0, width: 4, height: 2},
{x: 3, y: 1, width: 4, height: 2},
{x: 4, y: 1, width: 4, height: 1},
{x: 2, y: 3, width: 8, height: 1},
{x: 0, y: 4, width: 4, height: 1},
{x: 0, y: 3, width: 4, height: 1},
{x: 2, y: 4, width: 4, height: 1},
{x: 2, y: 5, width: 4, height: 1},
{x: 0, y: 6, width: 12, height: 1}
];
this.grid = $('.grid-stack').data('gridstack');
this.loadGrid = function () {
this.grid.removeAll();
var items = GridStackUI.Utils.sort(this.serializedData);
_.each(items, function (node, i) {
this.grid.addWidget($('<div><div class="grid-stack-item-content">' + i + '</div></div>'),
node.x, node.y, node.width, node.height);
}, this);
return false;
}.bind(this);
this.loadGrid();
resizeGrid();
};
});
</script>
</body>
</html>

121
demo/rtl.html Normal file
View file

@ -0,0 +1,121 @@
<!DOCTYPE html>
<html lang="en" dir="rtl">
<head>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>RTL demo</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="../dist/gridstack.js"></script>
<script src="../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
.grid-stack {
background: lightgoldenrodyellow;
}
.grid-stack-item-content {
color: #2c3e50;
background-color: #18bc9c;
}
</style>
</head>
<body>
<div class="container-fluid">
<h1>RTL Demo</h1>
<div>
<button data-bind="click: addNewWidget">Add new widget</button>
</div>
<br>
<div data-bind="component: {name: 'dashboard-grid', params: $data}"></div>
</div>
<script type="text/javascript">
ko.components.register('dashboard-grid', {
viewModel: {
createViewModel: function (controller, componentInfo) {
var ViewModel = function (controller, componentInfo) {
var grid = null;
this.widgets = controller.widgets;
this.afterAddWidget = function (items) {
if (grid == null) {
grid = $(componentInfo.element).find('.grid-stack').gridstack({
auto: false
}).data('gridstack');
}
var item = _.find(items, function (i) { return i.nodeType == 1 });
grid.addWidget(item);
ko.utils.domNodeDisposal.addDisposeCallback(item, function () {
grid.removeWidget(item);
});
};
};
return new ViewModel(controller, componentInfo);
}
},
template:
[
'<div class="grid-stack" data-bind="foreach: {data: widgets, afterRender: afterAddWidget}">',
' <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}">',
' <div class="grid-stack-item-content"><center><button data-bind="click: $root.deleteWidget">Delete me</button><br><h5 data-bind="text: index" /></center><br><p>lorem ipsum</p></div>',
' </div>',
'</div> '
].join('')
});
$(function () {
var Controller = function (widgets) {
var self = this;
this.widgets = ko.observableArray(widgets);
this.addNewWidget = function () {
this.widgets.push({
x: 0,
y: 0,
width: Math.floor(1 + 3 * Math.random()),
height: Math.floor(1 + 3 * Math.random()),
auto_position: true
});
return false;
};
this.deleteWidget = function (item) {
self.widgets.remove(item);
return false;
};
};
var widgets = [
{x: 0, y: 0, width: 2, height: 2, index: 1},
{x: 2, y: 0, width: 4, height: 2, index: 2},
{x: 6, y: 0, width: 2, height: 4, index: 3},
{x: 1, y: 2, width: 4, height: 2, index: 4}
];
var controller = new Controller(widgets);
ko.applyBindings(controller);
});
</script>
</body>
</html>

View file

@ -10,15 +10,15 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Serialization demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="../dist/gridstack.js"></script>
<script src="../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
.grid-stack {
@ -56,12 +56,11 @@
<script type="text/javascript">
$(function () {
var options = {
static_grid: true
};
$('.grid-stack').gridstack(options);
new function () {
this.serialized_data = [
this.serializedData = [
{x: 0, y: 0, width: 2, height: 2},
{x: 3, y: 1, width: 1, height: 2},
{x: 4, y: 1, width: 1, height: 1},
@ -74,17 +73,18 @@
this.grid = $('.grid-stack').data('gridstack');
this.load_grid = function () {
this.grid.remove_all();
var items = GridStackUI.Utils.sort(this.serialized_data);
this.loadGrid = function () {
this.grid.removeAll();
var items = GridStackUI.Utils.sort(this.serializedData);
_.each(items, function (node) {
this.grid.add_widget($('<div><div class="grid-stack-item-content" /><div/>'),
this.grid.addWidget($('<div><div class="grid-stack-item-content" /><div/>'),
node.x, node.y, node.width, node.height);
}, this);
return false;
}.bind(this);
this.save_grid = function () {
this.serialized_data = _.map($('.grid-stack > .grid-stack-item:visible'), function (el) {
this.saveGrid = function () {
this.serializedData = _.map($('.grid-stack > .grid-stack-item:visible'), function (el) {
el = $(el);
var node = el.data('_gridstack_node');
return {
@ -94,18 +94,20 @@
height: node.height
};
}, this);
$('#saved-data').val(JSON.stringify(this.serialized_data, null, ' '));
$('#saved-data').val(JSON.stringify(this.serializedData, null, ' '));
return false;
}.bind(this);
this.clear_grid = function () {
this.grid.remove_all();
this.clearGrid = function () {
this.grid.removeAll();
return false;
}.bind(this);
$('#save-grid').click(this.save_grid);
$('#load-grid').click(this.load_grid);
$('#clear-grid').click(this.clear_grid);
$('#save-grid').click(this.saveGrid);
$('#load-grid').click(this.loadGrid);
$('#clear-grid').click(this.clearGrid);
this.load_grid();
this.loadGrid();
};
});
</script>

View file

@ -10,16 +10,16 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Two grids demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/gridstack.css"/>
<link rel="stylesheet" href="../dist/gridstack-extra.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="../dist/gridstack.js"></script>
<script src="../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
#grid1 {
@ -35,12 +35,61 @@
text-align: center;
background-color: #18bc9c;
}
#grid2 .grid-stack-item-content {
background-color: #9caabc;
}
.grid-stack-item-removing {
opacity: 0.5;
}
.trash {
height: 150px;
margin-bottom: 20px;
background: rgba(255, 0, 0, 0.1) center center url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjY0cHgiIGhlaWdodD0iNjRweCIgdmlld0JveD0iMCAwIDQzOC41MjkgNDM4LjUyOSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDM4LjUyOSA0MzguNTI5OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPGc+CgkJPHBhdGggZD0iTTQxNy42ODksNzUuNjU0Yy0xLjcxMS0xLjcwOS0zLjkwMS0yLjU2OC02LjU2My0yLjU2OGgtODguMjI0TDMwMi45MTcsMjUuNDFjLTIuODU0LTcuMDQ0LTcuOTk0LTEzLjA0LTE1LjQxMy0xNy45ODkgICAgQzI4MC4wNzgsMi40NzMsMjcyLjU1NiwwLDI2NC45NDUsMGgtOTEuMzYzYy03LjYxMSwwLTE1LjEzMSwyLjQ3My0yMi41NTQsNy40MjFjLTcuNDI0LDQuOTQ5LTEyLjU2MywxMC45NDQtMTUuNDE5LDE3Ljk4OSAgICBsLTE5Ljk4NSw0Ny42NzZoLTg4LjIyYy0yLjY2NywwLTQuODUzLDAuODU5LTYuNTY3LDIuNTY4Yy0xLjcwOSwxLjcxMy0yLjU2OCwzLjkwMy0yLjU2OCw2LjU2N3YxOC4yNzQgICAgYzAsMi42NjQsMC44NTUsNC44NTQsMi41NjgsNi41NjRjMS43MTQsMS43MTIsMy45MDQsMi41NjgsNi41NjcsMi41NjhoMjcuNDA2djI3MS44YzAsMTUuODAzLDQuNDczLDI5LjI2NiwxMy40MTgsNDAuMzk4ICAgIGM4Ljk0NywxMS4xMzksMTkuNzAxLDE2LjcwMywzMi4yNjQsMTYuNzAzaDIzNy41NDJjMTIuNTY2LDAsMjMuMzE5LTUuNzU2LDMyLjI2NS0xNy4yNjhjOC45NDUtMTEuNTIsMTMuNDE1LTI1LjE3NCwxMy40MTUtNDAuOTcxICAgIFYxMDkuNjI3aDI3LjQxMWMyLjY2MiwwLDQuODUzLTAuODU2LDYuNTYzLTIuNTY4YzEuNzA4LTEuNzA5LDIuNTctMy45LDIuNTctNi41NjRWODIuMjIxICAgIEM0MjAuMjYsNzkuNTU3LDQxOS4zOTcsNzcuMzY3LDQxNy42ODksNzUuNjU0eiBNMTY5LjMwMSwzOS42NzhjMS4zMzEtMS43MTIsMi45NS0yLjc2Miw0Ljg1My0zLjE0aDkwLjUwNCAgICBjMS45MDMsMC4zODEsMy41MjUsMS40Myw0Ljg1NCwzLjE0bDEzLjcwOSwzMy40MDRIMTU1LjMxMUwxNjkuMzAxLDM5LjY3OHogTTM0Ny4xNzMsMzgwLjI5MWMwLDQuMTg2LTAuNjY0LDguMDQyLTEuOTk5LDExLjU2MSAgICBjLTEuMzM0LDMuNTE4LTIuNzE3LDYuMDg4LTQuMTQxLDcuNzA2Yy0xLjQzMSwxLjYyMi0yLjQyMywyLjQyNy0yLjk5OCwyLjQyN0gxMDAuNDkzYy0wLjU3MSwwLTEuNTY1LTAuODA1LTIuOTk2LTIuNDI3ICAgIGMtMS40MjktMS42MTgtMi44MS00LjE4OC00LjE0My03LjcwNmMtMS4zMzEtMy41MTktMS45OTctNy4zNzktMS45OTctMTEuNTYxVjEwOS42MjdoMjU1LjgxNVYzODAuMjkxeiIgZmlsbD0iI2ZmOWNhZSIvPgoJCTxwYXRoIGQ9Ik0xMzcuMDQsMzQ3LjE3MmgxOC4yNzFjMi42NjcsMCw0Ljg1OC0wLjg1NSw2LjU2Ny0yLjU2N2MxLjcwOS0xLjcxOCwyLjU2OC0zLjkwMSwyLjU2OC02LjU3VjE3My41ODEgICAgYzAtMi42NjMtMC44NTktNC44NTMtMi41NjgtNi41NjdjLTEuNzE0LTEuNzA5LTMuODk5LTIuNTY1LTYuNTY3LTIuNTY1SDEzNy4wNGMtMi42NjcsMC00Ljg1NCwwLjg1NS02LjU2NywyLjU2NSAgICBjLTEuNzExLDEuNzE0LTIuNTY4LDMuOTA0LTIuNTY4LDYuNTY3djE2NC40NTRjMCwyLjY2OSwwLjg1NCw0Ljg1MywyLjU2OCw2LjU3QzEzMi4xODYsMzQ2LjMxNiwxMzQuMzczLDM0Ny4xNzIsMTM3LjA0LDM0Ny4xNzJ6IiBmaWxsPSIjZmY5Y2FlIi8+CgkJPHBhdGggZD0iTTIxMC4xMjksMzQ3LjE3MmgxOC4yNzFjMi42NjYsMCw0Ljg1Ni0wLjg1NSw2LjU2NC0yLjU2N2MxLjcxOC0xLjcxOCwyLjU2OS0zLjkwMSwyLjU2OS02LjU3VjE3My41ODEgICAgYzAtMi42NjMtMC44NTItNC44NTMtMi41NjktNi41NjdjLTEuNzA4LTEuNzA5LTMuODk4LTIuNTY1LTYuNTY0LTIuNTY1aC0xOC4yNzFjLTIuNjY0LDAtNC44NTQsMC44NTUtNi41NjcsMi41NjUgICAgYy0xLjcxNCwxLjcxNC0yLjU2OCwzLjkwNC0yLjU2OCw2LjU2N3YxNjQuNDU0YzAsMi42NjksMC44NTQsNC44NTMsMi41NjgsNi41N0MyMDUuMjc0LDM0Ni4zMTYsMjA3LjQ2NSwzNDcuMTcyLDIxMC4xMjksMzQ3LjE3MnogICAgIiBmaWxsPSIjZmY5Y2FlIi8+CgkJPHBhdGggZD0iTTI4My4yMiwzNDcuMTcyaDE4LjI2OGMyLjY2OSwwLDQuODU5LTAuODU1LDYuNTctMi41NjdjMS43MTEtMS43MTgsMi41NjItMy45MDEsMi41NjItNi41N1YxNzMuNTgxICAgIGMwLTIuNjYzLTAuODUyLTQuODUzLTIuNTYyLTYuNTY3Yy0xLjcxMS0xLjcwOS0zLjkwMS0yLjU2NS02LjU3LTIuNTY1SDI4My4yMmMtMi42NywwLTQuODUzLDAuODU1LTYuNTcxLDIuNTY1ICAgIGMtMS43MTEsMS43MTQtMi41NjYsMy45MDQtMi41NjYsNi41Njd2MTY0LjQ1NGMwLDIuNjY5LDAuODU1LDQuODUzLDIuNTY2LDYuNTdDMjc4LjM2NywzNDYuMzE2LDI4MC41NSwzNDcuMTcyLDI4My4yMiwzNDcuMTcyeiIgZmlsbD0iI2ZmOWNhZSIvPgoJPC9nPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+Cjwvc3ZnPgo=) no-repeat;
}
.sidebar {
background: rgba(0, 255, 0, 0.1);
height: 150px;
padding: 25px 0;
text-align: center;
}
.sidebar .grid-stack-item {
width: 200px;
height: 100px;
border: 2px dashed green;
text-align: center;
line-height: 100px;
z-index: 10;
background: rgba(0, 255, 0, 0.1);
cursor: default;
display: inline-block;
}
.sidebar .grid-stack-item .grid-stack-item-content {
background: none;
}
</style>
</head>
<body>
<div class="container-fluid">
<h1>Two grids demo</h1>
<div class="row">
<div class="col-md-3">
<div class="sidebar">
<div class="grid-stack-item"><div class="grid-stack-item-content">Drag me</div></div>
</div>
</div>
<div class="col-md-9">
<div class="trash">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="grid-stack grid-stack-6" id="grid1">
@ -58,10 +107,15 @@
$(function () {
var options = {
width: 6,
float: true
float: false,
removable: '.trash',
removeTimeout: 100,
acceptWidgets: '.grid-stack-item'
};
$('#grid1').gridstack(options);
$('#grid2').gridstack(options);
$('#grid2').gridstack(_.defaults({
float: true
}, options));
var items = [
{x: 0, y: 0, width: 2, height: 2},
@ -75,10 +129,17 @@
var grid = $(this).data('gridstack');
_.each(items, function (node) {
grid.add_widget($('<div><div class="grid-stack-item-content" /><div/>'),
grid.addWidget($('<div><div class="grid-stack-item-content" /><div/>'),
node.x, node.y, node.width, node.height);
}, this);
});
$('.sidebar .grid-stack-item').draggable({
revert: 'invalid',
handle: '.grid-stack-item-content',
scroll: false,
appendTo: 'body'
});
});
</script>
</body>

41
dist/gridstack.all.js vendored Normal file

File diff suppressed because one or more lines are too long

79
dist/gridstack.css vendored
View file

@ -6,6 +6,14 @@
position: relative;
}
.grid-stack.grid-stack-rtl {
direction: ltr;
}
.grid-stack.grid-stack-rtl > .grid-stack-item {
direction: rtl;
}
.grid-stack .grid-stack-placeholder > .placeholder-content {
border: 1px dashed lightgray;
margin: 0;
@ -64,29 +72,22 @@
.grid-stack > .grid-stack-item > .ui-resizable-se,
.grid-stack > .grid-stack-item > .ui-resizable-sw {
text-align: right;
color: gray;
padding: 2px 3px 0 0;
margin: 0;
font: normal normal normal 10px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.grid-stack > .grid-stack-item > .ui-resizable-se::before,
.grid-stack > .grid-stack-item > .ui-resizable-sw::before {
content: "\f065";
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K);
background-repeat: no-repeat;
background-position: center;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.grid-stack > .grid-stack-item > .ui-resizable-se {
display: inline-block;
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.grid-stack > .grid-stack-item > .ui-resizable-nw {
@ -153,6 +154,10 @@
bottom: 15px;
}
.grid-stack > .grid-stack-item.ui-draggable-dragging > .ui-resizable-handle {
display: none !important;
}
.grid-stack > .grid-stack-item[data-gs-width='1'] {
width: 8.3333333333%;
}
@ -364,25 +369,19 @@
transition: left 0s, top 0s, height 0s, width 0s;
}
/** Uncomment this to show bottom-left resize handle **/
/*
.grid-stack > .grid-stack-item > .ui-resizable-sw {
display: inline-block;
@include vendor(transform, rotate(180deg));
.grid-stack.grid-stack-one-column-mode {
height: auto !important;
}
*/
@media (max-width: 768px) {
.grid-stack-item {
position: relative !important;
width: auto !important;
left: 0 !important;
top: auto !important;
margin-bottom: 20px;
}
.grid-stack-item .ui-resizable-handle {
display: none;
}
.grid-stack {
height: auto !important;
}
.grid-stack.grid-stack-one-column-mode > .grid-stack-item {
position: relative !important;
width: auto !important;
left: 0 !important;
top: auto !important;
margin-bottom: 20px;
max-width: none !important;
}
.grid-stack.grid-stack-one-column-mode > .grid-stack-item > .ui-resizable-handle {
display: none;
}

97
dist/gridstack.jQueryUI.js vendored Normal file
View file

@ -0,0 +1,97 @@
/**
* gridstack.js 0.3.0-dev
* http://troolee.github.io/gridstack.js/
* (c) 2014-2016 Pavel Reznikov, Dylan Weiss
* gridstack.js may be freely distributed under the MIT license.
* @preserve
*/
(function(factory) {
if (typeof define === 'function' && define.amd) {
define(['jquery', 'lodash', 'gridstack', 'jquery-ui/data', 'jquery-ui/disable-selection', 'jquery-ui/focusable',
'jquery-ui/form', 'jquery-ui/ie', 'jquery-ui/keycode', 'jquery-ui/labels', 'jquery-ui/jquery-1-7',
'jquery-ui/plugin', 'jquery-ui/safe-active-element', 'jquery-ui/safe-blur', 'jquery-ui/scroll-parent',
'jquery-ui/tabbable', 'jquery-ui/unique-id', 'jquery-ui/version', 'jquery-ui/widget',
'jquery-ui/widgets/mouse', 'jquery-ui/widgets/draggable', 'jquery-ui/widgets/droppable',
'jquery-ui/widgets/resizable'], factory);
} else if (typeof exports !== 'undefined') {
try { jQuery = require('jquery'); } catch (e) {}
try { _ = require('lodash'); } catch (e) {}
try { GridStackUI = require('gridstack'); } catch (e) {}
factory(jQuery, _, GridStackUI);
} else {
factory(jQuery, _, GridStackUI);
}
})(function($, _, GridStackUI) {
var scope = window;
/**
* @class JQueryUIGridStackDragDropPlugin
* jQuery UI implementation of drag'n'drop gridstack plugin.
*/
function JQueryUIGridStackDragDropPlugin(grid) {
GridStackUI.GridStackDragDropPlugin.call(this, grid);
}
GridStackUI.GridStackDragDropPlugin.registerPlugin(JQueryUIGridStackDragDropPlugin);
JQueryUIGridStackDragDropPlugin.prototype = Object.create(GridStackUI.GridStackDragDropPlugin.prototype);
JQueryUIGridStackDragDropPlugin.prototype.constructor = JQueryUIGridStackDragDropPlugin;
JQueryUIGridStackDragDropPlugin.prototype.resizable = function(el, opts) {
el = $(el);
if (opts === 'disable' || opts === 'enable') {
el.resizable(opts);
} else if (opts === 'option') {
var key = arguments[2];
var value = arguments[3];
el.resizable(opts, key, value);
} else {
el.resizable(_.extend({}, this.grid.opts.resizable, {
start: opts.start || function() {},
stop: opts.stop || function() {},
resize: opts.resize || function() {}
}));
}
return this;
};
JQueryUIGridStackDragDropPlugin.prototype.draggable = function(el, opts) {
el = $(el);
if (opts === 'disable' || opts === 'enable') {
el.draggable(opts);
} else {
el.draggable(_.extend({}, this.grid.opts.draggable, {
containment: this.grid.opts.isNested ? this.grid.container.parent() : null,
start: opts.start || function() {},
stop: opts.stop || function() {},
drag: opts.drag || function() {}
}));
}
return this;
};
JQueryUIGridStackDragDropPlugin.prototype.droppable = function(el, opts) {
el = $(el);
if (opts === 'disable' || opts === 'enable') {
el.droppable(opts);
} else {
el.droppable({
accept: opts.accept
});
}
return this;
};
JQueryUIGridStackDragDropPlugin.prototype.isDroppable = function(el, opts) {
el = $(el);
return Boolean(el.data('droppable'));
};
JQueryUIGridStackDragDropPlugin.prototype.on = function(el, eventName, callback) {
$(el).on(eventName, callback);
return this;
};
return JQueryUIGridStackDragDropPlugin;
});

13
dist/gridstack.jQueryUI.min.js vendored Normal file
View file

@ -0,0 +1,13 @@
/**
* gridstack.js 0.3.0-dev
* http://troolee.github.io/gridstack.js/
* (c) 2014-2016 Pavel Reznikov, Dylan Weiss
* gridstack.js may be freely distributed under the MIT license.
* @preserve
*/
!function(a){if("function"==typeof define&&define.amd)define(["jquery","lodash","gridstack","jquery-ui/data","jquery-ui/disable-selection","jquery-ui/focusable","jquery-ui/form","jquery-ui/ie","jquery-ui/keycode","jquery-ui/labels","jquery-ui/jquery-1-7","jquery-ui/plugin","jquery-ui/safe-active-element","jquery-ui/safe-blur","jquery-ui/scroll-parent","jquery-ui/tabbable","jquery-ui/unique-id","jquery-ui/version","jquery-ui/widget","jquery-ui/widgets/mouse","jquery-ui/widgets/draggable","jquery-ui/widgets/droppable","jquery-ui/widgets/resizable"],a);else if("undefined"!=typeof exports){try{jQuery=require("jquery")}catch(a){}try{_=require("lodash")}catch(a){}try{GridStackUI=require("gridstack")}catch(a){}a(jQuery,_,GridStackUI)}else a(jQuery,_,GridStackUI)}(function(a,b,c){/**
* @class JQueryUIGridStackDragDropPlugin
* jQuery UI implementation of drag'n'drop gridstack plugin.
*/
function d(a){c.GridStackDragDropPlugin.call(this,a)}window;return c.GridStackDragDropPlugin.registerPlugin(d),d.prototype=Object.create(c.GridStackDragDropPlugin.prototype),d.prototype.constructor=d,d.prototype.resizable=function(c,d){if(c=a(c),"disable"===d||"enable"===d)c.resizable(d);else if("option"===d){var e=arguments[2],f=arguments[3];c.resizable(d,e,f)}else c.resizable(b.extend({},this.grid.opts.resizable,{start:d.start||function(){},stop:d.stop||function(){},resize:d.resize||function(){}}));return this},d.prototype.draggable=function(c,d){return c=a(c),"disable"===d||"enable"===d?c.draggable(d):c.draggable(b.extend({},this.grid.opts.draggable,{containment:this.grid.opts.isNested?this.grid.container.parent():null,start:d.start||function(){},stop:d.stop||function(){},drag:d.drag||function(){}})),this},d.prototype.droppable=function(b,c){return b=a(b),"disable"===c||"enable"===c?b.droppable(c):b.droppable({accept:c.accept}),this},d.prototype.isDroppable=function(b,c){return b=a(b),Boolean(b.data("droppable"))},d.prototype.on=function(b,c,d){return a(b).on(c,d),this},d});
//# sourceMappingURL=gridstack.min.map

1658
dist/gridstack.js vendored Executable file → Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

30
dist/gridstack.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

51
doc/FAQ.md Normal file
View file

@ -0,0 +1,51 @@
Frequently asked questions
==========================
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
- [Gridstack doesn't use bootstrap 3 classes. Why you say it's bootstrap 3 friendly.](#gridstack-doesnt-use-bootstrap-3-classes-why-you-say-its-bootstrap-3-friendly)
- [How can I create a static layout using gridstack.](#how-can-i-create-a-static-layout-using-gridstack)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
### Gridstack doesn't use bootstrap 3 classes. Why you say it's bootstrap 3 friendly.
**Q:**
Original issue #390:
> Hi,
>
> Excuse my ignorance but on your site you write "responsive bootstrap v3 friendly layouts" but how?
>
> In none of the examples you actually make use of any bootstrap classes. You add it to head but if you do that with gridster it works exactly the same..
>
> What does gridstack do different then gridster?
>
> Reason I'm asking is because I have bootstrap HTML templates I want to put them in the grid so users can move it all around .. then when done have a normal html page (without the draggable grid). I thought gridstack would help to do that in favor of gridster but so far I have not seen any difference between the 2..
>
> Thanks!
**A:**
We never declare that gridstack uses bootstrap classes. We say that gridstack could be responsive (widgets are not fixed width) it works well on bootstrap 3 pages with fixed or responsive layout. That's why it says bootstrap 3 friendly.
It wasn't a goal for gridstack to create bootstrap 3 layouts. It's not a goal now neither. The goal of gridstack is to create dashboard layouts with draggable/resizable widgets.
Gridstack uses internal grid to implement its logic. DOM nodes are just interpretation of this grid. So we or you probably could create a third party library which exports this internal grid into bootstrap 3/bootstrap 4/absolute divs/whatever layout. But I don't see this as part of gridstack core. As the same as support of angular/knockout/whatever libraries. We're doing all necessary for smooth support but it will never be a part of core.
The main idea is to build as simple and flexible lib as possible.
### How can I create a static layout using gridstack.
**Q:**
How can I create a static layout not using jQuery UI, etc.
**A:**
The main propose of gridstack is creating dashboards with draggable and/or resizable widgets. You could disable this behavior by setting `static` option. At this point you will probably
still need to include jQuery UI. But we will try to decrease dependency of it in near future.

474
doc/README.md Normal file
View file

@ -0,0 +1,474 @@
gridstack.js API
================
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
- [Options](#options)
- [Grid attributes](#grid-attributes)
- [Item attributes](#item-attributes)
- [Events](#events)
- [added(event, items)](#addedevent-items)
- [change(event, items)](#changeevent-items)
- [disable(event)](#disableevent)
- [dragstart(event, ui)](#dragstartevent-ui)
- [dragstop(event, ui)](#dragstopevent-ui)
- [enable(event)](#enableevent)
- [removed(event, items)](#removedevent-items)
- [resizestart(event, ui)](#resizestartevent-ui)
- [resizestop(event, ui)](#resizestopevent-ui)
- [API](#api)
- [addWidget(el[, x, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id])](#addwidgetel-x-y-width-height-autoposition-minwidth-maxwidth-minheight-maxheight-id)
- [batchUpdate()](#batchupdate)
- [cellHeight()](#cellheight)
- [cellHeight(val)](#cellheightval)
- [cellWidth()](#cellwidth)
- [commit()](#commit)
- [destroy([detachGrid])](#destroydetachgrid)
- [disable()](#disable)
- [enable()](#enable)
- [enableMove(doEnable, includeNewWidgets)](#enablemovedoenable-includenewwidgets)
- [enableResize(doEnable, includeNewWidgets)](#enableresizedoenable-includenewwidgets)
- [getCellFromPixel(position[, useOffset])](#getcellfrompixelposition-useoffset)
- [isAreaEmpty(x, y, width, height)](#isareaemptyx-y-width-height)
- [locked(el, val)](#lockedel-val)
- [makeWidget(el)](#makewidgetel)
- [maxHeight(el, val)](#maxheightel-val)
- [minHeight(el, val)](#minheightel-val)
- [maxWidth(el, val)](#maxwidthel-val)
- [minWidth(el, val)](#minwidthel-val)
- [movable(el, val)](#movableel-val)
- [move(el, x, y)](#moveel-x-y)
- [removeWidget(el[, detachNode])](#removewidgetel-detachnode)
- [removeAll([detachNode])](#removealldetachnode)
- [resize(el, width, height)](#resizeel-width-height)
- [resizable(el, val)](#resizableel-val)
- [setAnimation(doAnimate)](#setanimationdoanimate)
- [setGridWidth(gridWidth, doNotPropagate)](#setgridwidthgridwidth-donotpropagate)
- [setStatic(staticValue)](#setstaticstaticvalue)
- [update(el, x, y, width, height)](#updateel-x-y-width-height)
- [verticalMargin(value, noUpdate)](#verticalmarginvalue-noupdate)
- [willItFit(x, y, width, height, autoPosition)](#willitfitx-y-width-height-autoposition)
- [Utils](#utils)
- [GridStackUI.Utils.sort(nodes[, dir[, width]])](#gridstackuiutilssortnodes-dir-width)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Options
- `acceptWidgets` - if `true` of jquery selector the grid will accept widgets dragged from other grids or from
outside (default: `false`) See [example](http://troolee.github.io/gridstack.js/demo/two.html)
- `alwaysShowResizeHandle` - if `true` the resizing handles are shown even if the user is not hovering over the widget
(default: `false`)
- `animate` - turns animation on (default: `false`)
- `auto` - if `false` gridstack will not initialize existing items (default: `true`)
- `cellHeight` - one cell height (default: `60`). Can be:
- an integer (px)
- a string (ex: '10em', '100px', '10rem')
- 0 or null, in which case the library will not generate styles for rows. Everything must be defined in CSS files.
- `'auto'` - height will be calculated from cell width.
- `ddPlugin` - class that implement drag'n'drop functionallity for gridstack. If `false` grid will be static. (default: `null` - first available plugin will be used)
- `disableDrag` - disallows dragging of widgets (default: `false`).
- `disableResize` - disallows resizing of widgets (default: `false`).
- `draggable` - allows to override jQuery UI draggable options. (default: `{handle: '.grid-stack-item-content', scroll: false, appendTo: 'body'}`)
- `handle` - draggable handle selector (default: `'.grid-stack-item-content'`)
- `handleClass` - draggable handle class (e.g. `'grid-stack-item-content'`). If set `handle` is ignored (default: `null`)
- `height` - maximum rows amount. Default is `0` which means no maximum rows
- `float` - enable floating widgets (default: `false`) See [example](http://troolee.github.io/gridstack.js/demo/float.html)
- `itemClass` - widget class (default: `'grid-stack-item'`)
- `minWidth` - minimal width. If window width is less, grid will be shown in one-column mode (default: `768`)
- `oneColumnModeClass` - class set on grid when in one column mode (default: 'grid-stack-one-column-mode')
- `placeholderClass` - class for placeholder (default: `'grid-stack-placeholder'`)
- `placeholderText` - placeholder default content (default: `''`)
- `resizable` - allows to override jQuery UI resizable options. (default: `{autoHide: true, handles: 'se'}`)
- `removable` - if `true` widgets could be removed by dragging outside of the grid. It could also be a jQuery selector string, in this case widgets will be removed by dropping them there (default: `false`) See [example](http://troolee.github.io/gridstack.js/demo/two.html)
- `removeTimeout` - time in milliseconds before widget is being removed while dragging outside of the grid. (default: `2000`)
- `rtl` - if `true` turns grid to RTL. Possible values are `true`, `false`, `'auto'` (default: `'auto'`) See [example](http://troolee.github.io/gridstack.js/demo/rtl.html)
- `staticGrid` - 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.
- `verticalMargin` - vertical gap size (default: `20`). Can be:
- an integer (px)
- a string (ex: '2em', '20px', '2rem')
- `width` - amount of columns (default: `12`)
## Grid attributes
- `data-gs-animate` - turns animation on
- `data-gs-width` - amount of columns
- `data-gs-height` - maximum rows amount. Default is `0` which means no maximum rows.
- `data-gs-current-height` - current rows amount. Set by the library only. Can be used by the CSS rules.
## Item attributes
- `data-gs-x`, `data-gs-y` - element position
- `data-gs-width`, `data-gs-height` - element size
- `data-gs-max-width`, `data-gs-min-width`, `data-gs-max-height`, `data-gs-min-height` - element constraints
- `data-gs-no-resize` - disable element resizing
- `data-gs-no-move` - disable element moving
- `data-gs-auto-position` - tells to ignore `data-gs-x` and `data-gs-y` attributes and to place element to the first
available position
- `data-gs-locked` - the widget will be locked. It means another widget wouldn't be able to move it during dragging or resizing.
The widget can still be dragged or resized. You need to add `data-gs-no-resize` and `data-gs-no-move` attributes
to completely lock the widget.
## Events
### added(event, items)
```javascript
$('.grid-stack').on('added', function(event, items) {
for (var i = 0; i < items.length; i++) {
console.log('item added');
console.log(items[i]);
}
});
```
### change(event, items)
Occurs when adding/removing widgets or existing widgets change their position/size
```javascript
var serializeWidgetMap = function(items) {
console.log(items);
};
$('.grid-stack').on('change', function(event, items) {
serializeWidgetMap(items);
});
```
### disable(event)
```javascript
$('.grid-stack').on('disable', function(event) {
var grid = event.target;
});
```
### dragstart(event, ui)
```javascript
$('.grid-stack').on('dragstart', function(event, ui) {
var grid = this;
var element = event.target;
});
```
### dragstop(event, ui)
```javascript
$('.grid-stack').on('dragstop', function(event, ui) {
var grid = this;
var element = event.target;
});
```
### enable(event)
```javascript
$('.grid-stack').on('enable', function(event) {
var grid = event.target;
});
```
### removed(event, items)
```javascript
$('.grid-stack').on('removed', function(event, items) {
for (var i = 0; i < items.length; i++) {
console.log('item removed');
console.log(items[i]);
}
});
```
### resizestart(event, ui)
```javascript
$('.grid-stack').on('resizestart', function(event, ui) {
var grid = this;
var element = event.target;
});
```
### resizestop(event, ui)
```javascript
$('.grid-stack').on('resizestop', function(event, ui) {
var grid = this;
var element = event.target;
});
```
## API
### addWidget(el[, x, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id])
Creates new widget and returns it.
Parameters:
- `el` - widget to add
- `x`, `y`, `width`, `height` - widget position/dimensions (optional)
- `autoPosition` - if `true` then `x`, `y` parameters will be ignored and widget will be places on the first available
position (optional)
- `minWidth` minimum width allowed during resize/creation (optional)
- `maxWidth` maximum width allowed during resize/creation (optional)
- `minHeight` minimum height allowed during resize/creation (optional)
- `maxHeight` maximum height allowed during resize/creation (optional)
- `id` value for `data-gs-id` (optional)
Widget will be always placed even if result height is more than actual grid height. You need to use `willItFit` method
before calling `addWidget` for additional check.
```javascript
$('.grid-stack').gridstack();
var grid = $('.grid-stack').data('gridstack');
grid.addWidget(el, 0, 0, 3, 2, true);
```
### batchUpdate()
Initailizes batch updates. You will see no changes until `commit` method is called.
### cellHeight()
Gets current cell height.
### cellHeight(val)
Update current cell height. This method rebuilds an internal CSS stylesheet. Note: You can expect performance issues if
call this method too often.
```javascript
grid.cellHeight(grid.cellWidth() * 1.2);
```
### cellWidth()
Gets current cell width.
### commit()
Finishes batch updates. Updates DOM nodes. You must call it after `batchUpdate`.
### destroy([detachGrid])
Destroys a grid instance.
Parameters:
- `detachGrid` - if `false` nodes and grid will not be removed from the DOM (Optional. Default `true`).
### disable()
Disables widgets moving/resizing. This is a shortcut for:
```javascript
grid.movable('.grid-stack-item', false);
grid.resizable('.grid-stack-item', false);
```
### enable()
Enables widgets moving/resizing. This is a shortcut for:
```javascript
grid.movable('.grid-stack-item', true);
grid.resizable('.grid-stack-item', true);
```
### enableMove(doEnable, includeNewWidgets)
Enables/disables widget moving. `includeNewWidgets` will force new widgets to be draggable as per `doEnable`'s value by changing the `disableDrag` grid option. This is a shortcut for:
```javascript
grid.movable(this.container.children('.' + this.opts.itemClass), doEnable);
```
### enableResize(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. This is a shortcut for:
```javascript
grid.resizable(this.container.children('.' + this.opts.itemClass), doEnable);
```
### getCellFromPixel(position[, useOffset])
Get the position of the cell under a pixel on screen.
Parameters :
- `position` - the position of the pixel to resolve in absolute coordinates, as an object with `top` and `left` properties
- `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.
### isAreaEmpty(x, y, width, height)
Checks if specified area is empty.
### locked(el, val)
Locks/unlocks widget.
- `el` - widget to modify.
- `val` - if `true` widget will be locked.
### makeWidget(el)
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 `addWidget` instead.
Makes the given element a widget and returns it.
Parameters:
- `el` - element to convert to a widget
```javascript
$('.grid-stack').gridstack();
$('.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>')
var grid = $('.grid-stack').data('gridstack');
grid.makeWidget('gsi-1');
```
### maxHeight(el, val)
Set the `maxHeight` for a widget.
- `el` - widget to modify.
- `val` - A numeric value of the number of rows
### minHeight(el, val)
Set the `minHeight` for a widget.
- `el` - widget to modify.
- `val` - A numeric value of the number of rows
### maxWidth(el, val)
Set the `maxWidth` for a widget.
- `el` - widget to modify.
- `val` - A numeric value of the number of columns
### minWidth(el, val)
Set the `minWidth` for a widget.
- `el` - widget to modify.
- `val` - A numeric value of the number of columns
### movable(el, val)
Enables/Disables moving.
- `el` - widget to modify
- `val` - if `true` widget will be draggable.
### move(el, x, y)
Changes widget position
Parameters:
- `el` - widget to move
- `x`, `y` - new position. If value is `null` or `undefined` it will be ignored.
### removeWidget(el[, detachNode])
Removes widget from the grid.
Parameters:
- `el` - widget to remove.
- `detachNode` - if `false` node won't be removed from the DOM (Optional. Default `true`).
### removeAll([detachNode])
Removes all widgets from the grid.
Parameters:
- `detachNode` - if `false` nodes won't be removed from the DOM (Optional. Default `true`).
### resize(el, width, height)
Changes widget size
Parameters:
- `el` - widget to resize
- `width`, `height` - new dimensions. If value is `null` or `undefined` it will be ignored.
### resizable(el, val)
Enables/Disables resizing.
- `el` - widget to modify
- `val` - if `true` widget will be resizable.
### setAnimation(doAnimate)
Toggle the grid animation state. Toggles the `grid-stack-animate` class.
- `doAnimate` - if `true` the grid will animate.
### setGridWidth(gridWidth, doNotPropagate)
(Experimental) Modify number of columns in the grid. Will attempt to update existing widgets to conform to new number of columns. Requires `gridstack-extra.css` or `gridstack-extra.min.css`.
- `gridWidth` - Integer between 1 and 12.
- `doNotPropagate` - if true existing widgets will not be updated.
### setStatic(staticValue)
Toggle the grid static state. Also toggle the `grid-stack-static` class.
- `staticValue` - if `true` the grid becomes static.
### update(el, x, y, width, height)
Parameters:
- `el` - widget to move
- `x`, `y` - new position. If value is `null` or `undefined` it will be ignored.
- `width`, `height` - new dimensions. If value is `null` or `undefined` it will be ignored.
Updates widget position/size.
### verticalMargin(value, noUpdate)
Parameters:
- `value` - new vertical margin value.
- `noUpdate` - if true, styles will not be updated.
### willItFit(x, y, width, height, autoPosition)
Returns `true` if the `height` of the grid will be less the vertical constraint. Always returns `true` if grid doesn't
have `height` constraint.
```javascript
if (grid.willItFit(newNode.x, newNode.y, newNode.width, newNode.height, true)) {
grid.addWidget(newNode.el, newNode.x, newNode.y, newNode.width, newNode.height, true);
}
else {
alert('Not enough free space to place the widget');
}
```
## Utils
### GridStackUI.Utils.sort(nodes[, dir[, width]])
Sorts array of nodes
- `nodes` - array to sort
- `dir` - `1` for asc, `-1` for desc (optional)
- `width` - width of the grid. If `undefined` the width will be calculated automatically (optional).

81
karma.conf.js Normal file
View file

@ -0,0 +1,81 @@
// Karma configuration
// Generated on Thu Feb 18 2016 22:00:23 GMT+0100 (CET)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'bower_components/jquery/dist/jquery.min.js',
'bower_components/jquery-ui/jquery-ui.min.js',
'bower_components/lodash/dist/lodash.min.js',
'src/gridstack.js',
'src/gridstack.jQueryUI.js',
'spec/*-spec.js'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'src/gridstack.js': ['coverage'],
'src/gridstack.jQueryUI.js': ['coverage'],
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage', 'coveralls'],
coverageReporter: {
type: 'lcov', // lcov or lcovonly are required for generating lcov.info files
dir: 'coverage/'
},
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN
// config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
});
}

33
package.json Executable file → Normal file
View file

@ -1,12 +1,16 @@
{
"name": "gridstack",
"version": "0.2.4",
"version": "0.3.0-dev",
"description": "gridstack.js is a jQuery plugin for widget layout",
"main": "dist/gridstack.js",
"repository": {
"type": "git",
"url": "git+https://github.com/troolee/gridstack.js.git"
},
"scripts": {
"build": "grunt",
"test": "karma start karma.conf.js"
},
"keywords": [
"gridstack",
"grid",
@ -20,12 +24,35 @@
"url": "https://github.com/troolee/gridstack.js/issues"
},
"homepage": "http://troolee.github.io/gridstack.js/",
"dependencies": {
"jquery": "^3.1.0",
"jquery-ui": "^1.12.0",
"lodash": "^4.14.2"
},
"devDependencies": {
"connect": "^3.4.1",
"coveralls": "^2.11.8",
"doctoc": "^1.0.0",
"grunt": "^0.4.5",
"grunt-cli": "^1.2.0",
"grunt-contrib-connect": "^0.11.2",
"grunt-contrib-copy": "^0.8.2",
"grunt-contrib-cssmin": "^0.14.0",
"grunt-contrib-uglify": "^0.10.1",
"grunt-contrib-jshint": "^1.0.0",
"grunt-contrib-uglify": "^0.11.1",
"grunt-contrib-watch": "^0.6.1",
"grunt-doctoc": "^0.1.1",
"grunt-jscs": "^2.8.0",
"grunt-protractor-runner": "^3.2.0",
"grunt-protractor-webdriver": "^0.2.5",
"grunt-sass": "^1.1.0",
"grunt-doctoc": "^0.1.1"
"jasmine-core": "^2.4.1",
"karma": "^1.1.2",
"karma-coverage": "^1.1.1",
"karma-coveralls": "^1.1.2",
"karma-jasmine": "^1.0.2",
"karma-phantomjs-launcher": "^1.0.0",
"phantomjs-prebuilt": "^2.1.5",
"serve-static": "^1.10.2"
}
}

12
protractor.conf.js Normal file
View file

@ -0,0 +1,12 @@
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['spec/e2e/*-spec.js'],
capabilities: {
browserName: 'firefox',
version: '',
platform: 'ANY',
loggingPrefs: {
browser: 'SEVERE'
}
},
};

View file

@ -0,0 +1,24 @@
describe('gridstack.js with height', function() {
beforeAll(function() {
browser.ignoreSynchronization = true;
});
beforeEach(function() {
browser.get('http://localhost:8080/spec/e2e/html/gridstack-with-height.html');
});
it('shouldn\'t throw exeption when dragging widget outside the grid', function() {
var widget = element(by.id('item-1'));
var gridContainer = element(by.id('grid'));
browser.actions()
.mouseDown(widget, {x: 20, y: 20})
.mouseMove(gridContainer, {x: 300, y: 20})
.mouseUp()
.perform();
browser.manage().logs().get('browser').then(function(browserLog) {
expect(browserLog.length).toEqual(0);
});
});
});

View file

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>gridstack.js tests</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../../../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="../../../dist/gridstack.js"></script>
<script src="../../../dist/gridstack.jQueryUI.js"></script>
<style type="text/css">
.grid-stack {
background: lightgoldenrodyellow;
}
.grid-stack-item-content {
color: #2c3e50;
text-align: center;
background-color: #18bc9c;
}
</style>
</head>
<body>
<div class="container-fluid">
<h1>gridstack.js tests</h1>
<br/>
<div class="grid-stack" id="grid">
</div>
</div>
<script type="text/javascript">
$(function() {
var options = {
height: 5
};
$('.grid-stack').gridstack(options);
new function() {
var items = [
{x: 0, y: 0, width: 2, height: 2},
{x: 2, y: 5, width: 1, height: 1}
];
this.grid = $('.grid-stack').data('gridstack');
this.grid.removeAll();
items = GridStackUI.Utils.sort(items);
var id = 0;
_.each(items, function(node) {
var w = $('<div><div class="grid-stack-item-content" /><div/>');
w.attr('id', 'item-' + (++id));
this.grid.addWidget(w,
node.x, node.y, node.width, node.height);
}, this);
};
});
</script>
</body>
</html>

View file

@ -0,0 +1,311 @@
describe('gridstack engine', function() {
'use strict';
var e;
var w;
beforeEach(function() {
w = window;
e = w.GridStackUI.Engine;
});
describe('test constructor', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12);
});
it('should be setup properly', function() {
expect(engine.width).toEqual(12);
expect(engine.float).toEqual(false);
expect(engine.height).toEqual(0);
expect(engine.nodes).toEqual([]);
});
});
describe('test _prepareNode', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12);
});
it('should prepare a node', function() {
expect(engine._prepareNode({}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({x: 10}, false)).toEqual(jasmine.objectContaining({x: 10, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({x: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({y: 10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 10, width: 1, height: 1}));
expect(engine._prepareNode({y: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({width: 3}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 3, height: 1}));
expect(engine._prepareNode({width: 100}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 12, height: 1}));
expect(engine._prepareNode({width: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({width: -190}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({height: 3}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 3}));
expect(engine._prepareNode({height: 0}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({height: -10}, false)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(engine._prepareNode({x: 4, width: 10}, false)).toEqual(jasmine.objectContaining({x: 2, y: 0, width: 10, height: 1}));
expect(engine._prepareNode({x: 4, width: 10}, true)).toEqual(jasmine.objectContaining({x: 4, y: 0, width: 8, height: 1}));
});
});
describe('test isAreaEmpty', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12, null, true);
engine.nodes = [
engine._prepareNode({x: 3, y: 2, width: 3, height: 2})
];
});
it('should be true', function() {
expect(engine.isAreaEmpty(0, 0, 3, 2)).toEqual(true);
expect(engine.isAreaEmpty(3, 4, 3, 2)).toEqual(true);
});
it('should be false', function() {
expect(engine.isAreaEmpty(1, 1, 3, 2)).toEqual(false);
expect(engine.isAreaEmpty(2, 3, 3, 2)).toEqual(false);
});
});
describe('test cleanNodes/getDirtyNodes', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12, null, true);
engine.nodes = [
engine._prepareNode({x: 0, y: 0, width: 1, height: 1, idx: 1, _dirty: true}),
engine._prepareNode({x: 3, y: 2, width: 3, height: 2, idx: 2, _dirty: true}),
engine._prepareNode({x: 3, y: 7, width: 3, height: 2, idx: 3})
];
});
beforeEach(function() {
engine._updateCounter = 0;
});
it('should return all dirty nodes', function() {
var nodes = engine.getDirtyNodes();
expect(nodes.length).toEqual(2);
expect(nodes[0].idx).toEqual(1);
expect(nodes[1].idx).toEqual(2);
});
it('should\'n clean nodes if _updateCounter > 0', function() {
engine._updateCounter = 1;
engine.cleanNodes();
expect(engine.getDirtyNodes().length).toBeGreaterThan(0);
});
it('should clean all dirty nodes', function() {
engine.cleanNodes();
expect(engine.getDirtyNodes().length).toEqual(0);
});
});
describe('test batchUpdate/commit', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12);
});
it('should work on not float grids', function() {
expect(engine.float).toEqual(false);
engine.batchUpdate();
expect(engine._updateCounter).toBeGreaterThan(0);
expect(engine.float).toEqual(true);
engine.commit();
expect(engine._updateCounter).toEqual(0);
expect(engine.float).toEqual(false);
});
});
describe('test batchUpdate/commit', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12, null, true);
});
it('should work on float grids', function() {
expect(engine.float).toEqual(true);
engine.batchUpdate();
expect(engine._updateCounter).toBeGreaterThan(0);
expect(engine.float).toEqual(true);
engine.commit();
expect(engine._updateCounter).toEqual(0);
expect(engine.float).toEqual(true);
});
});
describe('test _notify', function() {
var engine;
var spy;
beforeEach(function() {
spy = {
callback: function() {}
};
spyOn(spy, 'callback');
engine = new GridStackUI.Engine(12, spy.callback, true);
engine.nodes = [
engine._prepareNode({x: 0, y: 0, width: 1, height: 1, idx: 1, _dirty: true}),
engine._prepareNode({x: 3, y: 2, width: 3, height: 2, idx: 2, _dirty: true}),
engine._prepareNode({x: 3, y: 7, width: 3, height: 2, idx: 3})
];
});
it('should\'n be called if _updateCounter > 0', function() {
engine._updateCounter = 1;
engine._notify();
expect(spy.callback).not.toHaveBeenCalled();
});
it('should by called with dirty nodes', function() {
engine._notify();
expect(spy.callback).toHaveBeenCalledWith([
engine.nodes[0],
engine.nodes[1]
], true);
});
it('should by called with extra passed node to be removed', function() {
var n1 = {idx: -1};
engine._notify(n1);
expect(spy.callback).toHaveBeenCalledWith([
n1,
engine.nodes[0],
engine.nodes[1]
], true);
});
it('should by called with extra passed node to be removed and should maintain false parameter', function() {
var n1 = {idx: -1};
engine._notify(n1, false);
expect(spy.callback).toHaveBeenCalledWith([
n1,
engine.nodes[0],
engine.nodes[1]
], false);
});
});
describe('test _packNodes', function() {
describe('using not float mode', function() {
var engine;
var findNode = function(engine, id) {
return _.find(engine.nodes, function(i) { return i._id === id; });
};
beforeEach(function() {
engine = new GridStackUI.Engine(12, null, false);
});
it('shouldn\'t pack one node with y coord eq 0', function() {
engine.nodes = [
{x: 0, y: 0, width: 1, height: 1, _id: 1},
];
engine._packNodes();
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1}));
expect(findNode(engine, 1)._dirty).toBeFalsy();
});
it('should pack one node correctly', function() {
engine.nodes = [
{x: 0, y: 1, width: 1, height: 1, _id: 1},
];
engine._packNodes();
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1, _dirty: true}));
});
it('should pack nodes correctly', function() {
engine.nodes = [
{x: 0, y: 1, width: 1, height: 1, _id: 1},
{x: 0, y: 5, width: 1, height: 1, _id: 2},
];
engine._packNodes();
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1, _dirty: true}));
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 0, y: 1, width: 1, height: 1, _dirty: true}));
});
it('should pack nodes correctly', function() {
engine.nodes = [
{x: 0, y: 5, width: 1, height: 1, _id: 1},
{x: 0, y: 1, width: 1, height: 1, _id: 2},
];
engine._packNodes();
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 0, y: 0, width: 1, height: 1, _dirty: true}));
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, width: 1, height: 1, _dirty: true}));
});
it('should respect locked nodes', function() {
engine.nodes = [
{x: 0, y: 1, width: 1, height: 1, _id: 1, locked: true},
{x: 0, y: 5, width: 1, height: 1, _id: 2},
];
engine._packNodes();
expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, width: 1, height: 1}));
expect(findNode(engine, 1)._dirty).toBeFalsy();
expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 0, y: 2, width: 1, height: 1, _dirty: true}));
});
});
});
describe('test isNodeChangedPosition', function() {
var engine;
beforeAll(function() {
engine = new GridStackUI.Engine(12);
});
it('should return true for changed x', function() {
var widget = { x: 1, y: 2, width: 3, height: 4 };
expect(engine.isNodeChangedPosition(widget, 2, 2)).toEqual(true);
});
it('should return true for changed y', function() {
var widget = { x: 1, y: 2, width: 3, height: 4 };
expect(engine.isNodeChangedPosition(widget, 1, 1)).toEqual(true);
});
it('should return true for changed width', function() {
var widget = { x: 1, y: 2, width: 3, height: 4 };
expect(engine.isNodeChangedPosition(widget, 2, 2, 4, 4)).toEqual(true);
});
it('should return true for changed height', function() {
var widget = { x: 1, y: 2, width: 3, height: 4 };
expect(engine.isNodeChangedPosition(widget, 1, 2, 3, 3)).toEqual(true);
});
it('should return false for unchanged position', function() {
var widget = { x: 1, y: 2, width: 3, height: 4 };
expect(engine.isNodeChangedPosition(widget, 1, 2, 3, 4)).toEqual(false);
});
});
});

1269
spec/gridstack-spec.js Normal file

File diff suppressed because it is too large Load diff

109
spec/utils-spec.js Normal file
View file

@ -0,0 +1,109 @@
describe('gridstack utils', function() {
'use strict';
var utils;
beforeEach(function() {
utils = window.GridStackUI.Utils;
});
describe('setup of utils', function() {
it('should set gridstack utils.', function() {
expect(utils).not.toBeNull();
expect(typeof utils).toBe('object');
});
});
describe('test toBool', function() {
it('should return booleans.', function() {
expect(utils.toBool(true)).toEqual(true);
expect(utils.toBool(false)).toEqual(false);
});
it('should work with integer.', function() {
expect(utils.toBool(1)).toEqual(true);
expect(utils.toBool(0)).toEqual(false);
});
it('should work with Strings.', function() {
expect(utils.toBool('')).toEqual(false);
expect(utils.toBool('0')).toEqual(false);
expect(utils.toBool('no')).toEqual(false);
expect(utils.toBool('false')).toEqual(false);
expect(utils.toBool('yes')).toEqual(true);
expect(utils.toBool('yadda')).toEqual(true);
});
});
describe('test isIntercepted', function() {
var src = {x: 3, y: 2, width: 3, height: 2};
it('should intercept.', function() {
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 4, height: 3})).toEqual(true);
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 40, height: 30})).toEqual(true);
expect(utils.isIntercepted(src, {x: 3, y: 2, width: 3, height: 2})).toEqual(true);
expect(utils.isIntercepted(src, {x: 5, y: 3, width: 3, height: 2})).toEqual(true);
});
it('shouldn\'t intercept.', function() {
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 3, height: 2})).toEqual(false);
expect(utils.isIntercepted(src, {x: 0, y: 0, width: 13, height: 2})).toEqual(false);
expect(utils.isIntercepted(src, {x: 1, y: 4, width: 13, height: 2})).toEqual(false);
expect(utils.isIntercepted(src, {x: 0, y: 3, width: 3, height: 2})).toEqual(false);
expect(utils.isIntercepted(src, {x: 6, y: 3, width: 3, height: 2})).toEqual(false);
});
});
describe('test createStylesheet/removeStylesheet', function() {
it('should create/remove style DOM', function() {
var _id = 'test-123';
utils.createStylesheet(_id);
var style = $('STYLE[data-gs-style-id=' + _id + ']');
expect(style.length).toEqual(1);
expect(style.prop('tagName')).toEqual('STYLE');
utils.removeStylesheet(_id)
style = $('STYLE[data-gs-style-id=' + _id + ']');
expect(style.length).toEqual(0);
});
});
describe('test parseHeight', function() {
it('should parse height value', function() {
expect(utils.parseHeight(12)).toEqual(jasmine.objectContaining({height: 12, unit: 'px'}));
expect(utils.parseHeight('12px')).toEqual(jasmine.objectContaining({height: 12, unit: 'px'}));
expect(utils.parseHeight('12.3px')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'px'}));
expect(utils.parseHeight('12.3em')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'em'}));
expect(utils.parseHeight('12.3rem')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'rem'}));
expect(utils.parseHeight('12.3vh')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'vh'}));
expect(utils.parseHeight('12.3vw')).toEqual(jasmine.objectContaining({height: 12.3, unit: 'vw'}));
expect(utils.parseHeight('12.5')).toEqual(jasmine.objectContaining({height: 12.5, unit: 'px'}));
expect(function() { utils.parseHeight('12.5 df'); }).toThrowError('Invalid height');
});
it('should parse negative height value', function() {
expect(utils.parseHeight(-12)).toEqual(jasmine.objectContaining({height: -12, unit: 'px'}));
expect(utils.parseHeight('-12px')).toEqual(jasmine.objectContaining({height: -12, unit: 'px'}));
expect(utils.parseHeight('-12.3px')).toEqual(jasmine.objectContaining({height: -12.3, unit: 'px'}));
expect(utils.parseHeight('-12.3em')).toEqual(jasmine.objectContaining({height: -12.3, unit: 'em'}));
expect(utils.parseHeight('-12.3rem')).toEqual(jasmine.objectContaining({height: -12.3, unit: 'rem'}));
expect(utils.parseHeight('-12.3vh')).toEqual(jasmine.objectContaining({height: -12.3, unit: 'vh'}));
expect(utils.parseHeight('-12.3vw')).toEqual(jasmine.objectContaining({height: -12.3, unit: 'vw'}));
expect(utils.parseHeight('-12.5')).toEqual(jasmine.objectContaining({height: -12.5, unit: 'px'}));
expect(function() { utils.parseHeight('-12.5 df'); }).toThrowError('Invalid height');
});
});
});

97
src/gridstack.jQueryUI.js Normal file
View file

@ -0,0 +1,97 @@
/**
* gridstack.js 0.3.0-dev
* http://troolee.github.io/gridstack.js/
* (c) 2014-2016 Pavel Reznikov, Dylan Weiss
* gridstack.js may be freely distributed under the MIT license.
* @preserve
*/
(function(factory) {
if (typeof define === 'function' && define.amd) {
define(['jquery', 'lodash', 'gridstack', 'jquery-ui/data', 'jquery-ui/disable-selection', 'jquery-ui/focusable',
'jquery-ui/form', 'jquery-ui/ie', 'jquery-ui/keycode', 'jquery-ui/labels', 'jquery-ui/jquery-1-7',
'jquery-ui/plugin', 'jquery-ui/safe-active-element', 'jquery-ui/safe-blur', 'jquery-ui/scroll-parent',
'jquery-ui/tabbable', 'jquery-ui/unique-id', 'jquery-ui/version', 'jquery-ui/widget',
'jquery-ui/widgets/mouse', 'jquery-ui/widgets/draggable', 'jquery-ui/widgets/droppable',
'jquery-ui/widgets/resizable'], factory);
} else if (typeof exports !== 'undefined') {
try { jQuery = require('jquery'); } catch (e) {}
try { _ = require('lodash'); } catch (e) {}
try { GridStackUI = require('gridstack'); } catch (e) {}
factory(jQuery, _, GridStackUI);
} else {
factory(jQuery, _, GridStackUI);
}
})(function($, _, GridStackUI) {
var scope = window;
/**
* @class JQueryUIGridStackDragDropPlugin
* jQuery UI implementation of drag'n'drop gridstack plugin.
*/
function JQueryUIGridStackDragDropPlugin(grid) {
GridStackUI.GridStackDragDropPlugin.call(this, grid);
}
GridStackUI.GridStackDragDropPlugin.registerPlugin(JQueryUIGridStackDragDropPlugin);
JQueryUIGridStackDragDropPlugin.prototype = Object.create(GridStackUI.GridStackDragDropPlugin.prototype);
JQueryUIGridStackDragDropPlugin.prototype.constructor = JQueryUIGridStackDragDropPlugin;
JQueryUIGridStackDragDropPlugin.prototype.resizable = function(el, opts) {
el = $(el);
if (opts === 'disable' || opts === 'enable') {
el.resizable(opts);
} else if (opts === 'option') {
var key = arguments[2];
var value = arguments[3];
el.resizable(opts, key, value);
} else {
el.resizable(_.extend({}, this.grid.opts.resizable, {
start: opts.start || function() {},
stop: opts.stop || function() {},
resize: opts.resize || function() {}
}));
}
return this;
};
JQueryUIGridStackDragDropPlugin.prototype.draggable = function(el, opts) {
el = $(el);
if (opts === 'disable' || opts === 'enable') {
el.draggable(opts);
} else {
el.draggable(_.extend({}, this.grid.opts.draggable, {
containment: this.grid.opts.isNested ? this.grid.container.parent() : null,
start: opts.start || function() {},
stop: opts.stop || function() {},
drag: opts.drag || function() {}
}));
}
return this;
};
JQueryUIGridStackDragDropPlugin.prototype.droppable = function(el, opts) {
el = $(el);
if (opts === 'disable' || opts === 'enable') {
el.droppable(opts);
} else {
el.droppable({
accept: opts.accept
});
}
return this;
};
JQueryUIGridStackDragDropPlugin.prototype.isDroppable = function(el, opts) {
el = $(el);
return Boolean(el.data('droppable'));
};
JQueryUIGridStackDragDropPlugin.prototype.on = function(el, eventName, callback) {
$(el).on(eventName, callback);
return this;
};
return JQueryUIGridStackDragDropPlugin;
});

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,14 @@ $animation_speed: .3s !default;
.grid-stack {
position: relative;
&.grid-stack-rtl {
direction: ltr;
> .grid-stack-item {
direction: rtl;
}
}
.grid-stack-placeholder > .placeholder-content {
border: 1px dashed lightgray;
margin: 0;
@ -71,26 +79,17 @@ $animation_speed: .3s !default;
> .ui-resizable-se,
> .ui-resizable-sw {
text-align: right;
color: gray;
padding: 2px 3px 0 0;
margin: 0;
font: normal normal normal 10px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
&::before { content: "\f065"; }
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K);
background-repeat: no-repeat;
background-position: center;
@include vendor(transform, rotate(45deg));
}
> .ui-resizable-se {
display: inline-block;
@include vendor(transform, rotate(90deg));
@include vendor(transform, rotate(-45deg));
}
> .ui-resizable-nw { cursor: nw-resize; width: 20px; height: 20px; left: 10px; top: 0; }
> .ui-resizable-n { cursor: n-resize; height: 10px; top: 0; left: 25px; right: 25px; }
> .ui-resizable-ne { cursor: ne-resize; width: 20px; height: 20px; right: 10px; top: 0; }
@ -100,6 +99,12 @@ $animation_speed: .3s !default;
> .ui-resizable-sw { cursor: sw-resize; width: 20px; height: 20px; left: 10px; bottom: 0; }
> .ui-resizable-w { cursor: w-resize; width: 10px; left: $horizontal_padding / 2; top: 15px; bottom: 15px; }
&.ui-draggable-dragging {
&> .ui-resizable-handle {
display: none !important;
}
}
@for $i from 1 through $gridstack-columns {
&[data-gs-width='#{$i}'] { width: (100% / $gridstack-columns) * $i; }
&[data-gs-x='#{$i}'] { left: (100% / $gridstack-columns) * $i; }
@ -118,26 +123,18 @@ $animation_speed: .3s !default;
&.grid-stack-animate .grid-stack-item.grid-stack-placeholder{
@include vendor(transition, left .0s, top .0s, height .0s, width .0s);
}
}
/** Uncomment this to show bottom-left resize handle **/
/*
.grid-stack > .grid-stack-item > .ui-resizable-sw {
display: inline-block;
@include vendor(transform, rotate(180deg));
}
*/
@media (max-width: 768px) {
.grid-stack-item {
position: relative !important;
width: auto !important;
left: 0 !important;
top: auto !important;
margin-bottom: $vertical_padding;
.ui-resizable-handle { display: none; }
}
.grid-stack { height: auto !important; }
&.grid-stack-one-column-mode {
height: auto !important;
&> .grid-stack-item {
position: relative !important;
width: auto !important;
left: 0 !important;
top: auto !important;
margin-bottom: $vertical_padding;
max-width: none !important;
&> .ui-resizable-handle { display: none; }
}
}
}