From UI to Front-end Development

Leave a comment
.Net / APIs / Asp.Net / Web

UItoweb

In my previous post, I went over the user interface and application requirements.  Let’s  quickly revisit the project requirements:

  • Get  coordinates of the users and identify which cloud the ASP.NET Core app is running on.
  • Populate maps with custom pushpins.
  • Display  the number of  containers running on each cloud.

Get  Coordinates

In this app,  I am getting  the user location with a  button using  an onclick event handler.  In order to  grab the user’s coordinates,  I  used the Geolocation API .   Let’s  have a look at the code.

Get  location

function getLocation() {
    var x = document.getElementById("demo");
    if (navigator.geolocation) {
        navigator.geolocation.watchPosition(showPosition);
    }
    else {
        x.innerHTML = "Geolocation is not supported by this browser.";
    }
}

getlocation()  function simply shows  the user longitude and latitude  every time you load the page.  But,  in this case, I needed  the user’s coordinates to put the pins on the map. To do this we created a simple a  location web api  that, we can PUT our users longitudes and latitude into.

Store  location

function showPosition(position) {
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
    var xhr = new XMLHttpRequest();
    var params = "latitude=" + lat + "&longitude=" + lon;
    console.log("Params: " + params);
    xhr.open('PUT', '/locations', true);
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    xhr.onreadystatechange = function () {
        console.log("Response:" & this.responseText);
    };
    xhr.send(params); 
}

 

You might have noticed I am using XMLHttpRequest API.  XMLHttpRequest API  is used to transfer data between the  client and Server.  In this case, we are using it to PUT the users coordinates into a location API.

Since this was a public demo our team  thought  it might be a good  idea to offset the actual coordinate we were receiving.  For most people getting  their actual coordinates might  feel  a little creepy to people . To offset the coordinates  we  added  the toFixed( ) method ;  allowing the app to have an idea of where the user is but, not the exact location.

We didn’t creep :)

Full Script to get geolocation and PUT it into an API

function getLocation() {
    var x = document.getElementById("demo");
    if (navigator.geolocation) {
        navigator.geolocation.watchPosition(showPosition);
    }
    else {
        x.innerHTML = "Geolocation is not supported by this browser.";
    }
}

function showPosition(position) {
    var lat = position.coords.latitude.toFixed(2);
    var lon = position.coords.longitude.toFixed(2);
    document.getElementById("demo").innerHTML = "You're around Latitude: " + lat + " and Longitude: " + lon;

    var xhr = new XMLHttpRequest();
    var params = "latitude=" + lat + "&longitude=" + lon;
    console.log("Params: " + params);
    xhr.open('PUT', '/locations', true);
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    xhr.onreadystatechange = function () {
        console.log("Response:" & this.responseText);
    };
    xhr.send(params); 
}

If  you  would like to explore the geolocation API , check out theses resources:  Navigator.geolocationgetCurrentPosition, and WatchPosition.

Get Location Button

<a href="#" onclick="getLocation();  return false;" class="btn btn-default btn-xl wow tada">Get my Location</a>

Displaying  Active Cloud Logo

Include @model directive 

@model whereyouat.Settings

Display Cloud Name &  Logo

  <h3 id="demo"></h3>
      @{
          var largeIcon = $"~/img/large/{Model.Cloud_Name}.png";
       }
   <h3>You're running ASP.NET on @Model.Cloud_Name!</h3>
   <img src="@largeIcon" alt="@Model.Cloud_Name" />

 

By including the @model statement at  the top of my landing page (Views/Home/Index.cshtml), I am able to specify the type object that the view  expects. By using @model directive gives the view access to Cloud_Name through  the settings controller .

Results

 

Cloudgif (2)

 

Pushpins

Start by initializing the map.

var map;
function getLocations() {
       var mapOptions = {
           credentials: "Bing Key",
           mapTypeId: Microsoft.Maps.MapTypeId.road,
           zoom: 3
        };
        map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), mapOptions);

I used the JQuery $.get  method to retrieve the user’s coordinates from the location API.

 $.ajax({
                type: "GET",
                url: "/locations",
                dataType: "json",
                success: function (json) {
                    //console.log(json);
                    $.each(json, function (i, entry) {
                        plotEntry(entry.latitude, entry.longitude, entry.cloud_name);
                    });
                },
                error: function (err, status, errortext) {
                    console.log(errortext);
                }
            });

For this demo, we wanted to add  custom pushpin the showed not only the users locations but, the logos of the cloud their ASP.NET Core was running one.  To do this we used the pushpin class.  You can also use the pushpin class to add a default pins.

function plotEntry(latitude, longitude, cloud) {
            //console.log(latitude + ' ' + longitude);

            //Icons for each Cloud Type
            var pushpinOptions = { icon: '/img/' + cloud + '.png', width: 32, height: 32 };
            var pushpin = new Microsoft.Maps.Pushpin(
                new Microsoft.Maps.Location(latitude, longitude),
                pushpinOptions);

            map.entities.push(pushpin);
        }
        $().ready(getLocations);

Result

Maps

Number of  request per container

For the demo, we had a /cloudcounts  api that returns the  cloud name,  container, and count.  The API looked something like this:

{ "cloud_name": "Azure ACS", "container": "185f65604f23"", "Count": 14 }

To obtain the  number  of request per container , we used  a JQuery $.get method similar to what we did to retrieve the user coordinates. The only difference here is,  we need to account for the whitespaces in the cloud_name values using  the encodeURI function.  Looking back to our demo requirements,  we wanted to so split the number of request per container by cloud name.  It would look something like  the image below.

 

Maptemplate

To achieve the above we created three unordered lists; creating an id attribute for each cloud.  As I mentioned earlier we used the encodeURI function to account for the whitespaces in  cloud_name so, Azure  ACS  becomes Azure%20ACS.  Let’s  look at the code

JavaScript

var listoptions = {};
  
        function getcloud() {
           
            $.ajax({
                type: "GET",
                url: "/cloudcounts",
                dataType: "json",
                success: function (cloudinfo) {
                    console.log(cloudinfo);
                    $.each(cloudinfo, function (i, entry) {
                        //changes "foo bar" to "foo%20bar"
                        var cloudName = encodeURI(entry.cloud_name);
                        console.log(cloudName);
                        if (!listoptions[cloudName]) { listoptions[cloudName] = "" };
                        entry.container = entry.container.replace("whereyouat-web", "wya-w");
                        listoptions[cloudName] += '<li class="list-group-item">' + '<b>Container:</b> ' + entry.container + ' <br><b>' + entry.Count + '</b> PUTs received</li>';

                    });

                    for (var prop in listoptions) {
                        console.log(prop);
                        //Could use getElementByTagName, but here's how to do it in jQuery as "#foo" doens't work with late eval
                        var listElement = "ul[id='" + prop + "-listview']";
                        $(listElement).append(listoptions[prop])
                    }
                  
                },

                error: function (err, status, errortext) {
                    console.log(errortext);
                }

            })
 }
        $().ready(getcloud);

 

HTML

 

<ul id="Azure%20ACS-listview" data-role="listview" class="list-group"></ul>

 

Results

FinalCounts

Summary

In this and the previous post, I went over UI requirements, and  how I constructed it.  In  series  of post entitled  “WhereYouAt DemoBuild 2016:….” my team is going to cover a variety of topics that include : Load Balancing, traffic managers,  and containers. To read these post please visit the .Net Web Development and Tools Blog.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>