<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><atom:link rel="self" href="http://www.sandfield.co.nz/SandfieldNews.xml" xmlns:atom="http://www.w3.org/2005/Atom" /><title>Sandfield That’s Technical</title><link>http://www.sandfield.co.nz</link><description>That’s Technical</description><language>en-us</language><copyright>SANDFIELD ASSOCIATES LIMITED</copyright><lastBuildDate>Thu, 23 Oct 2014 11:00:00 GMT</lastBuildDate><ttl>60</ttl><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/342/Arduino-Not-just-childs-play</guid><title>Arduino - Not just childs play</title><description>&lt;p dir="ltr"&gt;An Arduino is essentially a small portable computer that is capable of taking inputs and interpreting that information to control various outputs.&lt;/p&gt;
&lt;p dir="ltr"&gt;Arduino bridges programming and the physical world. These are not merely for kids but allow you to build all types of prototypes and projects, including GPS, tweeting and camera snapping.&lt;/p&gt;
&lt;p dir="ltr"&gt;When for a school project my daughter wanted to invent a locking pencil case, I saw this as a good excuse to get an Arduino.&lt;/p&gt;
&lt;p dir="ltr"&gt;Our first step was to get a Sparkfun Inventor&amp;rsquo;s Kit from Mindkits, with some additional components that we would be needing.&lt;/p&gt;
&lt;p dir="ltr"&gt;The Kit is a great way to get started as it includes a guide book and all the pieces needed to get 14 basic circuits working.&lt;/p&gt;
&lt;p dir="ltr"&gt;&lt;img src="https://lh6.googleusercontent.com/pZtMZ6JXXfsfvhQfHueZQwMZ31lVZcto5-5oWbKjPAUxdFtIVQd_Q_sweabnRlbZXmrzOMkIKuTKF43nUJq08ukajZAczPR6kvzWMtDMcUZlcj90bfYjyUmPKlN9j6oAMg" alt="Arduino 1" width="400" height="300" /&gt;&lt;/p&gt;
&lt;p dir="ltr"&gt;To get a circuit constructed, you plug the electronic components (wires, registers, motors) into a breadboard. No soldering is required. You then connect wires from the ports on the Arduino to the breadboard.&lt;/p&gt;
&lt;p dir="ltr"&gt;To make it work, you write a sketch (an Arduino term for a program) using the Arduino software. You compile the sketch and load it through the USB cable onto the Arduino. Once loaded, if the circuit is connected correctly, things start happening.&lt;/p&gt;
&lt;p dir="ltr"&gt;The good part with the Kit, is that all these steps are documented for you, and it provides 14 different circuits for you to construct with example sketches, ready for you to load and run.&lt;/p&gt;
&lt;p dir="ltr"&gt;Sketch for controlling a motor:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;// We'll be controlling the motor from pin 9.
const int motorPin = 9;
　
void setup()
{
// Set up the motor pin to be an output:
pinMode(motorPin, OUTPUT);
}
void loop()
{
motorOnThenOff();
}
　
// This function turns the motor on and off like the blinking LED.
// Try different values to affect the timing.
void motorOnThenOff()
{
int onTime = 3000; // milliseconds to turn the motor on
int offTime = 3000; // milliseconds to turn the motor off
digitalWrite(motorPin, HIGH); // turn the motor on (full speed)
delay(onTime); // delay for onTime milliseconds
digitalWrite(motorPin, LOW); // turn the motor off
delay(offTime); // delay for offTime milliseconds
}
&lt;/pre&gt;
&lt;p dir="ltr"&gt;&lt;br /&gt;As you can see, a sketch is quite simple in its elements, but is very powerful with the results.&lt;/p&gt;
&lt;p dir="ltr"&gt;The Arduino is a great way to get your child interested in electronics and programming, as it provides a simple and tangible way of relating electronics to the real world. They can experiment by adjusting the example sketches to create new behaviour and learn basic programming skills.&lt;/p&gt;
&lt;p dir="ltr"&gt;So after experimenting with how the &amp;nbsp;Arduino works, my daughter decided that she wanted to have a keypad that would accept a code to unlock the pencil case.&lt;/p&gt;
&lt;p dir="ltr"&gt;So I helped her turn her design into a working prototype. We combined three Arduino sketches to make a&lt;a href="https://www.tyler-davies.co.nz/1312Dec/PencilPassLock.mp4" target="_blank"&gt; keypad controlled solenoid&lt;/a&gt; which moved to open the lock.&lt;/p&gt;
&lt;p dir="ltr"&gt;The three example sketches used were:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;
&lt;p dir="ltr"&gt;Electronic motor (replaced with a solenoid)&lt;/p&gt;
&lt;/li&gt;
&lt;li class="page-bullet"&gt;
&lt;p dir="ltr"&gt;Buzzer&lt;/p&gt;
&lt;/li&gt;
&lt;li class="page-bullet"&gt;
&lt;p dir="ltr"&gt;Keypad&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p dir="ltr"&gt;The hardest part was actually making the latch for the solenoid to click into.&lt;/p&gt;
&lt;p dir="ltr"&gt;Below is the final Pencil Passlock. Given the space that the Arduino took up, there wasn&amp;rsquo;t much room for the pencils.&lt;/p&gt;
&lt;p dir="ltr"&gt;&lt;img src="https://lh4.googleusercontent.com/SZ8mn96xpVSsyuifcwYt3A2eozsGWzHP3GHAaXIgCY8bnp4h5hBV0IKzjtdbx7i3IbArYlmAzD5_VH5ammhV3z04Hwsvbx8L2_f1trPVOsFJOTwXKRP6W7No6RibxkKLNw" alt="PencilPassLock1.jpg" width="400" height="300" /&gt;&lt;/p&gt;
&lt;p dir="ltr"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p dir="ltr"&gt;&lt;img src="https://lh4.googleusercontent.com/pw8hxqly0FnFBzIt6ULwxeWl981EWvtVTJl6y5gTAZSWFy1tfPb6nTc6IijXzlPYUxpDQ_xfsCOjb1CXW4g-2uKu_zdlSd-YLrQVjKq_WFV1PgiiG_vfk8KMJQj9CCf2yw" alt="PencilPassLock2.jpg" width="400;" height="300" /&gt;&lt;/p&gt;
&lt;p dir="ltr"&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class="prettyprint"&gt;// Pencil Passlock - keypad and solenoid
/*
note 	frequency
c 262 Hz
d 294 Hz
e 330 Hz
f 349 Hz
g 392 Hz
a 440 Hz
b 494 Hz
C 523 Hz
*/
const int buzzerPin = 9;
const int duration = 150;
const int note = 262;
const int solenoidPin = 10;
const int onTime = 3000; // milliseconds to turn the solenoid on
const int offTime = 3000; // milliseconds to turn the solenoid off
const int numRows = 4; // number of rows in the keypad
const int numCols = 3; // number of columns
const int debounceTime = 20; // number of milliseconds for switch to be 
// stable  keymap defines the character returned when the corresponding 
// key is pressed 
const char keymap[numRows][numCols] = {
{ '1', '2', '3' } ,
{ '4', '5', '6' } ,
{ '7', '8', '9' } ,
{ '*', '0', '#' }
};
// this array determines the pins used for rows and columns
const int rowPins[numRows] = { 8, 7, 6, 5 }; // Rows 0 through 3
const int colPins[numCols] = { 4, 3, 2 }; // Columns 0 through 2
String passcode = "4224";
String code;
void setup()
{
code = "";
// Set up the motor pin to be an output:
pinMode(solenoidPin, OUTPUT);
// Set up the buzzer:
pinMode(buzzerPin, OUTPUT);
// Set up the serial port:
Serial.begin(9600);
for (int row = 0; row &amp;lt; numRows; row++)
{
pinMode(rowPins[row],INPUT); // Set row pins as input
digitalWrite(rowPins[row],HIGH); // turn on Pull-ups
}
for (int column = 0; column &amp;lt; numCols; column++)
{
pinMode(colPins[column],OUTPUT); // Set column pins as outputs
digitalWrite(colPins[column],HIGH); // Make all columns inactive
}
}
　
void loop()
{
char key = getKey();
if( key != 0) { // if the character is not 0 then
// it's a valid key press
Serial.print("Got key ");
Serial.println(key);
tone(buzzerPin, note, duration);
delay(duration); // wait for tone to finish
if( isDigit(key) ) {
code = code + key;
}
if( key == '*') {
code = "";
}
if( key == '#') {
Serial.print("Got code ");
Serial.println(code);
if( code.compareTo(passcode) == 0){
Serial.println("Right code");
tone(buzzerPin, note, duration);
delay(duration); // wait for tone to finish
turnSolenoidOn();
}
code = "";
}
}
}
　
void turnSolenoidOn()
{
digitalWrite(solenoidPin, HIGH); // turn the motor on (full speed)
delay(onTime); // delay for onTime milliseconds
digitalWrite(solenoidPin, LOW); // turn the motor off
delay(offTime); // delay for offTime milliseconds
}
// returns with the key pressed, or 0 if no key is pressed
char getKey()
{
char key = 0; // 0 indicates no key pressed
for(int column = 0; column &amp;lt; numCols; column++)
{
digitalWrite(colPins[column],LOW); // Activate the current column.
for(int row = 0; row &amp;lt; numRows; row++) // Scan all rows for
// a key press.
{
if(digitalRead(rowPins[row]) == LOW) // Is a key pressed?
{
delay(debounceTime); // debounce
while(digitalRead(rowPins[row]) == LOW); // wait for key
    // to be released
key = keymap[row][column]; // Remember which key
     // was pressed.
}
}
digitalWrite(colPins[column],HIGH); // De-activate the current column.
}
return key; // returns the key pressed or 0 if none
}
&lt;/pre&gt;
&lt;p dir="ltr"&gt;&lt;br /&gt;To get going yourself, check out the following links:&lt;/p&gt;
&lt;p dir="ltr"&gt;&lt;a href="https://www.mindkits.co.nz/" target="_blank"&gt;https://www.mindkits.co.nz/&lt;/a&gt;&lt;/p&gt;
&lt;p dir="ltr"&gt;&lt;a href="https://www.mindkits.co.nz/store/kits/sparkfun-inventors-kit-v3-1" target="_blank"&gt;https://www.mindkits.co.nz/store/kits/sparkfun-inventors-kit-v3-1&lt;/a&gt;&lt;/p&gt;
&lt;p dir="ltr"&gt;&lt;a href="https://learn.sparkfun.com/" target="_blank"&gt;https://learn.sparkfun.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><author>Brent Tyler-Davies</author><link>http://www.sandfield.co.nz/News/Thats-Technical/342/Arduino-Not-just-childs-play</link><pubDate>Thu, 23 Oct 2014 11:00:00 GMT</pubDate></item><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/257/AngularJS</guid><title>AngularJS</title><description>&lt;h3&gt;What is AngularJS?&lt;/h3&gt;
&lt;p&gt;AngularJS is an open-source JavaScript framework that has been designed for the construction of single-page applications. It was first released in 2009 and is currently built and maintained by Google as well as the community.&lt;/p&gt;
&lt;p&gt;AngularJS was built with the MVC software pattern in mind and encourages loose coupling between presentation, data, and logic layers. It brings traditional server-side components such as view dependent controllers to the client-side. This removes much of the processing burden from the server and leads to a much lighter and more responsive web application.&lt;/p&gt;
&lt;h3&gt;Where does AngularJS fit in?&lt;/h3&gt;
&lt;p&gt;AngularJS is considered to be what HTML would have been had it been designed for applications. HTML is a great markup language for building static documents. However it doesn&amp;rsquo;t really contain much in the way of dynamic application building, and as a result, building web applications with HTML is an exercise in &amp;ldquo;what do I have to do to trick the browser into doing what I need it to do&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;This issue between dynamic applications and static documents is often solved with:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;a &lt;strong&gt;library&lt;/strong&gt; - a collection of functions where your code is in charge and it calls into the library when it needs to perform a specialised task e.g. jQuery.&lt;/li&gt;
&lt;li class="page-bullet"&gt;a &lt;strong&gt;framework&lt;/strong&gt; - a particular implementation of a web application where your code fills in the details. The framework is in charge and it calls into your code when it needs something app specific e.g. knockoutJS.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AngularJS takes a different approach to these. It attempts to enhance HTML for application building by adding new constructs known as directives. Directives are applied as extra attributes to HTML elements and are used by AngularJS to add additional functionality to a web application.&lt;/p&gt;
&lt;p&gt;Here are some common AngularJS directives that help improve HTML for application building.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-app&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Declares an element as the root of an application and is used to initialise directives that are nested inside it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-bind&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Automatically changes the text of a HTML element to the value of a given expression.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-model&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Similar to ng-bind, but facilitates two-way data binding between a view and the angular scope object (explained later).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-class&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Allows class attributes to be dynamically loaded into the page. This is useful because it allows the developer to change the class attribute of a particular element based on the result of an expression.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-controller&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Specifies a JavaScript controller class that can be used to evaluate HTML expressions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-repeat&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Used to iterate through an array of items and render a block of html for each item in the collection.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-show &amp;amp; ng-hide&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Used to conditionally show or hide an element which is determined by the result of a boolean expression.&lt;/p&gt;
&lt;h3&gt;Core components&lt;/h3&gt;
&lt;p&gt;Every angular application is comprised of the following core components which follow the Model-View-Controller (MVC) software engineering pattern.&lt;/p&gt;
&lt;h3&gt;Model (Scope)&lt;/h3&gt;
&lt;p&gt;In AngularJS scope is an object that is used to define the model of an application. Each application can have multiple scopes which are arranged in hierarchical structure to mimic the DOM. Scope can be thought of as the link between the application controller and the view.&lt;/p&gt;
&lt;p&gt;When an application is loaded, directives set up watchers on the scope. These watchers enable directives to be notified of value changes and perform actions based on those changes as they occur. As you interact with an AngularJS application, you&amp;rsquo;ll notice that variables bound to the scope automatically update the page as changes occur. This gives the user a dynamic experience without having to perform postbacks to display new information.&lt;/p&gt;
&lt;h3&gt;View&lt;/h3&gt;
&lt;p&gt;The view is a projection of the data model (scope) which is set up by the controller. The view consists of plain HTML code and AngularJS directives.&lt;/p&gt;
&lt;h3&gt;Controller&lt;/h3&gt;
&lt;p&gt;In AngularJS controllers are nothing but plain JavaScript functions which are bound to a particular scope object. Controllers reside in the code behind the view and their job is to construct the data model and publish it to the view for rendering.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key points&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;Controllers are written in JavaScript and should not contain any rendering information, such as DOM references or HTML fragments.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Views are written in HTML and should not contain any behaviour.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Controllers are not aware of the view they are attached to, so it&amp;rsquo;s possible to have multiple views attached to the same controller. This is useful because it enables you to create device specific views. For example, you can have a separate view for mobile and desktop devices and have them use the same controller for functionality.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="prettyprint lang-html linenums prettyprinted"&gt;&amp;lt;html ng-app&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Controllers&amp;lt;/title&amp;gt;
&amp;lt;script src="../Scripts/angular.min.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript"&amp;gt;
  //Controller takes $scope object as a parameter
  //to establish link to the view
  function ContactController($scope) {

    $scope.contacts = ["John", "Jane"];

      $scope.add = function () {
        $scope.contacts.push($scope.newcontact);
        $scope.newcontact = "";
    }
  }
