Getting the current language code in a Mendix app from JavaScript

When we’re working on a multi language application, we need to be aware of the user’s language ensure they receive content in their own language.

Mendix has great language support, and it also has great caching on the client side. These can cause problems together when you change the language of a user in your application, it may not always be reflected back to local cache.

There is a way around this, we can use the Mendix Client API to force a retrieve of the data from the application. We need to use an XPath request to ensure we bypass the cache.

let xPath = "//System.Language[System.User_Language=\"" + mx.session.getUserId() + "\"]";

We have the current user’s session ID, so we can retrieve the System.Language using this a constraint on the System.User_Language association.

Now we can just use an mx.data.get call to retrieve it.

mx.data.get({
    xpath: xPath,
    filter: {
        amount: 1
    }, 
    callback: function(obj) { 
        let lang = obj[0].jsonData.attributes.Code.value;
        console.log("Current language is " + lang);
    }
});

In this example, we are just echoing the language code back to the user on the console.

Fixing The National Rail Mobile Website For iPhones

I’ve been frustrated that the National Rail Enquiries mobile website doesn’t work properly on my Apple iPhone 4s, running iOS7, so I decided to take a look and see what is actually going on.

You can turn on debugging on your iPhone in the settings, so I turned this on, and loaded Safari on my Macbook Pro to take a look at what was actually happening.

The “Go” button on the mobile website acts as a submit button so I put a breakpoint on it to see what happened.

The event handler calls a function called setRecents, and it fails when it tries to save my recent stations to localStorage.

if (hasStorage) {
    localStorage.setItem("recentStations", recVal);
} else {
    setCookie("recentStations", recVal, 365);
}

The hasStorage global variable has a true value, allowing it to try to save to local storage, so I tried setting this to false and tried again. This time to website worked as it falls back to using cookies. So the problem is with localStorage on mobile Safari, I’m not sure why.

I then took a look to see how hasStorage was set. It was being set in the following function.

function checkStorage() {
    // Feature detect + local reference
    var storage,
    fail,
    uid;
    try {
        uid = new Date;
        (storage = window.localStorage).setItem(uid, uid);
        fail = storage.getItem(uid) != uid;
        storage.removeItem(uid);
        fail && (storage = false);
    } catch (e) {}
    if (storage) {
        hasStorage = true; //if localstorage available
    }
};

I set breakpoints through the function, reloaded and single stepped what was happening in the debugger.

The uid was correctly set to a Date object with the current date and time. The next line was where the problem occured. storage was assigned as a Storage object, but the setItem method failed. This meant that the storage variable was set, but an exception was thrown. The exception handler does nothing, so the line after was executed. This sees that storage is available, but not that it didn’t work, so sets hasStorage incorrectly to true.

The fix would be to modify the exception handler to set storage to false instead of doing nothing.

If any developers of the National Rail website are reading this, please add this line so I can use your website to plan my train journeys again using my iPhone!

The National Rail mobile website on an iPhone

All information correct at time of writing and publishing. 20th April 2014.

Data URI’s – Using and Generating

A recent project of mine needed an image embedding into some HTML via JavaScript. Rather than use a separate image, I decided to embed it directly using a data URI.

An image in a data URI is the MIME type of the image and it’s content encoded with base64 into a string. This is great as it cuts down HTTP requests but does cause the initial page weight to increase and be difficult to update as each change means the image needs re-encoding. Modern browsers support data URI’s very well, but older browsers such as IE 7 and below won’t like it.

Examples Using A Data URI Encoded Image

HTML Example

Here’s how I can embed the image of a red cross into an HTML <img> tag.

<img src="data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw==" alt="red cross" width="20" height="20" />

CSS Example

Here’s how I can embed the image of a red cross into background of an HTML element using CSS.

body { 
  background: url(data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw==) no-repeat left center;
}

JavaScript Example

Here’s how I can add an image element with the red cross in to an HTML page using JavaScript.

var imagestring = "data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw==";
var image = new Image();
image.src = imagestring;
image.onload = function() {
  document.body.appendChild(image);  
}

Encoding An Image To A Data URI

It’s easy to create the encoded image string using PHP as it comes with a Base64 encoder as part of the language. Automatically detecting the MIME type of an image is a bit harder, but we can use finfo_file with comes as an extension to PHP 5.3 and above to do this.

So assuming the filename of the image is in the variable $filename we can use the following code to get the mimetype, read the image and encode it to a data URI string.

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $filename);
finfo_close($finfo);

$contents = file_get_contents($filename);
echo "data:" . $mimetype . ";base64," . base64_encode($contents);

Conclusion

We’ve seen it’s easy to embed encoded images into code. I have wrapped the encoding routine into a command line PHP script and placed it on GitHub as php-base64-encode so it’s easy to quickly generate data URI’s.

