DotNetCurry Logo

Drag Drop Elements in ASP.NET MVC 5 using HTML 5, Web API and jQuery

Posted by: Mahesh Sabnis , on 9/9/2014, in Category ASP.NET MVC
Views: 59057
Abstract: HTML 5 can be used in ASP.NET MVC 5 applications to create some rich user experiences. This article shows how to use HTML 5 Native support for Drag-Drop in an ASP.NET MVC application. We also use Web API to pull data and jQuery to make Ajax calls.

Providing rich web UI experiences like Charts, Editable tabular interface, offline capabilities, dragging-dropping data on the page etc. can be a challenging task. To implement these features, a developer must plan the application based upon different browsers capabilities. A couple of years ago, this was achievable with a lot of efforts using some complex JavaScript code.

As the web progressed, modern browsers has made it possible to take web development to the next level. To complement, there are several libraries like jQuery, Angular, DOJO, etc. that can provide new UI rich features to enhance your applications. But wouldn’t it be nicer if the HTML itself provides some of these cool features using markup?

HTML5 has been developed with the current and future browser development in mind. Apart from being backward compatible, HTML5 contains many new elements and APIs for adding Rich UX capabilities to the application. Drag-Drop is one such useful feature available in HTML5 that can be used for data management on the page.

 

In HTML 5, an element can be made draggable using draggable=true in the markup. To monitor the process of drag-drop, we need to make use of the following events: dragstart, drag, dragenter, dragleave, dragover, drop, dragend.

The process of implementation has the following elements:

  • The source element applied with attribute draggable=true.
  • The data payload which means the data to be dragged and dropped.
  • The target where the drop is made.


 

Drag-Drop in ASP.NET MVC 5 using HTML 5, Web API and jQuery

To implement the Drag-Drop application, we will be using the following technologies:

  • ASP.NET MVC 5
  • WEB API with Attribute Routing
  • jQuery

Step 1: Open Visual Studio 2013 (the application uses Ultimate with Update 3), and create an Empty MVC application.

Step 2: In the App_Data folder of the application add a new SQL Server database with the name ‘Application.mdf’ as below:

app-mdf

In this database, add a new table called ‘Products’ using the following script:

CREATE TABLE [dbo].[Products] (
    [ProductId]   INT          IDENTITY (1, 1) NOT NULL,
    [ProductName] VARCHAR (50) NOT NULL,
    [Quantity]    INT          NOT NULL,
    PRIMARY KEY CLUSTERED ([ProductId] ASC)
);

The above table will contain products which we will fetch in our View.

Step 3: In the Models folder, add a new EntityFramework with the name ApplicationEDMX. In the wizard that comes up, select the Application.mdf database and the Products table designed in the above step. After completing the wizard, the following table mapping gets displayed.

products-table

Step 4: In the controllers folder, add a new Empty WEB API Controller with the name ProductsAPIController. In this API controller add the following code:

using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using A1_HTML5_DragDrop.Models;
 
namespace A1_HTML5_DragDrop.Controllers
{
    public class ProductsAPIController : ApiController
    {
        ApplicationEntities ctx;

        public ProductsAPIController()
        {
            ctx = new ApplicationEntities(); 
        }

        [Route("Products")]
        public IEnumerable<Product> GetProducts()
        {
            return ctx.Products.ToList();
        }
    }
}

The above code declares an object of ApplicationEntities, which got generated using EntityFramework. The GetProducts() returns a list of products. This method is applied with an Attribute Route ‘[Route(“Products”)]’ which will provide the URL to make call to this method using client-side framework (e.g. ajax method). You can read more on Attribute routing in my other article Practical Use of ASP.NET Web API Attribute Routing in an MVC application.

Step 5: In the controllers folder, add a new Empty MVC controller of the name ProductController. This controller class will generate an Index method. Scaffold a new Empty view from the Index method.

Step 6: Add the following markup in the Index view:

<table>
    <tr>
        <td>
            <h1>Product List</h1>
        </td>
        <td>
            <h1>Selected Products</h1>
        </td>
    </tr>
    <tr>
        <td>
            <div id="dvleft">
                <ul id="lstproducts">
                </ul>
            </div> 
        </td>
        <td>
            <div id="dvright">
                <ul id="lstselectedproducts"></ul>
            </div>
        </td>
    </tr>