&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;Controllers&amp;lt;/h1&amp;gt;

&amp;lt;!-- View with controller defined --&amp;gt;
&amp;lt;div ng-controller="ContactController"&amp;gt;
  Contact &amp;lt;input type="text" ng-model="newcontact"/&amp;gt;
          &amp;lt;button ng-click="add()"&amp;gt;Add&amp;lt;/button&amp;gt;
  &amp;lt;h3&amp;gt;Contacts&amp;lt;/h3&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;!-- Iterate over the contact array defined in scope --&amp;gt;
    &amp;lt;li ng-repeat="contact in contacts"&amp;gt;{{contact}}&amp;lt;/li&amp;gt;
  &amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;h3&gt;Filters&lt;/h3&gt;
&lt;p&gt;A common requirement when building an application is formatting the data before it is displayed to the user. AngularJS provides filters for this purpose. Filters are applied to expressions on the page, they can be chained together, and some can also take optional parameters.&lt;/p&gt;
&lt;p&gt;To apply a filter we use the following syntax.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{{ expression | filter:param }}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Some common filters include:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Number&lt;/strong&gt; - By default, the number filter will format a number to two decimal places. This can also take decimal places as an optional parameter.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{{ "12345.67123" | number:3 }}&lt;/code&gt; evaluates to 12345.671 at runtime.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Currency&lt;/strong&gt; - Formats a number as currency. This can also take an optional symbol parameter.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{{ "12345.67" | currency:"NZD$" }}&lt;/code&gt; evaluates to NZD$12,345.67 at runtime.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Date&lt;/strong&gt; - Formats a JavaScript date variable. This can also take an optional date format parameter, which could be one of the predefined date strings provided by AngularJS or a standard date format string.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{{ dateVariable | date:"mediumDate" }}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OrderBy&lt;/strong&gt; - A very useful filter which can be used to apply sorting to an array. In its simplest form the orderBy filter accepts a string for evaluation and uses the result for sorting.&lt;/p&gt;
&lt;pre class="prettyprint lang-html linenums prettyprinted"&gt;&amp;lt;html ng-app&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Date Filters&amp;lt;/title&amp;gt;
  &amp;lt;script src="../Scripts/angular.min.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script type="text/javascript"&amp;gt;

    function DateController($scope) {
      $scope.currentDate = new Date();
    }

  &amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;h1&amp;gt;Date Filters&amp;lt;/h1&amp;gt;
  &amp;lt;table ng-controller="DateController"&amp;gt;
    &amp;lt;tr&amp;gt;&amp;lt;th align="left"&amp;gt;Filter&amp;lt;/th&amp;gt;&amp;lt;th align="left"&amp;gt;Output&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;default:&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ currentDate | date }}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;mediumDate:&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ currentDate | date:"mediumDate" }}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;short:&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ currentDate | date:"short" }}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;fullDate:&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ currentDate | date:"fullDate" }}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;longDate:&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ currentDate | date:"longDate" }}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;shortDate:&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ currentDate | date:"shortDate" }}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;mediumTime:&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ currentDate | date:"mediumTime" }}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;shortTime:&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ currentDate | date:"shortTime" }}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
  &amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;h3&gt;Validation&lt;/h3&gt;
&lt;p&gt;AngularJS makes it very simple to add client-side validation without much effort. Although client-side validation doesn&amp;rsquo;t ensure that an application will be secure, it does allow us to provide feedback to the user on the current state of a form without having to call the server.&lt;/p&gt;
&lt;p&gt;Some common AngularJS validators include:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;required&lt;/strong&gt; - Provided in HTML5 and utilised by AngularJS. This ensures that the user enters a value into an input field.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-minlength &lt;/strong&gt;- Checks whether a field value is at least a specified number of characters in length.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-maxlength&lt;/strong&gt; - Checks whether a field value is no greater than a specified number of characters in length.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ng-pattern&lt;/strong&gt; - Checks whether a value matches a given regex pattern.&lt;/p&gt;
&lt;p&gt;AngularJS also provides validation properties on the $scope object. This is useful because it enables us to react to changes to validation in real time.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Validation properties available through the scope object include:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$pristine&lt;/strong&gt; - a boolean variable that evaluates to &amp;ldquo;True&amp;rdquo; if the user has not interacted with the form yet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$dirty&lt;/strong&gt; - a boolean variable that evaluates to &amp;ldquo;True&amp;rdquo; if the user has already interacted with the form.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$valid&lt;/strong&gt; - a boolean variable that evaluates to &amp;ldquo;True&amp;rdquo; if all of the containing forms and controls are valid.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$invalid&lt;/strong&gt; - a boolean variable that evaluates to &amp;ldquo;True&amp;rdquo; if at least one containing control or form is invalid.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$error&lt;/strong&gt; - an object hash containing references to all invalid controls or forms. This is useful for identifying specific controls that are invalid on the page.&lt;/p&gt;
&lt;p&gt;When AngularJS validates a form, special classes are applied to the element based on the validation applied to the element. This means that CSS can be used to style the page based on validation.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;AngularJS applies the following validation classes to elements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.ng-pristine&lt;/strong&gt; - added when the user has not interacted with the control being validated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.ng-dirty&lt;/strong&gt; - added if the user has interacted with the control being validated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.ng-valid&lt;/strong&gt; - added if the control being validated is valid.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.ng-invalid&lt;/strong&gt; - added if the control being validated is invalid.&lt;/p&gt;
&lt;pre class="prettyprint lang-html linenums prettyprinted"&gt;&amp;lt;html ng-app&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Validation&amp;lt;/title&amp;gt;
  &amp;lt;style type="text/css"&amp;gt;
     input.ng-valid 
     {
       background-color:lightgreen;
     }
     input.ng-invalid 
     {
       border:1px solid red !important;
     }
     input.ng-pristine 
     {
       border:1px solid #dadada !important;
     }
     .error 
     {
       display:inline;
     }
  &amp;lt;/style&amp;gt;
  &amp;lt;script src="../Scripts/angular.min.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;form name="frmSignUp"&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label&amp;gt;Enter your name&amp;lt;/label&amp;gt;

      &amp;lt;input type="text"
         placeholder="Name"
         class="form-control"
         name="name"
         ng-model="name"
         ng-minlength="3"
         ng-maxlength="20" 
         required  /&amp;gt;

      &amp;lt;br /&amp;gt;
      &amp;lt;button type="submit"
          ng-disabled="frmSignUp.$invalid"&amp;gt;Submit&amp;lt;/button&amp;gt;

      &amp;lt;div class="error"
         ng-show="frmSignUp.name.$dirty &amp;amp;&amp;amp; frmSignUp.name.$invalid"&amp;gt;

           &amp;lt;small class="error"
                  ng-show="frmSignUp.name.$error.required"&amp;gt;
              Your name is required.
           &amp;lt;/small&amp;gt;

           &amp;lt;small class="error"
                  ng-show="frmSignUp.name.$error.minlength"&amp;gt;
              Your name is required to be at least 3 characters.
           &amp;lt;/small&amp;gt;

           &amp;lt;small class="error"
                  ng-show="frmSignUp.name.$error.maxlength"&amp;gt;
              Your name cannot be longer than 20 characters.
           &amp;lt;/small&amp;gt;

       &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;AngularJS makes building applications faster by removing boilerplate code and presenting a higher level of abstraction. Its in-built expressions and data binding enables AngularJS to validate, format, and display updated information on the page without performing post backs, making AngularJS an ideal component for building single page applications.&lt;/p&gt;
