Add 'lib/gridster/' from commit 'a7ed9a4adec9f7c8361ad6f392993a1f0b9c1601'

git-subtree-dir: lib/gridster
git-subtree-mainline: 80f8419dac
git-subtree-split: a7ed9a4ade
This commit is contained in:
laf
2015-11-10 21:43:44 +00:00
56 changed files with 19022 additions and 0 deletions

4
lib/gridster/.bowerrc Normal file
View File

@@ -0,0 +1,4 @@
{
"directory": "libs",
"json": "package.json"
}

11
lib/gridster/.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
node_modules/
libs/
gh-pages/
demo/
.idea
.DS_Store
*.iml
vendor
*.gem
*.css.map
demos/assets/css/demo.css

103
lib/gridster/.jshintrc Normal file
View File

@@ -0,0 +1,103 @@
{
// http://www.jshint.com/docs/
// Based on node-jshint@2.x.x
// ENFORCING OPTIONS
// These options tell JSHint to be more strict towards your code. Use them if
// you want to allow only a safe subset of JavaScript—very useful when your
// codebase is shared with a big number of developers with different skill
// levels.
"bitwise": true, //prohibits the use of bitwise operators such as ^ (XOR), | (OR) and others
"camelcase": false, //force all variable names to use either camelCase style or UPPER_CASE with underscores
"curly": true, //requires you to always put curly braces around blocks in loops and conditionals
"eqeqeq": true, //prohibits the use of == and != in favor of === and !==
"es3": false, //tells JSHint that your code needs to adhere to ECMAScript 3 specification
"forin": false, //requires all `for in` loops to filter object's items with `hasOwnProperty()`
"immed": true, //prohibits the use of immediate function invocations without wrapping them in parentheses
"indent": 2, //enforces specific tab width
"latedef": true, //prohibits the use of a variable before it was defined
"newcap": true, //requires you to capitalize names of constructor functions
"noarg": true, //prohibits the use of `arguments.caller` and `arguments.callee`
"noempty": true, //warns when you have an empty block in your code
"nonew": true, //prohibits the use of constructor functions for side-effects
"plusplus": false, //prohibits the use of unary increment and decrement operators
"quotmark": true, //enforces the consistency of quotation marks used throughout your code
"undef": true, //prohibits the use of explicitly undeclared variables
"unused": "vars", //warns when you define and never use your variables
"strict": true, //requires all functions to run in ECMAScript 5's strict mode
"trailing": true, //makes it an error to leave a trailing whitespace in your code
"maxparams": false, //set the max number of formal parameters allowed per function
"maxdepth": 6, //control how nested do you want your blocks to be
"maxstatements": false, //set the max number of statements allowed per function
"maxcomplexity": false, //control cyclomatic complexity throughout your code
// RELAXING OPTIONS
// These options allow you to suppress certain types of warnings. Use them
// only if you are absolutely positive that you know what you are doing.
"asi": false, //suppresses warnings about missing semicolons
"boss": false, //suppresses warnings about the use of assignments in cases where comparisons are expected
"debug": false, //suppresses warnings about the debugger statements in your code
"eqnull": false, //suppresses warnings about == null comparisons
"esnext": false, //your code uses ES.next specific features such as const
"evil": false, //suppresses warnings about the use of eval
"expr": true, //suppresses warnings about the use of expressions where normally you would expect to see assignments or function calls
"funcscope": false, //suppresses warnings about declaring variables inside of control structures while accessing them later from the outside
"globalstrict": false, //suppresses warnings about the use of global strict mode
"iterator": false, //suppresses warnings about the `__iterator__` property
"lastsemic": false, //suppresses warnings about missing semicolons, but only when the semicolon is omitted for the last statement in a one-line block
"laxbreak": false, //suppresses most of the warnings about possibly unsafe line breakings in your code
"laxcomma": false, //suppresses warnings about comma-first coding style
"loopfunc": false, //suppresses warnings about functions inside of loops
"moz": false, //tells JSHint that your code uses Mozilla JavaScript extensions
"multistr": false, //suppresses warnings about multi-line strings
"proto": false, //suppresses warnings about the `__proto__` property
"scripturl": false, //suppresses warnings about the use of script-targeted URLs—such as `javascript:...`
"smarttabs": false, //suppresses warnings about mixed tabs and spaces when the latter are used for alignmnent only
"shadow": false, //suppresses warnings about variable shadowing
"sub": false, //suppresses warnings about using `[]` notation when it can be expressed in dot notation
"supernew": false, //suppresses warnings about "weird" constructions like `new function () { ... }` and `new Object;`
"validthis": false, //suppresses warnings about possible strict violations when the code is running in strict mode and you use `this` in a non-constructor function
// ENVIRONMENTS
// These options pre-define global variables that are exposed by popular
// JavaScript libraries and runtime environments—such as browser or node.js.
// Essentially they are shortcuts for explicit declarations like
// /*global $:false, jQuery:false */
"browser": true, //defines globals exposed by modern browsers
"couch": false, //defines globals exposed by CouchDB
"devel": true, //defines globals that are usually used for logging poor-man's debugging: `console`, `alert`, etc.
"dojo": false, //defines globals exposed by the Dojo Toolkit
"jquery": true, //defines globals exposed by the jQuery JavaScript library
"mootools": false, //defines globals exposed by the MooTools JavaScript framework
"node": true, //defines globals available when your code is running inside of the Node runtime environment
"nonstandard": false, //defines non-standard but widely adopted globals such as `escape` and `unescape`
"phantom": false, //defines globals available when your core is running inside of the PhantomJS runtime environment
"qunit": true, //defines globals available when your core is running inside of the Qqunit runtime environment
"prototypejs": false, //defines globals exposed by the Prototype JavaScript framework
"rhino": false, //defines globals available when your code is running inside of the Rhino runtime environment
"worker": true, //defines globals available when your code is running inside of a Web Worker
"wsh": false, //defines globals available when your code is running as a script for the Windows Script Host
"yui": false, //defines globals exposed by the YUI JavaScript framework
"globals": {
"define": false,
"throttle": false,
"delay": false,
"debounce": false,
"jQuery": true,
"require": false,
"Gridster": false
},
// LEGACY
// These options are legacy from JSLint. Aside from bug fixes they will not
// be improved in any way and might be removed at any point.
"nomen": false, //disallows the use of dangling `_` in variables
"onevar": false, //allows only one `var` statement per function
"passfail": false, //makes JSHint stop on the first error or warning
"white": false //make JSHint check your source code against Douglas Crockford's JavaScript coding style
}

4
lib/gridster/.npmignore Normal file
View File

@@ -0,0 +1,4 @@
*
!README.md
!LICENSE
!dist/**/*

10
lib/gridster/.travis.yml Normal file
View File

@@ -0,0 +1,10 @@
language: node_js
node_js:
- "0.10"
install:
- npm install
- npm install -g bower grunt-cli
before_script:
- bower install
script:
- grunt build --verbose

344
lib/gridster/CHANGELOG.md Normal file
View File

