Home & blog  /  2012  /  Jan  /

Numberfy: add line numbers to your textareas

posted: 23 Jan '12 18:31 tags: line numbers, textarea, jQuery

Ever wished textareas had native support for line numbers?

I, and doubtless the developers behind the many JSFiddle-esq sites out there these days, have.

So I've built a jQuery plugin that does precisely that. Just target the textarea(s) you want to add line number support to via a jQuery selector, call the numberfy method, and that's it.

Head over here to download, get usage info or view a demo.

$('#myTextarea').numberfy();

This tuned out to be an interesting little thing to build. The most challenging part, obviously, was getting the numbers to appear at the right positions vertically, to take into account line wrapping.

The solution here is simple but effective; on every keypress in the textarea, the textarea's current value is split into lines, then one by one each line is added to the clone and its offset height measured.

That tells us how tall the line is, including wrapping, and tells us therefore where to position the line number.

It's worth pointing out that the clone is not actually a clone of the textarea - it's a

tag; the reason is the clone needs to have fluid height, so we can read its offset height. A textarea's dimensions are never fluid.

IE, sod off

It doesn't currently work correctly in IE. This is because I discovered a little-known 'bug' in IE whereby text within textareas wraps differently from text in other areas - even where they have the same word-wrap / white-space CSS properties.

I moaned about it on Stack Overflow, and the consensus so far seems to be there's nothing that can be done about it. I'll keep looking at this.

Head over here to download, get usage info or view a demo.

Enjoy.

post a comment

JSON and PHP: formatting and validating

posted: 04 Jan '12 21:05 tags: PHP, JSON, formatting

Formatting JSON to look all lovely

It's always a happy day when I manage to use JSON in PHP. As a JS developer, it sort of feels like I'm marrying the two technologies. Take that, serialised arrays - I'm using JSON.

PHP, of course, has support for encoding and decoding JSON via json_encode() and json_decode() respectively. What it can't do natively, though, is format JSON.

Why would you want to format JSON in PHP to make it look all nice and indented? Well, if the system you're building uses JSON for a config file, and you want users to be able to edit that config file within the system, in a textarea, say.

I then found this function, which largely does the job.

It can, however, get the indentation wrong sometimes. Also, it can leave whitespace at the end of lines. So I extended it slightly. The following three snippets should be inserted just before the final return statement.

Firstly, let's clear any whitespace left at the end of lines.

$result = preg_replace('/\t+\n/', "\n", $result);

Next, let's fix the indentation. What I noticed was that the script was indenting lines containing closing brackets/braces precisely double what it should be - so four tabs instead of two, for example. So, the following halves each case.

1function PR_callback($match) { return substr($match[1], 0, strlen($match[1]) / 2).$match[2]; }

2$result = preg_replace_callback('/^(\t+)(\]|\})/m', 'PR_callback', $result);

Note I'm using a callback on preg_replace() - this gives me greater control over the nature of my replacements. preg_replace() automatically forwards to my callback one argument - an array of the match. As ever, key 0 in the array contains the whole match and any subsequent keys contain any sub-matches my pattern looked for.

Lastly, either the script or (more probably) my hacks above end up killing some of the line breaks, so let's restore them.

$result = preg_replace('/([^\t]+)\t/', "$1\n\t", $result);

Et voila - nicely formatted JSON.

Make sure your JSON's valid

JSON and JavaScript Object Notation are not always the same thing. How so? Well, this is valid JS but INvalid JSON:

1var someObj = {

2     one: 'one',

3     two: 'two'

4}

...because the JSON spec demands that a) property names are quoted; b) property names and strings must be encased in double, not single quotes.

So if you end up with invalid JSON, how will you know? PHP >= 5.3 defines json_last_error(), which returns a flag saying what went wrong.

Confusingly, it returns something even if nothing went wrong - JSON_ERROR_NONE. It does not return false, so it is insufficient to check the validity of JSON with:

1$badJSON = '{one: "one"}';

2$array = json_decode($badJSON, true); //2nd param means we get back an assoc. array, not an object

3if (!json_last_error()) echo "All OK!";

Instead, the last line should be:

if (json_last_error() != JSON_ERROR_NONE) echo "All OK!";

PHP versions prior to 5.3

If you're running PHP prior to v.5.3, you won't have json_last_error(). Instead, you can simply check the truthy/falsy value of json_decode(), so:

1$array = json_decode($badJSON, true);

2if (!$array) echo "Problem!";

Obviously this approach is more crude and won't tell you what went wrong - just that something did.

If you're looking for somewhere to host your PHP, whether Linux or Windows hosting, it always pays to make use of a good web hosting review site to find the right web hosting provider. This is a particularly good one, especially their WordPress hosting search page if you’re still on your way finding a suitable home for your WordPress blog.

post a comment
older posts >