&lt;p&gt;AngularJS was built with the Create, Read, Update and Delete (CRUD) application in mind, though in our opinion the best fit would be for simple CRUD applications. Applications that require intensive and tricky DOM manipulation are not a good fit for AngularJS, so a library such as jQuery should probably be used in these cases.&lt;/p&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angularjs.org/" target="_blank"&gt;https://angularjs.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.angularjs.org/" target="_blank"&gt;https://docs.angularjs.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://viralpatel.net/blogs/angularjs-controller-tutorial/" target="_blank"&gt;https://viralpatel.net/blogs/angularjs-controller-tutorial/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ng-newsletter.com/posts/validations.html" target="_blank"&gt;https://www.ng-newsletter.com/posts/validations.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://suhairhassan.com/2013/07/25/angularjs-in-depth-part-2.html#.Ul5UhlAwo2c" target="_blank"&gt;https://suhairhassan.com/2013/07/25/angularjs-in-depth-part-2.html#.Ul5UhlAwo2c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/AngularJS" target="_blank"&gt;https://en.wikipedia.org/wiki/AngularJS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><author>Mathew Porter</author><link>http://www.sandfield.co.nz/News/Thats-Technical/257/AngularJS</link><pubDate>Wed, 20 Nov 2013 11:00:00 GMT</pubDate></item><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/217/WordPress-Security</guid><title>WordPress Security</title><description>&lt;p&gt;WordPress is a popular and widely used content management system. In fact, around 19% of all websites to date are running on WordPress. The growing popularity and use of WordPress as a CMS makes securing it more important than ever. According to a &lt;a href="https://www.wptemplate.com/features/safety-and-security-of-wordpress-blog-infographic.html" target="_blank"&gt;security article&lt;/a&gt; written by WPTemplate.com the number of WordPress websites that were hacked in 2012 alone, reached a whopping 170,000. It is completely up to the website owner to ensure that their WordPress website is secured as tightly as possible to avoid being compromised.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/wordpress_security_statistics.png" alt="" width="525px;" height="389px;" /&gt;&lt;/p&gt;
&lt;h3&gt;WordPress security encompasses three major areas:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;the hosting environment&lt;/li&gt;
&lt;li&gt;the database environment&lt;/li&gt;
&lt;li&gt;WordPress specific settings and files&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This article covers the first of the three areas mentioned above. As we host a number of our clients' websites, we need to ensure that these websites are as secure as possible in order to avoid malicious attacks to the websites, or even worse, to our servers.&lt;/p&gt;
&lt;p&gt;According to WPTemplate.com, one of the main reasons WordPress sites get hacked is due to poor security considerations in the hosting environment.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/how_wordpress_get_hacked.png" alt="" width="454px;" height="320px;" /&gt;&lt;/p&gt;
&lt;p&gt;At Sandfield, our systems and websites are built and hosted on Windows servers. This makes dealing with WordPress slightly more complicated as the majority of WordPress websites are hosted on Linux/Apache environments and thus the documentation for a Windows environment is harder to find. I wrote this article in the hopes that my experiences will save others time and effort and also to illustrate that securing WordPress websites on a Windows/IIS environment can be done effectively.&lt;/p&gt;
&lt;h3&gt;The Initial Setup&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.microsoft.com/web/downloads/platform.aspx" target="_blank"&gt;Web Platform Installer&lt;/a&gt; (Web PI) is a tool that installs everything you need to get WordPress up and running on a Windows machine.&lt;/p&gt;
&lt;h3&gt;What is installed?&lt;/h3&gt;
&lt;p&gt;Web PI will only install dependencies to WordPress that your current environment doesn&amp;rsquo;t have. This includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;PHP&lt;/li&gt;
&lt;li class="page-bullet"&gt;IIS&lt;/li&gt;
&lt;li class="page-bullet"&gt;WordPress&lt;/li&gt;
&lt;li class="page-bullet"&gt;MySQL&lt;/li&gt;
&lt;li class="page-bullet"&gt;IIS URL Rewrite Module
&lt;ul&gt;
&lt;li class="page-bullet"&gt;&lt;a href="https://www.iis.net/downloads/microsoft/url-rewrite" target="_blank"&gt;https://www.iis.net/downloads/microsoft/url-rewrite&lt;/a&gt;&lt;/li&gt;
&lt;li class="page-bullet"&gt;This module is used to get &amp;ldquo;Pretty Permalinks&amp;rdquo; for WordPress working.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class="page-bullet"&gt;WinCache Extension for PHP
&lt;ul&gt;
&lt;li class="page-bullet"&gt;&lt;a href="https://www.iis.net/downloads/microsoft/wincache-extension" target="_blank"&gt;https://www.iis.net/downloads/microsoft/wincache-extension&lt;/a&gt;&lt;/li&gt;
&lt;li class="page-bullet"&gt;A PHP accelerator that is used to increase the speed of PHP applications on Windows.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Stores compiled versions of PHP scripts in memory in order to be readily available when needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What accounts get created?&lt;/h3&gt;
&lt;p&gt;During installation, you will be asked to create an account for the MySQL instance. You will need to set up the administrator (root) password for the MySQL database.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Be sure to save this information as you will need it later in the process.&lt;/li&gt;
&lt;li&gt;Make sure you don&amp;rsquo;t use default passwords.&lt;/li&gt;
&lt;li&gt;Remember to change the administrator's username from root to something harder to guess.&lt;/li&gt;
&lt;li&gt;You will then be prompted to enter the necessary information for your WordPress website.&lt;/li&gt;
&lt;li&gt;When it comes to entering a series of secret keys, I found &lt;a href="https://api.wordpress.org/secret-key/1.1/%20" target="_blank"&gt;this tool&lt;/a&gt; to be quite handy to generate four unique keys on the fly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;WordPress will now be successfully installed on your Windows machine.&lt;/p&gt;
&lt;h3&gt;IIS and File Permissions&lt;/h3&gt;
&lt;p&gt;This area cost me a lot of time and patience to get right due to the limited documentation and the different versions of IIS on different Windows servers. When initially starting up, I ran into many permission related issues. These ranged from not being able to automatically update WordPress and/or plugins, to getting 500 Internal errors upon clicking images when the files were uploaded to the server via a third party plugin. After countless failed attempts and much trial and error I have finally come up with a permissions system on IIS that is as tightly secured as possible and runs as expected.&lt;/p&gt;
&lt;p&gt;Firstly, you should never set your WordPress file permissions to be accessible by the generic &amp;ldquo;Everyone&amp;rdquo; group. This will give every user on the server access to your files and a malicious attacker could use this to their advantage.&lt;/p&gt;
&lt;h3&gt;IIS 7&lt;/h3&gt;
&lt;p&gt;In IIS 7, the IIS web server by default runs under its own user and user group - IUSR and IIS_IUSRS respectively. It is acceptable to set the file permissions on the website files to be read by the IIS_IUSRS group. Acceptable but not ideal as the IUSR runs as a NETWORK SERVICE account which can be tampered with by other services that run under the same identity. If possible we recommend upgrading to IIS 7.5.&lt;/p&gt;
&lt;h3&gt;IIS 7.5&lt;/h3&gt;
&lt;p&gt;With the release of IIS 7.5, the IIS worker processes became isolated from other Windows system services through a feature called &amp;ldquo;Virtual Accounts&amp;rdquo;. This feature allows IIS to create unique accounts for each Application Pool.&lt;/p&gt;
&lt;h4&gt;IIS 7.5 on Windows Server 2008 R2&lt;/h4&gt;
&lt;p&gt;If you are running IIS 7.5 on Windows Server 2008 R2, you don't have to do anything to use the new identity. For every application pool created, the IIS Admin Process (WAS) will create a virtual account with the same name as the Application Pool, and will run the Application Pool&amp;rsquo;s worker processes under this account. This gives another layer of security to the server as now files can be granted read/write access only by the specified application pool identity user.&lt;/p&gt;
&lt;h4&gt;IIS 7.5 on Windows Server 2008&lt;/h4&gt;
&lt;p&gt;If you are running IIS 7.5 on Windows Server 2008, you have to change the IdentityType property of the Application Pools you create to "AppPoolIdentity". Here is how:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open IIS Manager.&lt;/li&gt;
&lt;li&gt;Open the Application Pools node underneath the machine node. Select the Application Pool you want to change to run under an automatically generated Application Pool Identity.&lt;/li&gt;
&lt;li&gt;Right click the Application Pool and select "Advanced Settings..."&lt;br /&gt;&lt;br /&gt; &lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/application-pool-identities.png" alt="" width="345px;" height="421px;" /&gt;&lt;/li&gt;
&lt;li&gt;Set the Process Model "Identity" to "ApplicationPoolIdentity".&lt;br /&gt;&lt;br /&gt; &lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/application-pool-identities-_process_model.png" alt="" width="301px;" height="174px;" /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Securing your files (IIS 7.5 on 2008 and 2008 R2)&lt;/h3&gt;
&lt;p&gt;Once you have your App Pool Identity sorted out, you need to set authentication on IIS to use the Application Pool Identity as opposed to the default account IUSR.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In IIS Manager, click on the Website node.&lt;/li&gt;
&lt;li&gt;Double click the Authentication icon&lt;br /&gt; &lt;br /&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/iis_website_authentication.png" alt="" width="230px;" height="179px;" /&gt;&lt;/li&gt;
&lt;li&gt;Right click on the authentication your website uses (usually Anonymous) and select &amp;ldquo;Edit&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Select &amp;ldquo;Application pool identity&amp;rdquo; as the user that IIS will execute under.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/edit_anonymous_authentication.png" alt="" width="472px;" height="415px;" /&gt;&lt;/p&gt;
&lt;p&gt;Lastly, you need to change the permissions on your files. To grant access to this new virtual account, you would go to the root folder of your website installation. Right click -&amp;gt; &amp;ldquo;Properties&amp;rdquo;. Remove all groups that are not applicable, e.g. Everyone, Users. Do not remove System or Administrators, then click on &amp;ldquo;Edit&amp;hellip;&amp;rdquo;, then on &amp;ldquo;Add&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/virtual_folder_permissions_group.png" alt="" width="287px;" height="119px;" /&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/add_system_access.png" alt="" width="222px;" height="109px;" /&gt;&lt;/p&gt;
&lt;p&gt;In the object name to select, type in &amp;ldquo;IIS APPPOOL\App Pool Name&amp;rdquo;. (Make sure the location is set to the top level computer). Replacing &amp;ldquo;App Pool Name&amp;rdquo; with your application pool, in this case &amp;ldquo;Test&amp;rdquo;.&lt;br /&gt; &lt;br /&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/select_users_or_groups.png" alt="" width="477px;" height="289px;" /&gt;&lt;/p&gt;
&lt;p&gt;When you click &amp;ldquo;Check Names&amp;rdquo;, the name has been accepted if only the Application Pool name remains in underlined font.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/application_pool_underlined.png" alt="" width="441px;" height="80px;" /&gt;&lt;/p&gt;
&lt;p&gt;Once done, make sure the new Application Pool virtual account has the appropriate access to the folder selected. If it was the top level WordPress folder, then the Application Pool virtual account should only have Read/Execute access. Click OK.&lt;br /&gt;&lt;br /&gt; &lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/virtual_folder_access.png" alt="" width="343px;" height="344px;" /&gt;&lt;/p&gt;
&lt;p&gt;To ensure that these permissions get propagated all the way throughout the website folder structure, click on the Security tab -&amp;gt; Advanced and check the box that says &amp;ldquo;Replace all child object permission entries with inheritable permission entries from this object&amp;rdquo;.&lt;br /&gt; &lt;br /&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/advanced_security_settings_virtual_folder.png" alt="" width="523px;" height="353px;" /&gt;&lt;/p&gt;
&lt;p&gt;Once you are done with this step, all that is left to do is to give the new Application Pool virtual account write access to the folders you would like it to be writable to. If you want to update plugins automatically, the webserver needs &amp;ldquo;Write&amp;rdquo; access to the plugins folder. Similarly with theme updates. Generally it is okay to have the wp-content folder writable by the webserver, but you can restrict this as much as you like.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.sandfield.co.nz/AdditionalFiles/Images/blogs/ThatsTechnical/permission_for_wp-content.png" alt="" width="309px;" height="374px;" /&gt;&lt;/p&gt;
&lt;p&gt;If you have made it this far, congratulations. And remember, make sure you test your website!&lt;/p&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://venturebeat.com/2013/07/27/19-percent-of-the-web-runs-on-wordpress/" target="_blank"&gt;https://venturebeat.com/2013/07/27/19-percent-of-the-web-runs-on-wordpress/&lt;/a&gt;&lt;br /&gt;&lt;a href="https://codex.wordpress.org/Installing_on_Microsoft_IIS" target="_blank"&gt;https://codex.wordpress.org/Installing_on_Microsoft_IIS&lt;/a&gt;&lt;br /&gt;&lt;a href="https://codex.wordpress.org/Installing_WordPress#Easy_5_Minute_WordPress_Installation_on_Windows" target="_blank"&gt;https://codex.wordpress.org/Installing_WordPress#Easy_5_Minute_WordPress_Installation_on_Windows&lt;/a&gt;&lt;br /&gt;&lt;a href="https://docs.joomla.org/How_do_Windows_file_permissions_work%3F" target="_blank"&gt;https://docs.joomla.org/How_do_Windows_file_permissions_work%3F&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stackoverflow.com/questions/14934006/iis-iusrs-and-iusr-permissions-in-iis8" target="_blank"&gt;https://stackoverflow.com/questions/14934006/iis-iusrs-and-iusr-permissions-in-iis8&lt;/a&gt;&lt;br /&gt;&lt;a href="https://chris.wastedhalo.com/2011/01/wordpress-upload-permissions-on-iis-7-fix/" target="_blank"&gt;https://chris.wastedhalo.com/2011/01/wordpress-upload-permissions-on-iis-7-fix/&lt;/a&gt;&lt;br /&gt;&lt;a href="https://www.wptemplate.com/features/safety-and-security-of-wordpress-blog-infographic.html" target="_blank"&gt;https://www.wptemplate.com/features/safety-and-security-of-wordpress-blog-infographic.html&lt;/a&gt;&lt;/p&gt;</description><author>Ana Petreska</author><link>http://www.sandfield.co.nz/News/Thats-Technical/217/WordPress-Security</link><pubDate>Thu, 22 Aug 2013 12:00:00 GMT</pubDate></item><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/214/Web-SQL</guid><title>Web SQL</title><description>&lt;h3&gt;Web SQL and its possible applications&lt;/h3&gt;
&lt;p&gt;These days it's becoming more common that smart phones and tablets are being used for business applications. Some business applications need to store complex data on the device, and this is where Web SQL excels. Web SQL is a browser based API that allows data to be stored and retrieved with basic SQL statements. Having data stored on the device using Web SQL gives the ability to access information without the need to connect to a server.&lt;/p&gt;
&lt;p&gt;The alternative to Web SQL is IndexedDB, a NoSQL approach. IndexedDB allows you to store objects with the ability to query by a key and a combination of other attributes in the object. In late 2010 Web SQL was &lt;a href="https://www.w3.org/TR/webdatabase/" target="_blank"&gt;deprecated&lt;/a&gt;, but is still currently &lt;a href="https://caniuse.com/#feat=sql-storage" target="_blank"&gt;supported &lt;/a&gt;on the majority of mobile platforms, whereas IndexedDB &lt;a href="https://caniuse.com/#feat=indexeddb" target="_blank"&gt;is not.&lt;/a&gt; For this reason, if you are developing web applications for mobile platforms Web SQL is still a practical database to use.&lt;/p&gt;
&lt;p&gt;We use Web SQL as a means of data storage for a web application that runs on tablet devices for a client. The application handles large forms that users fill out with data that's stored and then periodically sent to a web server (if an Internet connection is available). Using Web SQL allows data to be stored locally, and thus gives the ability for the web application to be fully functional, even when an Internet connection is not available. For the client this was critical as the end users weren't always guaranteed to have access to an Internet connection.&lt;/p&gt;
&lt;h3&gt;Our Experience with Web SQL&lt;/h3&gt;
&lt;p&gt;Implementing Web SQL had a small learning curve as SQL is a common language used to query all sorts of databases. If you are familiar with JavaScript, learning to make calls to the Web SQL API is fairly straightforward. The only difficulty I discovered while implementing Web SQL was the asynchronous execution and callbacks. For the majority of the time where you are doing basic SELECTs, INSERTs, or UPDATEs as a single action, this is not an issue. However, if you need to execute an INSERT, UPDATE, and then a SELECT in that order, you will need to carefully manage the asynchronous callbacks for each query call. For example:&lt;/p&gt;
&lt;p&gt;If you wanted to update a record and then select it out, and the select finished executing before the update, it may return old data.&lt;/p&gt;
&lt;h3&gt;Using Web SQL&lt;/h3&gt;
&lt;h4&gt;Setup/Open DB&lt;/h4&gt;
&lt;p&gt;The following code opens the Web SQL DB. Opening the Web SQL DB is required each time a page is loaded.&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function setupDB() {
  var dbName = 'Sandfield_DB';
  var dbVersion = '1.0';
  var dbDescription = 'This is a Web SQL DB used for Sandfield.';
  var dbSize = 2 * 1024 * 1024; //2MB IN BYTES
  db = openDatabase(dbName, dbVersion, dbDescription, dbSize);
}
&lt;/pre&gt;
&lt;h4&gt;Query DB&lt;/h4&gt;
&lt;p&gt;As previously mentioned, to query the Web SQL DB you use SQL. The following function takes in three parameters: the SQL query, parameters for the SQL query (optional), and a success function that will be executed when the query has successfully completed.&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function dbQuery(query, params, fncOnSuccess) {
 //CREATE TRANSACTION
 db.transaction(function (tx) {
   tx.executeSql(query, params, function (tx, results){
     successCallback(tx, results, fncOnSuccess); }, sqlErrorHandler);
 });
}
&lt;/pre&gt;
&lt;p&gt;Here are a couple of examples of how you could use this function,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt; var query = 'SELECT * FROM tblCustomer';
   var successFnc = function (tx, results) {
     alert('The query has finished executing.');
   }
   dbQuery(query, null, successFnc);
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt; var query = 'UPDATE tblCustomer SET ' + 
   'Name = ?, Address = ?, PhoneNumber = ? ' + 
   'WHERE CustomerID = 1';
 var params = [ 'Joe Bloggs', '123 Sesame Street', '123-45678' ];
 var successFnc = function (tx, results) {
   alert('The customer has successfully updated.');
 }
 
 dbQuery(query, params, successFnc);
      &lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notice in example (2.) that the params array is used to replace the &amp;ldquo;?&amp;rdquo; placeholders in the query. This is the preferred way to put dynamic values into the query, as opposed to building the query string by concatenating values.&lt;/p&gt;
