Merge pull request #12 from rashidkpc/master

Dashboard, layout tweaks
This commit is contained in:
Rashid Khan 2014-02-26 09:21:04 -07:00
commit 82c12c22f2
32 changed files with 12964 additions and 7 deletions

View file

@ -25,7 +25,8 @@
"angular": "~1.2.10",
"lodash": "~2.4.1",
"d3": "~3.4.1",
"angular-route": "~1.2.12"
"angular-route": "~1.2.12",
"gridster": "~0.5.0"
},
"devDependencies": {}
}

View file

@ -0,0 +1,15 @@
{
"name": "gridster",
"homepage": "https://github.com/ducksboard/gridster.js",
"version": "0.5.0",
"_release": "0.5.0",
"_resolution": {
"type": "version",
"tag": "v0.5.0",
"commit": "340369a72e999a166243a611624f42a24da522af"
},
"_source": "git://github.com/ducksboard/gridster.js.git",
"_target": "~0.5.0",
"_originalSource": "gridster",
"_direct": true
}

View file

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

View file

@ -0,0 +1,7 @@
node_modules/
libs/
gh-pages/
demo/
.idea
.DS_Store
.idea

View file

@ -0,0 +1,110 @@
<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))

View file

@ -0,0 +1,143 @@
# 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.

View file

@ -0,0 +1,183 @@
/*global module:false*/
module.exports = function(grunt) {
// 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'
},
dist_css: {
src: ['src/jquery.<%= pkg.name %>.css'],
dest: 'dist/jquery.<%= pkg.name %>.css'
},
dist_demo_js: {
src: ['src/jquery.coords.js', 'src/jquery.collision.js', 'src/utils.js', 'src/jquery.draggable.js', 'src/jquery.<%= pkg.name %>.js'],
dest: 'gh-pages/dist/jquery.<%= pkg.name %>.js'
},
dist_extras_demo_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: 'gh-pages/dist/jquery.<%= pkg.name %>.with-extras.js'
},
dist_demo_css: {
src: ['src/jquery.<%= pkg.name %>.css'],
dest: 'gh-pages/dist/jquery.<%= pkg.name %>.css'
}
},
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 %>']
}
},
dist_demo: {
files: {
'gh-pages/dist/jquery.<%= pkg.name %>.min.js': ['<%= concat.dist_js.dest %>'],
}
},
dist_extras_demo: {
files: {
'gh-pages/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"],
"gh-pages/dist/jquery.<%= pkg.name %>.min.css": ["dist/jquery.<%= pkg.name %>.css"]
}
}
},
jshint: {
files: ['grunt.js', 'src/**/*.js', 'test/**/*.js']
},
watch: {
files: ['<%= lint.files %>', 'src/jquery.<%= pkg.name %>.css'],
tasks: 'min concat'
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
browser: true
},
globals: {
jQuery: true
}
},
yuidoc: {
compile: {
"name": 'gridster.js',
"description": 'gridster.js, a drag-and-drop multi-column jQuery grid plugin',
"version": '0.1.0',
"url": 'http://gridster.net/',
"logo": 'https://ducksboard.com/static/images/svg/logo-ducksboard-black-small.svg',
options: {
paths: "src/",
outdir: "gh-pages/docs/"
}
}
},
bump: {
options: {
files: ['package.json'],
updateConfigs: ['pkg'],
commit: true,
commitMessage: 'Release v%VERSION%',
commitFiles: ['package.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'
}
},
changelog: {
options: {
dest: 'CHANGELOG.md'
}
},
watch: {
files: ['libs/*.js', 'src/*.js', 'src/*.css', 'Gruntfile.js'],
tasks: ['concat', 'uglify', 'cssmin']
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-yuidoc');
grunt.loadNpmTasks('grunt-bump');
grunt.loadNpmTasks('grunt-conventional-changelog');
// Default task.
grunt.registerTask('default', ['jshint', 'concat', 'uglify', 'cssmin']);
grunt.registerTask('build', ['default']);
grunt.registerTask('docs', ['yuidoc']);
grunt.registerTask('release', ['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', 'bump-commit']);
grunt.registerTask('release:commit', ['bump-commit']);
};

19
src/bower_components/gridster/LICENSE vendored 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.

50
src/bower_components/gridster/README.md vendored Normal file
View file

@ -0,0 +1,50 @@
Gridster.js
===========
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/ducksboard/gridster.js/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
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/).
[Releases](https://github.com/ducksboard/gridster.js/releases)
[CHANGELOG](https://github.com/ducksboard/gridster.js/blob/master/CHANGELOG.md)
Gridster is maintained by Ducksboard occasionally but not actively.
@dustmoo and @pushmatrix have also write permissions as Gridster maintainers
they are. Thank you guys!
## Forks
Mr @dustmoo (maintainer of Gridster) has his own fork of gridster.js
with some new interesting features like widget-swapping and static widgets.
Can be found here: [dustmoo/gridster.js](https://github.com/dustmoo/gridster.js)
@dustmoo is working in his spare time to merge all these changes into
ducksboard/gridster.js
If anyone would like to help @dustmoo improve his fork and reconcile
it with the main library he would be happy for the help.
## 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).

View file

@ -0,0 +1,121 @@
/*! gridster.js - v0.5.0 - 2014-02-14
* http://gridster.net/
* Copyright (c) 2014 ducksboard; Licensed MIT */
.gridster {
position:relative;
}
.gridster > * {
margin: 0 auto;
-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;
}
.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 .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 .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;
}
*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
/*! gridster.js - v0.5.0 - 2014-02-14 - * http://gridster.net/ - Copyright (c) 2014 ducksboard; Licensed MIT */
.gridster{position:relative}.gridster>*{margin:0 auto;-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}.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 .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 .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}

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,41 @@
{
"name": "gridster",
"title": "gridster.js",
"description": "a drag-and-drop multi-column jQuery grid plugin",
"version": "0.5.0",
"homepage": "http://gridster.net/",
"author": {
"name": "ducksboard",
"email": "hackers@ducksboard.com"
},
"repository": {
"type": "git",
"url": "git://github.com/ducksboard/gridster.js.git"
},
"bugs": {
"url": "https://github.com/ducksboard/gridster.js/issues"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/ducksboard/gridster.js/blob/master/LICENSE"
}
],
"keywords": [],
"dependencies": {
"jquery": "git+https://github.com/jquery/jquery.git#2.0.3"
},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-jshint": "~0.3.0",
"grunt-contrib-concat": "~0.1.3",
"grunt-contrib-watch": "~0.3.1",
"grunt-contrib-cssmin": "~0.5.0",
"grunt-contrib-yuidoc": "~0.4.0",
"bower": "~0.9.2",
"qunitjs": "~1.11.0",
"grunt-bump": "0.0.11",
"grunt-conventional-changelog": "~1.0.0"
}
}

