$.ajax No 'Access-Control-Allow-Origin' header is present on the requested resource with WebAPI

I want to get data from a WebAPI with jquery

        $("#btnSend").click(function () {
            $("#sending").show();
            $.ajax({
                type: 'GET',
                url: '/Report/SendEmail?quote=18',
                crossDomain: true,
                success: function (msg) {
                    if (msg == 'True') {
                        alert('Email sent to the client');
                    }
                    $("#sending").hide();
                },
                error: function (request, status, error) {
                    $("#sending").hide();
                }
            });
        });

and it produce

‘No Access-Control-Allow-Origin' header is present on the requested resource error.

The solution is to add in the result of the WebAPI the following code:

            Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST");
            Response.Headers.Add("Access-Control-Allow-Headers", "accept, authority");
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");

Happy coding!

C# and HTML5: drag and Drop elements

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.

First of all we create an MVC project in C#. Under Controller folder in the HomeController we add this code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace HTML5DragAndDrop.Controllers {
   public class HomeController : Controller {
      ITestDatabase _testDatabase = new TestDatabase();

      public ActionResult Index() {
         return View();
      }

      public ActionResult About() {
         ViewBag.Message = "Your application description page.";

         return View();
      }

      public ActionResult Contact() {
         ViewBag.Message = "Your contact page.";

         return View();
      }

      [HttpPost]
      public JsonResult InsertTestElements(string testElement) {
         int? insertResult = null;

         if (!string.IsNullOrEmpty(testElement)) {
            string[] elementData = testElement.Split(':');

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

            insertResult = _testDatabase.InsertElement(symbol, name);
         }

         return Json(insertResult);
      }
   }
}

Now we create a folder in the root of the project called Code. Under this folder we create two new files:

ITestDatabase.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public interface ITestDatabase {
   int InsertElement(string symbol, string name);
}   
 

TestDatabase.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

public class TestDatabase : ITestDatabase {
   /// <summary>
   /// Save an element in the database and return the new ID
   /// </summary>
   /// <param name="symbol"></param>
   /// <param name="name"></param>
   /// <returns></returns>
   public int InsertElement(string symbol, string name) {
      // save the element in database
      // now it returns just a number: it will be the Id of the record
      return 1;
   }
}

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

DragAndDrop_App

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

h5utils.js

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);
            }
         }
      };
   }
})();

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);
   InsertTestElement(element);

   return false;
});

In the Index.cshtml we change as following code:

Index.cshtml

@{
   ViewBag.Title = "Home Page";
}

<div class="jumbotron">
    <h1>Drag and drop example</h1>
    <p class="lead">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.</p>
    <p><a href="http://puresourcecode.com" 
    class="btn btn-primary btn-lg">Learn more »</a></p>
</div>

<div class="row">
    <p id="1A">1: A</p>
    <p id="2B">2: B</p>
    <p id="3C">3: C</p>
    <p id="4D">4: D</p>
    <p id="5E">5: E</p>
    <div id="divBoxElements 
       style="border: 1px solid #dcdcdc; width: 300px; height: 300px;"
    ></div>
</div>

@section scripts {
    <script src="~/Scripts/html5utils.js"></script>
    <script>
        <!--
        function InsertTestElement(element) {
            var url = '@Url.Action("InsertTestElements", "Home")';

            $.post(url, { testElement: element }, function (data) {
                switch (data) {
                    case 1:
                        divBoxElements.innerHTML = 
                             element + " inserted OK";
                        setTimeout(function () { 
                             divBoxElements.innerHTML = ""; }, 2000);
                        break;

                    default:
                        alert("Error inserting the element");
                }
            });
        }
        //-->
    </script>
}

Download or fork tthis code on Github.

Happy coding!

Creating a URL shortener using ASP.NET WepAPI and MVC

In this tutorial, I use several techniques and tools. I use Microsoft Visual Studio 2015 and the latest version of all components.

  • ASP.NET MVC: Microsoft’s modern web application framework. As the name says, it pushes you to use the MVC (model view controller) software design principle.
  • ASP.NET Web API: Web API and MVC are used together in many applications. With MVC, the HTML of the web pages are rendered on the server, and with Web API you can, like the name says, create an API. Web API also uses the MVC principle, but returns XML (or JSON, or YAML, or … whatever you want) instead of HTML.
  • Microsoft SQL: this is my primary database choice.
  • Entity Framework: this is my favourite ORM (object relational mapping) framework. With Entity Framework, you can create a database “code-first”, meaning that you can create classes (called entities) that represent the database and create the database based on those entities and its relations. When you’ve updated one of these entities, you can add a new migration, which means that the changes to your entities will be written to the database.
  • Unity: Unity is a dependency injection framework. You can read more on dependency injection and inversion of control later in this tutorial.

Basic project structure

If you didn’t know already, Visual Studio works with solutions. A solution can contain multiple projects. When a solution is compiled, a DLL (or EXE if it’s a WPF or Console application) is created. These DLLs, in case of an MVC application, are deployed to the server. A project can reference another project in the same solution, or assemblies compiled from another solution. A third way of adding references is using NuGet; this is a package manager for ASP.NET applications. Using this, you can add a connector to MySQL, Entity Framework, xUnit.net (testing framework) and many, many more to your solution. You can compare it to Composer (PHP) or npm (Node.js).

Once you’ve started Visual Studio, go to File | New | Project. I always select “ASP.NET Web Application”. In the following dialog, select “MVC”, but also select “Web API”. On the right hand, change authentication to “No Authentication”, since we’re not going to use that (not for this tutorial though, maybe later). In the bottom fields, you can fill in the name and location of your solution. I call it “PSC.Shorturl.Web” (but call it anything you want). You can uncheck “Host in the cloud”, although I’m not sure what the difference is (I never hosted anything in Azure). You can now click OK.

A basic MVC site is created now. Once you click the “Run” button at the top, you’ll already be able to browse the basic website. A local IIS web server is launched and your favourite browser will be opened with the MVC website.

ASPNET_MVC_FirstStart

