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

array.prototype.pureSplice npm package

Michael Brown  June 25 2016 11:22:42 PM
I've just released my seventh npm package, array.prototype.pureSplice().  FYI, my seven packages now have over 2, 000 downloads per month, combined.  Okay, that may not be in the same league as ReactJS (over 160,000 downloads per month) or AngularJS (over half a million downloads per month), but hey, it's a start!!!

So, pureSplice() is an array method to return a new array with a specified number of elements removed. Unlike JavaScript's native array.splice() method, array.pureSplice does not modify the source array. This is important if immutability of data is important to you and/or you are using libraries such as Redux.

Full instructions for use are on the array.prototype.pureSplice page on npmjs.com.  Also, a new feature on the npmjs site: you can now check how pureSplice() works in your browser, via Tonicdev.

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!

    About