Posts

....
Technical Blog for .NET Developers ©

Showing posts with label HTML5. Show all posts
Showing posts with label HTML5. Show all posts

Sunday, March 4, 2018

HTML5 Drag and Drop

HTML5 API includes Drag and Drop (DnD) native functionality

The event listener methods for all the drag and drop events accept Event object which has a readonly attribute called dataTransfer. The event.dataTransfer returns DataTransfer object associated with the event

This is the list of events fired during the different stages

Event Description
dragstart Fires when the user starts dragging of the object.
dragenter Fired when the mouse is first moved over the target element while a drag is occuring. A listener for this event should indicate whether a drop is allowed over this location. If there are no listeners, or the listeners perform no operations, then a drop is not allowed by default.
dragover This event is fired as the mouse is moved over an element when a drag is occuring. Much of the time, the operation that occurs during a listener will be the same as the dragenter event.
dragleave This event is fired when the mouse leaves an element while a drag is occuring. Listeners should remove any highlighting or insertion markers used for drop feedback.
drag Fires every time the mouse is moved while the object is being dragged.
drop The drop event is fired on the element where the drop was occured at the end of the drag operation. A listener would be responsible for retrieving the data being dragged and inserting it at the drop location.
dragend Fires when the user releases the mouse button while dragging an object.



In this post we develop an application to handle the drag and drop events between two elements, and launch a HttpPost method in the server which will ends inserting the dragged value in database

The first step is the definition of the UXinterface, in sequence the display is this



We are adding h5utils.js file, with an implementation of AddEvent function to simplify our code


var AddEvent = (function () {
    if (document.addEventListener) {
        return function (el, type, fn) {
            if (el && el.nodeName || el === window) {
                el.addEventListener(type, fn, false);
            } else if (el && el.length) {
                for (var i = 0; i < el.length; i++) {
                    AddEvent(el[i], type, fn);
                }
            }
        };
    } else {
        return function (el, type, fn) {
            if (el && el.nodeName || el === window) {
                el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
            } else if (el && el.length) {
                for (var i = 0; i < el.length; i++) {
                    AddEvent(el[i], type, fn);
                }
            }
        };
    }
})();



Now the code to implement drag and drop events


    var pDragElement = document.createElement('p');

    var chemicalElements = document.querySelectorAll('div > p'), el = null;
    for (var i = 0; i < chemicalElements.length; i++) {

        el = chemicalElements[i];

        el.setAttribute('draggable', 'true');

        AddEvent(el, 'dragstart', dragStartElement);
        
        AddEvent(el, 'dragend', dragEndElement);        
    }

    function dragStartElement(e) {

        e.dataTransfer.effectAllowed = 'copy';
        e.dataTransfer.setData('Text', this.id);
        e.dataTransfer.setData('Type', this.innerHTML);
        
        this.style.backgroundColor = "#ffa31a";
    }
    
    function dragEndElement(e) {
        
        this.style.backgroundColor = "#fff9f0";
    }
    
    var divBoxElements = document.querySelector('#divBoxElements');

    AddEvent(divBoxElements, 'dragover', function (e) {

        if (e.preventDefault) e.preventDefault();
        e.dataTransfer.dropEffect = 'copy';
        return false;
    });

    AddEvent(divBoxElements, 'drop', function (e) {

        if (e.stopPropagation) e.stopPropagation();

        var element = e.dataTransfer.getData('Type');

        pDragElement.innerHTML = "Adding " + element + " element";

        var pClone = pDragElement.cloneNode(true);

        var newDiv = document.createElement("div");

        newDiv.appendChild(pClone);

        divBoxElements.appendChild(newDiv);

        InsertChemicalElement(element);

        return false;
    });



The function InsertChemicalElement will call the HttpPost server method


    function InsertChemicalElement(element) {
        
        var url = '@Url.Action("InsertChemicalElements", "Home")';

        $.post(url, { chemicalElement: element },
            
        function (data) {

            switch (data) {
                case 1:                    
                    divBoxElements.innerHTML = element + " inserted OK";
                    setTimeout(function() { divBoxElements.innerHTML = ""; }, 2000);
                    break;
                    
                default:
                    alert("Error inserting the element");
            }
        });
    }



The code in the server side makes use of EF, with one table and one stored procedure in the diagram



With a SOLID implementation, the code for inserting data is divided in two functions


    [HttpPost]
    public JsonResult InsertChemicalElements(string chemicalElement)
    {
        string[] elementData = chemicalElement.Split(':');

        string symbol = elementData[0].Trim();
        string name = elementData[1].Trim();

        int insertResult = _chemicalDatabase.InsertElement(symbol, name);

        return Json(insertResult);
    }


//////////


    public class ChemicalDatabase : IChemicalDatabase
    {
        public int InsertElement(string symbol, string name)
        {
            using (ChemicalsEntities entities = new ChemicalsEntities())
            {
                return entities.P_INSERT_ELEMENT(symbol, name);
            }
        }
    }


Thursday, February 4, 2016

HTML5 API Indexed Database

API Indexed Database is the officially supported by W3C way for the creation of databases with HTML5

This system takes the concept of key/value pairs to store data. the Database can contain Stores, the equivalent to the SQL tables, and each Object Store contains key/value pairs; this API is not a relational database, but object oriented. you can query this database inline as offline

