VAT : Oh what I would do for a world where things actually made sense.
by Developer @ pebbl.co.uk on Sunday, 28 April 2013
Another rant post I'm afraid. After finally managing to submit my first VAT Return online, I spotted a link where I could give feedback to HRMC. It's only after merrily filling out a short complaint in their textarea that I spot the words "350 character limit"... forget how simple it is to limit a textarea, or to give a character counter... as usual I'm not supposed to expect the same level of quality from a government run website to that of the rest of the commercial world, or so it would seem, but I keep falling into that trap. So rather than completely truncate what I wrote I thought I'd post it here:
350 chars is not enough!
As usual, whenever I end up having to do dealings with any branch of the HRMC online it's as if only those who have studied Tax law could navigate and understand exactly what is expected, and only those who spot small links at the top right (a very bad location for western eyes) will find some of the most important navigation items. After your tenth page, third dead-end and twentieth bullet point starting with a complicated "IF" statement, you are already lost as to what applies and what doesn't.
My main complaint is that there is hardly any tailoring to the individual user, or type of business, something that the business world has to do otherwise they face losing custom. The whole experience when dealing with anything tax related is so impersonal I spend most of my time unsure if I've actually managed to do things correctly -- which is all I wish to do. This has been so much to the point that I have now taken on an accountant, and even now, things are still murky.
If the above wasn't bad enough, you even have inaccuracies in your forms. I've recently signed up to the flat-rate VAT Scheme, and if I had gone ahead reading your nine box VAT form myself, I would have filled out the values as it was asked. Thankfully my accountant advised me that I should be filling out box 7 with gross figures... there is no mention of this on the form itself.
Overall, I got the same experience from the VAT system as I have done with the Self Assessment system, the only positive is that the VAT form is much, much shorter.
Anyone might think this complication is done on purpose to create jobs...
Oh and one more thing...
The form doesn't even allow for return characters...!?! It doesn't tell you this however, it just gives you an error back saying "incorrect format" — good work HRMC.
describe.js v0.4, 0.5 and 0.6 have all been, urm... skipped.
by Developer @ pebbl.co.uk on Saturday, 27 April 2013
Things have gone a little quiet on the describe.js front, and the reason for this is that the last three versions have failed to be finished, and so, have also failed to see the light of day. Mainly because I kept on coming up with better ideas, well at least according to my brain anyway.
So just to keep things going — until I actually post some code — I thought I'd report that I'm now working on version 0.7. There is a reason for these leaps, which I'll explain once I'm done, but it should mean that describe will be even more powerful and extensible than before.
You'll just have to take my word for it for the moment though.
- Leave your comment • Category: Coding, JavaScript
- Share on Twitter, Facebook, Delicious, Digg, Reddit
I just put this miniature library together to help work with Regular Expressions in a cleaner and abstracted manner. It's pretty simple, but RegExp interaction in JavaScript has always been a little clunky in my opinion, so it doesn't take much to smooth things out a little.
/// example usage
var result =
ExpReg(/\|/gi)
.haystack('[believe|dont]|[either,way]')
.replace(function(match, i){return '{'+i+'}';})
.haystack()
;
/// result = '[believe{8}dont]{14}[either,way]'
Whilst the above may actually be shorter to type in pure JavaScript:
String('[believe|dont]|[either,way]')
.replace(/\|?(\[[^\]]+\])/gi, function(match, i){
return '{'+i+'}';
})
;
.. the problem with the above is that it is completely different from the formation to step through items matched, for example:
var m, re = /\|?(\[[^\]]+\])/gi;
while( (m = re.exec('[believe|dont]|[either,way]')) ) {
/// do whatever processing required here.
};
The main benefit of using ExpReg would be that the way of dealing with Regular Expressions is standardised, and all the RegExp objects that are created are remembered, so you can refer back to them quickly — useful in code that reuses expressions. Plus it's easy to add new methods that work in a builder fashion — similar to jQuery.
/// another example using a string instead of literal RegExp
ExpReg('/./gi')
.haystack('this should match every letter')
.each(function(match, i){alert(i)})
;
/// an example of mapping
var words =
ExpReg(/\w+/gi)
.haystack('this should match every word')
.map(function(match){return match})
;
Just in case it comes in useful, here is the recently imagined source code of expreg.js :)
/**
* ExpReg 0.1
*
* ExpReg is just a simple RegExp wrapper that has some useful
* functions for dealing with Regular Expressions. This include
* is designed to work with require.js but can also operate as
* a normal js include.
*
* @author Phil Glanville - 2013/05
*/
var ExpReg;
/// define not-exist fallback
(typeof define === 'undefined' &&
(define=function(a){return (ExpReg = a())}));
/// hook into require.js
define(function(){
"use strict";
var global = {
delims: new RegExp('^([^a-z0-9\s])(.+?)\\1([gimy]{0,4})$','i'),
lookup: {}
};
/**
* The outer wrapping constructor that will be exposed as ExpReg
*/
var ExpReg = function(re, haystack){
var t;
if ( this instanceof ExpReg ) {
if ( !global.lookup[re] ) {
if ( re instanceof RegExp ) {
global.lookup[re] = re;
}
else if ( (t = global.delims.exec(re)) ) {
global.lookup[re] = new RegExp(t[2],t[3]);
}
}
this.exp = global.lookup[re];
this.source = haystack?haystack:'';
this.matches = [];
this.matched = false;
this.reversed = false;
}
else {
if ( typeof this == 'string' ) {
return new ExpReg(re, ''+this);
}
else {
return new ExpReg(re, haystack);
}
}
};
/**
* Simple jQuery like attr function
*/
ExpReg.prototype.attr = function( name, value ){
if ( arguments.length == 2 ) {
this.exp[name] = value;
}
else {
return this.exp[name];
}
};
/**
* Define the haystack that the RegExp will search
*/
ExpReg.prototype.haystack = function(string){
if ( arguments.length && (typeof string == 'string') ) {
this.source = string;
this.matched = false;
return this;
}
else {
return this.source;
}
};
/**
* Return a particular matched item. A matched item will
* be an object that contains a zero-indexed array of .groups
* and an .offset property that gives the start of where the
* match was found.
*/
ExpReg.prototype.item = function(n){
if ( arguments.length == 0 || n === undefined || n === null ) {
return this.matches;
}
else if ( n < 0 ) {
return this.matches[this.matches.length+n];
}
else if ( n < this.matches.length ) {
return this.matches[n];
}
else {
return null;
}
};
/**
*
*/
ExpReg.prototype.findAll = function(){
/// remove previously found items
this.matches.length = 0;
/// reset and scan
var groups; this.exp.lastIndex = 0;
/// if we are global we can findAll
if ( this.exp.global ) {
while( (groups = this.exp.exec(this.source)) ) {
this.matches[this.matches.length] = {
groups: groups,
offset: this.exp.lastIndex-groups[0].length
};
}
}
/// if not global, match the first and stop
else {
this.matches[this.matches.length] = {
groups: (groups = this.exp.exec(this.source)),
offset: this.exp.lastIndex-groups[0].length
};
}
///
this.matched = true;
};
/**
* Replace current selection with either string or result of callback
*/
ExpReg.prototype.replace = function(param){
if ( !this.matched ) { this.findAll(); }
if ( this.matches.length ) {
if ( typeof param == 'string' ) {
this.source = this.source.replace(this.exp, param);
}
else if ( param.call ) {
var exrg = this;
this.source = this.source
.replace(this.exp, function(a,b){return param(a,b,exrg)});
}
}
return this;
};
/**
* Call a callback for each match found
*/
ExpReg.prototype.each = function(callback){
if ( !this.matched ) { this.findAll(); }
if ( this.matches.length ) {
var i, l = this.matches.length;
for( i = 0; i < l; i++ ) {
callback.call(this, this.matches[i], i, this);
}
}
return this;
};
/**
* Map the matches to an array
*/
ExpReg.prototype.map = function(callback){
var a = [];
if ( !this.matched ) { this.findAll(); }
if ( this.matches.length ) {
var i, l = this.matches.length;
if( typeof callback == 'undefined' ) { callback = 1; }
if ( callback.call ) {
for( i = 0; i < l; i++ ) {
a[i] = callback.call(this, this.matches[i], i, this);
}
}
else {
for( i = 0; i < l; i++ ) {
if ( this.matches[i] &&
typeof this.matches[i].groups[callback] != 'undefined' ){
a[i] = this.matches[i].groups[callback];
}
}
}
}
return a;
};
/**
* wrap the matches with strings
*/
ExpReg.prototype.wrap = function(pre, post){
this.replace(function(match){
return pre+match+post;
});
return this;
};
ExpReg.prototype.reverse = function(){
if ( !this.matched ) { this.findAll(); }
this.matches.reverse();
this.reversed = !this.reversed;
return this;
};
/**
* debug log
*/
ExpReg.prototype.log = function(pre, post){
this.each(function(match, i){
console.log(i, match);
});
return this;
};
String.prototype.ExpReg = ExpReg;
return ExpReg;
});
/// remove our temporary define fallback
(ExpReg) && (define = undefined);
- Leave your comment • Category: Coding, JavaScript
- Share on Twitter, Facebook, Delicious, Digg, Reddit
Centre Image : The strange combination of position absolute, margin auto and an image tag
by Developer @ pebbl.co.uk on Thursday, 25 April 2013
Just recently I was charged with the task of upgrading the Slideshow ability on the Tate's website, basically finishing off the work so that it could display more than just images, and to finalise it's mobile support. Most of the work was quite straightforward and entailed reverting some of the previous bespoke modifications made to the default Flexslider plugin, and then enhancing the out-of-the-box functionality with things like full-screen mode, and managing audio or video files that might be contained within.
Stop it and tidy up
One of the main improvements I made was to try and get things working with as little JavaScript as possible, this meant refactoring the CSS somewhat, and due to not having worked closely with CSS for the last year — save for the odd stackoverflow answer — I was quickly reminded just how frustrating-a-language CSS is to debug and repair... especially in it's pure form, outside of any compilation framework like LESS.
Anyway, re-realisations aside, I got pretty much everything working via CSS save for two issues. The first of these problems was the age old annoyance of how to centre an element in the middle of a container on both the vertical and the horizontal. Now I've been using CSS since the early days — if you could refer to them as early — so I'm quite aware of the different vertical alignment tricks that can be employed. I was also aware that the only way(s) I knew of to get an element of unknown or variable dimensions to centre was either to use a table, display:table, or use a background-image instead (at least for images anyway). Any one of these would have taken some crowbarring to get working harmoniously with the slideshow system. Unfortunately, every one of my slideshow images had variable dimensions, which not only varied depending on itself, but was also responsive to the display size... so I had to find some nicer way of doing it.
Solution?
Considering the fact that the well known browsers are now developing at a rate of knots, I decided that there must be a better way by now. Obviously I could have used flexbox, but it's fluctuating and unreliable support would have meant more headaches in testing than I had time for. So I spent quite a bit of time searching around, finding pretty much all the ways I already knew about, until I stumbled upon this random suggestion:
img { position:absolute; left:0;top:0;right:0;bottom:0; margin:auto; }
At first glance that snippet made no sense to me, and I almost automatically dismissed it as nonsense. I'm quite glad I ignored my first thoughts however and tested it out, because — at least for every user agent I checked — it did exactly what I needed. Now, if anyone can explain why this has been built in, and why images should behave differently to any other element, I'd be interested to hear... until then I'll just mark it down to another strange oddity in the interpretation of the rather wholly strange language/construct that is CSS.
- Leave your comment • Category: Coding, HTML and CSS
- Share on Twitter, Facebook, Delicious, Digg, Reddit
Internet Explorer Detection : The power of conditional comments but via jQuery
by Developer @ pebbl.co.uk on Wednesday, 24 April 2013
I came across a situation the other day where I needed a specific browser check (IE7 or less), there wasn't a particular testable feature to hand that would do and I didn't have access to the markup. My usual fix for Internet Explorer specific bugs is to use conditional comments, they do exactly what it says on the tin, however.. not having access to the page markup thwarted this otherwise quick and easy solution.
Rather than falling back to tenuous agent string checking — particularly worrying when it comes to specific version number checks — or bashing my head against multiple feature tests that could be invalidated in the future, I thought the following implementation would be no less mad, and maybe even slightly useful:
var isOldIE = function(query){
return $('<!--['+(query||'if lte IE 7')+']>OLDIE<![endif]-->')
.text() === 'OLDIE'
;
}
Make of it what you will, but I rather like it... even though it is hideous from an optimisation point of view.
- Leave your comment • Category: Coding, JavaScript
- Share on Twitter, Facebook, Delicious, Digg, Reddit