Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Sunday, 30 November 2014

React.js Concepts

Overview

React.js is used to create components in your views, it specifically renders UI and responds to events.

Instagram and Facebook have come up with a FrontEnd client library that uses a virtual DOM diff implementation for ultra-high performance.  This works by comparing DOM changes in memory to calculate a patch required to update the DOM:

image

On every data change React re-renders the entire component in memory then uses a diff to apply a patch for what has changed in the DOM.  This means within React the virtual DOM UI is immutable, on each data change it’s completely replaced. 

Here is a stackoverflow comparing Angular’s dirty checking with Reacts virtual dom diffs, with the answer provided by the creator of React:

http://stackoverflow.com/questions/21109361/why-is-reacts-concept-of-virtual-dom-said-to-be-more-performant-than-dirty-mode

image

The syntax is a bit funky but quite simple once you get used to it.  It optionally uses a JSX transform library which is the preferred way of coding with React.  The following examples use JSX.

Concepts

React.createClass:  Creates a component by the developer providing a “render” function.

React.renderComponet:  Renders the component to a specified location

Props (or Properties):  Container object for immutable data, for example used with labels.  This example has two props: now and b.  Now is set to a javascript expression of todays date and b is set to a string literal.

image

Here is a more complex example showing default values, provided to React by using the getDefaultProps function, which are later overwritten by the component usage.

image

 

State:  Container object for mutable data for example used with input controls.  You can provide React the values for the initial state using the getInitialState function.  Here is an example of using state (note: state would usually be used with input controls rather than a label):

image

Controlled control:  Form component rendered with a value (or checked) property e.g.:

image

Mixins:  Common code that can be reused across components

ReactLink:  Used to streamline the updating of state so you don’t have to write your own onChange function to update state set.

image

Uncontrolled controls:  Form components rendered without a value (or checked) prop.  This enables React to ignore the component during the render process, allowing for better performance.  onChange event can still be used to detect changes outside of React.  You can also provide a defaultState value.  Beware, as React will not be tracking this component this will cause divergence from Reacts virtual DOM.

image

Ref:  Similar to the “ID” attribute in HTML, this attribute allows fast access to an item within your component instance:

image

getDOMNode(): Gets the underlying DOM node from an item within a React component instance.

PropType validation: By providing a propTypes property object you can validate your properties.  This example states the now property must be a string and the b property must be great than 5.

image

Flux:  Facebook have a separate optional complimentary library called Flux for single (or uni) directional data flow.  They have done this by introducing a dispatcher and (data) store.

image

The Dispatcher acts as a “traffic controller” for all the actions.

The (data) Store is the data layer that updates whenever it receives a new action from the dispatcher.

Saturday, 15 November 2014

Conferences

Quick list of conferences to keep an eye open for:

http://ng-conf.org/ Angular / Google March YouTube
http://ngeurope.org/  Angular / Google October YouTube
http://jsconf.com/ JavaScript Monthly YouTube
http://www.dotjs.eu/ JavaScript November YouTube
http://jqueryuk.com/2015/ jQuery March Vimeo
javascript-summit JS / jQuery November  
http://conf.reactjs.com/ React / Facebook January  
http://www.buildwindows.com/ Microsoft April Channel9
https://anglebrackets.org/ Microsoft May  
http://reactconf.com/ Reactive Systems April and Nov  
https://www.google.com/events/io Google June YouTube
https://developer.apple.com/wwdc/ Apple June Apple
https://fbf8.com/ Facebook April Facebook Live

Friday, 14 November 2014

ng-simple-rest-app

Here’s an example of a simple rest application, written to demonstrate simple techniques to get people started with Angular:

Source:  https://github.com/stevenh77/ng-simple-rest-app

Client features
- default page not being shown by the router
- automatic conversion of Json strings into JavaScript dates (generic/aop approach)
- date control bound to model object from a data service
- select control databound to model from a data service
- confirmation dialog
- rest service calls for get, post, put, delete
- bootstrap layout for form
- form validation
- app navigation from controller using location and window services
- logging abstraction
- promises for service calls including error handling
- generic application level error handling
- busy indicator
- unit tests with mocks and promises
- material design for form entry