The first step in this example will be creating a new database, for this we use the open() method, the syntax is as follows:
 
    indexedDB.open("database_name", version)    
    
    
If the database does not exist, it is created, else, it is open. The call to the open() function returns an IDBOpenDBRequest object with a result (success) or error value that you handle as an event

In this example we build the next web form, and implement a Web Method in the server side which returns an array of json objects for loading the database



The js code to open the database and create the object store is the next


    var HTML5DB = {};
    HTML5DB.indexedDB = {};
    HTML5DB.indexedDB.db = null;

    window.indexedDB = window.indexedDB || window.mozIndexedDB || 
                       window.webkitIndexedDB || window.msIndexedDB;
    window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || 
                            window.msIDBTransaction;
    window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || 
                         window.msIDBKeyRange;

    HTML5DB.indexedDB.onerror = function (e) { console.log(e); };

    HTML5DB.indexedDB.open = function () {

        var version = 1;
        var request = window.indexedDB.open("db_example", version);

        request.onupgradeneeded = function (e) {

            var db = e.target.result;
            e.target.transaction.onerror = HTML5DB.indexedDB.onerror;
            var store = db.createObjectStore("object_store", 
                { keyPath: "id", autoIncrement: true });
        };

        request.onsuccess = function (e) {
            HTML5DB.indexedDB.db = e.target.result;
            HTML5DB.indexedDB.getAllRecords();
        };

        request.onerror = HTML5DB.indexedDB.onerror;
    };
        


The code to add and delete records is the next:

Since the id has been declared autoIncrement, we are inserting a record initializing two fields in the value property (value, and timeStamp)


    HTML5DB.indexedDB.addRecord = function (value) {

        var db = HTML5DB.indexedDB.db;
        var trans = db.transaction(["object_store"], "readwrite");
        var store = trans.objectStore("object_store");

        var data = {
            "value": value,
            "timeStamp": new Date($.now()).toLocaleTimeString()
        };

        var request = store.put(data);

        request.onsuccess = function (e) {
            HTML5DB.indexedDB.getAllRecords();
        };

        request.onerror = function (e) {
            console.log("Error Adding: ", e);
        };
    };

    HTML5DB.indexedDB.deleteRecord = function(id) {
      var db = HTML5DB.indexedDB.db;
      var trans = db.transaction(["object_store"], "readwrite");
      var store = trans.objectStore("object_store");

      var request = store.delete(id);

      request.onsuccess = function(e) {
        HTML5DB.indexedDB.getAllRecords();
      };

      request.onerror = function(e) {
        console.log("Error deleting: ", e);
      };
    };
        


The next is the code to retrieve and render records from the database:


    HTML5DB.indexedDB.getAllRecords = function() {

      $('#dbRecords tr').remove();

      var db = HTML5DB.indexedDB.db;
      var trans = db.transaction(["object_store"], "readwrite");
      var store = trans.objectStore("object_store");

      var keyRange = IDBKeyRange.lowerBound(0);
      var cursorRequest = store.openCursor(keyRange);

      cursorRequest.onsuccess = function(e) {
        var result = e.target.result;
        if(!!result == false)
          return;

        renderRecord(result.value);
        result.continue();
      };

      cursorRequest.onerror = HTML5DB.indexedDB.onerror;
    };

    function renderRecord(record) {

        $("#dbRecords").find('tbody')
            .append($('<tr>')
                .append($('<td>')
                    .append($('<span>')
                        .html(record.value)
                    )
                )
                .append($('<td>')
                    .append($('<span>')
                        .html(record.timeStamp)
                    )
                )
                .append($('<td>')
                    .append($('<a>')
                        .attr('href', 
                              'javascript:HTML5DB.indexedDB.deleteRecord(' + record.id + ')')
                        .html('Delete')
                )
            ));
    }
        


Here is the result of this code in the client side:



Finally we have implemented this call to the server to retrieve a collection of json objects and preload the database:

 
    function getData() {

        $.ajax({
            url: "application.aspx/getData",
            type: "POST",
            data: {},
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (json) {

                var records = json.d.Data.records;

                for (var i = 0; i < records.length; i++) {

                    HTML5DB.indexedDB.addRecord(records[i].Data.value);
                }
            },
            error: function (e) {
                alert('ERROR: ' + e.status + ' : ' + e.statusText);
            }
        });
    }
        


    
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public static JsonResult getData()
    {
        List<JsonResult> recordSet = new List<JsonResult>();

        for (int i = 0; i < 10; i++)
        {
            Record rec = new Record();
            rec.value = "record " + i.ToString();
            recordSet.Add(new JsonResult() { Data = rec });
        }

        JsonResult result = new JsonResult();
        result.Data = new Result() { records = recordSet };
        return result;
    }

    private class Result
    {
        public List<JsonResult> records;
    }

    private class Record
    {
        public string value;
    }
        





<METHOD SOFTWARE © 2014>

Saturday, July 20, 2013

Adding HTML5 Intellisense

When we develop web applications with HTML5 API, we can add HTML5 Intellisense, here is the link to download the installer for Visual Studio and Visual Web Developer 2010 and 2008

HTML 5 Intellisense for Visual Studio 2010 and 2008

We just have to install and the option for HTML5 validation code will appear automatically in our tool bar

Now we will see how the Intellisense displays with HTML5 tags




<METHOD SOFTWARE © 2013>