HTML5, CSS3, jQuery, JSON, Responsive Design...

How to show current Git branch name in your terminal

Michael Brown  April 23 2016 09:36:55 PM
If you're using Git for your source control (and really, if not, why not?), then seeing what branch you're currently working on is a rather important feature!  Sadly, it's not one that's built into the terminals on either OS X or Linux.

Fortunately, you can implement this by editing you bash profile config file.  This is how the terminal looks on my Mac after I did this.  You can see that the Git branch name, "master" in this case, is shown in green:
OS X terminal showing the Git branch name

Here's the code that you need to add to your bash profile config file:
parse_git_branch() {
   git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\u@\h \W\[\033[32m\]\$(parse_git_branch)\[\033[00m\] $ "


You'll find the files to edit on your home folder on both OS X on Linux.

On OSX, it's the file ~/.bash_profile.

On Linux, it's ~/.profile.  (There maybe differences here between different distributions, that worked for me on Linux Mint.)

The files will be hidden by default.  Tip: on OS X, you can hit Command->Shift->full stop (that's a period to some of you) to show hidden files in an OS X File Open dialog.






Kendo UI with ES6 modules, via Webpack, SystemJS & Babel

Michael Brown  March 27 2016 07:14:36 PM
From my Github account.  I've set up a boilerplate repository that shows how to use the KendoUI Pro widget system with Webpack module loader and ES6 modules.

I discovered that Kendo is AMD compliant.  So my aim was to try and reduce the page load times by avoiding a full load of Kendo, which is 2.5 meg (900kb gzipped) for the file kendo.all.min.js!  By using Webpack to load up only the Kendo modules that I needed for my demo, I was able to reduce that to a single file of 900kb minified (300kb gzipped).

All this requires NodeJS/npm and a (shock, horror) build step!  Actually, it's not too bad when you get used to it, but I appreciate that for some web developers, requiring a build step for JavaScript is a step too far.  So, I've also included a SystemJS version in the repository too.  SystemJS loads all the individual kendo JS files on-the-fly for you; i.e. no build step.  It's slower, because it's loading the files individually, instead of as one combined file, and there can be quite a few files pulled in by Kendo.  For that reason, I'm not sure if SystemJS is viable for larger production projects, but see for yourself.  It should at least give you a feel for what module loaders are and what they can do for you, i.e:
  1. Break your code into manageable chunks, but without...
  2. ... having to manage a boat load of script tags on your HTML pages.  This includes avoiding any mutual dependency, infinite loop type problems.  
  3. Banish global variables and having all your functions in global scope.

Honestly, once you've coded using JavaScript modules, and see their benefits, then there's really no going back.  You can now have multiple developers working on an app, without running into save conflicts because they're all editing the same, massive JavaScript file!!  No more loading huge, third party function libraries when you only need one or two functions out of them anyway.

This is the future.  Modules are part of ES6, which is the next, official version of JavaScript.  It's not some third party, jury-rigged system, that may or may not become a de facto "standard" one day, if only enough developers come on board.  This is going to happen.  Well, it will as soon as the browser makers get off their backsides!   Many of them have native support for numerous other ES6 features, but so far, only Chrome has tentative native support for modules (the import statement), and even that's stuck behind a compatibility flag.  Until the, we have to rely on loaders like Webpac, SystemJS and Browserify.

https://github.com/brownieboy/kendo-webpack-systemjs

Array.prototypemove - another new npm package

Michael Brown  March 9 2016 02:18:25 AM
That's my fourth npm package, for anybody counting!

It adds an Array method (to the Array's prototype, yikes!) that allows you to move an element of that array from one index to another.

Syntax

The syntax is:

myArray.move(moveFromPosition, moveToPosition)


where:
  • `myArray` is your array.  It can be an array of objects, as well as an array of primitives (strings, numbers etc).
  • `moveFromPosition` is the index of the array element that you want to move, where zero is the first element.
  • `moveToPosition` is the index of the array where you want the element that you're moving to end up.

Example 1:

var simpleArray = ["Han Solo", "Luke Skywalker", "C3P0", "R2D2"];
simpleArray.move(3, 0);


will move R2 to the start of the array.

The method will also accept negative numbers for either of the "move" variables.  In that case, -1 is the last element of the array, -2 is the next to last element, and so on.

Example 2:

var simpleArray = ["Han Solo", "Luke Skywalker", "C3P0", "R2D2"];
simpleArray.move(0, -1);


will move Han to the end of the array.


Installation

Installation and import instructions are on the package's npmjs page.


Background

Taken from Reid's accepted answer from the most popular stackoverlow post on this topic.  All credit goes to Reid.  I've not changed his code at all.  I merely packaged it up and put it into npm.

I was inspired to do so by the author of very similar npm package, in a kind of backhanded way!  When I pointed out, via his Github repository, that I was having a problem with his package, he behaved like an ignorant arsehole.  He insisted that it couldn't possibly be his package, and how dare I even suggest such a thing!  Then locked the comments on my bug report, so he didn't have to trifle with trash like me any further.  The irony is, I now think that he was probably right about his package: I don't think the fault was there, after all.  But I couldn't tell him that, of course, because he'd locked the comments.  Well screw him.  I've got my own package now!



Web server for Chromebook

Michael Brown  February 29 2016 03:39:51 AM
I tend to use my Chromebook for web development when I'm on the road, or ferry in my case!  I have $2000 Macbook Pro, which I love, but I'm usually too scared to take it too many places.  My $330 Chromebook on the other hand...

Of course, to do much build work with npm, Git, Gulp, Webpack, Babel etc, I have to switch to my Linux crouton, which is a bit of cheat, but it works!  I also had to do that just to fire up a local web server, but not any more.  It seems that there is now a Web Server for Chrome.  It's called, wait for it, Web Server Chrome, and you can install it from the Chrome Store.

Once installed, just launch it from the Chrome Launcher and tell it which folder your HTML is in.  It will give you a link for your browser.  Really, it couldn't be easier.  And being a Chrome app, it runs on all platforms on which Chrome itself runs.  (The screenshot below is from my Macbook Pro.)

Now if I could only get a Chrome version of Git...
Web Server for Chrome

Steam Link and Controller shipping to Australia now!

Michael Brown  December 27 2015 07:15:10 PM
... and possibly in other countries too.

I’ve been after one of Valve’s new Steam Link devices and one of their Steam Controllers for ages now.  It was initially released in the USA only and whenever I open Steam, it always says “Coming soon”.  The official release date for Australia is supposed to be Feb 2016.

So I was quite surprised when I came across a forum comment (can’t remember which forum now) where an Aussie user said he'd simply ordered a Steam Link from Amazon.com.  Amazon.com hardly ever ships electrical or techie stuff to Australia, so I assumed that he must have used a third party mailing service, such as ShipItTo or PriceUSA, to get around Amazon’s geographical restrictions.

But he didn’t.  I know because I just ordered one myself!  I have a shipping confirmation and an arrival date of Jan 11 for one Steam Link and one Steam Controller.  As part of the Amazon order I was also emailed activation codes for 1 copy of Counter-Strike: Global Offensive and 1 copy of Left 4 Dead 2, yes, they worked.  Well, the Counter-Strike one did.  I already had Left 4 Dead 2.  I don’t know if these codes are transferable to another Steam subscriber.

  I’ll post a review  of both items when I’ve tested them out.

Parallel Ajax calls

Michael Brown  October 10 2015 01:23:17 AM
Some time ago (4+ years, yikes!) I wrote a post called Getting around Domino’s Ajax lookup restrictions.  In that post I outlined a way of breaking up a big Ajax call into a number of smaller ones, using recursion.

While this approach works, it does have a serious drawback: it's slow.  That's because with my recursion method, the Ajax calls had to run in sequence.  The second Ajax call was triggered by the .success() callback for first Ajax call.  Then the third Ajax call would be triggered by the .success() callback for the second Ajax call.  And so on.

It turns out that there's a much neater way of achieving this in jQuery, by using promises.  Here's the code:

 $.when(
  $.getJSON(dataPath1),
  $.getJSON(dataPath2),
  $.getJSON(dataPath3)
).then(function(data1, data2, data3) {
  console.log("data1 = " + JSON.stringify(data1[0]));
  console.log("data2 = " + JSON.stringify(data2[0]));
  console.log("data3 = " + JSON.stringify(data3[0]));
});


I've lined up three Ajax calls inside my $.when() call.  The chained .then() call is triggered when, and only when all three Ajax calls have completed and returned their data.  The returned data from each Ajax call is then passed into .then(function()) as variables in sequence; three Ajax calls so three data objects returned.  Nice and simple.

NB: the data objects returned the my function inside the .then() are actually arrays, of which the first member is the JSON data in which I'm interested.  Hence "data1[0]", "data2[0]" etc when I reference them.  (FYI, the second array member is the return status, and the third is the native XHR object.)

bindAll function for ES6 classes

Michael Brown  September 14 2015 05:48:32 AM
I've written a simple JavaScript function to bind multiple methods to an ES6 class's 'this' object.

Problem

The problem is that an ES6/ES2015 class method's context is not autobound to the class's object. This is a particular point of pain for ReactJS when using this syntax. (ReactJS's previous .createClass() syntax did autobind a component's methods to the component's own context.)  So in the code below, the close() and open() methods, which both call this.setState() will fail. This is because those method's this object is not autobound to the component's context, so this.setState() simply doesn't exist.

class ExampleModal extends React.Component {
constructor(props) {
  super(props);
}
close() {
  this.setState({ showModal: false });
}
open(){
  this.setState({ showModal: true });
}


You can bind all the methods manually in the constructor to get around this problem, but that's a massive pain to remember to do that, not to mention a lot of extra lines of code in your constructor.

How To Use es6BindAll

So I wrote the es6BindAll function to do it for you.  Those of you that have used Backbone.js can probably guess that this is inspired by Backbone's bindAll function.

You simply supply the function with the context object as its first parameter, then an array of method names that are to be bound to the object. Note: those methods must exist in the current component/class, i.e. they can't be external functions.
Example use:

import {es6BindAll} from "es6bindall";

class ExampleModal extends React.Component {
constructor(props) {
  super(props);
  es6BindAll(this, ["open", "close"]);
}
close() {
  this.setState({ showModal: false });
}

open(){
  this.setState({ showModal: true });
}



Browser Support

Supports Internet Explorer 9 and upwards, plus all good browsers (i.e. any browser not called Internet Explorer).


Installation

To install via NPM:
npm install es6bindall


Here's links to the packages on npmjs and github:
https://www.npmjs.com/package/es6bindall
https://github.com/brownieboy/es6bindall


Update December 2015

I've subsequently updated es6BindAll so that you can import it as the default, i.e.
import es6BindAll from "es6bindall";

although
import {es6BindAll} from "es6bindall";

will continue to work.

I've also added some proper tests, using Mocha and Chai (I know, like I should have done in the first place!).
 



ReactJS list sorting with jQuery-ui

Michael Brown  August 30 2015 09:50:39 PM
Overview
A simple, sortable list implemented using ReactJS and jQuery-ui's sortable() method.



Background

Although there's a number of drag and drop modules for ReactJS, they all seem to use the HTML5 drag and drop API for which browser support is still sadly lacking.  E.g. the documentation for the React DnD module says the following:

React DnD does not work on mobile browsers yet because it currently relies on the HTML5 drag and drop API which no mobile browsers implement.  -
https://github.com/gaearon/react-dnd

jQuery-ui seems to have fallen out of favour recently, but it still has the best drag and drop (and sortable) UI that I've seen.  But how to combine it with ReactJS?  The raison d'etre of both libraries is to control the UI!  But they can't both do it; I've had ReactJS throw warnings at me when my other code has tried to monkey with the UI without its knowledge.


Approach

The trick to getting them to work together was to not let jQuery-ui modify the UI at all, but only *appear* to do so.  All we want from jQuery-ui is the mechanics of the sortability.  In other words, we read its (and the user's) intentions, and then pass those to ReactJS to do the actual sorting.  This is possible because jQuery-ui's sortable() method has a cancel call that sets the UI back to how it was.  Here's the basic workflow then:

1. Attach the jquery-ui.sortable() method to a list of line items
2. Let the user drag and drop those line items to re-order them.
3. When the user starts dragging, we read the index of the line item (s)he's dragging
4. When the user drops the line item, we:
a. Read from jQuery-ui.sortable)() the new index position for the line item
b. Cancel jQuery-ui.sortable() so that the list goes backs to its original position, and the UI is unchanged.
c. Pass the old and new indexes of the dragged line item to ReactJS.  ReactJS then reorders the back-end data and calls a setState(), which re-orders the list in the UI.


Advantages & Disadvantages

The major advantage is that it actually works!  And works everywhere, including mobile (courtesy of the jquery-ui-touch-punch plugin).

The disadvantages are that ReactJS plus jQuery plus jQuery-ui is a pretty heavy set of dependencies, even when minified.  You can, however, cut jQuery-ui down to just the essentials needed for its .sortable() functionality.


Libraries and Build Tools

The sample list app requires ReactJS, jQuery and jQuery-UI as run time dependencies.  It's written in the new ES6, or ES2015 as it's now called, syntax using the module pattern.  So it requires Webpack and Babel as build tools.

To Install

Clone the github repository https://github.com/brownieboy/react-dragdrop-test-simple  In a terminal, cd to the folder that you just cloned the repository into and run  
npm install


You can build the app with either:
npm run build

or
npm run buildwin


The latter minifies and uglifies the resulting JavaScript libraries, which reduced to about a third of their unminified sizes.  However, build time is significantly higher!

Open the build/index.html file via a local server.  SublimeServer is good if you're running SubmlimeText.  Otherwise you can run:
npm run start

to start up webpack-dev-server.  When this is running, your test URL is http://localhost:8080.


Demo

http://www.users.on.net/~mikeandgeminoz/code/react-jqueryui-drag-drop/build/index.html


    Windows 10 install. How things have changed...not!

    Michael Brown  July 30 2015 02:50:19 AM
    I'm attempting to install Windows 10, more fool me.  Sadly, I downloaded a game from Steam recently - Wolfenstein The New Order since you ask - that only works on Windows 64-bit!  It seems that there's a number of games with this requirement, and they're only going to grow more prevalent.  So I thought, if I'm going to have to install a new version, I may as well get the latest.

    I was hoping against hope that Microsoft might have improved its installer since Windows 7.  (I skipped 8 and 8.1 for obvious reasons.)  But no.  I soon ran into this error from the Windows 10 install CD's partioner:

    "We couldn’t create a new partition or locate an existing one."

    I should have known what the problem was, since I wrote about it only a couple of years ago.

    Yep, Windows still won't play with other operating systems and installs.  Once again, I had to disconnect every internal drive from my system except for the one on which I wanted to install Windows 10.   Only then could I get past this error.

    Pathetic.


    On the plus side though, Windows 10 doesn't need an install CD just so I can get the the internet over my wired Ethernet connection, like Windows 7 did!

    Basic React Tutorial - Part 2

    Michael Brown  April 18 2015 12:05:33 AM
    As threatened in my previous post, Basic ReactJS Tutorial, I've now updated my sample ReactJS checkboxes app into "a kind of questions and answers, survey form thing".

    This post will walk through the steps that I went through to achieve that.  As you read this explanation, I hope it comes across to you just how easy this was for me to do.  Not because I'm any genius coder, or even that much of an expert in ReactJS yet.  It's just the way that ReactJS leads you into developing your app, especially the compositional, component based design that it encourages.  While it would be a stretch to say that the code wrote itself, it did pretty much design itself.  That's to say that before I sat down to type a single line of code, I already knew pretty much how I it was all going to break down.  In ReactThink (and I may just trademark that term) it means that knowing the components that created in my from the previous exercise, I just needed some higher level ones to put those existing components to work a bit more.


    CheckBoxInputFields Component

    The highest level React component that I was left with from my previous exercise was CheckBoxInputField.  This component groups together a number of CheckBoxInput components, to give us a "field" of HTML input elements of type "checkbox".  The number of elements in the field is determined by the array of data (or props) that we passed into the CheckboxInputField component.

    The next step to turning this single question in to list of questions - i.e. a survey - is to create a new React component called CheckboxInputFields.  The clue to what it does is in the name, or is intended to be so anyway!  CheckboxInputFields is a plural of CheckboxInputField, so guess what it does?  Yep, the CheckboxInputFields component renders a number of CheckboxInputField components.  How many CheckboxInputField components the CheckboxInputFields component renders is determined, once again, by the array data that is passed into it as props.

    Enough blurb.  Let's look at some code.

    Example 1 - React Survey App, state in wrong place



    You'll see that my source data is now an array of questions and answers, stored in the global variable, questions.  This data is passed into the CheckboxInputFields component, as props, by another React component called SurveyApp (of which more later).  The CheckboxInputFields component's render method maps through the questions array and creates a new CheckboxInputField component for each member, passing that member down as props to each new CheckboxInputField.  Each CheckboxInputField component so created is pushed onto an array variable called mappedInputFields.  Finally, the mappedInputFields variable, which is now a collection of CheckboxInputField components, is rendered via the return statement.

    I've no idea how easy that all looks to you, but I can tell you it took me about two minutes to type it out, and it ran perfectly the first time.   Furthermore, it did so without me having me to change anything in the CheckboxInputField component.  In fact, I'm not sure that I even had to look at the CheckboxInputField component!!!  I knew what that CheckboxInputField component does and what its props were from last time, so no real need to look at it again now.  Cool as!

    (Actually, I did modify CheckboxInputField later on, to have it render the question - or the blurb property as I've called it - just before the list of answers.)


    That pesky state again

    In my earlier post, I said the following:

    This is one of React's underlying principles: state should be handled at the highest level possible in your application.  High level state is then passed down to lower level components as props.


    Is that how state - i.e. are the checkboxes checked or unchecked? - is being handled in this new version of the app?  Most definitely not!   The state is still being handled down at the CheckboxInputField level.  The CheckboxInputFields component has no easy way of knowing whether any of the CheckboxInputField components that it created have been checked by a user.  Once again, the state is being handled at too low a level.  State needs to be handled at the CheckboxInputFields level.

    Or does it?

    Thinking ahead, what if we want our app to display a collection of CheckboxInputFields components?  In other words, we want a survey to consist of a collection of different groups of questions, each grouped by a theme or topic?  In that case, our state would again be at too low a level if it were handled in the CheckboxInputFields component.  We've have to refactor yet again to move the state to our new, higher level.  So let's skip that mistake and do it right first time, this time.


    If you want something done, then go to the top!

    I only have one CheckboxInputFields element in my Example 1 version above, but I never intended to handle state within it.  Instead, I've created a higher level React component, which is the SurveyApp component.  In Example 1, all it does is render my one CheckboxInputFields element with the necessary props, and nothing more.  But it was my intention from the beginning to handle my state in this top most element, so let's do that now.



    Example 2 - React Survey App, state in correct place




    In Example 2, state is handled in the SurveyApp component.  The state data is updated and setState() call is made within that component.  A setState call causes the SurveyApp to re-render, which causes the whole app to re-render, like so:

    SurveyApp -> CheckboxInputFields -> CheckboxInputField -> CheckboxInput

    With each CheckboxInputFields owning multiple CheckboxInputField components, and each CheckboxInputField owning multiple CheckboxInput components, the diagram of re-renders would actually look like a pyramid.  (I just couldn't be arsed to draw one!)

    And if you're thinking "re-rendering the whole app = performance nightmare", remember that React's virtual DOM and super fast diffing engine mean that this isn't the case.


    Passing the buck upwards again

    In order to have the SurveyApp component handle the state, I did have to rewrite the lower level components to ensure that the when events are triggered down there (i.e the user checks or unchecks a checkbox) the relevant information from that event reaches up to SurveyApp level.

    CheckboxInput required no changes because it was already passing its state changes upwards (to CheckboxInputField).

    CheckboxInputField gets the biggest rewrite because this is where we were handling state previously.  So, its getInitialState() method is removed.  Instead of looping through the (now non-existent) state array, its render() method now maps through an array of passed in props.  CheckboxInputField's handleFieldChange() method, which was resetting the state earlier, now simply passes the relevant data, with a little preprocessing, back up to CheckboxInputFields via the supplied (via props) callback function, i.e. this.props.handleChange().

    CheckboxInputFields does even less with that data!   There's no equivalent handleChange() or handleFieldChange() method in CheckboxInputFields.  The callback function that was passed down from CheckboxInputFields to CheckboxInputField is actually one that was originally passed from from SurveyApp to CheckboxInputFields.  So when the new event data is heading back upwards, the CheckboxInputFields component simply hands it on up to SurveyApp.  Think if of it as like how a passthrough server works.

    Finally, the new event data gets all the way up to SurveyApp's handleFieldChange() method, where the state is reset.  The method uses two passed up indexes, the index of the question where an element has been (un)checked and the index of element (i.e. which answer) within that question, to determine which data point to change.  The change is to add a .checked property if the underlying checkbox field has been ticked, and to delete that property if the field has been unticked.   Once the relevant data point is modified, we call a setState(), so re-rendering our whole app, and our work here is done.


    About