Server features:
- simple rest endpoints
- compression
- request logging to console
- CORS enabled
- object retrieved from JS array based on key
- object removed from JS array based on key

Saturday, 8 November 2014

Creating a simple REST API with Node Express

Install dependencies

Create: server.js

Create film-data.json

Start the server

image

image

image

image

You can download and run the full source without the need to install any dependencies:  https://github.com/stevenh77/simple-rest-express-server

Monday, 3 November 2014

Sunday, 26 October 2014

Intro.js

Here’s how to add an intro to your site:

1) Download intro.js from https://github.com/usablica/intro.js/tags (which also contains lots of example usages)

2) Add the bootstrap-responsive.min.css and introjs.css files to the head of your page (see lines 6 and 7)

3) Add data-step and data-intro attributes to the sections of your page where you want the introduction to display (see lines 11, 12 and 13)

4) Add a button or link which starts the intro (see line 14)

5) Add the intro.js file to the bottom of your page (see line 16)

 


Here is an example runs the intro only the first time a user visits your page


http://stevenhollidge.com/blog-source-code/introjs/index-with-cookie.html


Wednesday, 15 October 2014

Calculating color contrast in JavaScript

image

To calculate which foreground color to use on a background we have the following function:

Taken from: http://24ways.org/2010/calculating-color-contrast/

You can use this website to confirm it meets the W3C standards:  http://snook.ca/technical/colour_contrast/colour.html

Friday, 10 October 2014

Resolving within Angular routing

You can have your routing code make services or data available to your controller by using resolve.

image

This is how we expose these functions to the controller:

image

image

Thursday, 9 October 2014

Thursday, 19 June 2014

Faking XMLHttpRequest with SinonJS

 // uses sinon and jQuery

var server = sinon.fakeServer.create();
server.respondWith([200, { "Content-Type": "application/json" }, '{"myData":3}']);
$.getJSON('some/url');
console.log(server.response);
server.restore();
JSFiddle:  http://jsfiddle.net/stevenhollidge/crDCT/4/ 
// uses sinon and jquery

var xhr = sinon.useFakeXMLHttpRequest();
var requests = [];

xhr.onCreate = function (request) {
requests.push(request);
};

var responseData = '{"myData":3}';
$.getJSON('some/url', function(data) { console.log(data); });
requests[0].respond(200, { "Content-Type": "application/json" }, responseData);
console.log(requests[0].url);
xhr.restore();


JSFiddle:  http://jsfiddle.net/stevenhollidge/crDCT/2/


An example combined with Jasmine to mock out the http call:

// uses jasmine, sinon and jQuery

