##やりたいこと
下記のようなリストをドラック&ドロップで順番を入れ替えたい
- リスト1
- リスト2
- リスト3
##準備
ui-sortableライブラリを使用します。
他にもng-sortableなど似たライブラリがあったのですが、ui-sortableがシンプルだったのでこちらを使うことにしました。
https://github.com/angular-ui/ui-sortable
###インストール
bower install angular-ui-sortable --save
※ ui-sortableの他に、jQuryと、jQuery.UIも必要です。
###ライブラリを読み込む
angular.module('myApp', ['ui.sortable']);
##使い方
###最もシンプルな設定方法
入れ替えの制御をしたい要素を、scopeに入れます。
angular.module('App', ['ui.sortable'])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.items = ["いれかえたい", "とてもいれかえたい", "なんとかいれかえたい"];
}]);
入れ替えたい項目の親要素に、ui-sortable属性を設定。
scopeで入れた要素を、ng-modelに入れる。
<body ng-app="App" ng-controller="AppCtrl">
<ul ui-sortable ng-model="items">
<li ng-repeat="item in items">{{ item }}</li>
</ul>
</body>
cssでカーソルをmoveに設定すると、動かせそうな感じになります。
もしくは後述する、optionで**cursor: "move"**を設定する。
li{
cursor:move;
}
ユーザー側で入れ替えたデータは、ng-modelに反映されるので、controllerのscopeから取得できます。
##Optionを使う
###参考
http://api.jqueryui.com/sortable/
###Optionの設定方法
ui-sortable属性に追加して使用します。
<ul ui-sortable="sortableOptions" ng-model="items">
<li ng-repeat="item in items">{{ item }}</li>
</ul>
angular.module('App', ['ui.sortable'])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.items = ["いれかえたい", "とてもいれかえたい", "なんとかいれかえたい"];
$scope.sortableOptions = {
axis: 'y'
};
}]);
下記のような書き方でもいいみたいです。
<ul ui-sortable="{axis:'y'}" ng-model="items">
<li ng-repeat="item in items">{{ item }}</li>
</ul>
###各オプションの機能
####axis
移動方向を制御できる。
//横方向に固定
$scope.sortableOptions = {
axis: 'x'
};
//縦方向に固定
$scope.sortableOptions = {
axis: 'y'
};
####update
モデルデータが変更された際に実行される
angular.module('App', ['ui.sortable'])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.items = ["いれかえたい", "とてもいれかえたい", "なんとかいれかえたい"];
$scope.sortableOptions = {
update: function() {
alert('ok')
}
};
}]);
特定の要素だけ移動をキャンセルするには下記のようにupdateの引数を使って、キャンセルする。
ただ、他を入れ替えると入れ替わっちゃうので、使い方がちょっと違うのかもしれない。
angular.module('App', ['ui.sortable'])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.items = ["いれかえたい", "とてもいれかえたい", "動かさないで!!", "なんとかいれかえたい"];
$scope.sortableOptions = {
update: function(e, ui) {
if (ui.item.sortable.model === "動かさないで!!") {
ui.item.sortable.cancel();
}
}
};
}]);
####update以外のイベント
updateの他に下記のようなイベントが取得できる。
angular.module('App', ['ui.sortable'])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.items = ["いれかえたい", "とてもいれかえたい", "なんとかいれかえたい"];
$scope.sortableOptions = {
start: function(e, ui) {
console.log('start')
},
stop: function(e, ui) {
console.log('stop')
},
activate: function() {
console.log('activate')
},
deactivate: function() {
console.log('deactivate')
},
beforeStop: function() {
console.log('beforeStop')
}
};
}]);
####connectWith
connectWithを設定することで、違うmodel間での入れ替えが可能になる。
connectWithには、関連させるui-sortableのセレクタを指定する。
<body ng-app="App" ng-controller="AppCtrl">
<ul class="box" ui-sortable="sortableOptions" ng-model="items1">
<li ng-repeat="item in items1">{{ item }}</li>
</ul>
<ul class="box" ui-sortable="sortableOptions" ng-model="items2">
<li ng-repeat="item in items2">{{ item }}</li>
</ul>
</body>
angular.module('App', ['ui.sortable'])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.items1 = ["いれかえたい", "とてもいれかえたい", "なんとかいれかえたい"];
$scope.items2 = ["いいいいい", "あああああ", "ううううう"];
$scope.sortableOptions = {
connectWith: ".box"
};
}]);
####placeholder
placeholderは入れ替え位置をドラッグ中に表示することができます。
placeholderには、class名を指定することで、表示を変更できます。
angular.module('App', ['ui.sortable'])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.items1 = ["いれかえたい", "とてもいれかえたい", "なんとかいれかえたい"];
$scope.sortableOptions = {
placeholder:"placeholder"
};
}]);
.placeholder{
border:1px dotted #ccc;
height:30px;
background-color:#eee;
}
####opacity
opacityを設定することで、ドラック中の要素の透明度を調整できます。
angular.module('App', ['ui.sortable'])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.items1 = ["いれかえたい", "とてもいれかえたい", "なんとかいれかえたい"];
$scope.sortableOptions = {
opacity:0.5
};
}]);
####disabled
disabledを設定することで、要素の活性非活性を制御できます。
他にもたくさんオプションがあるので、こちらをみていただくと参考になると思います。