&lt;h4&gt;Display Results&lt;/h4&gt;
&lt;p&gt;The following function is used as the success function from a query. Inside the &lt;code&gt;results&lt;/code&gt; parameter is a rows object that contains the rows of data returned from the query. You can use the &lt;code&gt;Object.keys&lt;/code&gt; JavaScript function to read the columns returned from the query; here it uses it to write out the table header to show the column names. Once it has written out the rows of results into the table, it finally calls &lt;code&gt;otherSuccessCallback&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function successCallback(tx, results, otherSuccessCallback) { 
 var rows = results.rows;
 var rowsCount = rows.length;
 var resultsToDisplay = '';
 var tbl = document.createElement('table');

 for (var i = 0; i &amp;lt; rowsCount; i++) {
   var currentRow = rows.item(i);
   var keys = Object.keys(currentRow);
   var keysCount = keys.length;
   var tblRow = document.createElement('tr');

   if (i == 0) {
      for (var h = 0; h &amp;lt; keysCount; h++) {
         var tblHeader = document.createElement('th');

         tblHeader.innerHTML = keys[h];
         tblRow.appendChild(tblHeader);
      }

      tbl.appendChild(tblRow);
      tblRow = document.createElement('tr');
    }

   for (var k = 0; k &amp;lt; keysCount; k++) { 
         var tblCol = document.createElement('td'); 

         tblCol.innerHTML = currentRow[keys[k]];
         tblRow.appendChild(tblCol);
      }
 
      tbl.appendChild(tblRow);
   }

   tableResults().appendChild(tbl);

   if (otherSuccessCallback) {
      otherSuccessCallback();
   }
}
&lt;/pre&gt;
&lt;h4&gt;Handle SQL OnError&lt;/h4&gt;
&lt;p&gt;The following is a simple JavaScript function that handles any errors that may occur when trying to query the Web SQL DB.&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt; function sqlErrorHandler(tx, error) {
   console.log(error.code + ' - ' + error.message);
 }

 tx.executeSql(query, params, fncOnSuccess, sqlErrorHandler);