As you can see, there are some files and folders created for you in this project. I’m going to explain what these folders and files are.

ASPNET_MVC_Solution

  • App_Data: This folder is empty for now, but if you ever want to enable uploads on your websites, it’s best if they are placed here.
  • App_Start: this folder contains some classes which are needed to start up MVC and Web API when the application is first run. If you add new frameworks which need something of a setup, this can be placed in this folder.
  • Content: this folder contains your CSS files and images.
  • Controllers: this folder contains the controller classes of the MVC application.
  • fonts: as the name says, this folder contains fonts.
  • Models: this folder contains models which will be used to pass data from the controllers to the views.
  • Scripts: this folder contains (Java)script files.
  • Views: this folder contains the views for the MVC application.
  • Global.asax: this file is loaded when the application is started. In this file, the classes in the “App_Start” folder are called.
  • packages.config: if you’re going to add packages from NuGet to your project, a reference to that project will be added to this file. When someone else receives your code and tries to build our code, Visual Studio first downloads all packages defined in this file (else the build would fail because these DLLs aren’t available).
  • Web.config: this file contains general configuration for your application. Think of database connection strings, SMTP server settings etc.

First, let’s open HomeController.cs in the folder Controllers. You’ll see this code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace PSC.Shorturl.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

 

This method contains three methods. When the application is started, RouteConfig (which is located in App_Start) is read and mapped to the existing controllers. In this application it means that when you go to http://yourapp/Home/About, the method About in the HomeController will be executed. This is called convention over configuration; you don’t have to explicitly tell the application that you have added a new controller. This means that when you add a new controller, say UrlController with a method Shorten, this will be called when you go to http://yourapp/Url/Shorten.

You also see that the methods in this class return a View(). For example, when you browse to /Home/About, the View() searches in the folder Views to the file About.cshtml (can be another extension, but the file should be called “About”). Again, this is “convention over configuration”.

Every method in this controller returns an ActionResult. An ActionResult can be a view, but can also be a redirect (which we’ll use later when redirecting a short URL).

This default behaviour can be fine tuned, but I think that’s not necessary for now; I think it works fine this way.

Now that’s explained, let’s create a new controller. Right click the Controllers folder and create a new controller (MVC 5 Controller – Empty). I call it UrlController.

ASPNET_MVC_AddController1

ASPNET_MVC_AddController2

By adding a new controller, a new folder is also added in the “Views” folder; “Url”. In this folder, create a new view called “Index.cshtml”. This is the code for the view:

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

This is the main URL shortening view. Here, we'll show our form later on.

 

On the top of the view, you see a syntax you may have never seen before. This is MVC’s template syntax: Razor. The property “Title” of “ViewBag” is set to “URL shortener”. ViewBag is used to pass data from one view to another. In this case, the title will be rendered between the title tags of the master layout.

If you start the application now and head to /Url/Index (or just /Url, because Index is assumed if the second part isn’t set; see RouteConfig.cs), you’ll see our newly created view rendered. Later on, this view will contain the form where users can fill in their long URL to be shortened, so when the root URL is reached, we would like the user to see this page, we don’t want them to go to http://yourapp/Url. To accomplish this open RouteConfig.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace PSC.Shorturl.Web
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", 
                                id = UrlParameter.Optional }
            );
        }
    }
}

 

This is the default route configuration. You’ll see that by default the HomeController and Index action are selected. Change “Home” to “Url”. Now, when we go to the root URL, we’ll see our newly created view.

This view is a bit empty for now. First, add a new class called “Url” to the folder “Models”. Like I’ve said before, a model is responsible for passing data between a View and a Controller. Below, you’ll see the model I’ve created:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace PSC.Shorturl.Web.Models
{
    public class Url
    {
        public string LongURL { get; set; }

        public string ShortURL { get; set; }
    }
}

 

The model will contain the long URL and the short URL for now. When the user has filled in the URL he / she would like to have shortened, the LongURL property will be set and it will be sent to the business layer (which we will create lateron). The business layer will validate the URL and will return a short URL. The short URL will be set and the model will be returned to the view.

Now, let’s add a form to Index.cshtml.

@model PSC.Shorturl.Web.Models.Url
@{
    ViewBag.Title = "URL shortener";
}

<h2>Shorten a URL</h2>

@using (Html.BeginForm())
{
    <div class="form-group">
        @Html.TextBoxFor(model => model.LongURL, 
                         new { placeholder = "URL you would like to have shortened", 
                         @class = "form-control" })
    </div>

    <input type="submit" class="btn btn-primary" value="Shorten" />
}

 

As you can see, I’ve added a “@model” reference at the top. The view now knows that it should use the class we’ve just created (you can call the model anywhere by using @Model in the view). Further on, you see we start a new HTML form. In this form we start a new TextBox, with a reference to the LongURL property in the class “Url”. The second parameter in this method is an anonymous object with several HTML attributes, like placeholder and class (class is prefixed with an “@” because it is a reserved keyword in ASP.NET, the application won’t work otherwise). The last line is a plain old HTML submit button.

ASPNET_MVC_FirstScreen

All very nice, but there is no logic at all at the moment. Let’s go back to UrlController.cs.

using PSC.Shorturl.Web.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace PSC.Shorturl.Web.Controllers
{
    public class UrlController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            Url url = new Url();
            return View(url);
        }

        public ActionResult Index(Url url)
        {
            url.ShortURL = "http://www.puresourcecode.com";
            return View(url);
        }
    }
}

 

You now see that I’ve created two methods with the same name. One which doesn’t have any parameters, one with a Url object as parameter. The first method will only be called when the user is first directed to the page. The second method is used when the user has pushed the submit button. MVC will serialize the data filled in on the form, place it in a URL object and pass it to that function. Here, we will be able read the original LongURL property and send it to the business layer. As of now, nothing happens with it and the ShortURL property is set to “http://www.google.com” hard coded. This is fine for now. The object with the ShortURL property set is being passed to the view, so we can read this property in the view now. If you place the snippet below in “Index.cshtml” underneath the textbox, you’ll see the shortened URL when you push the submit button.