jQuery To Scroll To A Specific Element

I thought I’d share a useful snippit of jQuery code for scrolling to a specific element on a page.

$('html, body').animate({
    scrollTop: ($('#element').offset().top)
},500);

We use the .animate() method to scroll to the top of #element, over a period of 500 milliseconds.

jQuery To Scroll To The First Element With A Specific Class

A practical use of this could be in validating a form and you want to scroll to the first error for the user to correct. Assuming all elements with problems have been given the class of error, we can scroll to the first one using jQuery’s .first() method before chaining on .offset() and the property top as before.

$('html, body').animate({
    scrollTop: ($('.error').first().offset().top)
},500);

Now, go get scrolling!

Unit Testing JavaScript With QUnit And Phing

Recently I’ve been using both Phing for my PHP builds, and QUnit for my JavaScript unit tests, so I’ve been looking for a way to run these QUnit tests when Phing builds my application.

By default Phing can run PHPUnit tests, but not QUnit. However Martin Jonsson has come to the rescue with his Qunit Phing Task.

QUnit Phing Tasks lets QUnit tests be run during a build and Phing can either pass or fail based on these results. As QUnit is written in JavaScript, QUnit Phing Task runs PhantomJS to call a JavaScript wrapper that passes the output back to PHP and Phing. PhantomJS is a headless JavaScript browser that can excute on a command line.

Using QUnit Phing Task

To run the QUnit Phing Task you need to install PhantomJS. I downloaded a binary and placed it in /usr/local/bin on my system.

You need to download the QUnit Phing Task. I placed the files in a local ./lib directory in my project.

You will also need to download QUnit. I placed the files in a local ./tests directory in my project.

In the ./tests directory I created an HTML file called runner.html. This is the page we need to call to run our tests.

<!DOCTYPE html>

<html>
        <head>
                <meta chatset="utf-8" />
                <title>Qunit Tests</title>
                <link rel="stylesheet" href="./qunit.css">
                <script src="./qunit.js"></script>
                <script src="./test.js"></script>
        </head>

        <body>
                <div id="qunit"></div>
        </body>
</html>

I also create a JavaScript file called ./test.js in ./tests to hold my JavaScript tests in.

test("testing for true", function() {
        ok(true, "true is true");
});

Finally, I create a build.xml for my Phing build.

<?xml version="1.0" encoding="UTF-8"?>
<project name="qunit example" basedir="." default="qunit">

        <path id="project.class.path">
                <pathelement dir="./lib/" />
        </path>

        <taskdef name="qunit" classname="QunitTask">
                <classpath refid="project.class.path" />
        </taskdef>

        <target name="qunit" description="JavaScript Unit Test">
                <qunit executable="DISPLAY=:0 /usr/local/bin/phantomjs" haltonfailure="true" runner="./lib/run-qunit.js">
                        <fileset dir=".">
                                <include name="tests/runner.html" />
                        </fileset>
                </qunit>
        </target>

</project>

In this I am specifying a path to my ./lib directory as this is where the QUnit Phing Task code is. The path is then used in the taskdeftask which is used to create the <qunit> task. Now when I call <qunit> in my qunit target I just pass in the location of the executable – in this case where PhantomJS is, whether Phing should halt if the QUnit tests fail, and where to find the the JavaScript that runs QUnit. Inside the task, we pass in where our runner pages are, as we only have the one in this example we include it by name tests/runner.html.

Running this gives us the following…

rob@lamp ~/qunitphing> phing
Buildfile: /root/qunitphing/build.xml

qunit example > qunit:

    [qunit] ./tests/runner.html: 1 tests of 1 passed, 0 failed

BUILD FINISHED

Total time: 0.3275 seconds

So we can see our tests have passed. Let’s change our test.js so that it fails.

test("testing for true", function() {
        ok(true, "true is true");
        ok(false, "false is true");
});

This test should fail, as false is not true and will fail the ok assertion.

rob@lamp ~/qunitphing> phing
Buildfile: /root/qunitphing/build.xml

qunit example > qunit:

    [qunit] 1 tests failed on: ./tests/runner.html
    [qunit] Failed test: testing for true (1, 1, 2)
Execution of target "qunit" failed for the following reason: /root/qunitphing/build.xml:13:41: QUnit tests failed

BUILD FAILED
/root/qunitphing/build.xml:13:41: QUnit tests failed
Total time: 0.3258 seconds

So we can see that Phing has failed our build due to the QUnit tests failing, which is what we want.

Summary

Although a very simple and contrived example, I hope this has shown you how to add JavaScript unit tests using QUnit to your Phing build.

Using QUnit To Unit Test JavaScript

In this article I wanted to give you an introduction to unit testing in JavaScript using QUnit.