&lt;/pre&gt;
&lt;p&gt;The error codes and messages generally lack detail so you could improve the error handling by including the query and params that failed to execute. Having this information is very useful to debug any issues you may experience.&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function sqlErrorHandler(tx, error, query, params) {
   console.log(error.code + ' - ' + error.message);
   console.log('Query: ' + query);
   console.log('Params: ' + params);
}

tx.executeSql(query, params, fncOnSuccess, 
   function (tx, error) {
      sqlErrorHandler(tx, error, query, params);
   }
);
&lt;/pre&gt;
&lt;p&gt;A list of error codes can be found at &lt;a href="https://www.w3.org/TR/webdatabase/#errors-and-exceptions" target="_blank"&gt;https://www.w3.org/TR/webdatabase/#errors-and-exceptions&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Stored Procedures&lt;/h4&gt;
&lt;p&gt;JavaScript functions can be considered as a stored procedure for making calls to your Web SQL DB. A great way to have a consistent structure/schema for these functions is to store them in a JavaScript object.&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;var stp = {
   Customer: {
      Select: function (callback) { 
         //Select out customers from DB
      }
   },
   Job: {
      Select: function (callback) {
         //Select out jobs from DB
      }
   }
};
&lt;/pre&gt;
&lt;p&gt;From the structure above you will have clean and manageable code, and will find it easier to chain Web SQL transactions.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;stp.Customer.Select(stp.Job.Select)&lt;/code&gt; will firstly select customers and then once that is complete it will select out jobs.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;If you need a browser API to store and query data effectively on many mobile platforms (Android, iOS, Blackberry, etc), Web SQL is a powerful API to use. Setting up your web application to use Web SQL is simple if you are familiar with JavaScript and SQL. With the use of the example code above, you can add basic Web SQL functionality to your web application. The following links are great if you want to read and learn more about Web SQL,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/webdatabase/" target="_blank"&gt;https://www.w3.org/TR/webdatabase/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://html5doctor.com/introducing-web-sql-databases/" target="_blank"&gt;https://html5doctor.com/introducing-web-sql-databases/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.tutorialspoint.com/html5/html5_web_sql.htm" target="_blank"&gt;https://www.tutorialspoint.com/html5/html5_web_sql.htm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.html5rocks.com/en/tutorials/webdatabase/todo/" target="_blank"&gt;https://www.html5rocks.com/en/tutorials/webdatabase/todo/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><author>Phillip Moon</author><link>http://www.sandfield.co.nz/News/Thats-Technical/214/Web-SQL</link><pubDate>Sun, 21 Jul 2013 12:00:00 GMT</pubDate></item><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/211/Raw-JavaScript-vs-jQuery</guid><title>Raw JavaScript vs jQuery</title><description>&lt;p&gt;Recently in the office there has been some discussion of when to use raw JavaScript and when to use jQuery. In some cases I have seen people using jQuery like its a competition to replace all raw JavaScript.&lt;/p&gt;
&lt;p&gt;My general theory is that raw JavaScript will be faster performance-wise and jQuery quicker for development, so I decided to do put it to the test.&lt;/p&gt;
&lt;p&gt;Note that these are not necessarily real-world scenarios or the best examples of how to code.&lt;/p&gt;
&lt;h3&gt;Test 1 - Incrementing a textbox counter&lt;/h3&gt;
&lt;p&gt;The first test is incrementing the value in a textbox.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Raw JavaScript&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function incrementCounter() {
    document.getElementById('txtCounter').value++;
}
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;jQuery&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function incrementCounter() {
    var txtCounter = $('#txtCounter');

    txtCounter.val(parseInt(txtCounter.val()) + 1);
}
&lt;/pre&gt;
&lt;table class="speed-table" border="1" cellspacing="0" cellpadding="3"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raw JavaScript&lt;/td&gt;
&lt;td class="best-speed"&gt;0.003 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;jQuery&lt;/td&gt;
&lt;td class="worst-speed"&gt;0.010 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I ran this test multiple times to get an average time that it ran, the times above are for it running once. In this case the raw JavaScript is more simple and about 3 times faster than jQuery. Of course, if you were doing this just once the speed difference is negligible.&lt;/p&gt;
&lt;h3&gt;Test 2 - Appending HTML&lt;/h3&gt;
&lt;p&gt;A more common task is appending some HTML to a table or div. Commonly in raw JavaScript I see people use the innerHTML property and when using jQuery the .append function.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shared function&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function buildHTML(data) {
    var html = '';

    // LOOP THROUGH DATA
        html += name + ': ' + value + '&amp;lt;br /&amp;gt;';
    // END LOOP

    return html;
}
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Raw JavaScript&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function appendRows(data) {
    document.getElementById('div').innerHTML += buildHTML(data);
}
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;jQuery&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function appendRows(data) {
    $('#div').append(buildHTML(data));
}
&lt;/pre&gt;
&lt;table class="speed-table" border="1" cellspacing="0" cellpadding="3"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raw JavaScript&lt;/td&gt;
&lt;td class="best-speed"&gt;0 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;4 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;7 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;10 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;12 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;15 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;18 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;20 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;24 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;jQuery&lt;/td&gt;
&lt;td class="worst-speed"&gt;6 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;3 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;3 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;3 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;2 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;2 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;2 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;2 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;2 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If there is nothing in the div then both methods run fairly quickly. However once there is HTML in the div the raw JavaScript method gets incrementally slower as it appears the browser has to destroy the contents of the div and reload the entire div&amp;rsquo;s HTML.&lt;/p&gt;
&lt;p&gt;The jQuery append function actually builds a DOM object then appends it using the appendChild function. To get a similar result in raw JavaScript you would need to make your code look something like the following:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Raw JavaScript DOM Object&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function appendRows(data) {
    var append = document.createElement('div');
    append.innerHTML = buildHTML(data);

    document.getElementById('div').appendChild(append);
}
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Final results&lt;/strong&gt;&lt;/p&gt;
&lt;table class="speed-table" border="1" cellspacing="0" cellpadding="3"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raw JavaScript&lt;/td&gt;
&lt;td class="best-speed"&gt;0 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;4 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;7 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;10 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;12 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;15 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;18 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;20 ms&lt;/td&gt;
&lt;td class="worst-speed"&gt;24 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;jQuery&lt;/td&gt;
&lt;td class="worst-speed"&gt;6 ms&lt;/td&gt;
&lt;td class="good-speed"&gt;3 ms&lt;/td&gt;
&lt;td class="good-speed"&gt;3 ms&lt;/td&gt;
&lt;td class="good-speed"&gt;3 ms&lt;/td&gt;
&lt;td class="good-speed"&gt;2 ms&lt;/td&gt;
&lt;td class="good-speed"&gt;2 ms&lt;/td&gt;
&lt;td class="good-speed"&gt;2 ms&lt;/td&gt;
&lt;td class="good-speed"&gt;2 ms&lt;/td&gt;
&lt;td class="good-speed"&gt;2 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raw JavaScript DOM Object&lt;/td&gt;
&lt;td class="good-speed"&gt;1 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;1 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;1 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;1 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;1 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;1 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;1 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;1 ms&lt;/td&gt;
&lt;td class="best-speed"&gt;1 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Building a DOM object and using the appendChild function does not take much more code, and with the exception of the first run in an empty div it performs better than the other two options.&lt;/p&gt;
&lt;h3&gt;Test 3 - Calling web services&lt;/h3&gt;
&lt;p&gt;We call web services all the time, whether it be to get data or save data. Let&amp;rsquo;s see how it works in raw JavaScript.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Raw JavaScript AJAX function&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function ajax(url, arguments, successCallback, errorCallback) {
    var xhr;

    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    } else {
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }

    xmlhttp.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            if (xmlhttp.status == 200 &amp;amp;&amp;amp; successCallback) {
                successCallback(xhr);
            } else if (errorCallback) {
                errorCallback(xhr);
            }
        }
    }

    var first = true;

    // LOOP THROUGH DATA
        url += (first ? '?' : '&amp;amp;') + 
            urlencode(name) + '=' + urlencode(value);
        first = false;
    // LOOP

    xmlhttp.open('GET', url, true);
    xmlhttp.send();
}
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Raw JavaScript AJAX Usage&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;ajax(
  url,
  arguments,
  function() { alert('Success'); },
  function() { alert('Failure'); }
);
&lt;/pre&gt;
&lt;p&gt;It&amp;rsquo;s a reasonably-sized function, but what if you want to support JSON and JSONP, you&amp;rsquo;ll probably have to add more code to handle that. jQuery provides a nice function we can use called &amp;lsquo;ajax&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;jQuery AJAX Usage&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;$.ajax({
  url: url,
  data: arguments,
  success: function() { alert('Success'); },
  error: function() { alert('Failure'); }
});
&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s not worry about running performance on this one, your lag to the web service that you are calling will be much higher than the time it takes to run these scripts.&lt;/p&gt;
&lt;p&gt;The usage of the 2 functions end up being fairly similar, the difference is that jQuery is well tested across all browsers and provides many advanced features out of the box. Such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;Choice of asynchronous or synchronous calls&lt;/li&gt;
&lt;li class="page-bullet"&gt;Cross domain calls&lt;/li&gt;
&lt;li class="page-bullet"&gt;Different data responses (XML, JSON, HTML etc)&lt;/li&gt;
&lt;li class="page-bullet"&gt;Header modification&lt;/li&gt;
&lt;li class="page-bullet"&gt;HTTP authentication&lt;/li&gt;
&lt;li class="page-bullet"&gt;And much more, check out the &lt;a href="https://api.jquery.com/jQuery.ajax/" target="_blank"&gt;jQuery.ajax() reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sure, you could delve into the manual for XMLHttpRequest and add most of these features but it will take time and resources that could be better spent elsewhere.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As I had expected raw JavaScript did end up being faster performance-wise, although in general the difference is negligible and often jQuery would require less code. Using jQuery in the right place can help you to develop code faster. It can also help to simplify your code which will make your code more readable and easier to support.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Our recommendation is to use raw JavaScript as a default, definitely use raw JavaScript if you&amp;rsquo;re trying to squeeze out every bit of performance. Use jQuery where it makes complex JavaScript simpler, and if there&amp;rsquo;s no great performance hit.&lt;/p&gt;</description><author>Logan Benjamin</author><link>http://www.sandfield.co.nz/News/Thats-Technical/211/Raw-JavaScript-vs-jQuery</link><pubDate>Thu, 27 Jun 2013 12:00:00 GMT</pubDate></item><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/210/Handy-VSSSMS-Extensions</guid><title>Handy VS/SSMS Extensions</title><description>&lt;p&gt;IDE extensions provide developers with a great way to improve productivity.&lt;/p&gt;
&lt;p&gt;Here are just a few of our favourite extensions for Microsoft Visual Studio and SQL Server Management Studio (SSMS).&lt;/p&gt;
&lt;h3&gt;Web Essentials&lt;/h3&gt;
&lt;p&gt;This extension comes from &lt;a href="https://about.me/madskristensen" target="_blank"&gt;Mads Kristensen&lt;/a&gt;, Program Manager at the Microsoft Web Platform team, and should be considered essential for all Visual Studio web developers.&lt;/p&gt;
&lt;p&gt;There are too many features to list here but some highlights are:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;CSS
&lt;ul&gt;
&lt;li class="page-bullet"&gt;"Live Web Preview" of changes.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Vendor specific property generation.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Embed url() references as base64 strings.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Colour, font and image preview on mouse hover.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Support for defining #regions and TODO comments.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Easy conversion between hex, RGB and named colour values.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Easily apply the CSS hacks needed to target specific versions of Internet Explorer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are also several handy JavaScript and HTML features.&lt;/p&gt;
&lt;p&gt;Supported versions of Visual Studio: 2010, 2012.&lt;/p&gt;
&lt;p&gt;VS 2010: &lt;a href="https://visualstudiogallery.msdn.microsoft.com/6ed4c78f-a23e-49ad-b5fd-369af0c2107f" target="_blank"&gt;https://visualstudiogallery.msdn.microsoft.com/6ed4c78f-a23e-49ad-b5fd-369af0c2107f&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;VS 2012: &lt;a href="https://visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6" target="_blank"&gt;https://visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Image Optimizer&lt;/h3&gt;
&lt;p&gt;Another extension from Mads Kristensen, this one optimises PNG, GIF and JPG file sizes without any quality loss.&lt;/p&gt;
&lt;p&gt;Just right-click a file or folder in Solution Explorer and this extension will reduce the size of your image(s) by removing EXIF and other metadata.&lt;/p&gt;
&lt;p&gt;Supported versions of Visual Studio: 2010, 2012.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://visualstudiogallery.msdn.microsoft.com/a56eddd3-d79b-48ac-8c8f-2db06ade77c3" target="_blank"&gt;https://visualstudiogallery.msdn.microsoft.com/a56eddd3-d79b-48ac-8c8f-2db06ade77c3&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;JavaScript Parser&lt;/h3&gt;
&lt;p&gt;A set of useful tools which makes working with large JavaScript files much easier.&lt;/p&gt;
&lt;p&gt;There are lots of features but some of the the top ones are:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;Errors in your code are shown in the notification popup bar.&lt;/li&gt;
&lt;li class="page-bullet"&gt;The function tree view provides quick navigation (and shows comments on hover).&lt;/li&gt;
&lt;li class="page-bullet"&gt;If you use camel case names you can find a function by using the capital letters in its name.&lt;/li&gt;
&lt;li class="page-bullet"&gt;//TODO: comments are shown in the task list.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Supported versions of Visual Studio: 2008, 2010, 2012.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.google.com/p/js-addin/" target="_blank"&gt;https://code.google.com/p/js-addin/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;SSMS Boost&lt;/h3&gt;
&lt;p&gt;This extension provides a number of handy features that you wish SQL Server Management Studio came with natively.&lt;/p&gt;
&lt;p&gt;Here are some of the top ones:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;"Go to Definition" - right-click on the name of a stored procedure in the SQL editor and select "Script Object".&lt;/li&gt;
&lt;li class="page-bullet"&gt;Quick connection switch between different databases on different servers.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Auto format SQL code.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Find in the results grid.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Visualise data in the results grid, e.g. display an image from binary data.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Auto replacements and macros.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is both a professional and a free community edition.&lt;/p&gt;
&lt;p&gt;Supported versions of SSMS: 2008, 2012&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ssmsboost.com/" target="_blank"&gt;https://www.ssmsboost.com/&lt;/a&gt;&lt;/p&gt;</description><author>Oliver Muir</author><link>http://www.sandfield.co.nz/News/Thats-Technical/210/Handy-VSSSMS-Extensions</link><pubDate>Thu, 23 May 2013 12:00:00 GMT</pubDate></item><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/197/SignalR</guid><title>SignalR</title><description>&lt;p&gt;&lt;a href="https://signalr.net/" target="_blank"&gt;SignalR&lt;/a&gt; is &amp;ldquo;a client and server side library for .NET that provides messaging and an abstraction over a persistent connection&amp;rdquo;.&lt;br /&gt;&lt;br /&gt;Basically this means you can use SignalR to &amp;ldquo;push&amp;rdquo; messages to your client apps. &amp;nbsp;These messages may be notifications or updates to a web page and can be sent to individual (or groups of) clients or to all connected clients (e.g. system-wide notifications).&lt;br /&gt;&lt;br /&gt;There are a number of other different ways to implement this type of &amp;ldquo;push&amp;rdquo; functionality including polling, long polling, EventSource events and WebSockets. &amp;nbsp;SignalR provides an easy .Net centric way to achieve the same result.&lt;br /&gt;&lt;br /&gt;There are of course other &lt;a href="https://en.wikipedia.org/wiki/Comet_(programming)" target="_blank"&gt;Comet&lt;/a&gt; type technologies such as &lt;a href="https://socket.io/" target="_blank"&gt;socket.io&lt;/a&gt;, &lt;a href="https://github.com/Flotype/now" target="_blank"&gt;nowjs&lt;/a&gt; and all have their pros and cons. SignalR though is very easy to get started with if you are using .NET.&lt;br /&gt;&lt;br /&gt;SignalR supports a number of different clients, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;JavaScript&lt;/li&gt;
&lt;li class="page-bullet"&gt;.NET (includes WinRT)&lt;/li&gt;
&lt;li class="page-bullet"&gt;Windows Phone&lt;/li&gt;
&lt;li class="page-bullet"&gt;Silverlight&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;This means your server code can exchange SignalR messages with clients on a variety of different platforms.&lt;br /&gt;&lt;br /&gt;Adding SignalR to your Visual Studio project is easy using &lt;a href="https://nuget.org/" target="_blank"&gt;NuGet&lt;/a&gt; - just enter &amp;ldquo;Install-Package SignalR&amp;rdquo; in the Package Manager Console, or search for SignalR in the Manage NuGet Packages screen.&lt;br /&gt;&lt;br /&gt;The easiest way to use SignalR is to use Hubs. &amp;nbsp;A Hub object is created on the server which clients can connect to and use to send and receive messages to all (or specific) clients which are connected to the same Hub.&lt;br /&gt;&lt;br /&gt;The classic chat sample application can be created in just a few easy steps using SignalR:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;Create a new .NET 4 web application in Visual Studio.&lt;/li&gt;
&lt;li class="page-bullet"&gt;Add SignalR (using NuGet).&lt;/li&gt;
&lt;li class="page-bullet"&gt;Add the class that inherits from Hub to the project:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="prettyprint linenums lang-cs prettyprinted"&gt;public class ChatHub : SignalR.Hubs.Hub
{
   public void Send(string message)
   {
      Clients.receive(Caller.name, message);
   }
}
&lt;/pre&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;Add a new web page to the project with the following code:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="prettyprint linenums lang-html prettyprinted"&gt;&amp;lt;head&amp;gt;
   &amp;lt;script src="Scripts/jquery-1.8.2.min.js"&amp;gt;&amp;lt;/script&amp;gt;
   &amp;lt;script src="Scripts/jquery.signalR-0.5.3.min.js"&amp;gt;&amp;lt;/script&amp;gt;
   &amp;lt;script src="http://www.sandfield.co.nz/signalr/hubs"&amp;gt;&amp;lt;/script&amp;gt;
   &amp;lt;script&amp;gt;
   $(function () {
       var chat = $.connection.chatHub;
       chat.name = prompt('Who are you?', '');
       chat.receive = function (name, message) {
           $('#ulMessages').append('&amp;lt;li&amp;gt;' + name + ': ' + message + '&amp;lt;/li&amp;gt;');
       };
       $('#btnSend').click(function () {
           chat.send($('#txtMessage').val());
       });
       $.connection.hub.start();
   });
   &amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
   &amp;lt;input type="text" id="txtMessage" /&amp;gt;
   &amp;lt;input type="button" id="btnSend" value="Send" /&amp;gt;
   &amp;lt;br /&amp;gt;
   &amp;lt;ul id="ulMessages"&amp;gt;&amp;lt;/ul&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/pre&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;Run the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong id="internal-source-marker_0.19716268847696483"&gt;&lt;br /&gt;&lt;/strong&gt;Note that the &amp;ldquo;/signalr/hubs&amp;rdquo; script source is used to refer to a dynamically generated JavaScript proxy for the server-side Hub.&lt;br /&gt;&lt;br /&gt;If you need more control than what Hubs can provide then SignalR also provides a more low level PersistentConnection class.&lt;br /&gt;&lt;br /&gt;Scott Hanselman has a good blog post entitled &amp;ldquo;&lt;a href="https://www.hanselman.com/blog/AsynchronousScalableWebApplicationsWithRealtimePersistentLongrunningConnectionsWithSignalR.aspx" target="_blank"&gt;Asynchronous scalable web applications with real-time persistent long-running connections with SignalR&lt;/a&gt;&amp;rdquo;.&lt;br /&gt;&lt;br /&gt;The web chat application &lt;a href="https://jabbr.net/" target="_blank"&gt;JabbR&lt;/a&gt; is powered by SignalR.&lt;br /&gt;&lt;br /&gt;The following Channel 9 video entitled &lt;a href="https://channel9.msdn.com/Events/TechDays/Techdays-2012-the-Netherlands/2287" target="_blank"&gt;&amp;ldquo;C#5, ASP.NET MVC 4, and asynchronous Web applications&amp;rdquo;&lt;/a&gt; by Steven Sanderson is a great introduction on the various techniques and technologies behind creating asynchronous web applications.&lt;br /&gt;&lt;br /&gt;And of course the creators of SignalR, Damian Edwards and David Fowler, have a very interesting &lt;a href="https://channel9.msdn.com/Shows/Web+Camps+TV/Damian-Edwards-and-David-Fowler-Demonstrate-SignalR" target="_blank"&gt;introduction to SignalR video&lt;/a&gt; as well.&lt;/p&gt;</description><author>Oliver Muir</author><link>http://www.sandfield.co.nz/News/Thats-Technical/197/SignalR</link><pubDate>Tue, 15 Jan 2013 11:00:00 GMT</pubDate></item><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/191/5-Ways-To-Write-Faster-C</guid><title>5 Ways To Write Faster C#</title><description>&lt;p class="smalltxt"&gt;Much of my time is spent working on Sandfield&amp;rsquo;s &lt;a target="_blank" href="https://www.crossfireedi.com/"&gt;Crossfire EDI &lt;/a&gt;engine. &amp;nbsp;It is essentially a program similar to Biztalk, which convert files between different formats (e.g. CSV to XML)&lt;/p&gt;