describe("useFakeXMLHttpRequest", function() {
var xhr, requests;

beforeEach(function () {
xhr = sinon.useFakeXMLHttpRequest();
requests = [];

xhr.onCreate = function (request) {
requests.push(request);
};
},

afterEach: function () {
xhr.restore();
},

it('should be able to handle responses', function () {
var responseData = '{"myData":3}';
$.getJSON('some/url', function(data) { console.log(data); });
requests[0].respond(200, { "Content-Type": "application/json" }, responseData);
expect(requests[0].url).toBe('some/url');
}
}

JSFiddle:  http://jsfiddle.net/stevenhollidge/crDCT/

JavaScript revocable function


function revocable(f) {
return {
invoke: function () {
return f.apply(this, arguments);
},
revoke : function () {
f = null;
}
};
}

var temp = revocable(console.log);
temp.invoke('1'); // logs
temp.revoke();
temp.invoke('2'); // throws

// Works in FF, apparently Chrome has a bug... hmmm better ways to do this i think
// use with timeout to allow access
// to a fuction for a set period of time

JS Fiddle:  http://jsfiddle.net/stevenhollidge/tKC5Q/

Simple JavaScript counter

function counterf(value) {
return {
inc: function () {
return value += 1;
},
dec: function () {
return value -= 1;
}
};
}

var counter = counterf(10);
counter.inc() // 11
counter.dec() // 10

JSFiddle: http://jsfiddle.net/stevenhollidge/f9sKV/

JavaScript function that can be called only once

function add(a, b) {
return a+b;
}

function once(func) {
return function () {
var f = func;
func = null;
return f.apply(
this,
arguments
);
};
}

var add_once = once(add);
console.log(add_once(3, 4)); // 7
console.log(add_once(3, 4)); // throws as f is now null

JSFiddle: http://jsfiddle.net/stevenhollidge/uA6TH/


But I prefer the following code as it’s more readable:

function add(a, b) {
return a+b;
}

function once(func) {
var usageCount = 0;

return function () {
if (usageCount === 1) {
throw 'Already used';
}
usageCount += 1;
return func.apply(
this,
arguments
);

}
}

var add_once = once(add);
console.log(add_once(3, 4)); // 7
console.log(add_once(3, 4)); // throws

JSFiddle: http://jsfiddle.net/stevenhollidge/eqnU3/

Wednesday, 18 June 2014

JavaScript Functional Inheritance

Taken from Douglas Crockford:

function gizmo(id) {
return {
id: id,
toString: function () {
return "gizmo " + id;
}
};
}

function hoozit(id) {
var that = gizmo(id);
this.test = function (testid) {
return testid === id;
};
return that;
}

JS Fiddle: http://jsfiddle.net/stevenhollidge/FGbX6/

JavaScript Closures

Slow: digit_name creates the array each time it's invoked

var digit_name = function (n) {
var names = ['zero', 'one', 'two', 'three'];

return names[n];
};

console.log(digit_name(2)); // two

An example of a closure


Fast: digit_name immediately invokes a function and holds the result, a pointer to the array. This is a pointer to a variable that lives on outside of the scope of the function it was created in.


names is closed over the outer function.

var digit_name = (function () {
var names = ['zero', 'one', 'two', 'three'];

return function (n) {
return names[n];
};
}());

console.log(digit_name(2)); // two
JS Fiddle:  http://jsfiddle.net/stevenhollidge/22Ab7/

Tuesday, 17 June 2014

Simple JavaScript Interceptor

The function on line 14 amends an object method to intercept method calls to fire pre and post functions. The object can then continue to be used as normal.


var Calculator = function () {}
Calculator.prototype.Add = function (a, b) {
console.log("Adding a+b");
return a+b;
}

var SuperCalculator = function () {}
SuperCalculator.prototype = new Calculator();
SuperCalculator.prototype.Delete = function(a, b) {
console.log("Deleting a-b");
return a-b;
}

function createInterceptor (key, context, originalFunc, preFunc) {
var interceptor = function () {
preFunc();
var result = originalFunc.apply(context, arguments);
postFunc();
return result;
}
return interceptor;
}

var mySuperCalculator = new SuperCalculator();
var preFunc = function () { console.log("Pre func fired"); }
var postFunc = function () { console.log("Post func fired"); }

for(var key in mySuperCalculator) {
mySuperCalculator[key] = createInterceptor(key, mySuperCalculator, mySuperCalculator[key], preFunc, postFunc);
}

var addResult = mySuperCalculator.Add(1, 2);
console.log("AddResult: " + addResult);

var deleteResult = mySuperCalculator.Delete(2,1);
console.log("DeleteResult: " + deleteResult);

image


JSFiddle: http://jsfiddle.net/stevenhollidge/vb893/

Saturday, 14 June 2014

Setting default values for arguments in JavaScript

function complex (settings){
settings.option1 = (typeof settings.option1 === "undefined") ? "default option 1" : settings.option1;
settings.option2 = (typeof settings.option2 === "undefined") ? "default option 2" : settings.option2;
settings.option3 = (typeof settings.option3 === "undefined") ? "default option 3" : settings.option3;
settings.option4 = (typeof settings.option4 === "undefined") ? "default option 4" : settings.option4;

console.log(settings.option1);
console.log(settings.option2);
console.log(settings.option3);
console.log(settings.option4);
};
complex({option1: 'this is option 1', option3: 'this is option 3'});
image

JS Fiddle:  http://jsfiddle.net/stevenhollidge/w9z2g/

Thursday, 15 May 2014

Tab with deep linking

Demo:  http://stevenhollidge.com/blog-source-code/ng-tab-with-deep-linking/

Source:  https://github.com/stevenh77/ng-tab-with-deep-linking

Rotating tiles in jQuery

Click on the tiles on the right hand side to rotate.

Demo

The Code

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>Rotating Tiles</title>
<style>
#block-1 { background: #d5fcff; }
#block-2 { background: #e1ffd5; }
#block-3 { background: #ffffd8; }
#rotator > div {
position: absolute;
overflow: hidden;
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
}
#rotator .active { top: 20px; left: 20px; width: 580px; height: 280px; }
#rotator .non-active-top { top: 20px; left: 620px; height: 130px; width: 320px; }
#rotator .non-active-bottom { top: 170px; left: 620px; height: 130px; width: 320px; }
</style>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js'></script>
<script>
// DOM Ready
$(function() {
var current;

function rotate() {
if (current == 1) {
$("#block-1").removeClass().addClass("active");
$("#block-2").removeClass().addClass("non-active-top");
$("#block-3").removeClass().addClass("non-active-bottom");
} else if (current == 2) {
$("#block-1").removeClass().addClass("non-active-bottom");
$("#block-2").removeClass().addClass("active");
$("#block-3").removeClass().addClass("non-active-top");
} else {
$("#block-1").removeClass().addClass("non-active-top");
$("#block-2").removeClass().addClass("non-active-bottom");
$("#block-3").removeClass().addClass("active");
}
}

$("#rotator div").click(function() {
current = this.id.substr(6);
rotate();
});
});
</script>
</head>

<body>
<div id="rotator">
<div id="block-1" class="active"></div>
<div id="block-2" class="non-active-top"></div>
<div id="block-3" class="non-active-bottom"></div>
</div>
</body>
</html>

Originally taken from the website:   http://css-tricks.com/examples/RotatingBlocks/

Monday, 12 May 2014

Animating Angular Wizard

I have added a nice fade animation to each step of the wizard I created in my previous blog post.

Watch the video below or try out the live demo:

It turned out to be very simple indeed:

1) Add a script reference to the Angular-Animate.js library in your html page

2) Create an Animate.css file which will contain your animation details and add a reference within your html page.  I’ll explain the content of this code in a second.