</table>

The above markup has a table with two rows. The first row shows headers for Product List and selected products. The second row contains <div>s containing list in it. The ‘lstproducts’ list will show the Products retrieved from the server. The ‘lstselectedproducts’ will show selected products by the end-user using Drag-Drop.

Add the following styles in the View (better to use a separate stylesheet but I will keep it here for readability):

<style type="text/css">
    table, td {
        background-color:azure;
     border:double;
    }
    #dvright,#dvleft {
        background-color:azure;
       height:200px;
       width:300px;
    }
</style>

Step 7: In the page add the following Script:

<script type="text/javascript">
    $(document).ready(function () {

        loadProducts();

        //Function to set events for Drag-Drop
        function setEvents() {
            var lstProducts = $('li');
            //Set Drag on Each 'li' in the list 
                $.each(lstProducts, function (idx, val) {
                    $('li').on('dragstart', function (evt) {
                        evt.originalEvent.dataTransfer.setData("Text", evt.target.textContent);
                        evt.target.draggable = false;
                    });
                });
              
            //Set the Drop on the <div>
                $("#dvright").on('drop', function (evt) {
                    evt.preventDefault();
                    var data = evt.originalEvent.dataTransfer.getData("Text");
                    var lst = $("#lstselectedproducts");
                    var li = "<li>"+data+"</li>";
                    li.textContent = data;
                    lst.append(li);
                });

            //The dragover
                $("#dvright").on('dragover', function (evt) {
                    evt.preventDefault();
                });
        }

        ///Function to load products using call to WEB API
        function loadProducts() {
            var items="";
            $.ajax({
                url: "/Products",
                type: "GET"
            }).done(function (resp) {
                $.each(resp, function (idx, val) {
                    items += "<li draggable='true'>" + val.ProductName + "</li>";
                });
                $("#lstproducts").html(items);
                setEvents();
            }).error(function (err) {
                alert("Error! " + err.status);
            });
        }
    });
</script>

The script has the following specifications:

- The function ‘loadProducts()’ makes an ajax call to WEB API. When the call is successful, the iteration is done through the response. This iteration adds the <li> tag in the ‘lstproducts’ list with the draggable attribute set to true.

- The function ‘setEvents()’ performs the following two step operations:

  • subscribe to the ‘dragstart’ event for each <li> and set the data transfer with the ‘Text’ property. This is the text content of the <li> selected. Once any <li> is dragged, the drag on the same is disabled using evt.target.draggable =false; statement.
  • The <div> of id ‘dvright’ is subscribed to ‘drop’ event, it accepts the dragged Text. Once the text is accepted, it is set to the <li> which is dynamically appended in the list with id as ‘lstselectedproducts’.

Step 8: Run the application, the Products data gets loaded:

aspmvc-dragdrop

Drag the Product from the ‘Product List’ and drop it in the ‘Selected Products’ as seen here:

html5-dragdrop

The above Red Mark shows the Drag Action. Once the drop operation is over the result will be as seen here:

aspmvc-html5-dragdrop

Conclusion:

The HTML 5 Native support for Drag-Drop provides an easy mechanism of handling Data as well as UI operations. Since the support is native to HTML 5, no additional library is required.

Download the entire source code of this article (Github)

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Mahesh Sabnis is a DotNetCurry author and Microsoft MVP having over 17 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). Follow him on twitter @maheshdotnet


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by meh on Tuesday, September 9, 2014 6:05 AM
Don't forget to add GlobalConfiguration.Configure(WebApiConfig.Register); in Global is you get 404 for the API call
Comment posted by MAhesh Sabnis on Wednesday, November 12, 2014 3:22 AM
Hi meh,

Since the MVC project template is selected in VS2013 with checkboxes for MVC and WEB API, the GlobalConfiguration.Configure(WebApiConfig.Register); line is already added in global.asax.
Regards
MAhesh Sabnis
Comment posted by Hmm on Friday, January 9, 2015 5:27 PM
Although this is a good article it does not go deep enough. You do not show how to update the controller/database once an item is dropped. This is a bit of a let down and falls into the many sites that already show how to add the functionality of drag drop to a page but not how to sync the drop with the back end easily.
Thus, I will still need to find a good way to do that which I bet most people will want to know.