&lt;p&gt;Some customers do over over 50,000 conversions in just a working day, so we need to run frequent performance tests to ensure the code is running optimally.&lt;/p&gt;
&lt;p&gt;We use a tool called &lt;a target="_blank" href="https://www.red-gate.com/products/dotnet-development/ants-performance-profiler/"&gt;ANTS Performance Profiler&lt;/a&gt;, from Redgate which is excellent at identifying slow running functions. &amp;nbsp;Here are 5 easy ways to make your C# application run faster.&lt;/p&gt;
&lt;h3&gt;1. Use XmlNodeReader over XPath&lt;/h3&gt;
&lt;p&gt;The XmlNodeReader and XmlTextReader will perform significantly faster than using any XPath expression. It obviously has some limitations, but executed in almost half the time when we made this optimisation. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Slow&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint lang-cs prettyprinted"&gt;string text = nav.SelectSingleNode("/Text").value;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Fast&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-cs prettyprinted"&gt;XmlNodeReader nodeReader = new XmlNodeReader(root);
while (nodeReader.Read()) {
  if (nodeReader.Name == "Text")
  {
    string text = nodeReader.Value;
  }
} &lt;/pre&gt;
&lt;h3&gt;2. Use String.Compare instead of =&amp;rsquo;s&lt;/h3&gt;
&lt;p&gt;When doing a case-insensitive compare, the String.Compare function provides far greater performance than using the equals operator and two case modifying functions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Slow&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-cs prettyprinted"&gt;bool match = s1.ToLower() == s2.ToLower();&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Fast&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-cs prettyprinted"&gt;bool match = (string.Compare(s1, s2, true) == 0);&lt;/pre&gt;
&lt;h3&gt;3. Avoid many calls to Guid.NewGuid()&lt;/h3&gt;
&lt;p&gt;A GUID is a very easy way to give an object a unique id, so you would be tempted to use it, but this takes significantly longer than simply assigning a sequential counter.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Slow&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-cs prettyprinted"&gt;string uniqueID = Guid.NewGuid().ToString();&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Fast&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-cs prettyprinted"&gt;static int sequentialNumber;
string uniqueID = sequentialNumber++.ToString();&lt;/pre&gt;
&lt;h3&gt;4. Use For instead of ForEach&lt;/h3&gt;
&lt;p&gt;Using a for loop when not using collections can be up to twice as fast as running the same loop using foreach.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Slow&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-cs prettyprinted"&gt;int[] myInteger = new int[1];
int total = 0;
foreach (int i in myInteger) {
  total += i;
}&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Fast&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-cs prettyprinted"&gt;int[] myInteger = new int[1];
int total = 0;
for (int i = 0; i &amp;lt; myInteger.Length; i++) {
  total += myInteger[i];
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;There is a great explanation on the differences between &lt;a target="_blank" href="https://www.codeproject.com/Articles/6759/FOREACH-Vs-FOR-C"&gt;for and foreach loops here&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;5. Use Release Mode&lt;/h3&gt;
&lt;p&gt;Something every developer should be doing anyway, our live installations in release mode perform about 20% faster than in debug mode on the same machine.&lt;/p&gt;
&lt;p&gt;Hopefully, you find a use for at least one of these in your applications. &amp;nbsp;&amp;nbsp;Happy developing.&lt;/p&gt;</description><author>Henry Payne</author><link>http://www.sandfield.co.nz/News/Thats-Technical/191/5-Ways-To-Write-Faster-C</link><pubDate>Sat, 22 Dec 2012 11:00:00 GMT</pubDate></item><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/203/Retina-display-ready-websites</guid><title>Retina display ready websites</title><description>&lt;p&gt;Retina quality displays have been around&amp;nbsp;on smartphones for a couple of years now, in the last year we have seen retina displays extended to the iPad and MacBook Pro. In the Windows world devices with HiDPI (the Windows terminology for retina) will also ship in the coming months alongside Windows 8. Several Android devices also have retina-like displays.&lt;/p&gt;
&lt;h3&gt;What does this mean to us as developers?&lt;/h3&gt;
&lt;p&gt;When looking at the way we live, we are becoming dependable on small pocket devices to read news, communicate over social networks and even perform daily tasks. One of the keys of being a great developer means that the end user likes what they see and has a great experience using your products.&lt;/p&gt;
&lt;p&gt;Typically when the resolution of a screen increases all the user interface elements get smaller. To counter this, retina devices like the MacBook Pro have a scaling factor of 2 to scale the content up. This means that user interface elements maintain the correct size and the quality of the display rendering improves. A MacBook Pro can handle scaling at a window level, if you have a second screen like a projector connected, it will detect if this screen is a retina display and automatically adjust the scaling factor.&lt;/p&gt;
&lt;p&gt;What is important to note is that 1 CSS pixel is not equal to 1 device pixel, it is a relative measuring system. As a sample, an iPad 3 will have 4 device pixels for each CSS pixel due to its pixel density.&lt;/p&gt;
&lt;p&gt;One method to counter this is to manipulate the view port of a web site, which will tell the device what ratio to use to display content. Mobile Safari is assuming device pixels of 980 as the viewport, which means if you design a web site to have a width of 320px, it will use a calculation of 980/320=3.0625 to scale your content. We can manipulate this by setting a viewport in a meta tag:&lt;/p&gt;
&lt;p&gt;&lt;strong id="internal-source-marker_0.8781521134078503"&gt;&amp;lt;meta name="viewport" content="width=320" /&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Without setting the viewport setting, a div like &lt;strong id="internal-source-marker_0.8781521134078503"&gt;&amp;lt;div style="width:320px;background-color:red;"&amp;gt;My 320px div&amp;lt;/div&amp;gt;&lt;/strong&gt;&amp;nbsp;would end up using ⅓ of your screen, whereas the viewport setting would change this to display full screen.&lt;/p&gt;
&lt;h3&gt;Using Images&lt;/h3&gt;
&lt;p&gt;For the best results when using images on a web site, it is suggested to display an image in a container that is the same size as the actual image. To display an image with dimensions of 100 x 100px, we would use a tag like this:&lt;/p&gt;
&lt;p&gt;&lt;strong id="internal-source-marker_0.8781521134078503"&gt;&amp;lt;img src="image.jpg" width="100" height="100" /&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As retina devices double the scale factor, we will need to have images that are double the amount of pixels to prevent blurry images on the web site. Here are a couple of ways to achieve this:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="page-bullet"&gt;CSS Sizing&lt;/li&gt;
&lt;li class="page-bullet"&gt;Query Device Scale&lt;/li&gt;
&lt;li class="page-bullet"&gt;Image Set&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;br /&gt;CSS Sizing&lt;/h3&gt;
&lt;p&gt;This technique is always loading a high resolution image, e.g. an image with dimensions of 200 x 200px but we display it in a smaller container like the image tag above with a size of 100 x 100px. A retina device will then scale this image size up and load the correct sized element onto the page displaying the image at the correct ratio.&lt;/p&gt;
&lt;p&gt;It is important to remember that this technique will always work, but it is very bad for data bandwidth. As we are always downloading a bigger image, it will use a lot more bandwidth which will have a negative effect on users with small mobile data plans.&lt;/p&gt;
&lt;h3&gt;Query Device Scale&lt;/h3&gt;
&lt;p&gt;Media queries have been around for a few years and it can be used to target specific devices. This technique will only download an image that is targeted by this query and it will dynamically update if the device scale factor changes.&lt;/p&gt;
&lt;p&gt;Here are some css samples to target specific devices:&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-css prettyprinted"&gt;@media screen and (device-width: 320px) { 	
  /* For iPhone */ 
  body {
    width: 320px;
  } 
} 
@media screen and (device-width: 768px) { 	
  /* For iPad */ 
  body {
    width: 768px;
  }
} 
@media screen and (-webkit-device-pixel-ratio: 1) { 	
  /* For non-Retina display */ 
  .mainImage { 
    background-image: url(image.jpg);
    background-size: 100px 100px;
  } 
} 
@media screen and (-webkit-min-device-pixel-ratio: 2) { 	
  /* For Retina-Display */ 
  .mainImage {
    background-image: url(image@2x.jpg);
    background-size: 100px 100px;
  } 
}
&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;A similar result can be achieved by using a javascript loader for images, note that we need to attach a listen event for to detect when the device ratio changes:&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-js prettyprinted"&gt;function addImages() { 
  var image = new Image();

  //Method 1
  if ('styleMedia' in window &amp;amp;&amp;amp; 
      window.styleMedia.matchMedia('screen and (-webkit-min-device-pixel-ratio: 2)')) {
    // Load high resolution images 
    image.src = 'image@2x.jpg'; 
  } else { 
    image.src = 'image.jpg'; 
  } 

  //Method 2
  if (window.devicePixelRatio &amp;gt;= 2) { 
    // Load high resolution images 
    image.src = 'image@2x.jpg'; 
  } else { 
    image.src = 'image.jpg'; 
  } 

  document.body.appendChild(image); 
}