View file

@ -0,0 +1,225 @@
/*
* jquery.collision
* https://github.com/ducksboard/gridster.js
*
* Copyright (c) 2012 ducksboard
* Licensed under the MIT licenses.
*/
;(function($, window, document, undefined){
var defaults = {
colliders_context: document.body
// ,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 {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();
}
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 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 === 'C'){
var area_coords = self.calculate_overlapped_area_coords(
player_coords, collider_coords);
var area = self.calculate_overlapped_area(area_coords);
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 );
};
}(jQuery, window, document));

View file

@ -0,0 +1,108 @@
/*
* jquery.coords
* https://github.com/ducksboard/gridster.js
*
* Copyright (c) 2012 ducksboard
* Licensed under the MIT licenses.
*/
;(function($, window, document, undefined){
/**
* 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.width();
this.data.height = el.height();
}
if (el && update && !not_update_offsets) {
var offset = el.offset();
this.data.top = offset.top;
this.data.left = offset.left;
}
var d = this.data;
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;
};
//jQuery adapter
$.fn.coords = function() {
if (this.data('coords') ) {
return this.data('coords');
}
var ins = new Coords(this, arguments[0]);
this.data('coords', ins);
return ins;
};
}(jQuery, window, document));

View file

@ -0,0 +1,397 @@
/*
* jquery.draggable
* https://github.com/ducksboard/gridster.js
*
* Copyright (c) 2012 ducksboard
* Licensed under the MIT licenses.
*/
;(function($, window, document, undefined) {
var defaults = {
items: 'li',
distance: 1,
limit: true,
offset_left: 0,
autoscroll: true,
ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'],
handle: null,
container_width: 0, // 0 == auto
move_element: true,
helper: false // or 'clone'
// 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 pointer_events = {
start: isTouch ? 'touchstart.gridster-draggable' : 'mousedown.gridster-draggable',
move: isTouch ? 'touchmove.gridster-draggable' : 'mousemove.gridster-draggable',
end: isTouch ? 'touchend.gridster-draggable' : 'mouseup.gridster-draggable'
};
var capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
/**
* 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 {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.$body = $(document.body);
this.$container = $(el);
this.$dragitems = $(this.options.items, this.$container);
this.is_dragging = false;
this.player_min_left = 0 + this.options.offset_left;
this.init();
}
var fn = Draggable.prototype;
fn.init = function() {
this.calculate_dimensions();
this.$container.css('position', 'relative');
this.disabled = false;
this.events();
$(window).bind('resize.gridster-draggable',
throttle($.proxy(this.calculate_dimensions, this), 200));
};
fn.events = function() {
this.$container.on('selectstart.gridster-draggable',
$.proxy(this.on_select_start, this));
this.$container.on(pointer_events.start, this.options.items,
$.proxy(this.drag_handler, this));
this.$body.on(pointer_events.end, $.proxy(function(e) {
this.is_dragging = false;
if (this.disabled) { return; }
this.$body.off(pointer_events.move);
if (this.drag_start) {
this.on_dragstop(e);
}
}, this));
};
fn.get_actual_pos = function($el) {
var pos = $el.position();
return pos;
};
fn.get_mouse_pos = function(e) {
if (isTouch) {
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_offset_x);
var top = Math.round(this.el_init_offset.top +
diff_y - this.baseY + this.scroll_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_offset_x,
diff_top: diff_y + this.scroll_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 is_x = axis === 'x';
var window_size = is_x ? this.window_width : this.window_height;
var doc_size = is_x ? $(document).width() : $(document).height();
var player_size = is_x ? this.$player.width() : this.$player.height();
var next_scroll;
var scroll_offset = $window['scroll' + capitalize(dir_prop)]();
var min_window_pos = scroll_offset;
var max_window_pos = min_window_pos + window_size;
var mouse_next_zone = max_window_pos - area_size; // down/right
var mouse_prev_zone = min_window_pos + area_size; // up/left
var abs_mouse_pos = min_window_pos + data.pointer[dir_prop];
var max_player_pos = (doc_size - window_size + player_size);
if (abs_mouse_pos >= mouse_next_zone) {
next_scroll = scroll_offset + scroll_inc;
if (next_scroll < max_player_pos) {
$window['scroll' + capitalize(dir_prop)](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) {
$window['scroll' + capitalize(dir_prop)](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(e) {
this.window_height = $window.height();
this.window_width = $window.width();
};
fn.drag_handler = function(e) {
var node = e.target.nodeName;
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.$body.on(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);
this.initial_container_width = this.options.container_width || this.$container.width();
if (this.options.helper === 'clone') {
this.$helper = this.$player.clone()
.appendTo(this.$container).addClass('helper');
this.helper = true;
} else {
this.helper = false;
}
this.scroll_offset_y = 0;
this.scroll_offset_x = 0;
this.el_init_offset = this.$player.offset();
this.player_width = this.$player.width();
this.player_height = this.$player.height();
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.$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('.gridster-draggable');
this.$body.off('.gridster-draggable');
$(window).off('.gridster-draggable');
$.removeData(this.$container, 'drag');
};
fn.ignore_drag = function(event) {
if (this.options.handle) {
return !$(event.target).is(this.options.handle);
}
return $(event.target).is(this.options.ignore_dragging.join(', '));
};
//jQuery adapter
$.fn.drag = function ( options ) {
return new Draggable(this, options);
};
}(jQuery, window, document));

View file

@ -0,0 +1,117 @@
.gridster {
position:relative;
}
.gridster > * {
margin: 0 auto;
-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;
}
.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 .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 .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;
}
*/

View file

@ -0,0 +1,165 @@
;(function($, window, document, undefined) {
var fn = $.Gridster;
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.widgets_in_range = function(col1, row1, col2, row2) {
var valid_cols = [];
var valid_rows = [];
var $widgets = $([]);
var c, r, $w, wgd;
for (c = col2; c >= col1; c--) {
for (r = row2; r >= row1; r--) {
$w = this.is_widget(c, r);
if ($w !== false) {
wgd = $w.data('coords').grid;
if (wgd.col >= col1 && wgd.col <= col2 &&
wgd.row >= row1 && wgd.row <= row2
) {
$widgets = $widgets.add($w);
}
}
}
}
return $widgets;
};
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, max_rows) {
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 = 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, max_rows);
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 this.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) {
var cols_l = this.gridmap.length - 1;
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;
};
}(jQuery, window, document));

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,72 @@
;(function(window, undefined) {
/* 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,67 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>gridster.js Test Suite</title>
<!-- Load local jQuery, removing access to $ (use jQuery, not $). -->
<script src="../libs/jquery/jquery.js"></script>
<script>jQuery.noConflict()</script>
<script type="text/javascript" src="../libs/jquery/jquery.js"></script>
<script src="../dist/jquery.gridster.min.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="../dist/jquery.gridster.css">
<!-- Load local QUnit (grunt requires v1.0.0 or newer). -->
<link rel="stylesheet" href="../libs/qunit/qunit.css" media="screen">
<script src="../libs/qunit/qunit.js"></script>
<!-- Load local lib and tests. -->
<script src="../src/jquery.gridster.js"></script>
<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>
<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,38 @@
/*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/
/*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/
/*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/
(function($) {
/*
======== 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");
}
});
// test('is chainable', 1, function() {
// // Not a bad test to run on collection methods.
// strictEqual(this.el, this.el.gridster(), 'should be chaninable');
// });
}(jQuery));

View file

@ -14,7 +14,7 @@
</head>
<body>
<div ng-controller="kibana">
<nav class="navbar navbar-default">
<nav class="navbar navbar-inverse navbar-fixed-top">
<ul class="nav navbar-nav">
<li ng-repeat="app in apps" ng-class="{active: activeApp == app.id}">
<a href="#/{{app.id}}">{{app.name}}</a>

View file

@ -1 +1,5 @@
<h1>Dashboard</h1>
<div ng-controller="dashboard">
<div>
<ul dashboard-grid settings="gridSettings" panels="grid"></ul>
</div>
</div>

View file

@ -1,6 +1,114 @@
define(function (require) {
var angular = require('angular');
var _ = require('lodash');
var $ = require('jquery');
require('css!./styles/main.css');
require('css!../../../bower_components/gridster/dist/jquery.gridster.css');
require('gridster');
var app = angular.module('app/dashboard', []);
app.controller('dashboard', function ($scope) {
$scope.gridSettings = {
};
$scope.grid = [
{
col: 1,
row: 1,
size_x: 5,
size_y: 2
},
{
col: 6,
row: 1,
size_x: 4,
size_y: 2
},
{
col: 10,
row: 1,
size_x: 3,
size_y: 1
},
{
col: 10,
row: 2,
size_x: 3,
size_y: 1
},
{
col: 1,
row: 3,
size_x: 3,
size_y: 1
},
{
col: 4,
row: 3,
size_x: 3,
size_y: 1
},
{
col: 7,
row: 3,
size_x: 3,
size_y: 1
},
{
col: 10,
row: 3,
size_x: 3,
size_y: 1
}
];
});
app.directive('dashboardGrid', function () {
return {
restrict: 'A',
scope : {
panels: '=',
settings: '='
},
link: function ($scope, elem) {
var width, gridster;
elem.addClass('gridster');
elem.css({'list-style-type': 'none', width: '100%', display: 'block'});
width = elem.width();
gridster = elem.gridster({
widget_margins: [5, 5],
widget_base_dimensions: [((width - 80) / 12), 100],
min_cols: 12,
max_cols: 12,
resize: {
enabled: true,
stop: function (event, ui, widget) {
console.log(widget.height());
widget.children('.content').text('height: ' + widget.height() + ' / width: ' + widget.width());
}
}
}).data('gridster');
_.each($scope.panels, function (panel, i) {
gridster.add_widget('<li><div class="content"><h1><center>' +
i +
'</center></h1></div></li>', panel.size_x, panel.size_y, panel.col, panel.row);
});
elem.children('li.gs-w').css({
'padding' : '5px',
'border' : ($scope.settings.border || '1px solid #ddd'),
'background-color' : ($scope.settings.background || '#f4f4f4')
});
}
};
});
});

View file

@ -11,13 +11,17 @@ require.config({
elasticsearch: '../bower_components/elasticsearch/elasticsearch.angular',
jquery: '../bower_components/jquery/jquery',
lodash: '../bower_components/lodash/dist/lodash',
moment: '../bower_components/moment/moment'
moment: '../bower_components/moment/moment',
gridster: '../bower_components/gridster/dist/jquery.gridster'
},
shim: {
angular: {
deps: ['jquery'],
exports: 'angular'
},
gridster: {
deps: ['jquery']
},
'angular-route': {
deps: ['angular']
},

View file

@ -6113,5 +6113,5 @@ button.close {
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
}
body {
margin: 25px;
margin: 60px 10px;
}

View file

@ -2,5 +2,5 @@
@import "../../bower_components/bootstrap/less/theme.less";
body {
margin: 25px;
margin: 60px 10px;
}

View file

@ -1,4 +1,4 @@
// Lint and build CSS
module.exports = function (grunt) {
grunt.registerTask('default', ['jshint:source', 'test']);
grunt.registerTask('default', ['jshint:source', 'less', 'test']);
};