3) Add a css class to the area you are animating, this is so your css code can locate it.  I added “fade-animation” class to each of the three wizard steps.

4) Finally add a reference to ngAnimate for Angular

And that’s it.  Right, now for the trickiest part, here is the animate.css code:

.fade-animation.ng-hide-remove {
-webkit-transition:all linear 0.5s;
-moz-transition:all linear 0.5s;
-o-transition:all linear 0.5s;
transition:all linear 0.5s;
display:block!important;
}

.fade-animation.ng-hide-add.ng-hide-add-active,
.fade-animation.ng-hide-remove {
opacity:0;
}

.fade-animation.ng-hide-add,
.fade-animation.ng-hide-remove.ng-hide-remove-active {
opacity:1;
}

When you break this down there’s not much to it.  The first section is saying I want the animation to take half a second, in all the various browsers.  The display:block!important line is telling angular to override it’s default for hiding.

The other two css setters simply show and hide.  Now the interesting bit is the css selectors.  You’ll recognise the fade-animation selector as our class we are using for identification purposes. 

All the ng-hide-* css classes are what Angular adds as it cycles through its event lifecycle for showing and hiding.

This would be the lifecycle for moving for the user moving from Step One to Step Two:


  • Step One section is hidden:  ng-hide-add (start) then ng-hide-add-active (complete)
  • Step Two is no longer hidden:  ng-hide-remove then ng-hide-remove-active
Angular dynamically adds and removes these classes to the sections as it cycles through the events.  There’s lots more to animations but this makes for a nice simple introductory example.

Source code