File sorting (client side)

This commit is contained in:
jendib 2013-07-29 01:57:18 +02:00
parent cd97382f60
commit 74132103bb
8 changed files with 2397 additions and 134 deletions

View File

@ -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>

View File

@ -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.

View File

@ -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.
*/

View 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);
}
};
}
]);

File diff suppressed because it is too large Load Diff

View File

@ -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>

View File

@ -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>

View File

@ -9,136 +9,17 @@
}
}
.touchpanview-wrap {
position:relative;
display:block;
overflow:hidden;
border:1px solid black;
.thumbnail-file {
cursor: pointer;
}
.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;
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;
}
/*.thumbnails-file li.thumbnail-container {
&:nth-child(6n+1) {
margin-left: 0;
}
}*/
@-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); }
}
.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%;
}