if (!string.IsNullOrEmpty(Model.ShortURL))
{
    <div>
        lt;a href="@Model.ShortURL" target="_blank">@Model.ShortURL</a>
    </div>
}

 

It would be nice to have a little validation. For now, it’s enough to validate that the user has actually filled in anything as long URL. So go back to "Url.cs" and change LongURL to this:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace PSC.Shorturl.Web.Models
{
    public class Url
    {
        [Required]
        public string LongURL { get; set; }

        public string ShortURL { get; set; }
    }
}

 

By placing this attribute directly above this property, MVC knows that this property should be set. Next, change the second Index method in UrlController.cs to this:

public ActionResult Index(Url url)
{
    if (ModelState.IsValid)
    {
        url.ShortURL = "http://www.puresourcecode.com";
    }
    return View(url);
}

 

ModelState.IsValid checks if all validation requirements are met. If yes, set the ShortURL. Finally, we would like the user to get validation feedback. In “Index.cshtml”, place this piece of code anywhere you’d like (I place it directly beneath the H2 tags):

@Html.ValidationSummary()

At this point, I deleted the HomeController and Home folder in the Views folder; we don’t need it for the now.

Now, it’s time to set up the other projects. Right click the solution and add new projects. The project I’m describing should be of the type “Class Library”.

ShortUrl_NewProject

ShortUrl_ClassLibrary

  • PSC.Shorturl.Web.Business: this project will contain the interfaces and classes needed to execute numerous business actions; for example adding a new short URL to the database, searching a short URL etc.
  • PSC.Shorturl.Web.Data: this project will contain our data context for Entity Framework and the migrations will be saved in this project.
  • PSC.Shorturl.Web.Entities: this project will contain the entities (plain old classes) for our data structure.
  • PSC.Shorturl.Web.Exceptions: this project will contain custom exceptions. For example, when a specific URL isn’t found, an exception will be thrown and it will be caught by the MVC framework to show us a nice custom error page.

So, now we’ve created all project we’re going to need to add several NuGet packages to the projects.

ShortUrl_NuGet

Search and install the following packages. I’m going to describe in which projects every package has to be installed to.

Shorturl_Nuget_packages

  • EntityFramework: the ORM which we’re going to use.
    • Business
    • Data
    • Entities
    • Web
  • Newtonsoft.Json: a nice Json serializer for ASP.NET. This will be needed by Web API later on.
    • Business
    • Data
    • Entities
    • Web
  • Unity, Unity bootstrapper for ASP.NET MVC & Unity.WebAPI: this is an inversion of control (IoC) for ASP.NET. It is used for loose coupled web applications. I will explain this later on.
    • Web

The solution should be able to build now. If not, please leave a comment and maybe I can help you.

Dependency injection

Robust applications don’t have any hard coupling in their code. What I always like to do is constructor injection; whenever a controller (or any other class) is instantiated, you can fill in a few parameters in the constructor. These parameters are interfaces.

Unity, an inversion of control framework, finds out which implementation belongs to this interface, and injects it. With this framework, you don’t have hard coupling; there is only one place in your application where you fill in this interface/implementation mapping. Whenever you need to change the implementation (for example, you used Entity Framework, but want to switch to NHibernate), you just create a new class that implements that specific interface and you change the configuration for Unity. It might all sound a bit vague. Let’s try to setup Unity.

1. The web project should reference all other projects

Right click the web project and add a new reference.

ShortUrl_ReferencesMenu

ShortUrl_References

2. Add an interface IUrlManager and a class UrlManager (which implements IUrlManager)

IUrlManager
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSC.Shorturl.Web.Business
{
    public interface IUrlManager
    {
        Task<string> ShortenUrl(string longUrl);
    }
}
UrlManager

Create a folder named Implementations and under this folder create the following interface:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSC.Shorturl.Web.Business.Implementations
{
    public class UrlManager : IUrlManager
    {
        public Task<string> ShortenUrl(string longUrl)
        {
            return Task.Run(() =>
            {
                return "http://www.puresourcecode.com";
            });
        }
    }
}

We have to tell the application somehow that when an implementation for IUrlManager is desired, a UrlManager should be injected. The method RegisterTypes in the class UnityConfig will look like this now:

using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using PSC.Shorturl.Web.Business;
using PSC.Shorturl.Web.Business.Implementations;

namespace PSC.Shorturl.Web.App_Start
{
    /// <summary>
    /// Specifies the Unity configuration for the main container.
    /// </summary>
    public class UnityConfig
    {
        #region Unity Container
        private static Lazy<iunitycontainer> container = new Lazy<iunitycontainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Gets the configured Unity container.
        /// </summary>
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// <summary>Registers the type mappings with the Unity container.</summary>
        /// <param name="container" />The unity container to configure.</param>
        /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
        /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
        public static void RegisterTypes(IUnityContainer container)
        {
            // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
            // container.LoadConfiguration();

            // TODO: Register your types here
            // container.RegisterType<iproductrepository productrepository ,>();
            container.RegisterType<iurlmanager urlmanager ,>();
        }
    }
}

3. Update the existing UrlController

Let’s take a look at the new UrlController:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using PSC.Shorturl.Web.Business;
using PSC.Shorturl.Web.Models;

namespace PSC.Shorturl.Web.Controllers
{
    public class UrlController : Controller
    {
        private IUrlManager _urlManager;

        public UrlController(IUrlManager urlManager)
        {
            this._urlManager = urlManager;
        }

        [HttpGet]
        public ActionResult Index()
        {
            Url url = new Url();
            return View(url);
        }

        public async Task<actionresult> Index(Url url)
        {
            if (ModelState.IsValid)
            {
                url.ShortURL = await 
                    this._urlManager.ShortenUrl(url.LongURL);
            }
            return View(url);
        }
    }
}

As you see here, we’ve added a private field and a constructor. When the controller is selected, Unity knows that it should insert the UrlManager in the IUrlManager. We have no hard coupling on the implementation at the moment. The second Index method is now async, and returns a Task. This is because our final implementation of the UrlManager will call the database and check if the inserted URL actually exists. If this isn’t executed async, it will block the entire application until these actions are done; that’s something you don’t want.

