mirror of
https://github.com/sismics/docs.git
synced 2024-11-22 14:07:55 +01:00
File sorting (client side)
This commit is contained in:
parent
cd97382f60
commit
74132103bb
@ -15,6 +15,7 @@
|
||||
};
|
||||
</script>
|
||||
<script src="lib/jquery.js" type="text/javascript"></script>
|
||||
<script src="lib/jquery.ui.js" type="text/javascript"></script>
|
||||
<script src="lib/less.js" type="text/javascript"></script>
|
||||
<script src="lib/underscore.js" type="text/javascript"></script>
|
||||
<script src="lib/angular/angular.js" type="text/javascript"></script>
|
||||
@ -22,6 +23,7 @@
|
||||
<script src="lib/angular.ui-router.js" type="text/javascript"></script>
|
||||
<script src="lib/angular.ui-bootstrap.js" type="text/javascript"></script>
|
||||
<script src="lib/angular.ui-utils.js" type="text/javascript"></script>
|
||||
<script src="lib/angular.ui-sortable.js" type="text/javascript"></script>
|
||||
<script src="lib/angular.restangular.js" type="text/javascript"></script>
|
||||
<script src="js/app.js" type="text/javascript"></script>
|
||||
<script src="js/controller/Main.js" type="text/javascript"></script>
|
||||
|
@ -3,7 +3,7 @@
|
||||
/**
|
||||
* Trackino application.
|
||||
*/
|
||||
var App = angular.module('docs', ['ui.state', 'ui.bootstrap', 'ui.keypress', 'restangular', 'ngSanitize'])
|
||||
var App = angular.module('docs', ['ui.state', 'ui.bootstrap', 'ui.keypress', 'ui.sortable', 'restangular', 'ngSanitize'])
|
||||
|
||||
/**
|
||||
* Configuring modules.
|
||||
|
@ -7,6 +7,19 @@ App.controller('DocumentView', function($rootScope, $scope, $state, $stateParams
|
||||
// Load data from server
|
||||
$scope.document = Restangular.one('document', $stateParams.id).get();
|
||||
|
||||
/**
|
||||
* Configuration for file sorting.
|
||||
*/
|
||||
$scope.fileSortableOptions = {
|
||||
forceHelperSize: true,
|
||||
forcePlaceholderSize: true,
|
||||
tolerance: 'pointer',
|
||||
handle: '.handle',
|
||||
update: function(event, ui) {
|
||||
// TODO Send new positions to server
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Load files from server.
|
||||
*/
|
||||
|
111
docs-web/src/main/webapp/lib/angular.ui-sortable.js
Normal file
111
docs-web/src/main/webapp/lib/angular.ui-sortable.js
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
jQuery UI Sortable plugin wrapper
|
||||
|
||||
@param [ui-sortable] {object} Options to pass to $.fn.sortable() merged onto ui.config
|
||||
*/
|
||||
angular.module('ui.sortable', [])
|
||||
.value('uiSortableConfig',{})
|
||||
.directive('uiSortable', [ 'uiSortableConfig',
|
||||
function(uiSortableConfig) {
|
||||
return {
|
||||
require: '?ngModel',
|
||||
link: function(scope, element, attrs, ngModel) {
|
||||
|
||||
function combineCallbacks(first,second){
|
||||
if( second && (typeof second === "function") ){
|
||||
return function(e,ui){
|
||||
first(e,ui);
|
||||
second(e,ui);
|
||||
};
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
var opts = {};
|
||||
|
||||
var callbacks = {
|
||||
receive: null,
|
||||
remove:null,
|
||||
start:null,
|
||||
stop:null,
|
||||
update:null
|
||||
};
|
||||
|
||||
angular.extend(opts, uiSortableConfig);
|
||||
|
||||
if (ngModel) {
|
||||
|
||||
ngModel.$render = function() {
|
||||
element.sortable( "refresh" );
|
||||
};
|
||||
|
||||
callbacks.start = function(e, ui) {
|
||||
// Save position of dragged item
|
||||
ui.item.sortable = { index: ui.item.index() };
|
||||
};
|
||||
|
||||
callbacks.update = function(e, ui) {
|
||||
// For some reason the reference to ngModel in stop() is wrong
|
||||
ui.item.sortable.resort = ngModel;
|
||||
};
|
||||
|
||||
callbacks.receive = function(e, ui) {
|
||||
ui.item.sortable.relocate = true;
|
||||
// added item to array into correct position and set up flag
|
||||
ngModel.$modelValue.splice(ui.item.index(), 0, ui.item.sortable.moved);
|
||||
};
|
||||
|
||||
callbacks.remove = function(e, ui) {
|
||||
// copy data into item
|
||||
if (ngModel.$modelValue.length === 1) {
|
||||
ui.item.sortable.moved = ngModel.$modelValue.splice(0, 1)[0];
|
||||
} else {
|
||||
ui.item.sortable.moved = ngModel.$modelValue.splice(ui.item.sortable.index, 1)[0];
|
||||
}
|
||||
};
|
||||
|
||||
callbacks.stop = function(e, ui) {
|
||||
// digest all prepared changes
|
||||
if (ui.item.sortable.resort && !ui.item.sortable.relocate) {
|
||||
|
||||
// Fetch saved and current position of dropped element
|
||||
var end, start;
|
||||
start = ui.item.sortable.index;
|
||||
end = ui.item.index();
|
||||
|
||||
// Reorder array and apply change to scope
|
||||
ui.item.sortable.resort.$modelValue.splice(end, 0, ui.item.sortable.resort.$modelValue.splice(start, 1)[0]);
|
||||
|
||||
}
|
||||
if (ui.item.sortable.resort || ui.item.sortable.relocate) {
|
||||
scope.$apply();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
scope.$watch(attrs.uiSortable, function(newVal, oldVal){
|
||||
angular.forEach(newVal, function(value, key){
|
||||
|
||||
if( callbacks[key] ){
|
||||
// wrap the callback
|
||||
value = combineCallbacks( callbacks[key], value );
|
||||
}
|
||||
|
||||
element.sortable('option', key, value);
|
||||
});
|
||||
}, true);
|
||||
|
||||
angular.forEach(callbacks, function(value, key ){
|
||||
|
||||
opts[key] = combineCallbacks(value, opts[key]);
|
||||
});
|
||||
|
||||
// Create sortable
|
||||
|
||||
element.sortable(opts);
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
2252
docs-web/src/main/webapp/lib/jquery.ui.js
Normal file
2252
docs-web/src/main/webapp/lib/jquery.ui.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
<div class="row-fluid">
|
||||
<div class="span4 well">
|
||||
<p class="text-center">
|
||||
<button class="btn btn-primary" type="button" ng-click="addDocument()">Add a document</button>
|
||||
<button class="btn btn-primary" type="button" ng-click="addDocument()"><span class="icon-plus icon-white"></span> Add a document</button>
|
||||
</p>
|
||||
<p class="input-prepend text-center input-block-level">
|
||||
<span class="add-on"><span class="icon-search"></span></span>
|
||||
|
@ -10,16 +10,20 @@
|
||||
|
||||
<p ng-bind-html="document.description | newline"></p>
|
||||
|
||||
<ul class="thumbnails" ng-show="files.length > 0">
|
||||
<li class="span2" ng-repeat="file in files" ng-style="{ 'margin-left': $index % 6 == 0 ? '0' : '' }">
|
||||
<ul class="thumbnails thumbnails-file" ui-sortable="fileSortableOptions" ng-model="files" ng-show="files.length > 0">
|
||||
<li class="span2 thumbnail-container" ng-repeat="file in files">
|
||||
<div class="thumbnail">
|
||||
<a ng-click="openFile(file)">
|
||||
<img ng-src="api/file/{{ file.id }}/data?thumbnail=true" tooltip="{{ file.mimetype }}" tooltip-placement="top" />
|
||||
<img class="thumbnail-file" ng-src="api/file/{{ file.id }}/data?thumbnail=true" tooltip="{{ file.mimetype }}" tooltip-placement="top" />
|
||||
</a>
|
||||
<div class="caption">
|
||||
<p class="text-right">
|
||||
<div class="pull-left">
|
||||
<div class="btn handle"><span class="icon-resize-horizontal"></span></div>
|
||||
</div>
|
||||
<p class="pull-right">
|
||||
<button class="btn btn-danger" ng-click="deleteFile(file)"><span class="icon-trash icon-white"></span></button>
|
||||
</p>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -9,136 +9,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.touchpanview-wrap {
|
||||
position:relative;
|
||||
display:block;
|
||||
overflow:hidden;
|
||||
border:1px solid black;
|
||||
}
|
||||
|
||||
|
||||
.touchpanview-pan {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
display:block;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.touchpanview-pan img {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.touchpanview-pin {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
|
||||
display:block;
|
||||
width: 36px;
|
||||
height:36px;
|
||||
|
||||
background: url(touchpanview-pin.png) no-repeat;
|
||||
text-indent: -99999px;
|
||||
|
||||
.thumbnail-file {
|
||||
cursor: pointer;
|
||||
|
||||
-webkit-animation-fill-mode: both;
|
||||
-moz-animation-fill-mode: both;
|
||||
-ms-animation-fill-mode: both;
|
||||
-o-animation-fill-mode: both;
|
||||
animation-fill-mode: both;
|
||||
-webkit-animation: 1s ease;
|
||||
-moz-animation: 1s ease;
|
||||
-ms-animation: 1s ease;
|
||||
-o-animation: 1s ease;
|
||||
animation: 1s ease;
|
||||
|
||||
-webkit-animation-name: touchpanviewPinBounceIn;
|
||||
-moz-animation-name: touchpanviewPinBounceIn;
|
||||
-ms-animation-name: touchpanviewPinBounceIn;
|
||||
-o-animation-name: touchpanviewPinBounceIn;
|
||||
animation-name: touchpanviewPinBounceIn;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@-webkit-keyframes touchpanviewPinBounceIn {
|
||||
0% { opacity: 0; -webkit-transform: translateY(-2000px); }
|
||||
60% { opacity: 1; -webkit-transform: translateY(30px); }
|
||||
80% { -webkit-transform: translateY(-10px); }
|
||||
100% { -webkit-transform: translateY(0); }
|
||||
}
|
||||
|
||||
@-moz-keyframes touchpanviewPinBounceIn {
|
||||
0% { opacity: 0; -moz-transform: translateY(-2000px); }
|
||||
60% { opacity: 1; -moz-transform: translateY(30px); }
|
||||
80% { -moz-transform: translateY(-10px); }
|
||||
100% { -moz-transform: translateY(0); }
|
||||
}
|
||||
|
||||
@-ms-keyframes touchpanviewPinBounceIn {
|
||||
0% { opacity: 0; -ms-transform: translateY(-2000px); }
|
||||
60% { opacity: 1; -ms-transform: translateY(30px); }
|
||||
80% { -ms-transform: translateY(-10px); }
|
||||
100% { -ms-transform: translateY(0); }
|
||||
}
|
||||
|
||||
@-o-keyframes touchpanviewPinBounceIn {
|
||||
0% { opacity: 0; -o-transform: translateY(-2000px); }
|
||||
60% { opacity: 1; -o-transform: translateY(30px); }
|
||||
80% { -o-transform: translateY(-10px); }
|
||||
100% { -o-transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes touchpanviewPinBounceIn {
|
||||
0% { opacity: 0; transform: translateY(-2000px); }
|
||||
60% { opacity: 1; transform: translateY(30px); }
|
||||
80% { transform: translateY(-10px); }
|
||||
100% { transform: translateY(0); }
|
||||
/*.thumbnails-file li.thumbnail-container {
|
||||
&:nth-child(6n+1) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
.touchpanview-pin-center { border:1px solid red; }
|
||||
.touchpanview-pin-topLeft {
|
||||
border-top:1px solid red;
|
||||
border-left:1px solid red;
|
||||
}
|
||||
.touchpanview-pin-topRight {
|
||||
border-top:1px solid red;
|
||||
border-right:1px solid red;
|
||||
}
|
||||
.touchpanview-pin-bottomLeft {
|
||||
border-bottom:1px solid red;
|
||||
border-left:1px solid red;
|
||||
}
|
||||
.touchpanview-pin-bottomRight {
|
||||
border-bottom:1px solid red;
|
||||
border-right:1px solid red;
|
||||
.thumbnails-file [class*="span"]:first-child {
|
||||
margin-left: 2.5641%;
|
||||
}
|
Loading…
Reference in New Issue
Block a user