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>
|
||||||
<script src="lib/jquery.js" type="text/javascript"></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/less.js" type="text/javascript"></script>
|
||||||
<script src="lib/underscore.js" type="text/javascript"></script>
|
<script src="lib/underscore.js" type="text/javascript"></script>
|
||||||
<script src="lib/angular/angular.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-router.js" type="text/javascript"></script>
|
||||||
<script src="lib/angular.ui-bootstrap.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-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="lib/angular.restangular.js" type="text/javascript"></script>
|
||||||
<script src="js/app.js" type="text/javascript"></script>
|
<script src="js/app.js" type="text/javascript"></script>
|
||||||
<script src="js/controller/Main.js" type="text/javascript"></script>
|
<script src="js/controller/Main.js" type="text/javascript"></script>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
/**
|
/**
|
||||||
* Trackino application.
|
* 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.
|
* Configuring modules.
|
||||||
|
@ -7,6 +7,19 @@ App.controller('DocumentView', function($rootScope, $scope, $state, $stateParams
|
|||||||
// Load data from server
|
// Load data from server
|
||||||
$scope.document = Restangular.one('document', $stateParams.id).get();
|
$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.
|
* 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="row-fluid">
|
||||||
<div class="span4 well">
|
<div class="span4 well">
|
||||||
<p class="text-center">
|
<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>
|
||||||
<p class="input-prepend text-center input-block-level">
|
<p class="input-prepend text-center input-block-level">
|
||||||
<span class="add-on"><span class="icon-search"></span></span>
|
<span class="add-on"><span class="icon-search"></span></span>
|
||||||
|
@ -10,16 +10,20 @@
|
|||||||
|
|
||||||
<p ng-bind-html="document.description | newline"></p>
|
<p ng-bind-html="document.description | newline"></p>
|
||||||
|
|
||||||
<ul class="thumbnails" ng-show="files.length > 0">
|
<ul class="thumbnails thumbnails-file" ui-sortable="fileSortableOptions" ng-model="files" ng-show="files.length > 0">
|
||||||
<li class="span2" ng-repeat="file in files" ng-style="{ 'margin-left': $index % 6 == 0 ? '0' : '' }">
|
<li class="span2 thumbnail-container" ng-repeat="file in files">
|
||||||
<div class="thumbnail">
|
<div class="thumbnail">
|
||||||
<a ng-click="openFile(file)">
|
<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>
|
</a>
|
||||||
<div class="caption">
|
<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>
|
<button class="btn btn-danger" ng-click="deleteFile(file)"><span class="icon-trash icon-white"></span></button>
|
||||||
</p>
|
</p>
|
||||||
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@ -9,136 +9,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.thumbnail-file {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.touchpanview-wrap {
|
|
||||||
position:relative;
|
|
||||||
display:block;
|
|
||||||
overflow:hidden;
|
|
||||||
border:1px solid black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*.thumbnails-file li.thumbnail-container {
|
||||||
.touchpanview-pan {
|
&:nth-child(6n+1) {
|
||||||
position:absolute;
|
margin-left: 0;
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@-webkit-keyframes touchpanviewPinBounceIn {
|
.thumbnails-file [class*="span"]:first-child {
|
||||||
0% { opacity: 0; -webkit-transform: translateY(-2000px); }
|
margin-left: 2.5641%;
|
||||||
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;
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user