Every new business manager you’re going to add, can be injected using Unity.

Entity Framework

As I’ve explained before, Entity Framework is a object relational mapping framework. You define a few classes with a few properties. These properties match the fields in the database. Before we can do anything with Entity Framework, we have to make set up the MySQL connection in the Web.config file. The code snippet below should be inserted in the configuration tag of Web.config:

  <connectionStrings>
    <add name="Shorturl"
        connectionString="Server=YourServer;Database=PSCShortUrl;Uid=youruser;Pwd=yourpassword;"
        providerName="System.Data.SqlClient" />
  </connectionStrings>

Make sure you put in the correct server, username and password.

Let’s add two entities (so two tables) for the URL shortener application to the Entities project. These are just plain classes.

ShortUrl.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSC.Shorturl.Web.Entities
{
    [Table("short_urls")]
    public class ShortUrl
    {
        [Key]
        [Column("id")]
        public int Id { get; set; }

        [Required]
        [Column("long_url")]
        [StringLength(1000)]
        public string LongUrl { get; set; }

        [Required]
        [Column("segment")]
        [StringLength(20)]
        public string Segment { get; set; }

        [Required]
        [Column("added")]
        public DateTime Added { get; set; }

        [Required]
        [Column("ip")]
        [StringLength(50)]
        public string Ip { get; set; }

        [Required]
        [Column("num_of_clicks")]
        public int NumOfClicks { get; set; }

        public Stat[] Stats { get; set; }
    }
}
Stat.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSC.Shorturl.Web.Entities
{
    [Table("stats")]
    public class Stat
    {
        [Key]
        [Column("id")]
        public int Id { get; set; }

        [Required]
        [Column("click_date")]
        public DateTime ClickDate { get; set; }

        [Required]
        [Column("ip")]
        [StringLength(50)]
        public string Ip { get; set; }

        [Column("referer")]
        [StringLength(500)]
        public string Referer { get; set; }

        public ShortUrl ShortUrl { get; set; }
    }
}

This is a very basic entity setup.

  • Table tells Entity Framework what the actual table name should be.
  • Key tells Entity Framework that this property is the primary key.
  • Column tells Entity Framework what the columns name is in the database.
  • StringLength tells Entity Framework what the maximum string length of a property is (only if the type is “string”).

This actually doesn’t do anything. We have to define a “data context”. The data context is the central piece in Entity Framework: it contains the relations between the different entities and contains the repositories. A repository is a collection of all records in a specific table mapped to a specific entity. Let’s add a ShortUrlContext to the Data project.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PSC.Shorturl.Web.Entities;

namespace PSC.Shorturl.Web.Data
{
    public class ShorturlContext : DbContext
    {
        public ShorturlContext()
            : base("name=Shorturl")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<stat>()
                .HasRequired(s => s.ShortUrl)
                .WithMany(u => u.Stats)
                .Map(m => m.MapKey("shortUrl_id"));
        }

        public virtual DbSet<shorturl> ShortUrls { get; set; }
        public virtual DbSet<stat> Stats { get; set; }
    }
}

The string "name=Shorturl" in the constructor refers to the connection string in the Web.config file. The method OnModelCreating is where all the relations between the entities are configured. At the moment, there is only one relation, so not much going on there. The latest two properties are the repositories. Entity Framework knows that these should be filled with the correct entities.

Now that we have the entities and the database configured, it’s time to set up our first migration. A migration is a change to the database. When you add a migration, Entity Framework compares the database with your current entity configuration and creates a new migration. This new migration can then be pushed to the database.

First, we have to open the package manager console.

ShortUrl_PackageConsole

Make sure the default project is “PSC.Shorturl.Web.Data”.

ShortUrl_PackageConsole_Data

Next, execute the command “enable-migrations”.

ShortUrl_PackageConsole_EnableMigration

If you have a Windows 10 Pro Insider Preview Build 11099, you can’t execute this command or other commands with Entity Framework. For updates see http://stackoverflow.com/questions/35060821/visual-studio-2015-entity-framework-and-enable-migrations-error

A migrations configuration file will be added to the Data project. From now on, it will be possible to add new migrations. Execute the following command:

add-migration "InitialCreate"

This will add an initial migration to your Data project. When you execute the following command:

update-database

The migration will actually be written to the database. If everything went right, you’ll now see the created (but empty) tables in the newly created database.

Next step is the implementation on business layer.

Automatic Table of Contents

Any long page of content with distinct and well marked up content can benefit from a table to contents. A table of contents provides a quick way to jump down the page to the desired section. Of course you can create a table of contents manually, but it may be smart to build it dynamically on-the-fly with JavaScript. This is true for several reasons:

  • It's easier - write the JavaScript once and it can create the Table on Contents on every page you need it.
  • It's more reliable - the JavaScript isn't subject to authoring errors.
  • It's still accessible - A table of contents is good for the general concept of accessibility, but it is a bonus (not having it doesn't ruin the page) and nearly all screen readers run JavaScript.

This kind of thing has been done many times and many ways. But this time is ours! Plus it makes for a good tutorial.

HTML: Headers and IDs

A long page of different parts you wish to link to could be marked up a bunch of ways. Perhaps a FAQ page could be a <dl>. It could literally be <section> after <section>. In our case, we'll assume this structure:

<article>
   <h3 id="question-one">Title of Question</h3>
   <!-- whatever other content, probably some paragraphs and stuff. -->

   <h3 id="question-two">Another Question</h3>
   <!-- whatever other content, probably some paragraphs and stuff. -->

   <!-- etc -->
</article>

A perfectly legit page full of headers with IDs and the content between them. Note the ID's. They are unique, as any good ID ought to be. This is required because it gives us a link target.

A link like this:

<a href="#question-one">Link to Question One</a>

Will jump down the page when clicked until the element with the ID "question-one" is in view.

Building the Table of Contents with jQuery

