Introduction
In the previous article, I have shown you how to implement Treeview in AngularJS application. In this article I will show you reordering list via drag & drop in AngularJS.
In one of my recent AngularJS project that I have just completed, required that the user be able to reorder the list of data via drag & drop feature and the current order of the list shall be persisted on the database.
Today I will show you how to implement reordering list via drag & drop in AngularJS application.
Here in this AngularJS application, I have used "angular-drag-and-drop-lists" AngularJS directive that allows us to build sortable lists with the native HTML5 drag & drop API.
Follow the following steps in order to implement "Reordering list via drag & drop in AngularJS application".
Step - 1: Create New Project.
It will bring up a new dialog window for select template > here I will select empty template > and the checked MVC checkbox from Add folder and core references for > and then click on ok button.
Step-2: Add a Database.
Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add.
Step-3: Create a table in our database.
You can see here in this below image, I have added a column Order in our database table. This field is for ordering my tasks as the priority.
double click on the database under app_data folder for open the database in server explorer > expand the database and Right click on Tables node > click on Add New Table > here we will write schema of the table for the table we want to create > now click on Update button for create the table and then again click on Update Database button.
Step-4: Add Entity Data Model.
A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.
Step-5: Add required resource files into our project for "angular-drag-and-drop-lists" directive.
1."angular-drag-and-drop-lists.js" file
2."simple.css" file
Step-6: Add a javascript file, where we will write AngularJS code for creating an angular module and an angular controller.
In our application, I will add a javascript file into Scripts folder.
Go to solution explorer > Right click on "Scripts" folder > Add > new Item > Select Javascrip file under Scripts > Enter file name (here in my application it is "myApp.js") > and then click on Add button.
var app = angular.module('myApp', ['dndLists']);
app.controller('myController', ['$http', function ($http) {
var vm = this;
vm.Tasks = [];
vm.IsProcessing = false;
//Getting data from database
vm.LoadTask = function () {
vm.IsProcessing = true;
$http.get('/home/GetTasks').then(function (response) {
vm.Tasks = response.data;
}).finally(function () {
vm.IsProcessing = false;
})
}
vm.LoadTask();
//Update Tasks order
vm.Sorting = function (index) {
vm.IsProcessing = true;
vm.Tasks.splice(index, 1);
var newData = [];
angular.forEach(vm.Tasks, function (val, index) {
val.Order = index + 1;
newData.push(val);
})
//
$http.post('/home/SaveTaskOrder', newData).then(function (response) {
//you can write more code here after save new order
}).finally(function () {
vm.IsProcessing = false;
})
}
}])
Step-7: Create an MVC Controller.
Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name > Select Templete "empty MVC Controller"> Add.
Here I have created a controller named "HomeController"
Step-8: Add an MVC action into HomeController for fetch data from the database and return as JSON result.
public JsonResult GetTasks()
{
var tasks = new List<MyTask>();
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
tasks = dc.MyTasks.OrderBy(a => a.Order).ToList();
}
return new JsonResult { Data = tasks, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
Step-9: Add an another MVC action into HomeController for update my tasks data with a new order to the database.
public JsonResult SaveTaskOrder(List<MyTask> tasks)
{
bool status = false;
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
try
{
foreach (var i in tasks)
{
dc.MyTasks.Attach(i);
dc.Entry(i).State = System.Data.Entity.EntityState.Modified;
}
dc.SaveChanges();
status = true;
}
catch (Exception)
{
}
}
return new JsonResult { Data = new { status = status } };
}
Step-10: Add view for that(here Index action) action.
Now we will add a view for that Index action.
HTML Code
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div ng-app="myApp">
<div ng-controller="myController as vm" class="simpleDemo">
<h2> My Tasks</h2>
<div class="loader" ng-show="vm.IsProcessing">
Please Wait...
</div>
<ul dnd-list="vm.Tasks">
<li ng-repeat="item in vm.Tasks"
dnd-list-id="{{item.TaskID}}"
dnd-draggable="item"
dnd-moved="vm.Sorting($index)"
dnd-effect-allowed="move"
dnd-selected="models.selected = item"
ng-class="{'selected': models.selected === item}">
{{item.TaskDescription}}
</li>
</ul>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<script src="~/Scripts/angular-drag-and-drop-lists.js"></script>
<script src="~/Scripts/myApp.js"></script>
<link href="~/Content/simple.css" rel="stylesheet" />
<style>
.loader
{
position:absolute;
z-index:9;
background:yellow;
border:1px solid red;
padding:10px;
top:50%;
left:20%;
}
.simpleDemo {
position:relative;
}
.simpleDemo ul[dnd-list] li{
cursor:move;
}
</style>