function reload() { 	
  // Reload images based on window.devicePixelRatio 
}
 
window.matchMedia("( -webkit-device-pixel-ratio: 1)").addListener(reload);
&lt;/pre&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Image Set&lt;/h3&gt;
&lt;p&gt;Image set is the Apple introduced alternative which is scheduled to become part of the Image Level 4 module in CSS. This is new as of Safari 6 and Safari for iOS 6. Like media queries, only the correct image will be downloaded at all times. Note, unlike normal CSS behaviour where slices in borders are in the image coordinate system, image set will automatically take care of this for you and adjust the values as required.&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-css prettyprinted"&gt;#main {
  border-image-source: -webkit-image-set(url(images/low/DSC00402_burn.JPG) 1x,
                                        url(images/high/DSC00402_burn.JPG) 2x); 	
  border-width: 10px 10px 10px 10px; 	
  border-image-slice: 10 10 10 10; 
}
&lt;/pre&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Comparing these 3 techniques&lt;/h3&gt;
&lt;table border="1" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Method&lt;/th&gt;&lt;th&gt;Performance&lt;/th&gt;&lt;th&gt;Simplicity&lt;/th&gt;&lt;th&gt;Cross-Browser&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;CSS Sizing&lt;/th&gt;
&lt;td&gt;Very bad, always download a big image&lt;/td&gt;
&lt;td&gt;Very simple&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Query Device Scale&lt;/th&gt;
&lt;td&gt;Good, just download what it needs&lt;/td&gt;
&lt;td&gt;&lt;span style="color: #ff0000;"&gt;*&lt;/span&gt;Slightly complicated to maintain and keep track of what scale you are in&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Image Set&lt;/th&gt;
&lt;td&gt;Good, just download what it needs&lt;/td&gt;
&lt;td&gt;Simple and clean approach&lt;/td&gt;
&lt;td&gt;Not yet cross-browser.&lt;br /&gt; Supported in&lt;br /&gt; - Safari 6 OS X&lt;br /&gt; - Safari iOS 6&lt;br /&gt; - Chrome 21&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;br /&gt;&lt;span style="color: #ff0000;"&gt;*&lt;/span&gt; This might be complicated to use but there are a lot of javascript libraries you can find with a quick search, like &lt;a href="https://retinajs.com/" target="_blank"&gt;retina.js&lt;/a&gt;, that you can use to load these for you in a simple manner. Retina.js does have a few things to be aware though. It is hooking into window.onload which means you can&amp;rsquo;t use this event in your own javascript. It is also loading all low resolution images into the DOM and then make a further round trip to the server for each image to see if it can find a 2x image on the server by getting the headers for these files. This means that it will add extra traffic on the site and additionally download 2 images for each image that you have as a high resolution image.&lt;/p&gt;
&lt;p&gt;If you have a site that you want to get off the ground quickly with a few high resolution images, this library would be good to use still.&lt;/p&gt;
&lt;h3&gt;When to use which technique&lt;/h3&gt;
&lt;table border="1" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Method&lt;/th&gt;&lt;th&gt;Number Of Images&lt;/th&gt;&lt;th&gt;Type of Web content&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;CSS Sizing&lt;/th&gt;
&lt;td&gt;Small number of local images to prevent downloading over mobile networks&lt;/td&gt;
&lt;td&gt;Apps and Books&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Query Device Scale&lt;/th&gt;
&lt;td&gt;Many images&lt;/td&gt;
&lt;td&gt;Websites, Apps and Books&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Image Set&lt;/th&gt;
&lt;td&gt;Many images&lt;/td&gt;
&lt;td&gt;Anything targeting WebKit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description><author>Johannes Wannenburg</author><link>http://www.sandfield.co.nz/News/Thats-Technical/203/Retina-display-ready-websites</link><pubDate>Mon, 17 Dec 2012 11:00:00 GMT</pubDate></item><item><guid>http://www.sandfield.co.nz/News/Thats-Technical/201/Writing-Less-CSS</guid><title>Writing Less CSS</title><description>&lt;p&gt;Something I&amp;rsquo;ve been experimenting with recently is &amp;ldquo;LESS&amp;rdquo; &amp;lt;&lt;a href="https://lesscss.org/" target="_blank"&gt;https://lesscss.org/&lt;/a&gt;&amp;gt;. It&amp;rsquo;s a neat extension to CSS which provides some of the dynamic functionality you&amp;rsquo;re used to in programming languages in your stylesheets.&lt;/p&gt;
&lt;h3&gt;What can it do for me?&lt;/h3&gt;
&lt;p&gt;Less allows you to to write CSS in such a way that you can reuse specific values, styles, and even classes throughout your stylesheet. It does this by providing four key features: Variables, Mixins, Functions and Nested Rules.&lt;/p&gt;
&lt;p&gt;Variables allow you to define a value for reuse (and manipulation) through your stylesheet. For example, it would allow you to define a &amp;lsquo;default font size&amp;rsquo; variable which you can later pick up and use directly in your classes; or add to/subtract from to create larger and smaller text elements. If you change the variable, the entire stylesheet will change.&lt;/p&gt;
&lt;p&gt;Mixins are probably most simply described as a mixture of a CSS class and a function. Any class you define is automatically a mixin - there&amp;rsquo;s no special syntax required at the simplest level. It allows you to call another class from within your current class and pick up any rules it has and apply them to your current class. You can also pass parameters, which could be used to create &amp;lsquo;utility&amp;rsquo; mixins for certain UI elements in your page.&lt;/p&gt;
&lt;p&gt;Functions are predefined operations in the LESS library which allow you to process and manipulate properties to calculate new values. My favourite set of functions here is colour mathematics - allowing me to calculate &amp;ldquo;lighter&amp;rdquo; and &amp;ldquo;darker&amp;rdquo; versions of a base colour on the fly. In the client side implementation, these can also map to JavaScript code - allowing even greater flexibility.&lt;/p&gt;
&lt;p&gt;Nested rules allow you to build up complex CSS selectors as a single hierarchical tree - simplifying presentation, clearly showing inheritance and increasing readability of the code. It also allows you to nest all rules related to a specific element, making it very clear what rules will be in effect.&lt;/p&gt;
&lt;p&gt;LESS can be run through a client side library directly on the users browser. This only supports Chrome, Safari and Firefox though; which rules this out for most projects.&lt;/p&gt;
&lt;p&gt;LESS does however compile into standard CSS - this can be done on the server side through a HTTP handler or by preprocessing the LESS file into CSS in your development environment before deploying your project. This way you can ensure support for all browsers; and your users are none the wiser. As far as they can see, your site is just using standard CSS.&lt;/p&gt;
&lt;h3&gt;Example time!&lt;/h3&gt;
&lt;p&gt;The best thing I&amp;rsquo;ve found about LESS is that it&amp;rsquo;s truly an extension to CSS. Everything you already know about CSS still applies, and the new features integrate in a very fluid and natural way. Take variables, for example.&lt;/p&gt;
&lt;p&gt;In standard CSS, I might set my colours and font sizes to reuse a single colour, and have the sizes stepping up with different H-tags like so:&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-css prettyprinted"&gt;#header {
  color: #FF0000;
}