Our goal is to inject HTML on the page in the form of a table of contents. Like this:

<nav role="navigation" class="table-of-contents">
  <h2>On this page:</h2>
  <ul>
    <li><a href="#question-one">Question One</a></li>
  </ul>
</nav>

Step 1: A string of HTML

We'll build this entirely dynamically. Perhaps it would be smart to use some kind of JavaScript templating for this. But hey, this is so simple, let's just build a big string and append that.

var ToC =
  "<nav role='navigation' class='table-of-contents'>" +
    "<h2>On this page:</h2>" +
    "<ul>";

Step 2: Loop through the headers

The <h3>'s on our page indicate each section we wish to link to, so we'll find them all with a jQuery selector, then loop through each of them.

$("article h3").each(function() {
  // loop
});

Step 3: Get the bits of data we need

We need 1) the text of each header, which we will turn into a link and 2) the ID of each header which we can turn into a href attribute for that link.

var el, title, link;

$("article h3").each(function() {
  el = $(this);
  title = el.text();
  link = "#" + el.attr("id");
});

Inside of that loop, "this" refers to the header element currently targeted, so to speak. we set "el" to a jQuery version of it, so we can use jQuery methods on it to extract that text and ID.


Step 4: Create a new list item and append to string

var newLine, el, title, link;

$("article h3").each(function() {
  el = $(this);
  title = el.text();
  link = "#" + el.attr("id");

  newLine =
    "<li>" +
      "<a href='" + link + "'>" +
        title +
      "</a>" +
    "</li>";

  ToC += newLine;
});

The "+=" there means "append this new string to the already existing string stored in this variable.


Step 5: Close the "template"

ToC +=
   "</ul>" +
  "</nav>";

Step 6: Inject HTML onto page

Now you'll need to decide just exactly where you want this newly formed table to contents to be injected onto the page. Putting at the top of the page is probably smart.

Our example uses <article> to wrap everything, so to inject at the top of that, we would do:

$("article").prepend(ToC);

In "real life", perhaps you'd target a header and use insertAfter or another of jQuery's fancy DOM insertion methods.

See the Pen Automatic Table of Contents by Enrico (@erossini) on CodePen.

Write C#. Run JavaScript.

BridgeNet

Open Source C# to JavaScript Compiler and Frameworks. Run Your App On Any Device Using JavaScript.

Use Bridge.NET to build platform independent applications for mobile, web and desktop. Run on iOS, Windows, Mac, Linux and billions of other devices with JavaScript support. Compile your C# code into native JavaScript and deploy on Billions of devices.

Try it on bridge.net or fork it on GitHub

Track events for Google Analytics and Piwik

After my post of yesterday, I've worked for creating a script to integrate Google Analytics (new version with analytics.js) and Piwik (Piwik is the leading open-source analytics platform similar to Google Analytics. You can download it from its site or directly in your IIS with WebMatrix).

With this code you have only one function to call in every part of your page. Automatically the function detects download, email, phone number, external links and tracks them. You can insert in an anchor a code like:

<a href="http://www.puresourcecode.com/" 
   onclick="TrackEvent('Link to my site', 'PSC', 
            'Click from the user', 'Url or something else');">
   Visit PureSourceCode
</a>

You find the code for that here:

// Piwik
var _paq = _paq || [];
_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);
_paq.push(["setCookieDomain", "*"]);
_paq.push(["setDomains", ["*"]]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function () {
    var u = "//a.esia.info/";
    _paq.push(['setTrackerUrl', u + 'piwik.php']);
    _paq.push(['setSiteId', 28]);
    var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
    g.type = 'text/javascript'; g.async = true; g.defer = true; g.src = u + 'piwik.js'; s.parentNode.insertBefore(g, s);
})();