QUnit was originally developed by John Resig for testing jQuery, but it is now a stand alone project, without any dependancies on jQuery.

A quick example of using QUnit

Firstly, you need to download qunit.js and qunit.css, and store them locally.

Secondly you need to create an HTML page something like this to run your tests in.

<!DOCTYPE html>

<html>
	<head>
		<meta charset="utf-8">
		<title>QUnit Example</title>
		<link rel="stylesheet" href="./qunit.css">
		<script src="./qunit.js"></script>
		<script src="./test.js"></script>
	</head>
	<body>
		<div id="qunit"></div>
	</body>
</html>

You’ll notice the references to qunit.css and qunit.js are to the two files we downloaded just now. tests.js is the file where we’ll be placing our unit tests, and we’ll be creating this shortly. Finally, you’ll also see a <div> with an id of qunit. Ths is where the results of our unit tests will be displayed.

One of the simpliest tests is testing for true. Create a file called test.js and add the following.

test("testing for true", function() {
	ok(true, "true is true");
});

This should give us a result like looking like this.

QUnit Results

We can see that one test was successfully run, and that there were no errors found.

The name of our test, “testing for true” is shown, and clicking onto this expands the result and shows our success message “true is true”.

Qunit Results

So what is going on?

Well, we are calling the test function from QUnit, and we are passing in a name for our test – “testing for true”, and a function to execute the test in. Inside this function we calling the assertion ok from QUnit, passing in a value to test for truth against – in this case true, and a message about the assertion – “true is true”.

When the page is loaded into a browser, the script is run and the results of our unit test shown in the qunit <div>.

Testing For Equality

One of the most common unit tests is to compare the expected and actual values from a function.

QUnit has the equal assertion to help us here. Let’s add some more tests to test.js.

test("testing equality", function() {
	equal(1, 1, "1 is 1");
	equal("1","1", ""1" is "1"");
	equal(1, "1", "1 is "1"");
	equal(1, true, "1 is true");
	equal(1, !false, "1 is not false");
});

Run this and expand the results for “testing equality”, it should look something like this…

Qunit Results

You should see the obvious results such as 1 and 1 being equal, and “1” and “1” being equal. You should also see that 1 is the same as “1” as JavaScript is converting between types and checking the values are the same. Finally, you can see that 1 is also true, and not false, this is because 1 is truthy in JavaScript. The point to remember here is that the equal assertion behaves like JavaScript’s == comparator.

There may be occassions where you need to compare the value and the type, so the number 1 isn’t the same as the string “1”. In these situations we need to use the strictEqual assertion as this works like JavaScript’s === comparator.

Let’s add some more assertions to our “testing equality” test.

	strictEqual(1, "1", "1 is "1"");

Running this we can see that the number 1 is not the same as the string “1”, and QUnit has thrown an error to tell us this.

Qunit Results

However this isn’t very useful, as we know that 1 isn’t really “1”, so we want to test for this. This is where QUnit’s notStrictEqual assertion will come in handy, as it tests for false results.

Replace the strictEqual with the following…

	notStrictEqual(1, "1", "1 is not "1"");

Running this we can see that the number 1 is not the same as the string “1”, and QUnit has tested successfully for this.

QUnit Results

It’s useful to be able to compare objects, so let’s try this but adding the following code…

	var a = {'name' : 'rob'};
	var b = a;
	equal(a, b, "variables a and b are equal");
	b = {'name' : 'rob'};
	equal(a, b, "variables a and b are equal");

Running this we see that our first asserting that a and b are equal is correct, however, creating what looks like the same object and testing equality fails.

QUnit Results

This is because we’re not testing the actual contents of the object, just that the reference the variable points to is the same. In the first case they both point to the same object, in the second case they are different objects.

QUnit has another equality function called deepEqual that compares the content of an object with the content of another object. Let’s change the failing equal in our last example with the deepEqual and try again.

	deepEqual(a, b, "contents of variables a and b are equal");

QUnit Results

Our tests are working again now, as we are now comparing the actual contents of the objects.

Summary

QUnit can do much more than just testing for equality and I hope to touch on some of the other functionality in another article soon. However, I hope this basic overview has been a useful introduction to unit testing JavaScript and has provided enough information to get you started in testing your own JavaScript code.

Converting An HTML5 Canvas To Black And White

As part of the OCR in my Draw Something Solver, I needed to turn animage into a two tone black and white image. This is really simple to do. Firstly you need to turn the image to grayscale, then you need to turn all pixels with a value over a certain threshold to 255 for the red, green and blue values, or to 0 if under the threshold.

I’ve already covered Grayscaling an HTML 5 Canvas so I will assume this has already taken place and you have the ImageData from an HTML 5 Canvas in an object called imageData.