@@ -0,0 +1,344 @@
<a name="v0.6.10"></a>
### v0.6.10 (2015-05-31)
* Add Ruby on Rails support
<a name="v0.6.9"></a>
### v0.6.9 (2015-05-27)
* bug fixes for positions and overlap
* dist modified to support webpack deployements
* new 'sticky' layout option which allows widgets to be places absolutely into a position on the grid.
<a name="v0.6.8"></a>
### v0.6.8 (2015-04-28)
#### Bug Fixes
* **gridster:**
* responsive width now resizes based off wrapper not window ([e69c3e8f](http://github.com/dsmorse/gridster.js/commit/e69c3e8f64aa4557ef032e4d0d8185e83b1aed21))
* ensure coords instances are destroyed on widgets ([576b5ae3](http://github.com/dsmorse/gridster.js/commit/576b5ae3f0461b048d8ff9463509b860ffa8b194))
* `resize_widget` also accepts HTMLElements ([cda560f4](http://github.com/dsmorse/gridster.js/commit/cda560f4f3ca616d03d1e3230cd2ef4e69876d9c))
* changed "instanceof jQuery" to "instanceof $" ([c6226306](http://github.com/dsmorse/gridster.js/commit/c6226306c2ce9aa7d45d774d7de19088acba0c66))
* wrong addition solved in add_faux_rows/cols by adding parseInt ([d9471752](http://github.com/dsmorse/gridster.js/commit/d947175257d686801154a403016fd2ec7e6d40c2), closes [#426](http://github.com/dsmorse/gridster.js/issues/426), [#425](http://github.com/dsmorse/gridster.js/issues/425))
* preventing gridster from adding extra resize handles ([9d077da6](http://github.com/dsmorse/gridster.js/commit/9d077da676826606243c2552dc9997c492687203))
* destroy resize_api ([b1629326](http://github.com/dsmorse/gridster.js/commit/b16293268c6aa4be2ba0c8fb1b9806e590227606), closes [#473](http://github.com/dsmorse/gridster.js/issues/473))
* ensure widget dimensions and coords are always ints ([595a94f1](http://github.com/dsmorse/gridster.js/commit/595a94f1bdfaa4905ff51d9044e74105c81e6ff3))
#### Features
* **draggable:** autoscrolling ([d3f25f3f](http://github.com/dsmorse/gridster.js/commit/d3f25f3fbbcc738d8b3702d122533e64f37acd29))
* **gridster:**
* add config to set custom show/hide widget methods ([7de5bbab](http://github.com/dsmorse/gridster.js/commit/7de5bbabc0a01e8188a56881782dc74d6bf111d3))
* browserify compatibility ([43148b87](http://github.com/dsmorse/gridster.js/commit/43148b87e523352a7f9d01479c6fed3e87f46ba0))
* Common.js support ([446852a2](http://github.com/dsmorse/gridster.js/commit/446852a260aab2e7caf772a62fbde8b518c38816), closes [#434](http://github.com/dsmorse/gridster.js/issues/434))
* **gridster.css:** remove possible default pading ([2002c455](http://github.com/dsmorse/gridster.js/commit/2002c455957016cb441a317dbbb6e5f6662cb35a))
<a name="v0.6.7"></a>
### v0.6.7 (2015-04-16)
<a name="v0.6.6"></a>
### v0.6.6 (2015-04-08)
<a name="v0.6.5"></a>
### v0.6.5 (2015-04-06)
#### Bug Fixes
* **gridster:** fixed bugs in centering_widgets (widgets were getting smushed when being resized ([86053f8b](http://github.com/DecksterTeam/gridster.js/commit/86053f8be3d73a9db3d7eabc595324123dbcff13))
<a name="v0.6.4"></a>
### v0.6.4 (2015-03-19)
#### Bug Fixes
* **gridster:**
* added ability to center widgets in grid
<a name="v0.6.3"></a>
### v0.6.3 (2015-03-06)
#### Bug Fixes
* **gridster:**
* fixing resize limits when in fixed width mode feature(gridster): added fix_to_co ([6bb47dc1](http://github.com/DecksterTeam/gridster.js/commit/6bb47dc1ce36aef670b2acb7c244ec5f4ea440e0))
<a name="v0.6.2"></a>
### v0.6.2 (2015-02-23)
#### Bug Fixes
* **gridster:** forcing height of gridster container to auto when in collapsed mode ([749f37a5](http://github.com/DecksterTeam/gridster.js/commit/749f37a52074bd16362528f94ab28ec314379ee3))
<a name="v0.6.1"></a>
### v0.6.1 (2015-02-21)
#### Bug Fixes
* **gridster:**
* fixed expand_widget bug not expanding full width of window fix(gridster): user c ([dbc226d4](http://github.com/DecksterTeam/gridster.js/commit/dbc226d46c8224f753c07af6aff259785c60425f))
* fixing drag limit issues when using autogrow_cols ([afd83fea](http://github.com/DecksterTeam/gridster.js/commit/afd83fead8c719615ae01ef7b5d3863701ff2243))
* changed the way widgets were getting positioned so that margins are actually the ([a3913043](http://github.com/DecksterTeam/gridster.js/commit/a3913043579bae9f5ef28e34524ad7a8ae7dcafd))
<a name="v0.6.0"></a>
## v0.6.0 (2015-02-18)
#### Bug Fixes
* **gridster:** changed the way widgets were getting positioned so that margins are actually the ([a3913043](http://github.com/DecksterTeam/gridster.js/commit/a3913043579bae9f5ef28e34524ad7a8ae7dcafd))
#### Features
* **gridster:** make grid responsive ([a3913043](http://github.com/DecksterTeam/gridster.js/commit/a3913043579bae9f5ef28e34524ad7a8ae7dcafd))
<a name="v0.5.7"></a>
### v0.5.7 (2015-02-17)
<a name="v0.5.6"></a>
### v0.5.6 (2014-09-25)
#### Bug Fixes
* **draggable:** namespace events with unique ids ([79aff38c](http://github.com/ducksboard/gridster.js/commit/79aff38c60cc6ce2c0f0160bd3c6f93cb2511642))
<a name="v0.5.5"></a>
### v0.5.5 (2014-07-25)
#### Bug Fixes
* **gridster:** fire `positionschanged` when widget orig position changes ([9926ceff](http://github.com/ducksboard/gridster.js/commit/9926ceff59cba49c71542e45aa095be35eb1df58))
<a name="v0.5.4"></a>
### v0.5.4 (2014-07-16)
#### Bug Fixes
* **gridster:** serialize returns an Array object, not a jQuery object ([93df6cf6](http://github.com/ducksboard/gridster.js/commit/93df6cf6907fd0fb8787b3d068c9a9c467dcc020), closes [#394](http://github.com/ducksboard/gridster.js/issues/394))
<a name="v0.5.3"></a>
### v0.5.3 (2014-07-04)
#### Bug Fixes
* **gridster:**
* custom `ignore_dragging` overwrites the default value ([6bcfa6e1](http://github.com/ducksboard/gridster.js/commit/6bcfa6e16e4a88cbb5efff1ce29308737884a89d))
* sort widgets appropriately when reading them from DOM ([5c6d25cb](http://github.com/ducksboard/gridster.js/commit/5c6d25cbbe3de021806408f3cff6cb1e139c0a25))
#### Features
* make gridster AMD compatible ([589d7fd5](http://github.com/ducksboard/gridster.js/commit/589d7fd509a570fd02666c2f8231545211d6c83f))
* **gridster:** move widget up when added if there is space available ([8ec307b6](http://github.com/ducksboard/gridster.js/commit/8ec307b6f7173e94610409adcb1671372cc2c67d))
<a name="v0.5.2"></a>
### v0.5.2 (2014-06-16)
#### Bug Fixes
* **draggable:**
* handle both touch and click events ([021a6c23](http://github.com/ducksboard/gridster.js/commit/021a6c23e851210c1b817bd353a1e5e19ce10b90), closes [#207](http://github.com/ducksboard/gridster.js/issues/207), [#236](http://github.com/ducksboard/gridster.js/issues/236), [#329](http://github.com/ducksboard/gridster.js/issues/329), [#380](http://github.com/ducksboard/gridster.js/issues/380))
* replaced scrollX/Y with scrollLeft/Top ([bb7463a3](http://github.com/ducksboard/gridster.js/commit/bb7463a3241750397492dfbac133cea193f0254f))
* fix offset during drag ([c726c4ad](http://github.com/ducksboard/gridster.js/commit/c726c4ad9c18fea95e4b46b9bacd36c42aa9691c))
* bind drag events to $document ([dd6c7420](http://github.com/ducksboard/gridster.js/commit/dd6c7420087d5810a9f6b02bf9d81a04a60ae840))
* **gridster:**
* fix add_widget to use correct size_y when adding rows ([7d22e6c8](http://github.com/ducksboard/gridster.js/commit/7d22e6c8b201de33e33def77a93dc9009d0aa4cb))
* Removing previously added style tags before adding new one. ([93c46ff4](http://github.com/ducksboard/gridster.js/commit/93c46ff45ebe59f3658b7f32f05b67109aa87311))
#### Features
* **draggable:**
* allow ignore_dragging config option to be a function ([69fcfe45](http://github.com/ducksboard/gridster.js/commit/69fcfe459678e833cb53de040b9fbc96dd687543))
* option to not remove helper on drag stop ([03910df9](http://github.com/ducksboard/gridster.js/commit/03910df967a1ae7bcb2fa3aadd58255e0bcbf327))
<a name="v0.5.1"></a>
### v0.5.1 (2014-03-05)
#### Features
* **collision:** overlapping region as a config option ([720d487e](http://github.com/ducksboard/gridster.js/commit/720d487e3988593e2c60909c88aaff13fbd4f842))
* **coords:**
* allow both (left/x1) and (top/y1) attr keys ([6f22217f](http://github.com/ducksboard/gridster.js/commit/6f22217f056e4fc52f6405f2af49596105aae150))
* add destroy method ([fdeee4f6](http://github.com/ducksboard/gridster.js/commit/fdeee4f636266c7a0579ced833f04fec013b6863))
* **draggable:** keep container position prop if different than static ([04868a38](http://github.com/ducksboard/gridster.js/commit/04868a384d655d110f2d153d2fddb94b1c6d54a9))
* **gridster:** destroy element's data and optionally remove from DOM ([dc09f191](http://github.com/ducksboard/gridster.js/commit/dc09f191d8503669cfa4737122c77cb0f5b9c3d2))
<a name="v0.5.0"></a>
## v0.5.0 (2014-02-14)
#### Bug Fixes
* **autogrow:** refining autogrow_cols behavior and grid width issues ([835c2df8](http://github.com/ducksboard/gridster.js/commit/835c2df84419a92b1641b687fcf083f3ff102627))
* **resize.stop:** Call resize.stop at the latest possible moment ([e21f63a0](http://github.com/ducksboard/gridster.js/commit/e21f63a05a539f5c611eb49cd6861b1e38b36531))
#### Features
* **draggable:** Add toggle draggable method. ([073fdc40](http://github.com/ducksboard/gridster.js/commit/073fdc40e0a94dd371646fc54cd420e3ddab0254))
<a name="v0.4.4"></a>
### v0.4.4 (2014-02-13)
#### Features
* **resize:** add start/stop/resize event triggers ([7ca8deec](http://github.com/ducksboard/gridster.js/commit/7ca8deec8559d950097a6dc351cb0c6fcef3458d))
<a name="v0.4.3"></a>
### v0.4.3 (2014-02-11)
#### Bug Fixes
* **generated-styles:** cleaning cached serializations properly ([f8b04f29](http://github.com/ducksboard/gridster.js/commit/f8b04f298e12e46ca9b07f0bae0abc6b08ed6e18))
<a name="v0.4.2"></a>
### v0.4.2 (2014-02-07)
#### Bug Fixes
* recalculate grid width when adding widgets ([47745978](http://github.com/ducksboard/gridster.js/commit/4774597834300601fc81d5111a31a8c1672c55e1))
<a name="v0.4.1"></a>
### v0.4.1 (2014-02-07)
#### Bug Fixes
* add resize.min_size option to default config object ([5672edb0](http://github.com/ducksboard/gridster.js/commit/5672edb05e39c6b9ff5e3ca31d68c9e94dfaa617))
<a name="v0.4.0"></a>
## v0.4.0 (2014-02-07)
#### Bug Fixes
* **gridster:**
* leaking options with multiple Gridster instances ([07c71097](http://github.com/ducksboard/gridster.js/commit/07c7109771094d98be51d68448a20e1d2987b35d))
* resize.axes default option only 'both' ([62988780](http://github.com/ducksboard/gridster.js/commit/6298878077d5db129daa9780939fec5237b82af9))
* **licenses:** add required copyright message for underscore ([b563c094](http://github.com/ducksboard/gridster.js/commit/b563c094cf0f3a5da2288492f95759ae32e8967c))
* **readme:** link title jsfiddle -> jsbin, edit 5) of process steps ([0641aa89](http://github.com/ducksboard/gridster.js/commit/0641aa89833ecf9d167f7d8e89ee8bd5b4304248))
#### Features
* **draggable:**
* method to set drag limits dynamically ([d4482ec1](http://github.com/ducksboard/gridster.js/commit/d4482ec1476f8a0b6fb6cdeb25b7774ef678d81c))
* support horizontal scrolling while dragging ([ae4921b7](http://github.com/ducksboard/gridster.js/commit/ae4921b70798944211267cacf8a89e62d0818369))
* **gridster:** increase grid width when dragging or resizing ([37c4e943](http://github.com/ducksboard/gridster.js/commit/37c4e94358b9392710452b9e7f96454837bf9845))
* **resize:** add option to set min_size of a widget ([ff511872](http://github.com/ducksboard/gridster.js/commit/ff511872e65992ee89bd2a88d862caaf99733f38))
<a name="v0.3.0"></a>
## v0.3.0 (2013-11-18)
#### Features
* **draggable:**
* method to set drag limits dynamically ([d4482ec1](http://github.com/ducksboard/gridster.js/commit/d4482ec1476f8a0b6fb6cdeb25b7774ef678d81c))
* support horizontal scrolling while dragging ([ae4921b7](http://github.com/ducksboard/gridster.js/commit/ae4921b70798944211267cacf8a89e62d0818369))
* **gridster:** increase grid width when dragging or resizing ([b61df653](http://github.com/ducksboard/gridster.js/commit/b61df6535f728970fb8c6f25a208275dbde66550))
<a name="v0.2.1"></a>
### v0.2.1 (2013-10-28)
#### Features
* **resize:** Add start/stop/resize callbacks ([d4ec7140](http://github.com/ducksboard/gridster.js/commit/d4ec7140f736bc30697c75b54ed3242ddf1d75b9))
<a name="v0.2.0"></a>
## v0.2.0 (2013-10-26)
#### Bug Fixes
* fixes and improvements in widget-resizing. ([ae02b32b](http://github.com/ducksboard/gridster.js/commit/ae02b32b9210c6328f4acc339e215ae50c134f77), closes [#32](http://github.com/ducksboard/gridster.js/issues/32))
* **gridster:**
* the preview holder should not always use `li` ([1ade74e2](http://github.com/ducksboard/gridster.js/commit/1ade74e239485b07e870fca44e1eafb3ff1ae283))
* overlapping widget problem ([31fd8d6b](http://github.com/ducksboard/gridster.js/commit/31fd8d6ba893e4c39b91ba30d429e37f3da30b24))
* Orphan preview holder when dragging is interrupted ([1b13617d](http://github.com/ducksboard/gridster.js/commit/1b13617df2ce53235bdf3a1e38f1555f529663c3))
* remove_widget Returns the instance of the Gridster Class ([5bfbc5c0](http://github.com/ducksboard/gridster.js/commit/5bfbc5c0b5ab49c2a7c651327ce2e0f30f594985))
#### Features
* **draggable:**
* new config option to move or not the dragged element ([4d9b2a84](http://github.com/ducksboard/gridster.js/commit/4d9b2a84f11cb7cb2ddad51c158d92b82e7bc447))
* CSS selectors support in `ignore_dragging` config opt ([0f956249](http://github.com/ducksboard/gridster.js/commit/0f95624925be97aee7a8450707e04e887e4dac58))
* pass previous position to the drag callback ([055cc0e4](http://github.com/ducksboard/gridster.js/commit/055cc0e4f6f9de5721986515656ac894855f9e02))
* Don't start new drag if previous one hasn't stopped ([91ca6572](http://github.com/ducksboard/gridster.js/commit/91ca65721c2eb32b5dec82cdc5e5e7f81dac329e))
* pass useful data to all drag callbacks ([8dda2410](http://github.com/ducksboard/gridster.js/commit/8dda2410f300592706985c05141ca6b702977dc0))
* **gridster:** drag-and-drop widget resizing ([e1924053](http://github.com/ducksboard/gridster.js/commit/e19240532de0bad35ffe6e5fc63934819390adc5))
* **utils:** add delay helper to utils ([faa6c5db](http://github.com/ducksboard/gridster.js/commit/faa6c5db0002feccf681e9f919ed583eef152773))
dustmoo Modifications
===========
Changelog 2013-04-3
Fork now handles standard behavior properly with swap allowing larger widgets to shift down.
Changelog 2013-04-2
Added Demo to Repository.
Changelog 2013-02-27
Added "Static widget support" Static Items default to the "static" class.
You can customize this class by using the code below:
$.gridster({
static_class: 'custom_class',
draggable: {
items: ".gs_w:not(.custom_class)"
}
});
I have also added functions creating a much more thourough check of whether the player can occupy the space you are moving it too.
This version is much more reliable in swapping space with widgets.
There are also new options for Maximum Rows and Maximum Columns:
$.gridster({
max_rows: map_rows,
max_cols: map_cols,
shift_larger_widgets_down: false
});
Setting the maximum amount of rows only completely works if you disable shifting larger widgets down at the moment.
Changelog 11-26-2012
Reworked swapping functionality to better handle large to small widget handling.
---
Widgets of smaller or equal size to the dragged widget (player)
will swap places with the original widget.
This causes tiles to swap left and right as well as up and down.
By default smaller players will shift larger widgets down.
I have added an option to prevent this behavior:
$.gridster({
shift_larger_widgets_down: false
});
By setting shift_larger_widgets_down to false, smaller widgets will not displace larger ones.

View File

@@ -0,0 +1,200 @@
# Contributing to this project
Please take a moment to review this document in order to make the contribution
process easy and effective for everyone involved.
Following these guidelines helps to communicate that you respect the time of
the developers managing and developing this open source project. In return,
they should reciprocate that respect in addressing your issue or assessing
patches and features.
## Using the issue tracker
The issue tracker is the preferred channel for [bug reports](#bugs),
[features requests](#features) and [submitting pull
requests](#pull-requests), but please respect the following restrictions:
* Please **do not** use the issue tracker for personal support requests (use
[Stack Overflow](http://stackoverflow.com)).
* Please **do not** derail or troll issues. Keep the discussion on topic and
respect the opinions of others.
<a name="bugs"></a>
## Bug reports
A bug is a _demonstrable problem_ that is caused by the code in the repository.
Good bug reports are extremely helpful - thank you!
Guidelines for bug reports:
1. **Use the GitHub issue search** &mdash; check if the issue has already been
reported.
2. **Check if the issue has been fixed** &mdash; try to reproduce it using the
latest `master` or development branch in the repository.
3. **Isolate the problem** &mdash; ideally create a [reduced test
case](http://css-tricks.com/6263-reduced-test-cases/) and a live example (you can use something like [jsfiddle](http://jsfiddle.net/) or [jsbin](http://jsbin.com/)) .
A good bug report shouldn't leave others needing to chase you up for more
information. Please try to be as detailed as possible in your report. What is
your environment? What steps will reproduce the issue? What browser(s) and OS
experience the problem? What would you expect to be the outcome? All these
details will help people to fix any potential bugs.
Example:
> Short and descriptive example bug report title
>
> A summary of the issue and the browser/OS environment in which it occurs. If
> suitable, include the steps required to reproduce the bug.
>
> 1. This is the first step
> 2. This is the second step
> 3. Further steps, etc.
>
> `<url>` - a link to the reduced test case
>
> Any other information you want to share that is relevant to the issue being
> reported. This might include the lines of code that you have identified as
> causing the bug, and potential solutions (and your opinions on their
> merits).
<a name="features"></a>
## Feature requests
Feature requests are welcome. But take a moment to find out whether your idea
fits with the scope and aims of the project. It's up to *you* to make a strong
case to convince the project's developers of the merits of this feature. Please
provide as much detail and context as possible.
**Please, use the GitHub issue search** to check if the feature has already been requested.
<a name="pull-requests"></a>
## Pull requests
Good pull requests - patches, improvements, new features - are a fantastic
help. They should remain focused in scope and avoid containing unrelated
commits.
**Please ask first** before embarking on any significant pull request (e.g.
implementing features, refactoring code, porting to a different language),
otherwise you risk spending a lot of time working on something that the
project's developers might not want to merge into the project.
Code must follow, mostly, these [coding conventions](http://javascript.crockford.com/code.html) .
Adhering to the following this process is the best way to get your work
included in the project:
1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork,
and configure the remotes:
```bash
# Clone your fork of the repo into the current directory
git clone https://github.com/<your-username>/gridster.js
# Navigate to the newly cloned directory
cd gridster.js
# Assign the original repo to a remote called "upstream"
git remote add upstream https://github.com/ducksboard/gridster.js
```
2. If you cloned a while ago, get the latest changes from upstream:
```bash
git checkout master
git pull upstream master
```
3. Create a new topic branch (off the main project development branch) to
contain your feature, change, or fix:
```bash
git checkout -b <topic-branch-name>
```
4. Commit your changes in logical chunks. Please adhere to these [git commit
message guidelines](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y)
or your code is unlikely be merged into the main project. Use Git's
[interactive rebase](https://help.github.com/articles/interactive-rebase)
feature to tidy up your commits before making them public.
5. Merge or rebase the upstream development branch into your topic branch:
```bash
git pull --rebase upstream master
```
6. Push your topic branch up to your fork:
```bash
git push origin <topic-branch-name>
```
7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)
with a clear title and description.
**IMPORTANT**: By submitting a patch, you agree to allow the project owner to
license your work under the same license as that used by the project.
#commit Message Guidelines
We use [automatic changelog creation](https://github.com/ajoslin/conventional-changelog), so it best if your commit messages follow the following conventions:
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:
```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on github as well as in various git tools.
### Type
Must be one of the following:
* **feat**: A new feature
* **fix**: A bug fix
* **docs**: Documentation only changes
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
semi-colons, etc)
* **refactor**: A code change that neither fixes a bug or adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing tests
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
generation
### Scope
The scope could be anything specifying place of the commit change. For example `$location`,
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
### Subject
The subject contains succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes"
The body should include the motivation for the change and contrast this with previous behavior.
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.
**Breaking Changes** are detected as such if the Body contains a line starting with
`BREAKING CHANGES:` The rest of the commit message is then used for this.
A detailed explanation can be found in this [document](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/).

233
lib/gridster/Gruntfile.js Normal file
View File

@@ -0,0 +1,233 @@
/*global module:false*/
module.exports = function(grunt) {
'use strict';
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
meta: {
banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage : "" %>\n' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n\n',
minibanner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> - ' +
'<%= pkg.homepage ? "* " + pkg.homepage + " - " : "" %>' +
'Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */ '
},
concat: {
options: {
stripBanners: true,
banner: '<%= meta.banner %>'
},
dist_js: {
src: ['src/jquery.coords.js', 'src/jquery.collision.js', 'src/utils.js', 'src/jquery.draggable.js', 'src/jquery.<%= pkg.name %>.js'],
dest: 'dist/jquery.<%= pkg.name %>.js'
},
dist_extras_js: {
src: ['src/jquery.coords.js', 'src/jquery.collision.js', 'src/utils.js', 'src/jquery.draggable.js', 'src/jquery.<%= pkg.name %>.js', 'src/jquery.<%= pkg.name %>.extras.js'],
dest: 'dist/jquery.<%= pkg.name %>.with-extras.js'
}
},
uglify: {
options: {
banner: '<%= meta.minibanner %>'
},
dist: {
files: {
'dist/jquery.<%= pkg.name %>.min.js': ['<%= concat.dist_js.dest %>']
}
},
dist_extras: {
files: {
'dist/jquery.<%= pkg.name %>.with-extras.min.js': ['<%= concat.dist_extras_js.dest %>']
}
}
},
cssmin: {
compress: {
options: {
keepSpecialComments: 0,
banner: '<%= meta.minibanner %>'
},
files: {
'dist/jquery.<%= pkg.name %>.min.css': ['dist/jquery.<%= pkg.name %>.css']
}
}
},
jshint: {
options: {
verbose: true,
reporter: require('jshint-stylish'),
jshintrc: '.jshintrc'
},
files: ['GruntFile.js', 'src/**/*.js','sample/**/*.js', 'test/**/*.js']
},
yuidoc: {
compile: {
'name': 'gridster.js',
'description': 'gridster.js, a drag-and-drop multi-column jQuery grid plugin',
'version': 'v<%= pkg.version %>',
'url': 'http://gridster.net/',
'logo': 'https://ducksboard.com/static/images/svg/logo-ducksboard-black-small.svg',
options: {
paths: 'src/',
outdir: 'gh-pages/docs/'
}
}
},
replace: {
'rails-version': {
src: ['lib/gridster.js-rails/version.rb'],
dest: 'lib/gridster.js-rails/version.rb',
replacements: [{
from: /(\S*)(VERSION = ).*/g,
to: '$1$2"<%= pkg.version %>"'
}]
}
},
copy: {
dist: {
files: [{
expand: true,
dest: 'gh-pages/',
src: ['dist/*', 'demos/**']
},{
expand: true,
dest: 'dist',
src: ['src/jquery.gridster.less']
}]
},
rails: {
files: [{
expand: true,
flatten: true,
dest: 'vendor/assets/javascripts/',
src: ['dist/*.js']
}, {
expand: true,
flatten: true,
dest: 'vendor/assets/stylesheets/',
src: ['dist/*.css']
}]
}
},
shell: {
'build-rails-gem': {
command: 'gem build gridster.js-rails.gemspec'
},
'publish-rails-gem': {
command: 'gem push gridster.js-rails-<%= pkg.version %>.gem'
}
},
'gh-pages': {
target: {
options: {
message: 'update docs for changes from v<%= pkg.version %> ',
base: 'gh-pages',
add: true,
push: true
},
src: '**'
}
},
bump: {
options: {
files: ['package.json', 'bower.json'],
updateConfigs: ['pkg'],
commit: true,
commitMessage: 'Release v%VERSION%',
commitFiles: ['package.json', 'bower.json', 'CHANGELOG.md', 'dist/'], // '-a' for all files
createTag: true,
tagName: 'v%VERSION%',
tagMessage: 'Version %VERSION%',
push: false,
pushTo: 'origin',
gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d' // options to use with '$ git describe'
}
},
clean: {
dist: [
'gridster.js-rails*.gem',
'.grunt',
'gh-pages',
'dist',
'vendor'
]
},
changelog: {
options: {
dest: 'CHANGELOG.md'
}
},
watch: {
files: ['libs/*.js', 'src/*.js', 'src/*.less', 'Gruntfile.js'],
tasks: ['concat', 'uglify', 'less', 'cssmin']
},
qunit: {
files: [
'test/jquery.gridster.html'
]
},
less: {
default: {
options: {
sourceMap: true,
sourceMapFilename: 'dist/jquery.gridster.css.map'
},
files: {
'dist/jquery.gridster.css': 'src/jquery.gridster.less'
}
},
demo: {
options: {
sourceMap: true,
sourceMapFilename: 'demos/assets/css/demo.css.map'
},
files: {
'demos/assets/css/demo.css': 'demos/assets/less/demo.less'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-yuidoc');
grunt.loadNpmTasks('grunt-bump');
grunt.loadNpmTasks('grunt-conventional-changelog');
grunt.loadNpmTasks('grunt-gh-pages');
grunt.loadNpmTasks('grunt-text-replace');
grunt.loadNpmTasks('grunt-shell');
// Default task.
grunt.registerTask('default', ['jshint', 'concat', 'less', 'uglify', 'cssmin', 'replace:rails-version', 'copy:rails']);
grunt.registerTask('build', ['default', 'qunit', 'shell:build-rails-gem']);
grunt.registerTask('test', ['jshint','qunit']);
grunt.registerTask('docs', ['clean', 'build', 'yuidoc', 'copy:dist', 'gh-pages']);
//builds and releases the gem files
grunt.registerTask('rails:publish', ['clean', 'build', 'shell:publish-rails-gem']);
//use one of the four release tasks to build the artifacts for the release (it will push the docs pages only)
grunt.registerTask('release:patch', ['build', 'bump-only:patch', 'build', 'docs', 'changelog']);
grunt.registerTask('release:minor', ['build', 'bump-only:minor', 'build', 'docs', 'changelog']);
grunt.registerTask('release:major', ['build', 'bump-only:major', 'build', 'docs', 'changelog']);
grunt.registerTask('release:git', ['build', 'bump-only:git', 'build', 'docs', 'changelog']);
//use this task to publish the release artifacts
grunt.registerTask('release:commit', ['bump-commit', 'shell:publish-rails-gem']);
};

19
lib/gridster/LICENSE Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2012 Ducksboard
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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.

73
lib/gridster/README.md Normal file
View File

@@ -0,0 +1,73 @@
[![Build Status](https://travis-ci.org/dsmorse/gridster.js.svg)](http://travis-ci.org/dsmorse/gridster.js)
[![GitHub version](https://badge.fury.io/gh/dsmorse%2Fgridster.js.svg)](http://dsmorse.github.io/gridster.js/)
[![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/)
[![Gem Version](https://badge.fury.io/rb/gridster.js-rails.svg)](https://rubygems.org/gems/gridster.js-rails)
[![Bower version](https://badge.fury.io/bo/gridster-js.svg)](http://bower.io/search/?q=gridster-js)
Gridster.js
===========
Gridster is a jQuery plugin that makes building intuitive draggable
layouts from elements spanning multiple columns. You can even
dynamically add and remove elements from the grid.
More at [http://gridster.net/](http://gridster.net/).
### Live Preview at: [http://dsmorse.github.io/gridster.js/](http://dsmorse.github.io/gridster.js/)
[Releases](https://github.com/dsmorse/gridster.js/releases)
[CHANGELOG](https://github.com/dsmorse/gridster.js/blob/master/CHANGELOG.md)
Gridster was created by Ducksboard but they have basiclly abondoned the project
and even those who had write permissions to the repo are not merging pull requests.
## Forks
As of result of the inactivity over the last year in the [Ducksboard](https://github.com/ducksboard/gridster.js) repository, [@dsmorse](https://github.com/dsmorse/gridster.js) has created a fork
for current support. He will GLADLY accept pull requests, and will be working to merge existing
Pull Requests from Ducksboard repo.
## Ruby on Rails integration
This artifact is published to [rubygems.org](https://rubygems.org/gems/gridster.js-rails) to be consumed by ruby on rails applications.
Include gridster.js-rails in Gemfile;
``` ruby
gem 'gridster.js-rails'
```
and run bundle install.
### Configuration
Add this line to app/assets/stylesheets/application.css
``` css
*= require jquery.gridster
```
Add this line to app/assets/javascripts/application.js
``` javascript
//= require jquery.gridster
```
## Contributing to this project
Anyone and everyone is welcome to contribute. Please take a moment to review the guidelines for contributing.
* [Bug reports](CONTRIBUTING.md#bugs)
* [Feature requests](CONTRIBUTING.md#features)
* [Pull requests](CONTRIBUTING.md#pull-requests)
## License
Distributed under the MIT license.
## Whodunit
Gridster is built by [Ducksboard](http://ducksboard.com/) with the help of all
these [wonderful people](https://github.com/ducksboard/gridster.js/graphs/contributors).

31
lib/gridster/bower.json Normal file
View File

@@ -0,0 +1,31 @@
{
"name": "gridster",
"homepage": "dsmorse.github.io/gridster.js/",
"version": "0.6.10",
"dependencies": {
"jquery": "^2.1.3"
},
"devDependencies": {
"requirejs": "^2.1.17",
"qunit": "~1.18.0"
},
"main": [
"dist/jquery.gridster.js",
"dist/jquery.gridster.css"
],
"private": false,
"ignore": [
".bowerrc",
".jshintrc",
".gitignore",
".travis.yml",
"CONTRIBUTING.md",
"Gruntfile.js",
"package.json",
"test/",
"gridster.js-rails.gemspec",
"Gemfile",
"Gemfile.lock",
"lib"
]
}

View File

@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Gridster Grid Swapping Demo</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var gridster = "";
$(document).ready(function () {
$(".gridster ul").gridster({
widget_margins: [10, 10],
widget_base_dimensions: [140, 140],
shift_larger_widgets_down: false
});
});
</script>
</head>
<body>
<style>
.gridster, .content {
width: 940px;
margin: 0 auto;
}
</style>
<div class="content">
<h1>Grid with larger widgets swapping spots with smaller ones</h1>
<p>This demo represents using the branch in swap mode. This works best with shift_larger_widgets_down set to "false". However, smaller widgets do
not displace larger ones.</p>
</div>
<div class="gridster">
<ul style="height: 480px; position: relative; ">
<li data-row="1" data-col="1" data-sizex="2" data-sizey="1" class="gs_w"></li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1" class="gs_w"></li>
<li data-row="3" data-col="2" data-sizex="2" data-sizey="1" class="gs_w"></li>
<li data-row="1" data-col="3" data-sizex="2" data-sizey="2" class="gs_w"></li>
<li class="try gs_w" data-row="1" data-col="5" data-sizex="1" data-sizey="1"></li>
<li data-row="2" data-col="1" data-sizex="2" data-sizey="1" class="gs_w"></li>
<li data-row="3" data-col="4" data-sizex="1" data-sizey="1" class="gs_w"></li>
<li data-row="1" data-col="6" data-sizex="1" data-sizey="1" class="gs_w"></li>
<li data-row="3" data-col="5" data-sizex="1" data-sizey="1" class="gs_w"></li>
<li data-row="2" data-col="5" data-sizex="1" data-sizey="1" class="gs_w"></li>
<li data-row="2" data-col="6" data-sizex="1" data-sizey="2" class="gs_w"></li>
</ul>
</div>
</body>
</html>

View File

@@ -0,0 +1,54 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Add widgets dynamically &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Add widgets dynamically</h1>
<p>Create a grid adding widgets from an Array (not from HTML) using <code>add_widget</code> method. Widget position (col, row) not specified.</p>
<div class="gridster">
<ul></ul>
</div>
<script type="text/javascript" id="code">
var gridster;
$(function () {
gridster = $(".gridster > ul").gridster({
widget_margins: [5, 5],
widget_base_dimensions: [100, 55]
}).data('gridster');
var widgets = [
['<li>0</li>', 1, 2],
['<li>1</li>', 3, 2],
['<li>2</li>', 3, 2],
['<li>3</li>', 2, 1],
['<li>4</li>', 4, 1],
['<li>5</li>', 1, 2],
['<li>6</li>', 2, 1],
['<li>7</li>', 3, 2],
['<li>8</li>', 1, 1],
['<li>9</li>', 2, 2],
['<li>10</li>', 1, 3]
];
$.each(widgets, function (i, widget) {
gridster.add_widget.apply(gridster, widget)
});
});
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,25 @@
// Avoid `console` errors in browsers that lack a console.
(function () {
var method;
var noop = function () {
};
var methods = [
'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
'timeStamp', 'trace', 'warn'
];
var length = methods.length;
var console = (window.console = window.console || {});
while (length--) {
method = methods[length];
// Only stub undefined methods.
if (!console[method]) {
console[method] = noop;
}
}
}());
// Place any jQuery/helper plugins in here.

View File

@@ -0,0 +1,86 @@
/*! gridster.js - v0.6.10 - 2015-05-31
* https://dsmorse.github.io/gridster.js/
* Copyright (c) 2015 ducksboard; Licensed MIT */
@bg-color: #26941f;
body {
background: @bg-color;
font-size: 16px;
font-family: 'Helvetica Neue', Arial, sans-serif;
color: #ffffff;
margin: 0;
}
h1, h2, h3, p {
margin: 10px;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
.demo {
margin: 3em 0;
padding: 7.5em 0 5.5em;
background: @bg-color;
}
.demo:hover {
.gridster {
margin: 0 auto;
opacity: .8;
-webkit-transition: opacity .6s;
-moz-transition: opacity .6s;
-o-transition: opacity .6s;
-ms-transition: opacity .6s;
transition: opacity .6s;
}
}
.content {
color: white;
}
.gridster {
.gs-w {
background: #61A9CF;
cursor: pointer;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
.player {
-webkit-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
background: #BBB;
}
.gs-w.try {
background-image: url(../img/sprite.png);
background-repeat: no-repeat;
background-position: 37px -169px;
}
.preview-holder {
border: none !important;
border-radius: 0 !important;
background: red !important;
}
ul {
background-color: #EFEFEF;
}
li {
font-size: 1em;
font-weight: bold;
text-align: center;
line-height: 100%;
}
}
ul {
list-style-type: none;
}
li {
list-style: none;
font-weight: bold;
}
.gridster-box {
position: relative;
width: 100%;
height: 100%;
}
.controls {
margin-bottom: 20px;
}

View File

@@ -0,0 +1,90 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Resize &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src=//cdnjs.cloudflare.com/ajax/libs/seedrandom/2.3.10/seedrandom.min.js></script>
<script src="../dist/jquery.gridster.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Resize</h1>
<p>As hommage to Netflix's <a href="https://github.com/Netflix/SimianArmy/wiki/Chaos-Monkey">Chaos Monkey</a>, this demo page is for testing. It attempts to insert a widget at a random location to ensure the overlap deconfliction locic works.</p>
<div class="controls">
<button class="js-fixed-random">Insert widget at random location</button>
<button class="js-random-random">Insert random sized widget at random location</button>
</div>
<div class="gridster">
<ul style="z-index: 2; float: left;position: absolute">
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">0</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">1</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="3">9</li>
</ul>
<svg width="100%" height="800px" xmlns="http://www.w3.org/2000/svg" style="float: left;
position: relative;
z-index: 5;
margin-top: 15px;">
<defs>
<pattern id="grid" width="105" height="105" patternUnits="userSpaceOnUse">
<rect width="105" height="105" fill="url(#smallGrid)"/>
<path d="M 105 0 L 0 0 0 105" fill="none" stroke="black" stroke-width="1"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid)" />
</svg>
</div>
<script type="text/javascript">
Math.seedrandom();
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
<script type="text/javascript">
var gridster;
var nextSimian = 10;
$(function () {
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 100],
avoid_overlapped_widgets: true,
widget_margins: [5, 5],
helper: 'clone',
resize: {
enabled: true
}
}).data('gridster');
$('.js-random-random').on('click', function () {
gridster.add_widget('<li>' + nextSimian + '</li>', getRandomInt(1, 5), getRandomInt(1, 5), getRandomInt(1, 15), getRandomInt(1, 15));
nextSimian++;
});
$('.js-fixed-random').on('click', function () {
gridster.add_widget('<li>' + nextSimian + '</li>', 1 , 1, getRandomInt(1, 15), getRandomInt(1, 15));
nextSimian++;
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,96 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Custom drag handle &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Custom drag handle</h1>
<p>Restricts dragging from starting unless the mousedown occurs on the specified element(s).</p>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">
<header>|||</header>
0
</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">
<header>|||</header>
1
</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">
<header>|||</header>
2
</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">
<header>|||</header>
3
</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">
<header>|||</header>
4
</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">
<header>|||</header>
5
</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">
<header>|||</header>
6
</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">
<header>|||</header>
7
</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">
<header>|||</header>
8
</li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="3">
<header>|||</header>
9
</li>
</ul>
</div>
<style type="text/css">
.gridster li header {
background: #999;
display: block;
font-size: 20px;
line-height: normal;
padding: 4px 0 6px;
margin-bottom: 20px;
cursor: move;
}
</style>
<script type="text/javascript">
var gridster;
$(function () {
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 120],
widget_margins: [5, 5],
draggable: {
handle: 'header'
}
}).data('gridster');
});
</script>
</body>
</html>

View File

@@ -0,0 +1,52 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Dynamic grid width &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Dynamic grid width</h1>
<p>Drag or resize some widgets to the right side. Use <code>max_cols</code> option to set a maximum number of columns for the grid.</p>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">0</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">1</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="3">9</li>
</ul>
</div>
<script type="text/javascript">
var gridster;
$(function () {
var log = document.getElementById('log');
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 55],
widget_margins: [5, 5],
autogrow_cols: true,
resize: {
enabled: true
}
}).data('gridster');
});
</script>
</body>
</html>

View File

@@ -0,0 +1,64 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Expandable widgets &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Expandable widgets</h1>
<p>Expand widgets when hover on them using <code>resize_widget</code> method.</p>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">0</li>
<li data-row="1" data-col="2" data-sizex="1" data-sizey="1">1</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="1">2</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">3</li>
<li data-row="2" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="2" data-col="2" data-sizex="1" data-sizey="1">5</li>
<li data-row="2" data-col="3" data-sizex="1" data-sizey="1">6</li>
<li data-row="2" data-col="4" data-sizex="1" data-sizey="1">7</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">8</li>
<li data-row="3" data-col="2" data-sizex="1" data-sizey="1">9</li>
<li data-row="3" data-col="3" data-sizex="1" data-sizey="1">10</li>
<li data-row="3" data-col="4" data-sizex="1" data-sizey="1">11</li>
</ul>
</div>
<script type="text/javascript">
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
<script type="text/javascript">
var gridster;
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 100],
widget_margins: [5, 5],
helper: 'clone'
}).data('gridster');
gridster.$el.ready(function () {
// resize widgets on hover
gridster.$el
.on('mouseenter', 'li', function () {
gridster.resize_widget($(this), 3, 3);
})
.on('mouseleave', 'li', function () {
gridster.resize_widget($(this), 1, 1);
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,63 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Grid from serialize &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Build grid from serialized positions</h1>
<p>Build a entire new grid from previously stored positions obtained with <code>serialize</code> method.</p>
<div class="controls">
<button class="js-seralize">Build from serialize</button>
</div>
<div class="gridster">
<ul>
</ul>
</div>
<script type="text/javascript">
var gridster;
// same object than generated with gridster.serialize() method
var serialization = [
{ col: 1, row: 1, size_x: 2, size_y: 2 },
{ col: 3, row: 1, size_x: 1, size_y: 2 },
{ col: 4, row: 1, size_x: 1, size_y: 1 },
{ col: 2, row: 3, size_x: 3, size_y: 1 },
{ col: 1, row: 4, size_x: 1, size_y: 1 },
{ col: 1, row: 3, size_x: 1, size_y: 1 },
{ col: 2, row: 4, size_x: 1, size_y: 1 },
{ col: 2, row: 5, size_x: 1, size_y: 1 }
];
// sort serialization
serialization = Gridster.sort_by_row_and_col_asc(serialization);
$(function () {
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 55],
widget_margins: [5, 5]
}).data('gridster');
$('.js-seralize').on('click', function () {
gridster.remove_all_widgets();
$.each(serialization, function () {
gridster.add_widget('<li />', this.size_x, this.size_y, this.col, this.row);
});
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<title>Gridster Demos</title>
<link rel="stylesheet" href="assets/css/demo.css">
</head>
<body>
<div class="content">
<h2>Samples</h2>
</div>
<ul>
<li><a href="adding-widgets-dynamically.html">Adding widgets dynamically</a></li>
<li><a href="custom-drag-handle.html">Custom drag handle</a></li>
<li><a href="expandable-widgets.html">Expandable widgets</a></li>
<li><a href="grid-from-serialize.html">Build grid from serialize</a></li>
<li><a href="multiple-grids.html">Multiple gridster instances on the same page</a></li>
<li><a href="resize.html">Resizable widgets</a></li>
<li><a href="chaosWidget.html">Chaos Widgets</a></li>
<li><a href="resize-limits.html">Resizable widgets with constraints</a></li>
<li><a href="serialize.html">Serialize widgets positions</a></li>
<li><a href="using-drag-callbacks.html">Using drag callbacks</a></li>
<li><a href="using-resize-callbacks.html">Using resize callbacks</a></li>
<li><a href="dynamic-grid-width.html">Dynamic grid width</a></li>
<li><a href="responsive.html">Responsive grid width</a></li>
<li><a href="SwapDrop.html">Grid with larger widgets swapping spots with smaller ones</a></li>
<li><a href="sticky-postion.html">Grid that allows widgets to be exactly placed anywhere</a></li>
</ul>
</body>
</html>

View File

@@ -0,0 +1,59 @@
<!doctype html>
<html>
<head>
<title>demo</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="3" data-sizey="3"></li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="3"></li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1"></li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1"></li>
<li data-row="4" data-col="3" data-sizex="1" data-sizey="1"></li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1"></li>
</ul>
</div>
<script type="text/javascript">
var api;
$(function () {
api = $(".gridster ul").gridster({
draggable: {
stop: function (event, ui, self) {
// $('.overlapped-area').hide();
this.$wrapper.addClass('sorting');
},
start: function (event, ui, self) {
this.$wrapper.removeClass('sorting');
// $('.overlapped-area').show();
}
},
collision: {
on_overlap_start: function (collider) {
// $(collider).data('graph').show();
//$(this).data('collision', collider);
},
on_overlap_stop: function (collider) {
//$(this).data('collision', null);
},
on_overlap: function (c) {
//$(this).data('collision', c);
}
}
}).data('gridster');
});
</script>
</body>
</html>

View File

@@ -0,0 +1,71 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Multiple gridster intances &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Multiple gridster instances with different configurations</h1>
<p>When using multiple gridster instances on the same page you can scope the CSS code generated by gridster using <code>namespace</code> config
option.</p>
<h2>Demo 1</h2>
<div id="demo-1" class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">0</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">1</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
</ul>
</div>
<h2>Demo 2</h2>
<div id="demo-2" class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">0</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">1</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
</ul>
</div>
<script type="text/javascript">
var gridster = [];
$(function () {
gridster[0] = $("#demo-1 ul").gridster({
namespace: '#demo-1',
widget_base_dimensions: [100, 55],
widget_margins: [5, 5]
}).data('gridster');
gridster[1] = $("#demo-2 ul").gridster({
namespace: '#demo-2',
widget_base_dimensions: [200, 110],
widget_margins: [10, 10]
}).data('gridster');
});
</script>
</body>
</html>

View File

@@ -0,0 +1,76 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Resize &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Resize with limits</h1>
<p>Use <code>resize.max_size</code> and <code>resize.min_size</code> config options or <code>data-max-sizex</code>, <code>data-max-sizey</code>,
<code>data-min-sizex</code> and <code>data-min-sizey</code> HTML attributes to limit widget dimensions when resizing.</p>
<p>If a global max_size is specified through the config option, can be overwrited in specified widgets with HTML data-attributes or using <code>set_widget_max_size</code>
method. This page has a global max limit of 4x4</p>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="6" data-min-sizex="2" data-min-sizey="6" data-max-sizex="2" data-max-sizey="6">
0
<br>
<small>Overridden to 2, 6</small>
</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2" data-max-sizex="6" data-max-sizey="2">
1
<br>
<small>Overridden max-size to 6, 2</small>
</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
<li data-row="1" data-col="5" data-sizex="3" data-sizey="3" data-min-sizex="3" data-min-sizey="3">
9
<br>
<small>Overridden min-size to 3, 3</small>
</li>
<li data-row="5" data-col="1" data-sizex="1" data-sizey="2">10</li>
<li data-row="4" data-col="3" data-sizex="1" data-sizey="2">11</li>
<li data-row="5" data-col="4" data-sizex="1" data-sizey="1">12</li>
<li data-row="6" data-col="2" data-sizex="3" data-sizey="1">13</li>
<li data-row="4" data-col="5" data-sizex="1" data-sizey="2">14</li>
<li data-row="6" data-col="5" data-sizex="1" data-sizey="1">15</li>
<li data-row="7" data-col="3" data-sizex="1" data-sizey="1">16</li>
</ul>
</div>
<script type="text/javascript">
var gridster;
$(function () {
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 100],
widget_margins: [5, 5],
helper: 'clone',
resize: {
enabled: true,
max_size: [4, 4],
min_size: [1, 1]
}
}).data('gridster');
});
</script>
</body>
</html>

View File

@@ -0,0 +1,65 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Resize &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Resize</h1>
<p>Grab the right or bottom border and drag to the desired width or height.</p>
<div class="controls">
<button class="js-resize-random">Resize random widget</button>
</div>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">0</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">1</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="3">9</li>
</ul>
</div>
<script type="text/javascript">
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
<script type="text/javascript">
var gridster;
$(function () {
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 100],
widget_margins: [5, 5],
helper: 'clone',
resize: {
enabled: true
}
}).data('gridster');
$('.js-resize-random').on('click', function () {
gridster.resize_widget(gridster.$widgets.eq(getRandomInt(0, 9)),
getRandomInt(1, 4), getRandomInt(1, 4))
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,96 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Gridster Responsive Demo</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var gridster = null;
$(document).ready(function () {
gridster = $(".gridster ul").gridster({
widget_base_dimensions: ['auto', 140],
autogenerate_stylesheet: true,
min_cols: 1,
max_cols: 6,
widget_margins: [5, 5],
resize: {
enabled: true
}
}).data('gridster');
$('.gridster ul').css({'padding': '0'});
});
</script>
</head>
<body>
<div class="content">
<h1>Responsive Layout</h1>
<p>This demo represents using the branch in responsive mode. This makes the grid as wide as the screen and responds to changes in browser
width.</p>
</div>
<div class="gridster">
<ul>
<li data-sizey="2" data-sizex="2" data-col="4" data-row="1">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="1" data-sizex="1" data-col="1" data-row="3">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="1" data-sizex="1" data-col="2" data-row="3">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="2" data-sizex="2" data-col="1" data-row="1">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="1" data-sizex="1" data-col="3" data-row="1">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="1" data-sizex="1" data-col="3" data-row="3">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="1" data-sizex="1" data-col="4" data-row="3">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="1" data-sizex="1" data-col="6" data-row="1">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="1" data-sizex="1" data-col="5" data-row="3">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="1" data-sizex="1" data-col="3" data-row="2">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
<li data-sizey="1" data-sizex="1" data-col="6" data-row="2">
<div class="gridster-box">
<div class="handle-resize"></div>
</div>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -0,0 +1,89 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Serialize &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
#log {
display: block;
width: 100%;
height: 20px;
margin-bottom: 20px;
-webkit-transition: height 0.3s ease;
-moz-transition: height 0.3s ease;
-ms-transition: height 0.3s ease;
-o-transition: height 0.3s ease;
transition: height 0.3s ease;
}
#log:focus {
height: 100px;
}
</style>
</head>
<body>
<h1>Serialize positions</h1>
<p>Use <code>serialize</code> method to get widget positions. It returns a Array of objects that can be used as a JSON object.</p>
<div class="controls">
<button class="js-seralize">Serialize</button>
</div>
<textarea id="log"></textarea>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">0</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">1</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="3">9</li>
<li data-row="5" data-col="1" data-sizex="1" data-sizey="2">10</li>
<li data-row="4" data-col="3" data-sizex="1" data-sizey="2">11</li>
<li data-row="5" data-col="4" data-sizex="1" data-sizey="1">12</li>
<li data-row="6" data-col="2" data-sizex="3" data-sizey="1">13</li>
<li data-row="4" data-col="5" data-sizex="1" data-sizey="2">14</li>
<li data-row="6" data-col="5" data-sizex="1" data-sizey="1">15</li>
<li data-row="7" data-col="3" data-sizex="1" data-sizey="1">16</li>
</ul>
</div>
<script type="text/javascript">
var gridster;
$(function () {
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 55],
widget_margins: [5, 5]
}).data('gridster');
$('.js-seralize').on('click', function () {
var s = gridster.serialize();
$('#log').val(JSON.stringify(s));
})
});
</script>
</body>
</html>

View File

@@ -0,0 +1,50 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; sticky position widgets &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Sticky position widgets</h1>
<p>Widgets can be moved to an exact postion on the grid and the grid will not attempt to collapse it down to a smaller size. Also widgets will not move out of the way automatically, but will move only on mouse up</p>
<div class="gridster">
<ul>
<ul class="task-card-list">
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1" class="task-card">0</li>
<li data-row="1" data-col="2" data-sizex="1" data-sizey="1" class="task-card">1</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="1" class="task-card">2</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1" class="task-card">3</li>
<li data-row="2" data-col="1" data-sizex="1" data-sizey="1" class="task-card">4</li>
<li data-row="2" data-col="3" data-sizex="1" data-sizey="2" class="task-card">5</li>
<li data-row="2" data-col="4" data-sizex="1" data-sizey="1" class="task-card">6</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1" class="task-card">7</li>
<li data-row="3" data-col="2" data-sizex="1" data-sizey="1" class="task-card">8</li>
<li data-row="3" data-col="4" data-sizex="1" data-sizey="1" class="task-card">9</li>
</ul>
</div>
<script type="text/javascript">
var gridster;
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 100],
widget_margins: [5, 5],
shift_widgets_up: false,
shift_larger_widgets_down: false,
collision: {
wait_for_mouseup: true
}
}).data('gridster');
</script>
</body>
</html>

View File

@@ -0,0 +1,75 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Using drag callbacks &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
<style>
#log {
margin-top: 20px;
max-height: 400px;
overflow: auto;
max-width: 250px;
border: 1px solid #DDD;
}
</style>
</head>
<body>
<h1>Drag callbacks</h1>
<p>Drag some widgets and see the log below.</p>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">0</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">1</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="3">9</li>
</ul>
</div>
<h3>Log</h3>
<div id="log"></div>
<script type="text/javascript">
var gridster;
$(function () {
var log = document.getElementById('log');
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 55],
widget_margins: [5, 5],
draggable: {
start: function (e, ui, $widget) {
log.innerHTML = 'START position: ' + ui.position.top + ' ' + ui.position.left + "<br >" + log.innerHTML;
},
drag: function (e, ui, $widget) {
log.innerHTML = 'DRAG offset: ' + ui.pointer.diff_top + ' ' + ui.pointer.diff_left + "<br >" + log.innerHTML;
},
stop: function (e, ui, $widget) {
log.innerHTML = 'STOP position: ' + ui.position.top + ' ' + ui.position.left + "<br >" + log.innerHTML;
}
}
}).data('gridster');
});
</script>
</body>
</html>

View File

@@ -0,0 +1,78 @@
<!doctype html>
<html>
<head>
<title>Demo &raquo; Using resize callbacks &raquo; gridster.js</title>
<link rel="stylesheet" type="text/css" href="assets/css/demo.css">
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
<style>
#log {
margin-top: 20px;
max-height: 400px;
overflow: auto;
max-width: 250px;
border: 1px solid #DDD;
}
</style>
</head>
<body>
<h1>Resize callbacks</h1>
<p>Resize some widgets and see the log below.</p>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">0</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">1</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="3">9</li>
</ul>
</div>
<h3>Log</h3>
<div id="log"></div>
<script type="text/javascript">
var gridster;
$(function () {
var log = document.getElementById('log');
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 55],
widget_margins: [5, 5],
resize: {
enabled: true,
start: function (e, ui, $widget) {
log.innerHTML = 'START position: ' + ui.position.top + ' ' + ui.position.left + "<br >" + log.innerHTML;
},
resize: function (e, ui, $widget) {
log.innerHTML = 'RESIZE offset: ' + ui.pointer.diff_top + ' ' + ui.pointer.diff_left + "<br >" + log.innerHTML;
},
stop: function (e, ui, $widget) {
log.innerHTML = 'STOP position: ' + ui.position.top + ' ' + ui.position.left + "<br >" + log.innerHTML;
}
}
}).data('gridster');
});
</script>
</body>
</html>

109
lib/gridster/dist/jquery.gridster.css vendored Normal file
View File

@@ -0,0 +1,109 @@
/*! gridster.js - v0.6.10 - 2015-05-31
* https://dsmorse.github.io/gridster.js/
* Copyright (c) 2015 ducksboard; Licensed MIT */
.gridster {
position: relative;
}
.gridster > * {
-webkit-transition: height .4s, width .4s;
-moz-transition: height .4s, width .4s;
-o-transition: height .4s, width .4s;
-ms-transition: height .4s, width .4s;
transition: height .4s, width .4s;
}
.gridster .gs-w {
z-index: 2;
position: absolute;
}
.gridster .preview-holder {
z-index: 1;
position: absolute;
background-color: #fff;
border-color: #fff;
opacity: 0.3;
}
.gridster .player-revert {
z-index: 10!important;
-webkit-transition: left .3s, top .3s!important;
-moz-transition: left .3s, top .3s!important;
-o-transition: left .3s, top .3s!important;
transition: left .3s, top .3s!important;
}
.gridster.collapsed {
height: auto !important;
}
.gridster.collapsed .gs-w {
position: static !important;
}
.ready .gs-w:not(.preview-holder) {
-webkit-transition: opacity .3s, left .3s, top .3s;
-moz-transition: opacity .3s, left .3s, top .3s;
-o-transition: opacity .3s, left .3s, top .3s;
transition: opacity .3s, left .3s, top .3s;
}
.ready .gs-w:not(.preview-holder),
.ready .resize-preview-holder {
-webkit-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
-moz-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
-o-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
}
.gridster .dragging,
.gridster .resizing {
z-index: 10!important;
-webkit-transition: all 0s !important;
-moz-transition: all 0s !important;
-o-transition: all 0s !important;
transition: all 0s !important;
}
.gs-resize-handle {
position: absolute;
z-index: 1;
}
.gs-resize-handle-both {
width: 20px;
height: 20px;
bottom: -8px;
right: -8px;
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=');
background-position: top left;
background-repeat: no-repeat;
cursor: se-resize;
z-index: 20;
}
.gs-resize-handle-x {
top: 0;
bottom: 13px;
right: -5px;
width: 10px;
cursor: e-resize;
}
.gs-resize-handle-y {
left: 0;
right: 13px;
bottom: -5px;
height: 10px;
cursor: s-resize;
}
.gs-w:hover .gs-resize-handle,
.resizing .gs-resize-handle {
opacity: 1;
}
.gs-resize-handle,
.gs-w.dragging .gs-resize-handle {
opacity: 0;
}
.gs-resize-disabled .gs-resize-handle {
display: none!important;
}
[data-max-sizex="1"] .gs-resize-handle-x,
[data-max-sizey="1"] .gs-resize-handle-y,
[data-max-sizey="1"][data-max-sizex="1"] .gs-resize-handle {
display: none !important;
}
/* Uncomment this if you set helper : "clone" in draggable options */
/*.gridster .player {
opacity:0;
}
*/
/*# sourceMappingURL=dist/jquery.gridster.css.map */

5095
lib/gridster/dist/jquery.gridster.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
/*! gridster.js - v0.6.10 - 2015-08-05 - * https://dsmorse.github.io/gridster.js/ - Copyright (c) 2015 ducksboard; Licensed MIT */
.gridster{position:relative}.gridster>*{-webkit-transition:height .4s,width .4s;-moz-transition:height .4s,width .4s;-o-transition:height .4s,width .4s;-ms-transition:height .4s,width .4s;transition:height .4s,width .4s}.gridster .gs-w{z-index:2;position:absolute}.gridster .preview-holder{z-index:1;position:absolute;background-color:#fff;border-color:#fff;opacity:.3}.gridster .player-revert{z-index:10!important;-webkit-transition:left .3s,top .3s!important;-moz-transition:left .3s,top .3s!important;-o-transition:left .3s,top .3s!important;transition:left .3s,top .3s!important}.gridster.collapsed{height:auto!important}.gridster.collapsed .gs-w{position:static!important}.ready .gs-w:not(.preview-holder),.ready .resize-preview-holder{-webkit-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-moz-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-o-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;transition:opacity .3s,left .3s,top .3s,width .3s,height .3s}.gridster .dragging,.gridster .resizing{z-index:10!important;-webkit-transition:all 0s!important;-moz-transition:all 0s!important;-o-transition:all 0s!important;transition:all 0s!important}.gs-resize-handle{position:absolute;z-index:1}.gs-resize-handle-both{width:20px;height:20px;bottom:-8px;right:-8px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=);background-position:top left;background-repeat:no-repeat;cursor:se-resize;z-index:20}.gs-resize-handle-x{top:0;bottom:13px;right:-5px;width:10px;cursor:e-resize}.gs-resize-handle-y{left:0;right:13px;bottom:-5px;height:10px;cursor:s-resize}.gs-w:hover .gs-resize-handle,.resizing .gs-resize-handle{opacity:1}.gs-resize-handle,.gs-w.dragging .gs-resize-handle{opacity:0}.gs-resize-disabled .gs-resize-handle,[data-max-sizex="1"] .gs-resize-handle-x,[data-max-sizey="1"] .gs-resize-handle-y,[data-max-sizey="1"][data-max-sizex="1"] .gs-resize-handle{display:none!important}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
# coding: utf-8
require File.expand_path('../lib/gridster.js-rails/version', __FILE__)
Gem::Specification.new do |spec|
spec.name = "gridster.js-rails"
spec.version = Gridster::Rails::VERSION
spec.authors = ["dsmorse"]
spec.email = ['https://github.com/dsmorse']
spec.summary = %q{jQuery plugin for draggable grid layouts}
spec.description = %q{Gridster is a jQuery plugin that makes building intuitive draggable layouts from elements spanning multiple columns. You can even dynamically add and remove elements from the grid.}
spec.homepage = "https://github.com/dsmorse/gridster.js"
spec.licenses = ['MIT']
spec.files = Dir["{demos,lib,vendor}/**/*"] + ["LICENSE", "bower.json", "package.json", "CHANGELOG.md", "README.md"]
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.9"
spec.add_development_dependency "rake", "~> 10.0"
end

View File

@@ -0,0 +1,5 @@
module Gridster
module Rails
require "gridster.js-rails/engine"
end
end

View File

@@ -0,0 +1,6 @@
module Gridster
module Rails
class Engine < ::Rails::Engine
end
end
end

View File

@@ -0,0 +1,5 @@
module Gridster
module Rails
VERSION = "0.6.10"
end
end

58
lib/gridster/package.json Normal file
View File

@@ -0,0 +1,58 @@
{
"name": "gridster",
"title": "gridster.js",
"description": "a drag-and-drop multi-column jQuery grid plugin",
"version": "0.6.10",
"homepage": "https://dsmorse.github.io/gridster.js/",
"author": {
"name": "ducksboard"
},
"repository": {
"type": "git",
"url": "git://github.com/dsmorse/gridster.js.git"
},
"bugs": {
"url": "https://github.com/dsmorse/gridster.js/issues"
},
"license": "MIT",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/dsmorse/gridster.js/blob/master/LICENSE"
}
],
"keywords": [],
"devDependencies": {
"bower": "~0.9.2",
"grunt": "~0.4.5",
"grunt-bump": "0.0.11",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-concat": "^0.5.0",
"grunt-contrib-copy": "^0.8.0",
"grunt-contrib-cssmin": "~0.10.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-less": "^1.0.1",
"grunt-contrib-qunit": "^0.7.0",
"grunt-contrib-uglify": "~0.6.0",
"grunt-contrib-watch": "~0.6.1",
"grunt-contrib-yuidoc": "~0.7.0",
"grunt-conventional-changelog": "~1.0.0",
"grunt-gh-pages": "^0.10.0",
"grunt-shell": "^1.1.2",
"grunt-text-replace": "^0.4.0",
"jshint-stylish": "^1.0.1"
},
"scripts": {
"test": "grunt test"
},
"main": "dist/jquery.gridster.js",
"directories": {
"test": "test"
},
"jspm": {
"main": "jquery.gridster",
"directories": {
"lib": "dist"
}
}
}

View File

@@ -0,0 +1,247 @@
/*
* jquery.collision
* https://github.com/ducksboard/gridster.js
*
* Copyright (c) 2012 ducksboard
* Licensed under the MIT licenses.
*/
;(function(root, factory) {
'use strict';
if(typeof exports === 'object') {
module.exports = factory(require('jquery'));
}
else if (typeof define === 'function' && define.amd) {
define('gridster-collision', ['jquery', 'gridster-coords'], factory);
} else {
root.GridsterCollision = factory(root.$ || root.jQuery,
root.GridsterCoords);
}
}(this, function($, Coords) {
'use strict';
var defaults = {
colliders_context: document.body,
overlapping_region: 'C'
// ,on_overlap: function(collider_data){},
// on_overlap_start : function(collider_data){},
// on_overlap_stop : function(collider_data){}
};
/**
* Detects collisions between a DOM element against other DOM elements or
* Coords objects.
*
* @class Collision
* @uses Coords
* @param {HTMLElement} el The jQuery wrapped HTMLElement.
* @param {HTMLElement|Array} colliders Can be a jQuery collection
* of HTMLElements or an Array of Coords instances.
* @param {Object} [options] An Object with all options you want to
* overwrite:
* @param {String} [options.overlapping_region] Determines when collision
* is valid, depending on the overlapped area. Values can be: 'N', 'S',
* 'W', 'E', 'C' or 'all'. Default is 'C'.
* @param {Function} [options.on_overlap_start] Executes a function the first
* time each `collider ` is overlapped.
* @param {Function} [options.on_overlap_stop] Executes a function when a
* `collider` is no longer collided.
* @param {Function} [options.on_overlap] Executes a function when the
* mouse is moved during the collision.
* @return {Object} Collision instance.
* @constructor
*/
function Collision(el, colliders, options) {
this.options = $.extend(defaults, options);
this.$element = el;
this.last_colliders = [];
this.last_colliders_coords = [];
this.set_colliders(colliders);
this.init();
}
Collision.defaults = defaults;
var fn = Collision.prototype;
fn.init = function() {
this.find_collisions();
};
fn.overlaps = function(a, b) {
var x = false;
var y = false;
if ((b.x1 >= a.x1 && b.x1 <= a.x2) ||
(b.x2 >= a.x1 && b.x2 <= a.x2) ||
(a.x1 >= b.x1 && a.x2 <= b.x2)
) { x = true; }
if ((b.y1 >= a.y1 && b.y1 <= a.y2) ||
(b.y2 >= a.y1 && b.y2 <= a.y2) ||
(a.y1 >= b.y1 && a.y2 <= b.y2)
) { y = true; }
return (x && y);
};
fn.detect_overlapping_region = function(a, b){
var regionX = '';
var regionY = '';
if (a.y1 > b.cy && a.y1 < b.y2) { regionX = 'N'; }
if (a.y2 > b.y1 && a.y2 < b.cy) { regionX = 'S'; }
if (a.x1 > b.cx && a.x1 < b.x2) { regionY = 'W'; }
if (a.x2 > b.x1 && a.x2 < b.cx) { regionY = 'E'; }
return (regionX + regionY) || 'C';
};
fn.calculate_overlapped_area_coords = function(a, b){
var x1 = Math.max(a.x1, b.x1);
var y1 = Math.max(a.y1, b.y1);
var x2 = Math.min(a.x2, b.x2);
var y2 = Math.min(a.y2, b.y2);
return $({
left: x1,
top: y1,
width : (x2 - x1),
height: (y2 - y1)
}).coords().get();
};
fn.calculate_overlapped_area = function(coords){
return (coords.width * coords.height);
};
fn.manage_colliders_start_stop = function(new_colliders_coords, start_callback, stop_callback){
var last = this.last_colliders_coords;
for (var i = 0, il = last.length; i < il; i++) {
if ($.inArray(last[i], new_colliders_coords) === -1) {
start_callback.call(this, last[i]);
}
}
for (var j = 0, jl = new_colliders_coords.length; j < jl; j++) {
if ($.inArray(new_colliders_coords[j], last) === -1) {
stop_callback.call(this, new_colliders_coords[j]);
}
}
};
fn.find_collisions = function(player_data_coords){
var self = this;
var overlapping_region = this.options.overlapping_region;
var colliders_coords = [];
var colliders_data = [];
var $colliders = (this.colliders || this.$colliders);
var count = $colliders.length;
var player_coords = self.$element.coords()
.update(player_data_coords || false).get();
while(count--){
var $collider = self.$colliders ?
$($colliders[count]) : $colliders[count];
var $collider_coords_ins = ($collider.isCoords) ?
$collider : $collider.coords();
var collider_coords = $collider_coords_ins.get();
var overlaps = self.overlaps(player_coords, collider_coords);
if (!overlaps) {
continue;
}
var region = self.detect_overlapping_region(
player_coords, collider_coords);
//todo: make this an option
if (region === overlapping_region || overlapping_region === 'all') {
var area_coords = self.calculate_overlapped_area_coords(
player_coords, collider_coords);
var area = self.calculate_overlapped_area(area_coords);
if ( 0 !== area ) {
var collider_data = {
area: area,
area_coords : area_coords,
region: region,
coords: collider_coords,
player_coords: player_coords,
el: $collider
};
if (self.options.on_overlap) {
self.options.on_overlap.call(this, collider_data);
}
colliders_coords.push($collider_coords_ins);
colliders_data.push(collider_data);
}
}
}
if (self.options.on_overlap_stop || self.options.on_overlap_start) {
this.manage_colliders_start_stop(colliders_coords,
self.options.on_overlap_start, self.options.on_overlap_stop);
}
this.last_colliders_coords = colliders_coords;
return colliders_data;
};
fn.get_closest_colliders = function(player_data_coords){
var colliders = this.find_collisions(player_data_coords);
colliders.sort(function(a, b) {
/* if colliders are being overlapped by the "C" (center) region,
* we have to set a lower index in the array to which they are placed
* above in the grid. */
if (a.region === 'C' && b.region === 'C') {
if (a.coords.y1 < b.coords.y1 || a.coords.x1 < b.coords.x1) {
return - 1;
}else{
return 1;
}
}
if (a.area < b.area) {
return 1;
}
return 1;
});
return colliders;
};
fn.set_colliders = function(colliders) {
if (typeof colliders === 'string' || colliders instanceof $) {
this.$colliders = $(colliders,
this.options.colliders_context).not(this.$element);
}else{
this.colliders = $(colliders);
}
};
//jQuery adapter
$.fn.collision = function(collider, options) {
return new Collision( this, collider, options );
};
return Collision;
}));

View File

@@ -0,0 +1,134 @@
/*
* jquery.coords
* https://github.com/ducksboard/gridster.js
*
* Copyright (c) 2012 ducksboard
* Licensed under the MIT licenses.
*/
;(function(root, factory) {
'use strict';
if(typeof exports === 'object') {
module.exports = factory(require('jquery'));
}
else if (typeof define === 'function' && define.amd) {
define('gridster-coords', ['jquery'], factory);
} else {
root.GridsterCoords = factory(root.$ || root.jQuery);
}
}(this, function($) {
'use strict';
/**
* Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height)
* to simulate DOM elements on the screen.
* Coords is used by Gridster to create a faux grid with any DOM element can
* collide.
*
* @class Coords
* @param {HTMLElement|Object} obj The jQuery HTMLElement or a object with: left,
* top, width and height properties.
* @return {Object} Coords instance.
* @constructor
*/
function Coords(obj) {
if (obj[0] && $.isPlainObject(obj[0])) {
this.data = obj[0];
}else {
this.el = obj;
}
this.isCoords = true;
this.coords = {};
this.init();
return this;
}
var fn = Coords.prototype;
fn.init = function(){
this.set();
this.original_coords = this.get();
};
fn.set = function(update, not_update_offsets) {
var el = this.el;
if (el && !update) {
this.data = el.offset();
this.data.width = el[0].scrollWidth;
this.data.height = el[0].scrollHeight;
}
if (el && update && !not_update_offsets) {
var offset = el.offset();
this.data.top = offset.top;
this.data.left = offset.left;
}
var d = this.data;
if ( d.left === undefined ) {
d.left = d.x1;
}
if ( d.top === undefined ) {
d.top = d.y1;
}
this.coords.x1 = d.left;
this.coords.y1 = d.top;
this.coords.x2 = d.left + d.width;
this.coords.y2 = d.top + d.height;
this.coords.cx = d.left + (d.width / 2);
this.coords.cy = d.top + (d.height / 2);
this.coords.width = d.width;
this.coords.height = d.height;
this.coords.el = el || false ;
return this;
};
fn.update = function(data){
if (!data && !this.el) {
return this;
}
if (data) {
var new_data = $.extend({}, this.data, data);
this.data = new_data;
return this.set(true, true);
}
this.set(true);
return this;
};
fn.get = function(){
return this.coords;
};
fn.destroy = function() {
this.el.removeData('coords');
delete this.el;
};
//jQuery adapter
$.fn.coords = function() {
if (this.data('coords') ) {
return this.data('coords');
}
var ins = new Coords(this);
this.data('coords', ins);
return ins;
};
return Coords;
}));

View File

@@ -0,0 +1,456 @@
/*
* jquery.draggable
* https://github.com/ducksboard/gridster.js
*
* Copyright (c) 2012 ducksboard
* Licensed under the MIT licenses.
*/
;(function(root, factory) {
'use strict';
if(typeof exports === 'object') {
module.exports = factory(require('jquery'));
}
else if (typeof define === 'function' && define.amd) {
define('gridster-draggable', ['jquery'], factory);
} else {
root.GridsterDraggable = factory(root.$ || root.jQuery);
}
}(this, function($) {
'use strict';
var defaults = {
items: 'li',
distance: 1,
limit: true,
offset_left: 0,
autoscroll: true,
ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'], // or function
handle: null,
container_width: 0, // 0 == auto
move_element: true,
helper: false, // or 'clone'
remove_helper: true
// drag: function(e) {},
// start : function(e, ui) {},
// stop : function(e) {}
};
var $window = $(window);
var dir_map = { x : 'left', y : 'top' };
var isTouch = !!('ontouchstart' in window);
var capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
var idCounter = 0;
var uniqId = function() {
return ++idCounter + '';
};
/**
* Basic drag implementation for DOM elements inside a container.
* Provide start/stop/drag callbacks.
*
* @class Draggable
* @param {HTMLElement} el The HTMLelement that contains all the widgets
* to be dragged.
* @param {Object} [options] An Object with all options you want to
* overwrite:
* @param {HTMLElement|String} [options.items] Define who will
* be the draggable items. Can be a CSS Selector String or a
* collection of HTMLElements.
* @param {Number} [options.distance] Distance in pixels after mousedown
* the mouse must move before dragging should start.
* @param {Boolean} [options.limit] Constrains dragging to the width of
* the container
* @param {Object|Function} [options.ignore_dragging] Array of node names
* that sould not trigger dragging, by default is `['INPUT', 'TEXTAREA',
* 'SELECT', 'BUTTON']`. If a function is used return true to ignore dragging.
* @param {offset_left} [options.offset_left] Offset added to the item
* that is being dragged.
* @param {Number} [options.drag] Executes a callback when the mouse is
* moved during the dragging.
* @param {Number} [options.start] Executes a callback when the drag
* starts.
* @param {Number} [options.stop] Executes a callback when the drag stops.
* @return {Object} Returns `el`.
* @constructor
*/
function Draggable(el, options) {
this.options = $.extend({}, defaults, options);
this.$document = $(document);
this.$container = $(el);
this.$scroll_container = this.options.scroll_container === window ?
$(window) : this.$container.closest(this.options.scroll_container);
this.is_dragging = false;
this.player_min_left = 0 + this.options.offset_left;
this.id = uniqId();
this.ns = '.gridster-draggable-' + this.id;
this.init();
}
Draggable.defaults = defaults;
var fn = Draggable.prototype;
fn.init = function() {
var pos = this.$container.css('position');
this.calculate_dimensions();
this.$container.css('position', pos === 'static' ? 'relative' : pos);
this.disabled = false;
this.events();
$window.bind(this.nsEvent('resize'),
throttle($.proxy(this.calculate_dimensions, this), 200));
};
fn.nsEvent = function(ev) {
return (ev || '') + this.ns;
};
fn.events = function() {
this.pointer_events = {
start: this.nsEvent('touchstart') + ' ' + this.nsEvent('mousedown'),
move: this.nsEvent('touchmove') + ' ' + this.nsEvent('mousemove'),
end: this.nsEvent('touchend') + ' ' + this.nsEvent('mouseup')
};
this.$container.on(this.nsEvent('selectstart'),
$.proxy(this.on_select_start, this));
this.$container.on(this.pointer_events.start, this.options.items,
$.proxy(this.drag_handler, this));
this.$document.on(this.pointer_events.end, $.proxy(function(e) {
this.is_dragging = false;
if (this.disabled) { return; }
this.$document.off(this.pointer_events.move);
if (this.drag_start) {
this.on_dragstop(e);
}
}, this));
};
fn.get_actual_pos = function($el) {
return $el.position();
};
fn.get_mouse_pos = function(e) {
if (e.originalEvent && e.originalEvent.touches) {
var oe = e.originalEvent;
e = oe.touches.length ? oe.touches[0] : oe.changedTouches[0];
}
return {
left: e.clientX,
top: e.clientY
};
};
fn.get_offset = function(e) {
e.preventDefault();
var mouse_actual_pos = this.get_mouse_pos(e);
var diff_x = Math.round(
mouse_actual_pos.left - this.mouse_init_pos.left);
var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top);
var left = Math.round(this.el_init_offset.left +
diff_x - this.baseX +
this.$scroll_container.scrollLeft() -
this.scroll_container_offset_x);
var top = Math.round(this.el_init_offset.top +
diff_y - this.baseY +
this.$scroll_container.scrollTop() -
this.scroll_container_offset_y);
if (this.options.limit) {
if (left > this.player_max_left) {
left = this.player_max_left;
} else if(left < this.player_min_left) {
left = this.player_min_left;
}
}
return {
position: {
left: left,
top: top
},
pointer: {
left: mouse_actual_pos.left,
top: mouse_actual_pos.top,
diff_left: diff_x + (this.$scroll_container.scrollLeft() -
this.scroll_container_offset_x),
diff_top: diff_y + (this.$scroll_container.scrollTop() -
this.scroll_container_offset_y)
}
};
};
fn.get_drag_data = function(e) {
var offset = this.get_offset(e);
offset.$player = this.$player;
offset.$helper = this.helper ? this.$helper : this.$player;
return offset;
};
fn.set_limits = function(container_width) {
container_width || (container_width = this.$container.width());
this.player_max_left = (container_width - this.player_width +
- this.options.offset_left);
this.options.container_width = container_width;
return this;
};
fn.scroll_in = function(axis, data) {
var dir_prop = dir_map[axis];
var area_size = 50;
var scroll_inc = 30;
var scrollDir = 'scroll' + capitalize(dir_prop);
var is_x = axis === 'x';
var scroller_size = is_x ? this.scroller_width : this.scroller_height;
var doc_size;
if (this.$scroll_container === window){
doc_size = is_x ? this.$scroll_container.width() :
this.$scroll_container.height();
}else{
doc_size = is_x ? this.$scroll_container[0].scrollWidth :
this.$scroll_container[0].scrollHeight;
}
var player_size = is_x ? this.$player.width() : this.$player.height();
var next_scroll;
var scroll_offset = this.$scroll_container[scrollDir]();
var min_scroll_pos = scroll_offset;
var max_scroll_pos = min_scroll_pos + scroller_size;
var mouse_next_zone = max_scroll_pos - area_size; // down/right
var mouse_prev_zone = min_scroll_pos + area_size; // up/left
var abs_mouse_pos = min_scroll_pos + data.pointer[dir_prop];
var max_player_pos = (doc_size - scroller_size + player_size);
if (abs_mouse_pos >= mouse_next_zone) {
next_scroll = scroll_offset + scroll_inc;
if (next_scroll < max_player_pos) {
this.$scroll_container[scrollDir](next_scroll);
this['scroll_offset_' + axis] += scroll_inc;
}
}
if (abs_mouse_pos <= mouse_prev_zone) {
next_scroll = scroll_offset - scroll_inc;
if (next_scroll > 0) {
this.$scroll_container[scrollDir](next_scroll);
this['scroll_offset_' + axis] -= scroll_inc;
}
}
return this;
};
fn.manage_scroll = function(data) {
this.scroll_in('x', data);
this.scroll_in('y', data);
};
fn.calculate_dimensions = function() {
this.scroller_height = this.$scroll_container.height();
this.scroller_width = this.$scroll_container.width();
};
fn.drag_handler = function(e) {
// skip if drag is disabled, or click was not done with the mouse primary button
if (this.disabled || e.which !== 1 && !isTouch) {
return;
}
if (this.ignore_drag(e)) {
return;
}
var self = this;
var first = true;
this.$player = $(e.currentTarget);
this.el_init_pos = this.get_actual_pos(this.$player);
this.mouse_init_pos = this.get_mouse_pos(e);
this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top;
this.$document.on(this.pointer_events.move, function(mme) {
var mouse_actual_pos = self.get_mouse_pos(mme);
var diff_x = Math.abs(
mouse_actual_pos.left - self.mouse_init_pos.left);
var diff_y = Math.abs(
mouse_actual_pos.top - self.mouse_init_pos.top);
if (!(diff_x > self.options.distance ||
diff_y > self.options.distance)
) {
return false;
}
if (first) {
first = false;
self.on_dragstart.call(self, mme);
return false;
}
if (self.is_dragging === true) {
self.on_dragmove.call(self, mme);
}
return false;
});
if (!isTouch) { return false; }
};
fn.on_dragstart = function(e) {
e.preventDefault();
if (this.is_dragging) { return this; }
this.drag_start = this.is_dragging = true;
var offset = this.$container.offset();
this.baseX = Math.round(offset.left);
this.baseY = Math.round(offset.top);
if (this.options.helper === 'clone') {
this.$helper = this.$player.clone()
.appendTo(this.$container).addClass('helper');
this.helper = true;
} else {
this.helper = false;
}
this.scroll_container_offset_y = this.$scroll_container.scrollTop();
this.scroll_container_offset_x = this.$scroll_container.scrollLeft();
this.el_init_offset = this.$player.offset();
this.player_width = this.$player.width();
this.set_limits(this.options.container_width);
if (this.options.start) {
this.options.start.call(this.$player, e, this.get_drag_data(e));
}
return false;
};
fn.on_dragmove = function(e) {
var data = this.get_drag_data(e);
this.options.autoscroll && this.manage_scroll(data);
if (this.options.move_element) {
(this.helper ? this.$helper : this.$player).css({
'position': 'absolute',
'left' : data.position.left,
'top' : data.position.top
});
}
var last_position = this.last_position || data.position;
data.prev_position = last_position;
if (this.options.drag) {
this.options.drag.call(this.$player, e, data);
}
this.last_position = data.position;
return false;
};
fn.on_dragstop = function(e) {
var data = this.get_drag_data(e);
this.drag_start = false;
if (this.options.stop) {
this.options.stop.call(this.$player, e, data);
}
if (this.helper && this.options.remove_helper) {
this.$helper.remove();
}
return false;
};
fn.on_select_start = function(e) {
if (this.disabled) { return; }
if (this.ignore_drag(e)) {
return;
}
return false;
};
fn.enable = function() {
this.disabled = false;
};
fn.disable = function() {
this.disabled = true;
};
fn.destroy = function() {
this.disable();
this.$container.off(this.ns);
this.$document.off(this.ns);
$window.off(this.ns);
$.removeData(this.$container, 'drag');
};
fn.ignore_drag = function(event) {
if (this.options.handle) {
return !$(event.target).is(this.options.handle);
}
if ($.isFunction(this.options.ignore_dragging)) {
return this.options.ignore_dragging(event);
}
if (this.options.resize) {
return ! $(event.target).is(this.options.items);
}
return $(event.target).is(this.options.ignore_dragging.join(', '));
};
//jQuery adapter
$.fn.gridDraggable = function ( options ) {
return new Draggable(this, options);
};
$.fn.dragg = function (options) {
return this.each(function () {
if (!$.data(this, 'drag')) {
$.data(this, 'drag', new Draggable(this, options));
}
});
};
return Draggable;
}));

View File

@@ -0,0 +1,151 @@
;(function(root, factory) {
'use strict';
if(typeof exports === 'object') {
module.exports = factory(require('jquery'), require('./jquery.gridster.js'));
}
else if (typeof define === 'function' && define.amd) {
define(['jquery', 'gridster'], factory);
} else {
root.Gridster = factory(root.$ || root.jQuery, root.Gridster);
}
}(this, function($, Gridster) {
'use strict';
var fn = Gridster.prototype;
fn.widgets_in_col = function(col) {
if (!this.gridmap[col]) {
return false;
}
for (var i = this.gridmap[col].length - 1; i >= 0; i--) {
if (this.is_widget(col, i) !== false) {
return true;
}
}
return false;
};
fn.widgets_in_row = function(row) {
for (var i = this.gridmap.length; i >= 1; i--) {
if (this.is_widget(i, row) !== false) {
return true;
}
}
return false;
};
fn.get_bottom_most_occupied_cell = function() {
var row = 0;
var col = 0;
this.for_each_cell(function($el, c, r) {
if ($el && r > row) {
row = r;
col = c;
}
});
return {col: col, row: row};
};
fn.get_right_most_occupied_cell = function() {
var row = 0;
var col = 0;
this.for_each_cell(function($el, c, r) {
if ($el) {
row = r;
col = c;
return false;
}
});
return {col: col, row: row};
};
fn.for_each_cell = function(callback, gridmap) {
gridmap || (gridmap = this.gridmap);
var cols = gridmap.length;
var rows = gridmap[1].length;
cols_iter:
for (var c = cols - 1; c >= 1; c--) {
for (var r = rows - 1; r >= 1; r--) {
var $el = gridmap[c] && gridmap[c][r];
if (callback) {
if (callback.call(this, $el, c, r) === false) {
break cols_iter;
} else { continue; }
}
}
}
};
fn.next_position_in_range = function(size_x, size_y) {
size_x || (size_x = 1);
size_y || (size_y = 1);
var ga = this.gridmap;
var cols_l = ga.length;
var valid_pos = [];
var rows_l;
for (var c = 1; c < cols_l; c++) {
rows_l = this.options.max_rows || ga[c].length;
for (var r = 1; r <= rows_l; r++) {
var can_move_to = this.can_move_to({
size_x: size_x,
size_y: size_y
}, c, r);
if (can_move_to) {
valid_pos.push({
col: c,
row: r,
size_y: size_y,
size_x: size_x
});
}
}
}
if (valid_pos.length >= 1) {
return Gridster.sort_by_col_asc(valid_pos)[0];
}
return false;
};
fn.closest_to_right = function(col, row) {
if (!this.gridmap[col]) { return false; }
var cols_l = this.gridmap.length - 1;
for (var c = col; c <= cols_l; c++) {
if (this.gridmap[c][row]) {
return { col: c, row: row };
}
}
return false;
};
fn.closest_to_left = function(col, row) {
if (!this.gridmap[col]) { return false; }
for (var c = col; c >= 1; c--) {
if (this.gridmap[c][row]) {
return { col: c, row: row };
}
}
return false;
};
return Gridster;
}));

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
/*! gridster.js - v0.6.10 - 2015-05-31
* https://dsmorse.github.io/gridster.js/
* Copyright (c) 2015 ducksboard; Licensed MIT */
.gridster {
position:relative;
& > * {
-webkit-transition: height .4s, width .4s;
-moz-transition: height .4s, width .4s;
-o-transition: height .4s, width .4s;
-ms-transition: height .4s, width .4s;
transition: height .4s, width .4s;
}
.gs-w {
z-index: 2;
position: absolute;
}
.preview-holder {
z-index: 1;
position: absolute;
background-color: #fff;
border-color: #fff;
opacity: 0.3;
}
.player-revert {
z-index: 10!important;
-webkit-transition: left .3s, top .3s!important;
-moz-transition: left .3s, top .3s!important;
-o-transition: left .3s, top .3s!important;
transition: left .3s, top .3s!important;
}
}
.gridster.collapsed {
height: auto !important;
.gs-w {
position: static !important;
}
}
.ready {
.gs-w:not(.preview-holder) {
-webkit-transition: opacity .3s, left .3s, top .3s;
-moz-transition: opacity .3s, left .3s, top .3s;
-o-transition: opacity .3s, left .3s, top .3s;
transition: opacity .3s, left .3s, top .3s;
}
}
.ready .gs-w:not(.preview-holder),.ready .resize-preview-holder {
-webkit-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
-moz-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
-o-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
}
.gridster .dragging,.gridster .resizing {
z-index: 10!important;
-webkit-transition: all 0s !important;
-moz-transition: all 0s !important;
-o-transition: all 0s !important;
transition: all 0s !important;
}
.gs-resize-handle {
position: absolute;
z-index: 1;
}
.gs-resize-handle-both {
width: 20px;
height: 20px;
bottom: -8px;
right: -8px;
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=');
background-position: top left;
background-repeat: no-repeat;
cursor: se-resize;
z-index: 20;
}
.gs-resize-handle-x {
top: 0;
bottom: 13px;
right: -5px;
width: 10px;
cursor: e-resize;
}
.gs-resize-handle-y {
left: 0;
right: 13px;
bottom: -5px;
height: 10px;
cursor: s-resize;
}
.gs-w:hover .gs-resize-handle,.resizing .gs-resize-handle {
opacity: 1;
}
.gs-resize-handle,.gs-w.dragging .gs-resize-handle {
opacity: 0;
}
.gs-resize-disabled {
.gs-resize-handle {
display: none!important;
}
}
[data-max-sizex="1"] .gs-resize-handle-x,[data-max-sizey="1"] .gs-resize-handle-y,[data-max-sizey="1"][data-max-sizex="1"] .gs-resize-handle {
display: none !important;
}
/* Uncomment this if you set helper : "clone" in draggable options */
/*.gridster .player {
opacity:0;
}
*/

85
lib/gridster/src/utils.js Normal file
View File

@@ -0,0 +1,85 @@
(function (window, undefined) {
'use strict';
/* Delay, debounce and throttle functions taken from underscore.js
*
* Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and
* Investigative Reporters & Editors
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE 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.
*/
window.delay = function (func, wait) {
var args = Array.prototype.slice.call(arguments, 2);
return setTimeout(function () {
return func.apply(null, args);
}, wait);
};
window.debounce = function (func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
if (immediate && !timeout) {
func.apply(context, args);
}
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
window.throttle = function (func, wait) {
var context, args, timeout, throttling, more, result;
var whenDone = debounce(
function () {
more = throttling = false;
}, wait);
return function () {
context = this;
args = arguments;
var later = function () {
timeout = null;
if (more) {
func.apply(context, args);
}
whenDone();
};
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (throttling) {
more = true;
} else {
result = func.apply(context, args);
}
whenDone();
throttling = true;
return result;
};
};
})(window);

View File

@@ -0,0 +1,53 @@
//Based on https://github.com/jonnyreeves/qunit-require
/* global require, QUnit*/
'use strict';
require.config({
//set the baseUrl to the src dir so that gridster
//AMD modules can be found.
baseUrl: '../src/',
paths: {
'QUnit': '../libs/qunit/qunit/qunit',
'jquery': '../libs/jquery/dist/jquery',
'gridster': 'jquery.gridster'
},
map: {
// '*' means all modules will get 'jquery-private'
// for their 'jquery' dependency.
'*': { 'jquery': '../test/jquery-private' },
// 'jquery-private' wants the real jQuery module
// though. If this line was not here, there would
// be an unresolvable cyclic dependency.
'../test/jquery-private': { 'jquery': 'jquery' }
},
shim: {
'QUnit': {
exports: 'QUnit',
init: function() {
QUnit.config.autoload = false;
QUnit.config.autostart = false;
}
}
}
});
/*
Load all of our require'd files
We have to load all of the gridster jquery.* modules so
that they are defined for when gridster needs them.
Lastly, load the testsuite which defines some tests.
*/
require([
'QUnit',
'utils',
'jquery.coords',
'jquery.collision',
'jquery.draggable',
'../test/testsuite'
//Require'd files are passed as args, but we don't use them.
], function(QUnit/*, utils, coords, collision, draggable, testsuite*/) {
QUnit.load();
QUnit.start();
}
);

4
lib/gridster/test/jquery-private.js vendored Normal file
View File

@@ -0,0 +1,4 @@
define(['jquery'], function (jq) {
'use strict';
return jq.noConflict( true );
});

View File

@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>gridster.js AMD Test Suite</title>
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.css">
<link rel="stylesheet" href="../libs/qunit/qunit/qunit.css" media="screen">
<!-- Load requirejs which will load amd-main.js and start from there-->
<script data-main="amd-main.js" src="../libs/requirejs/require.js"></script>
</head>
<body>
<h1 id="qunit-header">gridster.js AMD Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">
<div class="wrapper">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2"></li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2"></li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1"></li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1"></li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1"></li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1"></li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1"></li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1"></li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1"></li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="3"></li>
<li data-row="5" data-col="1" data-sizex="1" data-sizey="2"></li>
<li data-row="4" data-col="3" data-sizex="1" data-sizey="2"></li>
<li data-row="5" data-col="4" data-sizex="1" data-sizey="1"></li>
<li data-row="6" data-col="2" data-sizex="3" data-sizey="1"></li>
<li data-row="4" data-col="5" data-sizex="1" data-sizey="2"></li>
<li data-row="6" data-col="5" data-sizex="1" data-sizey="1"></li>
<li data-row="7" data-col="3" data-sizex="1" data-sizey="1"></li>
</ul>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>gridster.js Test Suite</title>
<!-- Load JQuery dependency. -->
<script src="../libs/jquery/dist/jquery.js"></script>
<script>jQuery.noConflict()</script>
<!-- load the gridster source files, run the tests against the broken out javascipt in the source dir-->
<script src="../src/jquery.coords.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/jquery.collision.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/utils.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/jquery.draggable.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/jquery.gridster.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="../src/jquery.gridster.css">
<!-- Load QUnit dependency. -->
<link rel="stylesheet" href="../libs/qunit/qunit/qunit.css" media="screen">
<script src="../libs/qunit/qunit/qunit.js"></script>
<!-- Load local lib and tests. -->
<script src="jquery.gridster_test.js"></script>
</head>
<body>
<h1 id="qunit-header">gridster.js Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">
<div class="wrapper">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2"></li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2"></li>
</ul>
</div>
</div>
<div id="qunit-testresult"></div>
</body>
</html>

View File

@@ -0,0 +1,395 @@
//jshint quotmark:false
/*global module:false, test:false */
/*global ok:false, equal:false, notEqual:false, deepEqual:false*/
/*global notDeepEqual:false */
(function ($) {
'use strict';
/*
======== A Handy Little QUnit Reference ========
http://docs.jquery.com/QUnit
Test methods:
expect(numAssertions)
stop(increment)
start(decrement)
Test assertions:
ok(value, [message])
equal(actual, expected, [message])
notEqual(actual, expected, [message])
deepEqual(actual, expected, [message])
notDeepEqual(actual, expected, [message])
strictEqual(actual, expected, [message])
notStrictEqual(actual, expected, [message])
raises(block, [expected], [message])
*/
module('jQuery#gridster', {
setup: function () {
this.el = $('#qunit-fixture').find(".wrapper ul");
this.serialization = [
{name: "A", col: "1", row: "1", size_x: "2", size_y: "2"},
{name: "B", col: "4", row: "1", size_x: "1", size_y: "2"},
{name: "C", col: "10", row: "10", size_x: "10", size_y: "10"},
{name: "D", col: "3", row: "1", size_x: "1", size_y: "1"},
{name: "E", col: "2", row: "3", size_x: "3", size_y: "1"}
];
this.serialization_small = [
{col: 1, row: 1, size_x: 2, size_y: 2},
{col: 3, row: 1, size_x: 1, size_y: 2},
{col: 6, row: 1, size_x: 1, size_y: 1}
];
}
});
test('can count and clear widgets', 2, function () {
var grid = this.el.gridster().data('gridster');
equal(grid.get_num_widgets(), 2, 'Count the default widgets from the HTML config');
grid.remove_all_widgets();
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
});
test('Above and below', 12, function () {
var grid = this.el.gridster({ max_cols: 4, max_rows: 4, widget_base_dimensions: [100, 55]}).data('gridster');
//remove any widgets from the html config
grid.remove_all_widgets();
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
$.each(this.serialization, function () {
grid.add_widget('<li />', this.size_x, this.size_y, this.col, this.row);
});
equal(grid.get_num_widgets(), this.serialization.length, 'Loaded the widgets for the test');
var widgets_above = $([]);
//the call here checks above as the user see's it on the screen which will check row below 4
grid.for_each_widget_above(3, 4, function(tcol, trow) {
widgets_above = widgets_above.add(this);
});
//widgets B (3,1) & E (2-4, 3) should be below cell 3,4
equal(2, widgets_above.length);
var widgets_found_above = grid.serialize(widgets_above);
equal(widgets_found_above[1].col, parseInt(this.serialization[4].col));
equal(widgets_found_above[1].row, parseInt(this.serialization[4].row));
equal(widgets_found_above[1].size_x, parseInt(this.serialization[4].size_x));
equal(widgets_found_above[1].size_y, parseInt(this.serialization[4].size_y));
var widgets_below = $([]);
grid.for_each_widget_below(3, 2, function(tcol, trow) {
widgets_below = widgets_below.add(this);
});
//widget E (2-4, 3) should be above cell 3,2
equal(1, widgets_below.length);
var widgets_found_below = grid.serialize(widgets_below);
equal(widgets_found_below[0].col, parseInt(this.serialization[4].col));
equal(widgets_found_below[0].row, parseInt(this.serialization[4].row));
equal(widgets_found_below[0].size_x, parseInt(this.serialization[4].size_x));
equal(widgets_found_below[0].size_y, parseInt(this.serialization[4].size_y));
});
test('get_widgets_from', 5, function () {
var input = {col: 2, row: 1, size_x: 3, size_y: 1};
var grid = this.el.gridster().data('gridster');
//remove any widgets from the html config
grid.remove_all_widgets();
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
grid.add_widget('<li />', input.size_x, input.size_y, input.col, input.row);
var widget = grid.get_widgets_at_cell(input.col, input.row);
// normally you would call parseInt on a return from
// .attr(), but qunit takes care of it for us
equal(widget.attr('data-row'), input.row);
equal(widget.attr('data-col'), input.col);
equal(widget.attr('data-sizex'), input.size_x);
equal(widget.attr('data-sizey'), input.size_y);
});
test('get_cells_occupied', 3, function () {
var input = {col: 2, row: 3, size_x: 3, size_y: 1};
var grid = this.el.gridster().data('gridster');
//remove any widgets from the html config
grid.remove_all_widgets();
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
var cellsUsed = grid.get_cells_occupied(input);
deepEqual(cellsUsed.rows, [3]);
deepEqual(cellsUsed.cols, [2,3,4]);
});
test('get_highest_occupied_cell', 1, function () {
var grid = this.el.gridster().data('gridster');
deepEqual(grid.get_min_col(), 1);
});
test('get_highest_occupied_cell', 1, function () {
var grid = this.el.gridster().data('gridster');
deepEqual(grid.get_highest_occupied_cell(), {col: 3, row: 2});
});
//todo tests to add:
// setup_resize & add_resize_handle
// get_min_col
// shift_cols
// get_widgets_from_DOM dom_to_coords, get_widgets_from_DOM set_dom_grid_height set_dom_grid_width
// generate_stylesheet
// set_num_columns
test('add_style_tag', 4, function () {
var grid = this.el.gridster({autogenerate_stylesheet: true}).data('gridster');
var generatedStyleSheet = $('#gridster-stylesheet');
notEqual(generatedStyleSheet, null);
ok(generatedStyleSheet.length > 0);
grid.destroy();
grid = this.el.gridster({autogenerate_stylesheet: true, namespace: 'qunit'}).data('gridster');
generatedStyleSheet = $('#gridster-stylesheet-qunit');
notEqual(generatedStyleSheet, null);
ok(generatedStyleSheet.length > 0);
});
test('resize_widget', 4, function () {
this.resizeGrid = [
{col: 1, row: 1, size_x: 1, size_y: 1},
{col: 2, row: 1, size_x: 1, size_y: 1},
{col: 3, row: 1, size_x: 1, size_y: 1},
{col: 1, row: 2, size_x: 1, size_y: 1},
{col: 2, row: 2, size_x: 1, size_y: 1},
{col: 3, row: 2, size_x: 1, size_y: 1},
{col: 1, row: 3, size_x: 1, size_y: 1},
{col: 2, row: 3, size_x: 1, size_y: 1},
{col: 3, row: 3, size_x: 1, size_y: 1}
];
var grid = this.el.gridster({widget_base_dimensions: [100, 55]}).data('gridster');
//remove any widgets from the html config
grid.remove_all_widgets();
var numBefore = grid.get_num_widgets();
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
$.each(this.resizeGrid, function () {
grid.add_widget('<li />', this.size_x, this.size_y, this.col, this.row);
});
equal(grid.get_num_widgets(), numBefore + this.resizeGrid.length, 'Loading the widgets to prepare for tests');
//check for widgets in the space it will occupy
var widgets = grid.get_widgets_in_range(1,1,2,2);
var numberInSpaceBefore = widgets.length;
equal(numberInSpaceBefore, 4, 'Expect there to be four widgets in the first two rows and cols');
//get the widget from 1,1 and resize it.
grid.resize_widget(grid.get_widgets_at_cell(1, 1), 2, 2);
//check for widgets in the space it will occupy
widgets = grid.get_widgets_in_range(1,1,2,2);
var numberInSpaceAfter = widgets.length;
equal(numberInSpaceAfter, 1, 'Expected a single widget in the expanded area');
});
test('can serialize correctly', 4, function () {
var grid = this.el.gridster({widget_base_dimensions: [100, 55]}).data('gridster');
//remove any widgets from the html config
grid.remove_all_widgets();
var numBefore = grid.get_num_widgets();
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
$.each(this.serialization_small, function () {
grid.add_widget('<li />', this.size_x, this.size_y, this.col, this.row);
});
equal(grid.get_num_widgets(), numBefore + this.serialization_small.length);
var serialized = grid.serialize();
equal(grid.get_num_widgets(), serialized.length);
deepEqual(serialized, this.serialization_small);
});
test('can serialize extended properties', 4, function () {
var input = [{col: 6, row: 3, size_x: 1, size_y: 1}];
var grid = this.el.gridster({widget_base_dimensions: [100, 55], serialize_params: function($w, wgd) {
return {
col: wgd.col,
row: wgd.row
};}}).data('gridster');
//remove any widgets from the html config
grid.remove_all_widgets();
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
grid.add_widget('<li />', input[0].size_x, input[0].size_y, input[0].col, input[0].row);
var serialized = grid.serialize();
//due to custom serialization, input and output should NOT match
notDeepEqual(serialized, input);
equal(serialized[0].col, 6);
equal(serialized[0].size_x, undefined);
});
test('When Adding widgets rows auto condense', 2, function () {
var input = [{col: 6, row: 3, size_x: 1, size_y: 1}];
var output = [{col: 6, row: 1, size_x: 1, size_y: 1}];
var grid = this.el.gridster().data('gridster');
//remove any widgets from the html config
grid.remove_all_widgets();
//make sure we are empty
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
grid.add_widget('<li />', input[0].size_x, input[0].size_y, input[0].col, input[0].row);
var serialized = grid.serialize();
deepEqual(serialized, output);
});
test('When Adding widgets rows static placement is supported', 2, function () {
var input = [{col: 6, row: 3, size_x: 1, size_y: 1}];
var grid = this.el.gridster().data('gridster');
grid.options.shift_widgets_up = false;
//remove any widgets from the html config
grid.remove_all_widgets();
//make sure we are empty
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
grid.add_widget('<li />', input[0].size_x, input[0].size_y, input[0].col, input[0].row);
var serialized = grid.serialize();
deepEqual(serialized, input);
});
test('When Adding widgets cols are respected', 2, function () {
var input = [{col: 6, row: 1, size_x: 1, size_y: 1}];
var grid = this.el.gridster().data('gridster');
//remove any widgets from the html config
grid.remove_all_widgets();
//make sure we are empty
equal(grid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
grid.add_widget('<li />', input[0].size_x, input[0].size_y, input[0].col, input[0].row);
var serialized = grid.serialize();
deepEqual(serialized, input);
});
test('can_move_to', 7, function () {
var input = {col: 6, row: 1, size_x: 1, size_y: 1};
var defaultGrid = this.el.gridster().data('gridster');
//remove any widgets from the html config
defaultGrid.remove_all_widgets();
//make sure we are empty
equal(defaultGrid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
//check with the default config we can place an widget in a skipped col
var canMove = defaultGrid.can_move_to({size_x: input.size_x, size_y: input.size_y}, input.col, input.row);
equal(canMove, true, 'with the default config we can place an widget in a skipped col');
//check with the default config we can not place an widget in a skipped row
canMove = defaultGrid.can_move_to({size_x: input.size_x, size_y: input.size_y}, input.col, input.row+3);
equal(canMove, true, 'with the default config we can not place an widget in a skipped row');
defaultGrid.destroy();
//now repeat the tests with custom settings
var customGrid = this.el.gridster({max_rows : 2, max_cols : 4}).data('gridster');
//remove any widgets from the html config
customGrid.remove_all_widgets();
//make sure we are empty
equal(customGrid.get_num_widgets(), 0, 'Clearing the widgets to prepare for tests');
//check with the Custom config we can place an widget outside the grid
canMove = customGrid.can_move_to({size_x: input.size_x, size_y: input.size_y}, input.col, input.row);
equal(canMove, false, 'with the Custom config we can place an widget outside the grid');
//check with the custom config we can not place an widget outside the grid
canMove = customGrid.can_move_to({size_x: input.size_x, size_y: input.size_y}, 1, input.row+3);
equal(canMove, false, 'with the custom config we can not place an widget outside the grid');
//check to see if we can't move an widget to where there is one
customGrid.add_widget('<li />', 1, 1, 1, 1);
canMove = customGrid.can_move_to({size_x: 1, size_y: 1}, 1, 1);
equal(canMove, false, 'we cant move an widget to where there is one');
});
test('is chainable', 1, function () {
// Not a bad test to run on collection methods.
strictEqual(this.el, this.el.gridster(), 'should be chaninable');
});
test('is Responsive', 1, function () {
var grid = this.el.gridster(
{autogenerate_stylesheet: true,
widget_base_dimensions: ['auto', 'auto'],
max_cols: 4}).data('gridster');
equal(grid.is_responsive(), true);
});
test('Gridster.sort_by_row_asc', 4, function (assert) {
var sorted = Gridster.sort_by_row_asc(this.serialization);
var result = pickup(sorted, 'name').join(',');
var expected = 'A,B,D,E,C';
//since the test data contains 3 #1, they could be in any order
ok( result.substring(0,5).indexOf('A') > -1, 'A is found in within the first 3 results');
ok( result.substring(0,5).indexOf('B') > -1, 'B is found in within the first 3 results');
ok( result.substring(0,5).indexOf('D') > -1, 'D is found in within the first 3 results');
//check the last to chars
equal( result.substring(6), expected.substring(6), 'E,C are the last two - In that order');
});
test('Gridster.sort_by_row_and_col_asc', function (assert) {
var sorted = Gridster.sort_by_row_and_col_asc(this.serialization);
var result = pickup(sorted, 'name').join(',');
var expected = 'A,D,B,E,C';
assert.equal(result, expected);
});
test('Gridster.sort_by_col_asc', function (assert) {
var sorted = Gridster.sort_by_col_asc(this.serialization);
var result = pickup(sorted, 'name').join(',');
var expected = 'A,E,D,B,C';
assert.equal(result, expected);
});
test('Gridster.sort_by_row_desc',4, function (assert) {
var sorted = Gridster.sort_by_row_desc(this.serialization);
var result = pickup(sorted, 'name').join(',');
var expected = 'C,E,A,B,D';
//since the test data contains 3 #1, they could be in any order
ok( result.substring(4).indexOf('A') > -1, 'A is found in within the last 3 results');
ok( result.substring(4).indexOf('B') > -1, 'B is found in within the last 3 results');
ok( result.substring(4).indexOf('D') > -1, 'D is found in within the last 3 results');
//check the last to chars
equal( result.substring(0,3), expected.substring(0,3), 'C,E are the first two - In that order');
});
// errors
test('sort_by_row_asc: Throws not exists property', function (assert) {
assert.throws(function () {
//missing col
var data = [{row: 1, size_x: 1, size_y: 1}, {col: 2, row: 1, size_x: 1, size_y: 1}];
Gridster.sort_by_row_asc(data);
},
Error,
'raise error not exists required property'
);
});
test('sort_by_row_asc: Throws invalid type of value', function (assert) {
var secWidget = {col: 2, row: 1, size_x: 1, size_y: 1};
// inconvertible types
assert.throws(function () {
//col is not a number
Gridster.sort_by_row_asc([{col: "AAA", row: 1, size_x: 1, size_y: 1}, secWidget]);
}, Error, 'raise error inconvertible types' );
// null
assert.throws(function () {
// coll is null
Gridster.sort_by_row_asc([{col: null, row: 1, size_x: 1, size_y: 1}, secWidget]);
}, Error, 'raise error value is null' );
// array
assert.throws(function () {
//col does not accept an array
Gridster.sort_by_row_asc([{col: [1, 2, 3], row: 1, size_x: 1, size_y: 1}, secWidget]);
}, Error, 'raise error value is array' );
// object
assert.throws(function () {
//col does not accept an onbject
Gridster.sort_by_row_asc([{col: {k: 1}, row: 1, size_x: 1, size_y: 1}, secWidget]);
},Error, 'raise error value is object');
});
// helper
function pickup (data, prop) {
return data.map(function (elm) {
return elm[prop];
});
}
}(jQuery));

View File

@@ -0,0 +1,200 @@
/* global u, SPEED*/
'use strict';
window.serialization = {
'default': function() {
return [
{name: 'A', col: 1, row: 1, size_x: 1, size_y: 2},
{name: 'B', col: 2, row: 1, size_x: 3, size_y: 2},
{name: 'C', col: 5, row: 1, size_x: 3, size_y: 2},
{name: 'D', col: 8, row: 1, size_x: 2, size_y: 1},
{name: 'E', col: 1, row: 3, size_x: 4, size_y: 1},
{name: 'F', col: 10, row: 1, size_x: 1, size_y: 2},
{name: 'G', col: 8, row: 2, size_x: 2, size_y: 1},
{name: 'H', col: 5, row: 3, size_x: 3, size_y: 2},
{name: 'I', col: 8, row: 3, size_x: 1, size_y: 1},
{name: 'J', col: 9, row: 3, size_x: 2, size_y: 2},
{name: 'K', col: 1, row: 4, size_x: 1, size_y: 3}
];
}
};
window.u = {
pick: function(data, prop) {
return data.map(function(elm) {
return elm[prop];
});
},
getRandomColor: function() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.round(Math.random() * 10)];
}
return color;
},
createGridster: function(config, serialize, fromDom) {
var defaults = {
widget_margins: [5, 5],
widget_base_dimensions: [100, 55],
min_cols: 10,
max_cols: 10
};
serialize || (serialize = window.serialization.default());
var widgets = [];
$.each(serialize, function(i, w) {
widgets.push(['<li>' + w.name + '</li>', w.size_x, w.size_y, w.col, w.row]);
});
this.$fixture = $('#fixture');
this.$fixture.html('<div class="gridster"><ul></ul></div>');
this.$el = $('.gridster > ul');
if (fromDom) {
var html = [];
$.each(serialize, function(i, w) {
html.push('<li data-col="' + w.col + '" data-row="' + w.row + '" data-sizex="' + w.size_x + '" data-sizey="' + w.size_y + '">' + w.name + '</li>');
});
this.$el.html(html.join('\n'));
}
this.gridster = this.$el.gridster(
$.extend({}, defaults, config)).data('gridster');
if (!fromDom) {
$.each(widgets, function(i, widget) {
this.gridster.add_widget.apply(this.gridster, widget);
}.bind(this));
}
this.drag_from_to = u._dragFromTo;
return this.gridster;
},
createEvent: function(type, offset) {
var event = document.createEvent('MouseEvents');
event.initMouseEvent(type, true, true, window, 0, 0, 0,
offset.left, offset.top, false, false, false, false, 0, null);
return event;
},
dispatchEvent: function(elem, type, event) {
if (elem.dispatchEvent) {
elem.dispatchEvent(event);
} else if (elem.fireEvent) {
elem.fireEvent('on' + type, event);
}
},
_dragFromTo: function(fromCoords, toCoords) {
var d = $.Deferred();
var gridster = this.gridster;
var $el;
function getMousePos(coords) {
var size = gridster.options.widget_base_dimensions;
var margin = gridster.options.widget_margins;
var left = ((coords[0] - 1) * size[0]) + (margin[0] * ((coords[0] * 2) - 1));
var top = ((coords[1] - 1) * size[1]) + (margin[1] * ((coords[1] * 2) - 1));
var parentOffset = gridster.$wrapper.offset();
return {
left: parentOffset.left + left + 20,
top: parentOffset.top + top + 20
};
}
function addPoint(offset) {
$('<span/>').css({
left: offset.left + 'px',
top: offset.top + 'px',
width: '2px',
height: '2px',
background: 'red',
display: 'inline-block',
position: 'absolute',
zIndex: '9999'
}).appendTo('body');
}
var from_offset;
if (fromCoords instanceof $) {
$el = fromCoords;
var offset = $el.offset();
from_offset = {
left: offset.left + ($el.width() / 2),
top: offset.top + ($el.height() / 2)
};
} else {
$el = this.gridster.gridmap[fromCoords[0]][fromCoords[1]];
from_offset = getMousePos(fromCoords);
}
if (! $el) {
return;
}
var to_offset = getMousePos(toCoords);
var el = $el.get(0);
addPoint(from_offset);
addPoint(to_offset);
// Simulating drag start
var type = 'mousedown';
var event = u.createEvent(type, from_offset);
u.dispatchEvent(el, type, event);
// Simulating drop
type = 'mousemove';
u.dispatchEvent(el, type, u.createEvent(type, {
top: from_offset.top + 2,
left: from_offset.left + 2
}));
this.gridster.$el.on('gridster:dragstop gridster:resizestop', function() {
setTimeout(function() {
d.resolveWith(this);
}.bind(this), SPEED);
}.bind(this));
var diff_x = to_offset.left - from_offset.left;
var diff_y = to_offset.top - from_offset.top;
var steps = 10;
var step_x = diff_x / steps;
var step_y = diff_y / steps;
var tmp_offset = {
left: from_offset.left,
top: from_offset.top
};
for (var i = 0; i < steps; i++) {
tmp_offset.left += step_x;
tmp_offset.top += step_y;
addPoint(tmp_offset);
u.dispatchEvent(el, type, u.createEvent(type, tmp_offset));
}
u.dispatchEvent(el, type, u.createEvent(type, to_offset));
addPoint(to_offset);
// Simulating drag end
type = 'mouseup';
var dragEndEvent = u.createEvent(type, to_offset);
u.dispatchEvent(el, type, dragEndEvent);
return d.promise();
}
};

View File

@@ -0,0 +1,27 @@
'use strict';
define([
'QUnit',
'jquery',
'gridster'
], function(QUnit, $, gridster) {
QUnit.module('Gridster AMD', {
setup: function () {
},
teardown: function () {
}
});
QUnit.test('window.$ should be undefined.', function() {
equal(typeof window.$, 'undefined', 'window.$ should be undefined');
equal(typeof window.jQuery, 'undefined', 'window.jQuery should be undefined');
});
QUnit.test('gridster should be initialized.', function() {
$('.wrapper ul').gridster();
equal($('.wrapper').hasClass('ready'), true, 'Gridster should initialized wrapper.');
equal($('.wrapper ul li').length, $('.gs-w').length, 'grid elements get a .gs-w class');
});
}
);