h1, h2, h3 {
  color: #FF0000;
}

h1 {
  font-size: 20px;
}

h2 {
  font-size: 15px;
}

h3 {
  font-size: 12px;
}

p {
  font-size: 10px;
}
&lt;/pre&gt;
&lt;p&gt;Easy enough. But if I decide to change the colour scheme of the site, or increase the font size, all of the properties will need to be updated. Time to break out find and replace. Alternatively, in LESS, I could have just assigned variables:&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-css prettyprinted"&gt;@base-color: #FF0000;
@base-font-size: 10px;

#header {
  color: @base-color;
}

h1 {
  color: @base-color;
  font-size: @base-font-size * 2;
}

h2 {
  color: @base-color;
  font-size: @base-font-size * 1.5;
}

h3 {
  color: @base-color;
  font-size: @base-font-size * 1.2;
}

p {
  font-size: @base-font-size;
}
&lt;/pre&gt;
&lt;p&gt;In this example the LESS ends up just as long - but as your stylesheet grows in size to encompass your entire project, variable reuse will make your UI far more flexible, and make sweeping changes to the look and feel quick and easy.&lt;/p&gt;
&lt;p&gt;You can also use mixins to create reusable UI elements. For example, you can make a generic &amp;ldquo;rounded corners&amp;rdquo; mixin which you can apply to classes. This example is straight from the LESS website - but I think it&amp;rsquo;s the most elegant way to represent it.&lt;/p&gt;
&lt;pre class="prettyprint linenums lang-css prettyprinted"&gt;@base-color: #FF0000;
@base-font-size: 10px;

.rounded-corners (@radius: 5px) {
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
  -ms-border-radius: @radius;
  -o-border-radius: @radius;
  border-radius: @radius;
}

#header {
  .rounded-corners;
}
#footer {
  .rounded-corners(10px);
}
&lt;/pre&gt;
&lt;p&gt;The ideal use case for LESS is when building a stylesheet for a system which you intend to retheme for different purposes. It would allow you to set up some base rules which drive all of the colours, positioning, image sets etc. You can use LESS to create &amp;lsquo;settings&amp;rsquo; type files which include a &amp;lsquo;base&amp;rsquo; type file which has all of the LESS required to generate the stylesheet. Sort of like your own stylesheet framework.&lt;/p&gt;
&lt;p&gt;Speaking of frameworks, the Twitter Bootstrap &amp;lt;&lt;a href="https://twitter.github.com/bootstrap/" target="_blank"&gt;https://twitter.github.com/bootstrap/&lt;/a&gt;&amp;gt; framework utilises LESS in exactly this way. A core settings allows for the look and feel to be completely changed quickly and easily, while retaining the same class names and grid functionality.&lt;/p&gt;
&lt;h3&gt;Some implementation tips and tricks&lt;/h3&gt;
&lt;p&gt;During development, using a HTTP Handler such as the one provided by dotless &amp;lt;&lt;a href="https://www.dotlesscss.org/" target="_blank"&gt;https://www.dotlesscss.org/&lt;/a&gt;&amp;gt; will make things quick and easy, and allow you to test your LESS without too many hassles.&lt;/p&gt;
&lt;p&gt;As mentioned, the client side library only works on Chrome, Safari and Firefox. This will probably rule it out for most people, but if you&amp;rsquo;ve got an app which you&amp;rsquo;re specifically targeting a specific platform, the benefits of having the JavaScript integration might be worth the trade off.&lt;/p&gt;
&lt;p&gt;Dotless also has a command line utility for compiling LESS to CSS - I&amp;rsquo;d recommend implementing this as a post-build step rather than relying on the handler in a production environment. The file isn&amp;rsquo;t going to change, so a static CSS file would be the ideal way to serve this up.&lt;/p&gt;
&lt;p&gt;LESS also plays well with minifiers- dotless includes a CSS minifier to clean up all of that unnecessary whitespace. It could make life hard in the development environment; but for your live release this is definitely worth considering.&lt;/p&gt;</description><author>Matt Weston</author><link>http://www.sandfield.co.nz/News/Thats-Technical/201/Writing-Less-CSS</link><pubDate>Tue, 04 Dec 2012 11:00:00 GMT</pubDate></item></channel></rss>