To turn this to a black and white image we can use the following code…

for (var i = 0; i < imageData.data.length; i+=4) {
  imageData.data[i] = imageData.data[i+1] = imageData.data[i+2] = imageData.data[i] > threshold ? 255 : 0;
}

You just need to change the value of the threshold variable to adjust the sensitivity of the conversion.

Taking the previous red channel image conversion…

grayscale image

Setting the threshold to 200, the converted black and white image looks like this…

black and white image

Draw Something Solver – A Working OCR System

I’ve already mentioned about my first OCR attempt for my Draw Something Solver, and the disappointing results.

I said the letters did not appear to be consistant, this turned out to be on my iPhone 4S, the spacing of the letters is not consistant, there are a few pixels difference between the letters on the left and those on the right. Once I had discovered this, the letters matched.

However, taking this approach meant only images taken from a retina enabled iPhone would work, those from a lower resolution screen would not match. I would need to take screenshots of every letter on every device at every resolution to be consistant. Not a very good idea.

My next approach was to scale to image down to a common size using an HTML5 canvas, that didn’t produce consistant results. I tried to grayscale, and to turn to black and white, but although close, they were still too different.

My final approach, and one that seems to work for now is to still scale and turn the images to black and white, but instead of hashing this result, I am instead doing some pixel comparison and generating probabilities of matching a letter. This is a simple neural network. I have trained it with all the letters from my iPhone 4S so that runs consistantly each time. When I ran against images from an iPhone 3GS, not all images matched, letters like “I” and “J” caused confusion, so where a match was wrong I added some extra training data for those letters so they all now match. I have yet to try images from an iPad as I don’t have one, but I hope they will match first time without further training.

Using The DOM Ready Event

One of the great advantages of using a library like jQuery is that is provides functions like ready() so you can activate your JavaScript code when the DOM is ready, and not when everything has been loaded. This can be significantly earlier, especially if you an image heavy page.

The ready() function is quite chunky, and has to account for a variety of browsers and versions. However, if you know you are running on a recent browser, you can always look at hooking directly into the DOMContentLoaded event. This is part of the HTML5 spec.

To use it you need to add an event listener using the document.addEventListener method. This takes two parameters, the name of the event – in this case DOMContentLoaded, and a callback function to call when the event is triggered.

document.addEventListener("DOMContentLoaded", function domready() {
  document.removeEventListener("DOMContentLoaded", domready);
  console.log("DOM Ready");
});

Notice how I have given the function a name – domready(), this is so I can unhook the function from the event listener once the event has fired.

Grayscaling An HTML5 Canvas

I’ve been looking at how to turn a colour image into a grayscale one using JavaScript on an HTML 5 Canvas. I had done something similar a few years back to an image using Perl.

Wikipedia has a good article on converting colour to grayscale, and it’s very simple formula based on the luminance of the image. The recommendation is to add together 30% of the red value, 59% of the green value and 11% of the blue value.

var luma = red * 0.3 + green * 0.59 + blue * 0.11;

We can easily apply this formula over the ImageData in an HTML 5 Canvas Context object to turn the image held in the Canvas to grayscale. The ImageData.data holds an array with four pieces of data per pixel, the red, the green, the blue and the alpha values. These are integer values between 0 and 255. The code to grayscale the ImageData would look like this.

for (var i = 0; i < imageData.data.length; i+=4) {
  var luma = Math.floor(imageData.data[i] * 0.3 +
  imageData.data[i+1] * 0.59 +
  imageData.data[i+2] * 0.11);
  imageData.data[i] = imageData.data[i+1] = imageData.data[i+2] = luma;
  imageData.data[i+3] = 255;
}

Notice the use of Math.floor(), this is just to round the luminance down into an integer value.

Colour

Grayscale

There is another common way to grayscale an image, and that is to get the red, green and blue pixels to all match. You can pick the colour you want to be the key, for example red, then just make sure the values for the green and blue for each pixel match that of the red one. This is making use of a single channel, and can give very different effects depending on your source image.

To use the red channel we could the following code over some ImageData.

for (var i = 0; i < imageData.data.length; i+=4) {
  imageData.data[i+1] = imageData.data[i+2] = imageData.data[i];
  imageData.data[i+3] = 255;
}

Grayscale Red Channel

To use the green channel, use the following.

for (var i = 0; i < imageData.data.length; i+=4) {
  imageData.data[i] = imageData.data[i+2] = imageData.data[i+1];
  imageData.data[i+3] = 255;
}

Grayscale Green Channel

To use the blue channel, use the following.

for (var i = 0; i < imageData.data.length; i+=4) {
  imageData.data[i] = imageData.data[i+1] = imageData.data[i+2];
  imageData.data[i+3] = 255;
}

Grayscale Blue Channel