DailyJS

DailyJS

The JavaScript blog.


AuthorRic Roberts
Featured

linked-data tutorial

A Simple Linked Data and JavaScript Tutorial

Posted on .

Disclaimer: This article by Ric is a short tutorial on how to consume Linked Data using JavaScript. Some of the examples use Ric's company's new Linked Data publishing platform, [PublishMyData](http://publishmydata.com).

Introduction

Mention Linked Data or RDF and many developers run screaming. The truth
is that Linked Data is
really rather simple (and in many cases you don't even need to use
RDF if you don't want to). In this tutorial we're going to use jQuery to request some data from a Linked Data
service, and then display the results in a table and on a map. You can
see the final result of the tutorial
here (just view source to see all the code).

Writing the SPARQL Query

We'll need to run some SPARQL to get the data we're interested in
(SPARQL is a query language analogous to SQL for relational databases). The following query selects
the names and locations (northing and easting) of all the secondary
schools in the City of Manchester (district
'00BN'
).

PREFIX rdfs: 

SELECT ?name ?northing ?easting WHERE {
  ?school   .
  ?school rdfs:label ?name .
  ?school   .
  ?school  ?northing .
  ?school  ?easting .
}

Constructing the URL to call against the endpoint

The SPARQL endpoint we're using expects requests in the following
format:

http://sparql.publishmydata.com?query=URL-ENCODED-SPARQL&output=FORMAT

We could have used the encodeURI JavaScript function to
encode the SPARQL, but I just copied and pasted the url from the
browser's address bar after clicking on the "JSON" link under the
results on this
page
,
where I originally wrote the SPARQL.

{
  "head": {
    "vars": [ "name" , "northing" , "easting" ]
  } ,
  "results": {
    "bindings": [
      {
        "name": { "type": "literal" , "value": "Parrs Wood High School" } ,
        "northing": { "datatype": "http://www.w3.org/2001/XMLSchema#integer" , "type": "typed-literal" , "value": "390094" } ,
        "easting": { "datatype": "http://www.w3.org/2001/XMLSchema#integer" , "type": "typed-literal" , "value": "385464" }
      },
      ...
    ]
  }
}

The array in head.vars contains the variables that we
selected in the SPARQL query, and results.bindings contains
one object per row of results.

Using jQuery to call the URL

We'll just call the query against the endpoint using jQuery's
ajax function (but you could use any other framework if you
prefer). Notice that we use
JSONP data type to avoid CORS issues.

  //<![CDATA[
  var queryUrl = "http://publishmydata.com/sparql.json?q=PREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0D%0A%0D%0ASELECT+%3Fname+%3Fnorthing+%3Feasting+WHERE+%7B%0D%0A%0D%0A++%3Fschool+%3Chttp%3A%2F%2Feducation.data.gov.uk%2Fdef%2Fschool%2FdistrictAdministrative%3E+%3Chttp%3A%2F%2Fstatistics.data.gov.uk%2Fid%2Flocal-authority-district%2F00BN%3E+.+%0D%0A%0D%0A++%3Fschool+rdfs%3Alabel+%3Fname+.%0D%0A%0D%0A++%3Fschool+%3Chttp%3A%2F%2Feducation.data.gov.uk%2Fdef%2Fschool%2FphaseOfEducation%3E+%3Chttp%3A%2F%2Feducation.data.gov.uk%2Fdef%2Fschool%2FPhaseOfEducation_Secondary%3E+.%0D%0A%0D%0A++%3Fschool+%3Chttp%3A%2F%2Fdata.ordnancesurvey.co.uk%2Fontology%2Fspatialrelations%2Fnorthing%3E+%3Fnorthing+.%0D%0A%0D%0A++%3Fschool+%3Chttp%3A%2F%2Fdata.ordnancesurvey.co.uk%2Fontology%2Fspatialrelations%2Feasting%3E+%3Feasting+.%0D%0A%7D";

  $.ajax({
    dataType: "jsonp",  
    url: queryUrl
  });             
  //]]>

Making an HTML table from the results

Let's create a table in the html:

... and add a success callback, to populate it with the results of the SPARQL.

$.ajax({
  dataType: "jsonp",
  url: queryUrl
  success: function(data) {    
    // get the table element
    var table = $("#results");              

    // get the sparql variables from the 'head' of the data.
    var headerVars = data.head.vars; 

    // using the vars, make some table headers and add them to the table;
    var trHeaders = getTableHeaders(headerVars);
    table.append(trHeaders);  

    // grab the actual results from the data.                                          
    var bindings = data.results.bindings;

    // for each result, make a table row and add it to the table.
    for(rowIdx in bindings){
      table.append(getTableRow(headerVars, bindings[rowIdx]));
    } 
  }
});

In the code above, I've used a few simple helper functions which just
loop through the data from the JSON, and make table rows and cells from
it.

function getTableHeaders(headerVars) {
  var trHeaders = $("");
  for(var i in headerVars) {
    trHeaders.append( $("" + headerVars[i] + "") );
  }
  return trHeaders;
}

function getTableRow(headerVars, rowData) {
  var tr = $("");
  for(var i in headerVars) {
    tr.append(getTableCell(headerVars[i], rowData));
  }
  return tr;
}

function getTableCell(fieldName, rowData) {
  var td = $("");
  var fieldData = rowData[fieldName];
  td.html(fieldData["value"]);
  return td;
}

Plotting the schools on a map

Now things start to get interesting. To draw the map, we'll need to
include a couple of external scripts:

The LatLngToOSGB.js script is for converting
northings/eastings into latitude/longitudes. Frustratingly, Google uses
the World Geodetic System
(WGS84)
, for lat/long but the NEtoLL function from that library returns
values using the Ordnance Survey National Grid
(OSGB36)
. So we'll need to do a 2-step process to convert them if we want accurate positions for the map
points. The functions below wrap up that conversion for you:

// extra conversion functions: Google uses WGS84 whereas the National Grid uses OSGB36
// (thanks to: http://www.roxburgh.net/projects/googlemaps/)

// Returns object with attributes lat and lon
function ENtoLL84(easting, northing) {
  var vlatlng = NEtoLL(easting, northing);
  return OGBToWGS84(vlatlng.lat, vlatlng.lon, 0);
}

// Returns object with attributes east and north
function LL84toEN(lat, lon) {
  var vlatlon = WGS84ToOGB(lat, lon, 0);
  return LLtoNE(vlatlon.lat, vlatlon.lon);
} 

Now we've got that out of the way, lets make a div for the map to live
in:

... and a function to plot the schools' locations:

function drawMap(data) {
  // make a map, centred on Manchester
  var manchesterLatLon = new google.maps.LatLng(53.480110, -2.237940);
  var myOptions = {
    zoom: 11,
    center: manchesterLatLon,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

  // add a marker for each school 
  var bindings = data.results.bindings; 
  for (var i in bindings) {

    var schoolData = data.results.bindings[i];

    var northing = schoolData["northing"]["value"];
    var easting = schoolData["easting"]["value"];
    var name = schoolData["name"]["value"];

    // call our 2-step conversion
    var latLng = ENtoLL84(easting, northing);

    // make a marker with the label as the school name
    var marker = new google.maps.Marker({
      position: new google.maps.LatLng( latLng.lat, latLng.lon ),
      map: map,
      title: name
    });
  } 
} 

Now all that's left to do is to add the call to drawMap to
the ajax success callback.

$.ajax({
  url: queryUrl
  success: function(data) {

    // ... existing code here

    drawMap(data);
  }
});

You should now have something that looks a bit like this
page
.

Featured

reviews learning

JavaScript Master Class: A Review

Posted on .

Last week I attended Amy Hoy's and Thomas Fuchs's JavaScript
Masterclass: Virtual Edition October
2010
. This article is an account of
my experience. Hopefully it will help you decide whether to attend their
next class.

Ric's Disclaimer: Although I admit to generally being a fan of Amy's and Thomas's work, I've tried to write a balanced review, and I
paid full price for my ticket.

Format

The class mainly took the form of either Amy or Thomas - one at a time -
talking through slides and examples via live video and screen-sharing
(using Adobe Connect). There were two four-hour sessions (across 2 days) with breaks every hour or so, during which there were optional exercises
to complete based on the content just covered. There was also a more
challenging 'homework' exercise after the first day's session.

Whoever of Amy or Thomas weren't presenting were available in a
Campfire room for questions, clarification and general chat. There were twenty or so people in the class (and therefore
the chatroom), so I was initially worried that the chat room would be
too busy, but in my class only about half a dozen people actively
participated in the chat room, so it was easy to get my questions
answered.

This format worked really well, and didn't require an especially fast
Internet connection (I know this because my ISP was having problems on
the second day, and I had to connect using a 3G mobile modem!).

The slides (in original, and printable format) were available for
download before the course started, which I found useful since I
occasionally wanted to dwell on a slide. A recording of the video and a
transcript of the chat room were available for download a few days after
the class.

As a bonus, included in the price of the course (\$429), was a copy of
the JavaScript Performance Rocks e-book, which we
reviewed last year.

Content

Day One

The first day was presented by Amy (with Thomas in the chat room) and
covered JavaScript language principles including:

  • JavaScript's object model
  • Metaprogramming
  • Functions
  • Closures and scope
  • Extending the language
  • JSON
  • Constructors and prototypes
  • Mix-ins and inheritance

Day Two

Day Two moved on from esoteric language concepts on to how most of us
use JavaScript 'in the real' world i.e. in a browser context. The first
part was presented by Amy again and covered:

  • Browsers
  • The DOM
  • Events
  • Frameworks, such as Prototype.js

For the latter part of the second day, Thomas took over presenting and
Amy migrated to the chat room. Thomas gave some advice about how to
manage your own JavaScript projects, with the following topics:

  • Minification
  • Namespaces
  • Deployment
  • Preprocessors like Sprockets.js
  • Refactoring
  • Performance
  • Unit Testing
  • Documentation

Conclusion

The class was billed as a framework-agnostic course intermediate for
advanced level JavaScript developers, who want to "level up to expert".

I don't consider myself to be particularly advanced when it comes to
JavaScript, but I found that the Language parts of the course (i.e. Day
One and the first part of Day 2) were mainly just revision, although
Amy's and Thomas's explanations of the concepts (as well as the
exercises) did help to clarify my understanding.

It was great to get an insight into how experts like Thomas go about
organising large projects such as
Prototype.js, Script.aculo.us and Freckle (their time-tracking app).

Regarding framework agnosticism, although no prior knowledge of any
frameworks were required before the course, many examples were taken
from Prototype.js, (so being familiar with this helped) and the
presenters certainly weren't afraid of voicing their opinions of other
popular JavaScript frameworks. :)

I would have liked to have seen less focus on language concepts,
although they certainly did a good job of explaining them, and more
practical advice on applying them in different situations.

Having said that, I certainly felt that I got something from the course.
The content was engaging and well prepared, and it was fun to chat with
Amy, Thomas and the other participants (and ask their advice and
opinions on the matters covered). It's not often you get the opportunity
to get the attention of a true JavaScript master like Thomas Fuchs for a
full eight hours - for me, this was worth the admission fee alone.

Featured

libraries data underscore

backbone.js: JavaScript MVC

Posted on .

backbone.js from DocumentCloud is a small (2KB, packed) open-source library which allows you to apply the MVC
(Model-View-Controller) principle to your JavaScript applications. It helps provide a bit of structure for rich client side apps, by
preventing you from having to tie data directly to the DOM. When models
change, the views representing the data can be notified, causing them to
automatically re-render.

To define a model, you extend Backbone.Model with your own
properties and methods, and the framework provides ways to get and set
the attributes, set up validations, serialize the object, detect if it
has changed, etc. To save a valid model to the persistence layer,
Backbone will delegate to its sync function and make a
relevant RESTful request (using JSON by default) to the server.

Backbone proxies to DocumentCloud's
underscore library for dealing with collections of models.

For views, create a custom view class which extends
Backbone.view, and then instantiate it, passing some
options which can include the model, a collection, the HTML element,
etc... You can define a render function on the view to
setup the view (with whatever flavour of templating or DOM manipulation
you like), and this can be bound to model events.

The documentation is well
written and comprehensive, providing good examples, and there's a
test-suite too. Get the code on
Github

Featured

tutorials libraries jquery iPhone

jQTouch: Build iPhone Apps With JavaScript

Posted on .

jQTouch is a jQuery plugin for mobile web development. It lets you create native-feeling iPhone applications using
just HTML, CSS and JavaScript by taking advantage of native webkit
animations and by capturing events
such as swipes and orientation changes.

As the author, David Kaneda, writes in the online
documentation
, it's easy to get
started: Just include jQuery and jQTouch along with any
themes and extensions in your page, then initialize jQTouch with any
options.

So the head of your document might look a bit like this:

  jQTouch Example
  @import "../../jqtouch/jqtouch.min.css";
  @import "../../themes/jqt/theme.min.css";





    var jQT = new $.jQTouch({
      icon: 'jqtouch.png',
      addGlossToIcon: false,
      startupScreen: 'jqt_startup.png',
      statusBar: 'black'
    });

    // ... more js here ...

There are a few extensions provided (including one for access to the
iPhone's geo-location features, and another for auto-setting the title
in the toolbar from the referrer page), but it's possible to add your
own by writing a function and passing it to
\$.jQTouch.addExtension().

(function($) {
    if ($.jQTouch)
    {
        $.jQTouch.addExtension(function Counter(jQTouch){
            var mycount = 0;          
            function addOne() {
                ++mycount;
            }
            function getCount() {
                return mycount;
            }
            return {
                addOne: addOne,
                getCount: getCount
            }
        });
    }
})(jQuery);

It's even possible to make your jQTouch sites run
offline
, like a
native iPhone app, by using HTML5's Cache
Manifest
feature.

A great way to get started with jQTouch is by exploring the demos that
David has provided in the
download. These cover all of the features I've mentioned here, plus lots more besides: I've only
scraped the surface.

If you want to dig deeper, there's a screencast on
PeepCode
, and online in a
Creative Commons O'Reilly book called Building iPhone Apps with HTML,
CSS, and
JavaScript
.

Featured

libraries jquery css

Uniform - Sexy Forms With jQuery

Posted on .

Uniform is a jQuery plugin from Pixelmatrix design which lets you style form elements such as checkboxes, drop down menus, radio buttons, and
file upload inputs in a consistent and accessible way across different
browsers (unfortunately, this doesn't include IE6 at the moment).

To use it, just link to the uniform JavaScript and css files from your
html page, and then call the uniform function against the form
element(s), passing in any parameters. Full details of the parameters
are available on the Uniform
site
.

$(function(){ $("select").uniform(); });

You don't need to just stick with the default style: you can design
your own
or download
others from the Internet.