// Google analytics
(function (i, s, o, g, r, a, m) {
    i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
        (i[r].q = i[r].q || []).push(arguments)
    }, i[r].l = 1 * new Date(); a = s.createElement(o),
    m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

ga('create', 'UA-XXXXXXXX-1', 'auto');
ga('send', 'pageview');

if (typeof jQuery != 'undefined') {
    jQuery(document).ready(function ($) {
        var filetypes = /\.(zip|exe|dmg|pdf|doc.*|xls.*|ppt.*|mp3|txt|rar|wma|mov|avi|wmv|flv|wav)$/i;
        var baseHref = '';
        if (jQuery('base').attr('href') != undefined) baseHref = jQuery('base').attr('href');

        jQuery('a').on('click', function (event) {
            var el = jQuery(this);
            var track = true;
            var href = (typeof (el.attr('href')) != 'undefined') ? el.attr('href') : "";
            var isThisDomain = href.match(document.domain.split('.').reverse()[1] + '.' + document.domain.split('.').reverse()[0]);
            if (!href.match(/^javascript:/i)) {
                var elEv = []; elEv.value = 0, elEv.non_i = false;
                if (href.match(/^mailto\:/i)) {
                    elEv.category = "email";
                    elEv.action = "click";
                    elEv.label = href.replace(/^mailto\:/i, '');
                    elEv.loc = href;
                }
                else if (href.match(filetypes)) {
                    var extension = (/[.]/.exec(href)) ? /[^.]+$/.exec(href) : undefined;
                    elEv.category = "download";
                    elEv.action = "click-" + extension[0];
                    elEv.label = href.replace(/ /g, "-");
                    elEv.loc = baseHref + href;
                }
                else if (href.match(/^https?\:/i) && !isThisDomain) {
                    elEv.category = "external";
                    elEv.action = "click";
                    elEv.label = href.replace(/^https?\:\/\//i, '');
                    elEv.non_i = true;
                    elEv.loc = href;
                }
                else if (href.match(/^tel\:/i)) {
                    elEv.category = "telephone";
                    elEv.action = "click";
                    elEv.label = href.replace(/^tel\:/i, '');
                    elEv.loc = href;
                }
                else if (href.match(/^call\:/i)) {
                    elEv.category = "telephone";
                    elEv.action = "click";
                    elEv.label = href.replace(/^call\:/i, '');
                    elEv.loc = href;
                }
                else track = false;

                if (track) {
                    TrackEvent(elEv.category.toLowerCase(), elEv.action.toLowerCase(), elEv.label.toLowerCase(), elEv.value);
                    if (el.attr('target') == undefined || el.attr('target').toLowerCase() != '_blank') {
                        setTimeout(function () { location.href = elEv.loc; }, 400);
                        return false;
                    }
                }
            }
        });
    });
}

/* Tracking events */
function TrackEvent(category, action, label, value) {
    // add to Google Analytics
    ga('send', 'event', category, action, label, value);
    // add to Westhill Analtics
    _paq.push(['trackEvent', category, action, label, value]);
}

In attach the code trackingGenerator.js (4KB)

How to Track Downloads & Outbound Links in Google Analytics

Since Google Analytics does not track file downloads, email, telephone or other outbound link clicks automatically, we saw an opportunity to provide this code to the community.

Dynamically Track Downloads & Other External Links

For those who have a lot of links and would like to dynamically detect clicks on links to file downloads, we have provided updated code below.  As before, this code requires the jQuery JavaScript library to be set before the code.

We have updated the code to make it more manageable and easier to extend.  In addition, we are using the jQuery on() method for attaching the click event handler to links.  Since we are using the on() method you will need to use jQuery v1.7+.  If you are using an earlier version of jQuery the .live() method can be used instead.

The primary benefit of using the on() method is performance.  Instead of looping through all ‘a’ elements on a page after the page loads (takes processing power on pages with lots of links), we instead listen for any clicks on the ‘a’ elements and invoke our custom JavaScript on the fly.

Again, feel free to customize this code to suite your needs.  It can be placed in its own .js file and should be placed in the <head> of your pages.  This script automates the following:

  • Tracks file downloads as events for the following extensions: .zip, .exe, dmg, .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .txt, rar, wma, mov, avi, wmv, flv, wav (again feel free to modify the list)
  • Tracks outbound clicks as events if the href value contains http:// or https:// and the domain value doesn’t match the current domain
  • Tracks mailto email clicks
  • Tracks Tel telephone clicks
<script type="text/javascript">
if (typeof jQuery != 'undefined') {
  jQuery(document).ready(function($) {
    var filetypes = /\.(zip|exe|dmg|pdf|doc.*|xls.*|ppt.*|mp3|txt|rar|wma|mov|avi|wmv|flv|wav)$/i;
    var baseHref = '';
    if (jQuery('base').attr('href') != undefined) baseHref = jQuery('base').attr('href');

    jQuery('a').on('click', function(event) {
      var el = jQuery(this);
      var track = true;
      var href = (typeof(el.attr('href')) != 'undefined' ) ? el.attr('href') :"";
      var isThisDomain = href.match(document.domain.split('.').reverse()[1] + '.' + document.domain.split('.').reverse()[0]);
      if (!href.match(/^javascript:/i)) {
    	var elEv = []; elEv.value=0, elEv.non_i=false;
        if (href.match(/^mailto\:/i)) {
          elEv.category = "email";
          elEv.action = "click";
          elEv.label = href.replace(/^mailto\:/i, '');
          elEv.loc = href;
        }
        else if (href.match(filetypes)) {
          var extension = (/[.]/.exec(href)) ? /[^.]+$/.exec(href) : undefined;
          elEv.category = "download";
          elEv.action = "click-" + extension[0];
          elEv.label = href.replace(/ /g,"-");
          elEv.loc = baseHref + href;
        }
        else if (href.match(/^https?\:/i) && !isThisDomain) {
          elEv.category = "external";
          elEv.action = "click";
          elEv.label = href.replace(/^https?\:\/\//i, '');
          elEv.non_i = true;
          elEv.loc = href;
        }
        else if (href.match(/^tel\:/i)) {
          elEv.category = "telephone";
          elEv.action = "click";
          elEv.label = href.replace(/^tel\:/i, '');
          elEv.loc = href;
        }
        else track = false;

       	if (track) {
          _gaq.push(['_trackEvent', elEv.category.toLowerCase(), elEv.action.toLowerCase(), elEv.label.toLowerCase(), elEv.value, elEv.non_i]);
          if ( el.attr('target') == undefined || el.attr('target').toLowerCase() != '_blank') {
            setTimeout(function() { location.href = elEv.loc; }, 400);
            return false;
	  }
	}
      }
    });
  });
}
</script>

The script sets download, email and tel link clicks as interaction events while the external site clicks are non-interaction which can be adjusted if desired.

As before, the script will detect if the link is opening in a new window or not and automatically uses setTimeout() for 400ms if you are not. This is to allow time for the hit request to process before taking the user to the new page.

Inline Download & Other External Links Tracking

If you’d rather not use the above method to place a single javascript file on your site and automate the tracking for all link elements, you can use the manual inline approach by tagging each link element individually.  The inline approach can be time consuming and is not scalable.

The original syntax for adding the code inline remains the same.

New window/tab
For links that open a new window or tab (such as using target=”_blank” for example) you will want to use the code below:

<a onclick="_gaq.push(['_trackEvent','Download','PDF','Description']);" 
   href="my-file.pdf" target="_blank">
   Download my file
</a>

In current window
For links that open within the same window, replacing the current page, you will want to use the code below:

<a onclick="var that=this;_gaq.push(['_trackEvent','Download','PDF',this.href]);
   setTimeout(function(){location.href=that.href;},400);
   return false;" 
   href="my-file.pdf">
   Download my file
</a>

These type of links require a slight delay to allow time for the hit request to process before taking the user to the new page.

Detailed Download & External Link Reports

After all of your hard work you will have event tracking reports with neatly organized data around file downloads, external link, email link, and telephone link clicks.  From these reports you can gauge the usage and usefulness of your file downloads and various links.

events_report1

 

By diving into the download category and selecting event label as the primary dimension you are able to see a report on all of the individual files downloaded from your site.

events_downloads

 

Lastly, since events are associated with the page they were fired on, you are able to apply a secondary dimension of page to find out which page contained the download or external link click that occurred.

Crypt and decrypt your email with JavaScript

If you want to publish an email on your site but you want to protect it, I have a simple solution Sorriso

 

HTML

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="crypto.js"></script>
    <script src="uncrypto.js"></script>
</head>
<body>
    <h1>JavaScript eMail Encrypter</h1>

    <p>You can encrypt mailto: links on a website, so that spiders can't detect them, with a simple javascript.</p>
    <p>Example: <a href="javascript:linkTo_UnCryptMailto('nbjmup;spttjojAftjb/dp');">rossini [at] esia [dot] co</a></p>

    <form>
        <div>
            <div class="container">
                <div class="desc">enter your eMail address:</div>
                <div><input type="text" name="emailField" size="40" maxlength="255" /></div>
            </div>

            <div class="container">
                <div class="desc"><input type="button" name="ecrypt" value="Crypt eMail Address" onclick="CryptMailto()" /></div>
                <div>&#160;&#160;</div>
                <div>

                    <br />
                    <br />

                    <div class="container">
                        <div class="desc">crypted eMail:</div>
                        <div><input type="text" name="cyptedEmailField" size="40" maxlength="255" /></div>
                    </div>

                    <div class="container">
                        <div class="desc">html code:</div>
                        <div><textarea name="HTMLCyptedEmailField" cols="50" rows="8"></textarea></div>
                    </div>
                </div>
            </div>
        </div>
    </form>
</body>
</html>

Crypt (js)

function CryptMailto() {
    var n = 0;
    var r = "";
    var s = "mailto:" + document.forms[0].emailField.value;
    var e = document.forms[0].emailField.value;

    e = e.replace(/@/, " [at] ");
    e = e.replace(/\./g, " [dot] ");

    for (var i = 0; i < s.length; i++) {
        n = s.charCodeAt(i);
        if (n >= 8364) {
            n = 128;
        }
        r += String.fromCharCode(n + 1);
    }

    document.forms[0].cyptedEmailField.value = r;
    document.forms[0].HTMLCyptedEmailField.value = "<a href=\"javascript:linkTo_UnCryptMailto('" + r + "');\">" + e + "</a>";
}

Decrypt (js)

function UnCryptMailto(s) {
    var n = 0;
    var r = "";
    for (var i = 0; i < s.length; i++) {
        n = s.charCodeAt(i);
        if (n >= 8364) {
            n = 128;
        }
        r += String.fromCharCode(n - 1);
    }
    return r;
}

function linkTo_UnCryptMailto(s) {
    var a = document.createElement('a');
    a.href = UnCryptMailto(s);
    document.body.appendChild(a); // Add to the DOM
    a.click();
    document.body.removeChild(a); // Remove it back
}

 

Happy coding!

Classical Inheritance in JavaScript

JavaScript is a class-free, object-oriented language, and as such, it uses prototypal inheritance instead of classical inheritance. This can be puzzling to programmers trained in conventional object-oriented languages like C++ and Java. JavaScript's prototypal inheritance has more expressive power than classical inheritance, as we will see presently.

Java JavaScript
Strongly-typed Loosely-typed
Static Dynamic
Classical Prototypal
Classes Functions
Constructors Functions
Methods Functions


But first, why do we care about inheritance at all? There are primarily two reasons. The first is type convenience. We want the language system to automatically cast references of similar classes. Little type-safety is obtained from a type system which requires the routine explicit casting of object references. This is of critical importance in strongly-typed languages, but it is irrelevant in loosely-typed languages like JavaScript, where object references never need casting.

The second reason is code reuse. It is very common to have a quantity of objects all implementing exactly the same methods. Classes make it possible to create them all from a single set of definitions. It is also common to have objects that are similar to some other objects, but differing only in the addition or modification of a small number of methods. Classical inheritance is useful for this but prototypal inheritance is even more useful.

To demonstrate this, we will introduce a little sugar which will let us write in a style that resembles a conventional classical language. We will then show useful patterns which are not available in classical languages. Then finally, we will explain the sugar.

Classical Inheritance

First, we will make a Parenizor class that will have set and get methods for its value, and a toString method that will wrap the value in parens.

function Parenizor(value) {
    this.setValue(value);
}

Parenizor.method('setValue', function (value) {
    this.value = value;
    return this;
});

Parenizor.method('getValue', function () {
    return this.value;
});

Parenizor.method('toString', function () {
    return '(' + this.getValue() + ')';
});

The syntax is a little unusual, but it is easy to recognize the classical pattern in it. The method method takes a method name and a function, adding them to the class as a public method.

So now we can write

myParenizor = new Parenizor(0);
myString = myParenizor.toString();

As you would expect, myString is "(0)".

Now we will make another class which will inherit from Parenizor, which is the same except that its toString method will produce "-0-" if the value is zero or empty.

function ZParenizor(value) {
    this.setValue(value);
}

ZParenizor.inherits(Parenizor);

ZParenizor.method('toString', function () {
    if (this.getValue()) {
        return this.uber('toString');
    }
    return "-0-";
});

The inherits method is similar to Java's extends. The uber method is similar to Java's super. It lets a method call a method of the parent class. (The names have been changed to avoid reserved word restrictions.)

So now we can write

myZParenizor = new ZParenizor(0);
myString = myZParenizor.toString();

This time, myString is "-0-".

JavaScript does not have classes, but we can program as though it does.

Multiple Inheritance

By manipulating a function's prototype object, we can implement multiple inheritance, allowing us to make a class built from the methods of multiple classes. Promiscuous multiple inheritance can be difficult to implement and can potentially suffer from method name collisions. We could implement promiscuous multiple inheritance in JavaScript, but for this example we will use a more disciplined form called Swiss Inheritance.

Suppose there is a NumberValue class that has a setValue method that checks that the value is a number in a certain range, throwing an exception if necessary. We only want its setValue and setRange methods for our ZParenizor. We certainly don't want its toString method. So, we write

ZParenizor.swiss(NumberValue, 'setValue', 'setRange');

This adds only the requested methods to our class.

Parasitic Inheritance

There is another way to write ZParenizor. Instead of inheriting from Parenizor, we write a constructor that calls the Parenizor constructor, passing off the result as its own. And instead of adding public methods, the constructor adds privileged methods.

function ZParenizor2(value) {
    var that = new Parenizor(value);
    that.toString = function () {
        if (this.getValue()) {
            return this.uber('toString');
        }
        return "-0-"
    };
    return that;
}

Classical inheritance is about the is-a relationship, and parasitic inheritance is about the was-a-but-now's-a relationship. The constructor has a larger role in the construction of the object. Notice that the uber née super method is still available to the privileged methods.

Class Augmentation

JavaScript's dynamism allows us to add or replace methods of an existing class. We can call the method method at any time, and all present and future instances of the class will have that method. We can literally extend a class at any time. Inheritance works retroactively. We call this Class Augmentation to avoid confusion with Java's extends, which means something else.

Object Augmentation

In the static object-oriented languages, if you want an object which is slightly different than another object, you need to define a new class. In JavaScript, you can add methods to individual objects without the need for additional classes. This has enormous power because you can write far fewer classes and the classes you do write can be much simpler. Recall that JavaScript objects are like hashtables. You can add new values at any time. If the value is a function, then it becomes a method.

So in the example above, I didn't need a ZParenizor class at all. I could have simply modified my instance.

myParenizor = new Parenizor(0);
myParenizor.toString = function () {
    if (this.getValue()) {
        return this.uber('toString');
    }
    return "-0-";
};
myString = myParenizor.toString();

We added a toString method to our myParenizor instance without using any form of inheritance. We can evolve individual instances because the language is class-free.

Sugar

To make the examples above work, I wrote four sugar methods. First, the method method, which adds an instance method to a class.

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

This adds a public method to the Function.prototype, so all functions get it by Class Augmentation. It takes a name and a function, and adds them to a function's prototype object.

It returns this. When I write a method that doesn't need to return a value, I usually have it return this. It allows for a cascade-style of programming.

Next comes the inherits method, which indicates that one class inherits from another. It should be called after both classes are defined, but before the inheriting class's methods are added.

Function.method('inherits', function (parent) {
    this.prototype = new parent();
    var d = {}, 
        p = this.prototype;
    this.prototype.constructor = parent; 
    this.method('uber', function uber(name) {
        if (!(name in d)) {
            d[name] = 0;
        }        
        var f, r, t = d[name], v = parent.prototype;
        if (t) {
            while (t) {
                v = v.constructor.prototype;
                t -= 1;
            }
            f = v[name];
        } else {
            f = p[name];
            if (f == this[name]) {
                f = v[name];
            }
        }
        d[name] += 1;
        r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
        d[name] -= 1;
        return r;
    });
    return this;
});

Again, we augment Function. We make an instance of the parent class and use it as the new prototype. We also correct the constructor field, and we add the uber method to the prototype as well.

The uber method looks for the named method in its own prototype. This is the function to invoke in the case of Parasitic Inheritance or Object Augmentation. If we are doing Classical Inheritance, then we need to find the function in the parent's prototype. The return statement uses the function's apply method to invoke the function, explicitly setting this and passing an array of parameters. The parameters (if any) are obtained from the arguments array. Unfortunately, the arguments array is not a true array, so we have to use apply again to invoke the array slice method.

Finally, the swiss method.

Function.method('swiss', function (parent) {
    for (var i = 1; i < arguments.length; i += 1) {
        var name = arguments[i];
        this.prototype[name] = parent.prototype[name];
    }
    return this;
});

The swiss method loops through the arguments. For each name, it copies a member from the parent's prototype to the new class's prototype.

Using the UpdateProgress to lock down controls in the browser

If it takes awhile for the server to process the postback (e.g. complex rules or badly written code ), the user may not realize that the server is processing the request. This can lead to all kinds of issues with users that are not savvy or familiar with web applications (multiple clicks, moving off the page, etc.). Consequently, I want to tell the user that the server is processing the request and disable the controls on the page. Let's break this down into two steps: show a message, and disable the user's interaction with the controls.

You can use the UpdateProgress control alone with the UpdatePanel to provide a message to the user during the postback. This is very simple -- put the UpdateProgress control within the UpdatePanel like so:

<asp:UpdateProgress ID="UpdateProgress1" runat="server">
    <ProgressTemplate>
        Update in progress. Please wait ...
    </ProgressTemplate>
</asp:UpdateProgress>
 

This will display the "Update in progress. Please wait ..." message to the the user while the server is processing the request. However, it doesn't prevent the user from continuing to interact with the web application. To provide this type of functionality, we will use the PageRequestManager to invoke some JavaScript while also using CSS and DHTML to lock down the UI.

First, we'll add a little more to our UpdateProgress control:

<ProgressTemplate>
    <div id="blur" />
    <div id="progress">
        Update in progress. Please wait ...
    </div>
</ProgressTemplate>
 

We'll use the "blur" and "progress" controls to _overlay _the controls in the UI while also providing a message to the user. To provide the functionality we require, we need to use the following CSS elements:

#blur
{
    width: 100%;
    background-color: black;
    moz-opacity: 0.5;
    khtml-opacity: .5;
    opacity: .5;
    filter: alpha(opacity=50);
    z-index: 120;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
}

#progress
{
    z-index: 200;
    background-color: White;
    position: absolute;
    margin-left: auto;
    margin-right: auto;
    border: solid 1px black;
    padding: 5px 5px 5px 5px;
    text-align: center;
    width: 100%;
    left: 0px;
    height: 75px;
    padding-top: 40px;
    padding-bottom: 60px;
}
 

The purpose of the "blur" control is to provide a tag that lays over everything in the browser. Since the opacity is 0.5 (and 50), it appears gray while allowing the user to continue to see the controls behind it. However, since the "blur" control exists between the user and the other controls, the user cannot interact with any other controls.

image

Advertsing

125X125_06

Planet Xamarin

Planet Xamarin

Calendar

<<  November 2017  >>
MonTueWedThuFriSatSun
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

Month List