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:

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.

  • 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:

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

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

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.