Saturday, August 30, 2008

Table Cell Editor v1.0

Table Cell Editor v1.0


Download: Version 1

About the table cell editor:
Its fairly straightforward, but a nifty little tool. It allows in-line editing for cells the way I think editing should be. Right now it takes a text field, but could easily be updated to take a textarea, a dropdown menu... anything.

I have put in stubs for an ajax call, but commented it out, since I'm not interested in hooking that in. It is at work, but for the demo I just edited it out.

Doesn't look like much, does it? Well, thats a good thing. This fits into my philosophy of getting the job done with as little effort as possible while maintaining usability and intuitiveness.

However, under the surface is a whole range of concerns that the user will never be privy to. This is one of the aspects of user interface design that makes new coders go nuts. The sheer amount of use cases even for such a small interface can be overwhelming.

So, if you want to know how it all works, then read below. I have not just provided the interface, but I have anticipated a wide variety of use cases regarding submittal of the request to the server, and cleansing of data.

By the way... everything I add on my blog will always be browser compatible (IE, FireFox, Safari, Opera). I don't think anyone really needs to say that anymore. If you are coding for one browser and your not confined by the constraints of the enterprise world (the only valid excuse for this), then your doing everyone a disservice. That being said, if you can't get it to work in Opera, then don't kill yourself, just put in your Opera hack and move on.

I won't go into a tremendous amount of detail, but I do (for my sanity) assume the following things.
  • More than a moderate understanding of javascript and event handling
  • More than a basic level of JSON.
  • More than a basic understanding of javascript toolkits like mooTools. Although I am using mooTools methods, it is not hard to understand the equivalent concepts in prototype, JQuery, YUI and the like. (If you want to convert this into your own toolkit, feel free).
Regarding edits, I recommend you:
  • Leave the JSON syntax and method partitioning alone, as much as you are able to. I keep my methods short (if I can), focusing on one thing only. The idea here is to modularize your work, so that the code is easy to maintain and understand.
  • "app" is your basic program. It is the only global variable you need to create.
Overview of interface:
  • Blue text indicates editable.
  • Double-click opens edit.
  • Enter submits edit.
  • Escape rejects edit.
  • Ajax call allows edit to process and can accept or fail the request.
Overview of code:
  • For our purposes, I am coding using JSON, with mootools framework, and have segmented my methods inside of an "app" variable, which is the only global variable I need. That is why you will see references to "app".
  • I decided that showing the code here is tedious and useless, when all you have to do is download the js and look at it yourself. I will, however, highlight small bits of code out of context. This is to explain anything I feel is just not quite obvious.
  • setUpRowEvents. allows mousenter, mouseleave, click, doubleclick and mousedown events. Don't use mooTools addEvent for hundreds of rows or memory will grow too fast.
  • standardResponseDiv: used to return the ajax request, if necessary.
  • currentConCell if a cell is being converted
  • selectedRows an array of rows for later manipulation
  • freeze: a command to stop any auto-updating code you may have, to give the edit request time to process.
  • You'll need this if you have click doing other things as well, as I do in my original code. You want to stop the user from moving forward unless they accept or decline their edits.
  • Do not use "blur" on the field to either accept or reject the edit. This can be called way to easily.
  • This is the ajax call that takes your edits and actually updates the record.
_cleanse() and _escape()
  • A couple of convenience methods to help make sure data is not cross-site script, and to ensure that the server and database can read the edits, especially regarding special characters.
  • A stub used to generate your string to send over the ajax request.
evaluateButtons() and resetButtons():
  • The idea here is that you may have buttons somewhere that light up or disable depending on what row you click. I have put these stub methods in place for you to put your own logic. I inserted these method calls at exactly the right place so you don't have to worry about where they go in the event scheme.
  • There is a lot going on in here, but there doesn't need to be. I have code for changing the color as you mouse around, and for clicking.
  • The code for soft color change (mouseenter, mouseleave) must not be triggered when a row is selected (a hard color change).
  • The hard color change indicates row focus. This is the selected row, which can not only take edits, but when you call evaluateButtons(), it can trigger other parts of the UI to light up as well. (does not take multiple selections at the time).
  • mousedown ensures that the events don't get called out of order and they stay in-line.
  • click adds or subtracts to an array of rows. I put this in here so you could, as I said before, light up or disable other buttons or widgets based on the row in focus. I have an array here so you can add up the rows and potentially use this for multiple selections.
  • In general, I use a soft color for soft focus, or when the user is just mousing around, and a hard or "punch" color as I call it for direct focus and edit.
  • I use mouseenter and mouseleave as opposed to mouseover and mouseout because these methods fire only once instead of continuously.
*If there are any errors, regardless of the kind of browser you use, then please bring it to my attention. Nobody is perfect.

Thursday, August 28, 2008

Latest Freelance Website

Every now and then I do some freelance stuff. I do it for cheap or free (free-lance), depending on the person.

In this case, this is the first time I've started with a template and then modified the graphics, layout, text to create what you see here. I needed to put something together one or two nights and that isn't easy to do with my free time. So, I think these results are great, considering the time.

Local community theater

Optimize your javascript for enterprise v1.2

Updated 9.10.08 to 1.2. Items added/modified for 1.2 are in blue.

The following are optimizations you can use for any browser when writing client-side code... most especially for Internet Explorer (ahem), and most especially when you are focused on enterprise installs. First, read a few paragraphs on where I am coming from.

This blog will be continually updated, instead of me just making new blogs. You'll know it is updated, because I will attach a version number every time I change it.

These will help speed up the performance of your code if you are dealing with large amounts of data that you need to store in memory over long periods of time. You may see this more nowadays as you use your wonderful Ajax parsing code to keep users on the same page or view.

Unless you are using perhaps the nicest browsers ever to be created (imo), Safari, then I suggest you stick to the lowest common denominator... and what is that? It's Internet Explorer 7. Up until this year, it was IE6, with all of its shortcomings. At an ancient and withering age of 7 years old, IE6 is the official lowest of the low and the dumbest of the dumb.

Many heavy hitters that purchase enterprise software are slow to upgrade. And since IE is a standard install on Windows machines - it means - you guessed it, guys like me have to code for older browsers. With web, it's IE7. With enterprise, your lowest common denominator is ie6. (more on why this is true and a more comprehensive list of differences between web and enterprise in a future blog).

The most salient point I can make about coding for enterprise versus web is that at the end of the day, your customers absolutely must have working code - and code that works fast, is reliable and consistent. An engineering disaster-miracle like will not cut it in the enterprise world. Often there are not millions of users hitting your system, so you have no excuse and customers know this. To that end, it is your job to find the path that gets the job done - which is not always the cleanest or best path.

Internet purists are going to scoff at me, but I am truly a standards guy. I am a purist and a perfectionist. But I am also an enterprise guy - not a web guy (although my colleague Matt is helping me turn a new leaf in this area) - so I have to do what I can to manage extremely large amounts of information on top of a leviathanic, sprawling multi-tiered enterprise framework with multiple millions of lines of code and literally billions of dollars at stake.

The analogy I use for the enterprise thin client interface is that of the Hoover dam. Have a look. That relatively tiny and thin wall is all that stands between godly oceans of information and your users. Do it right and the dam acts as a usability filter - only what is required gets through. Do it wrong... and you're soaked. Memory leaks. Browser CPU hangs. Usability issues over SSL connections and RDP. Anyone in my position understands these problems.

So, to repeat, here are optimizations that are always good, that in some cases are browser-specific, and work wonders for long-standing interfaces that must avoid memory leaks. Most of this is through my experience, but I will try to site references where I can.

1. Don't put classes directly on your HTML elements during an iteration, where said iteration is more than 25-50 items.
  • If you must use classes in order to satisfy a requirement for getElementsByClassName(), then always programmatically capture and then assign classes after the document is loaded.
  • It's IE that suffers the most from this. And as you will find, it's IE, even IE7 that suffers the most from everything you try to do intuitively. Firefox adheres to standards and deals with DOM in a way that fosters intuitive programming. IE adheres to standards and deals with DOM in a way that fosters kludges.
  • See this performance analysis I did on version 1.0 of a select box factory I am working on. Bottom line, is that it shows other browsers do better when classes are set inline, and IE does worse, but moreso than other browsers do better. Your call. Results of performance testing
2. Avoid using a table element for large matrixes, or page it if you can't.
  • Unless you have lazy loading implemented, browsers like IE will not show the table until the contents of table are loaded. This means perceptual slowness.
  • Can you get CSS to work instead? Go for it. But if you must have a table, then implement server-side or client-side paging. The assumption here is that you have so much data that you can't show it all at once. Page it.
  • In all other cases: tables are fine! Yes! I give you freedom to use tables, and get out of the world of CSS for a minute. Tables are great things - and they allow you to add a structure to a page in no time flat - without having to hack away at CSS styles for hours on end. For Enterprise, and for the more moderate amounts of data, tables are the way to go.

3. Avoid memory leaks and circular references

  • These can creep up on you, especially in IE. The best tool to use that I have found is ProcessExplorer. It tells you how much memory has been allocated by the process locally, as opposed to how much memory the process is currently using. Memory leaks are obvious once the program in question (IE) never releases memory and in fact, grows it over time. This can not only kill your process, but in some cases can hang your computer.
  • Assigning objects to references may cause circular references in IE. Try sending on the id of the object, then manipulating the item directly. Circular references can cause memory leaks or, if you are using mooTools v.1, they may cause the mooTools GarbageCollection to take longer than the browser timeout for unload(). This will make the browser alert the user that a "script is running slowly" when in fact mooTools has just not cleared the memory yet.
  • Opacity manipulation through javascript will cause memory leaks in IE.
3. Do / Don't do this in mooTools v.1.1 (and possibly in v.2).
  • Just like classNames, don't programmatically make new Elements() over iterated items because this takes up way too much memory per item. Your browser will complain when you to try unload().
  • Morphing works poorly in ie6 with mooTools v.1.1 Many styles are not supported. mooTools has fixed much of this in v1.2
  • mooTools v1.1 and ie6 is a terrible combination to deal with regarding CSS. Bottom line: you are going to hate life if you have to deal with this. The number one reason is that you can't use selectors effectively during morphs or style changes in mooTools in ie6 - so your going to have a huge CSS file with many duplicate classes to support transitions.
  • Can't seem to get the keyUp, keyDown or keyPress events to fire in Firefox when you add them to a div? Well, take that div and set the tab index to -1. div.setAttribute("tabIndex","-1"). This fixes what I think is a bug in attaching events for gecko. Source (may not be a valid link)
  • converting from mooTools 1.1 to mooTools 1.2? Oops! Don't use the document.firstChild as your droppables target, for drag and drop elements. Will cause cpu hang 100%. This was not an issue in version 1.11.
  • When converting from mooTools 1.1 to 1.2, watch for these very common transitions.
  1. is now Browser.Engine.Trident, and many more located (here)
  2. is no longer used. try Fx.Tween.
  3. Many more to come. These were just the easiest ones to spot.

  • Still finding your cpu pegged at 100% in IE when performing a click event in mooTools but can't for the life of you find the reason? There are two ways to solve this issue:
  1. You are probably swapping innerHTML right? Or modifying it? Be careful. There is a bug in IE where you must initialize the html with a string first, then attach your html.prepended to the innerHTML you want to add. You may also lose all your events that have been added. This will cause you a major headache! To solve, place any string in quotes += " ". Be sure not to use an empty string - but anything else should work.
  2. Or, Take the focus() off the page by placing the focus() on another element. This short-circuits the process and stops the CPU from pegging out.

4. Avoid these common mistakes
  • Use THEAD if you are injecting a table into the DOM. If you don't then IE won't show it.
  • Don't rely heavily on margins. of all the CSS styles in the universe that are browser-compatible, margins have the most variation. If you use margins too heavily, then you are subject to a wide range of kludges for different browsers and different DTD declarations. Regardless, you're safer off with padding if you can use that as your styling mechanism for spacing.
  • When assigning highlight effects with mouseover and mouseout, or mouseenter and mouseleave, don't try to change the background color of two elements at once. For example, if you have a table row with a button inside the table cell - and you want the button to change also when you highlight the row - your going to pay for it. Changing two styles on two elements is extremely expensive.
  • Know the difference between keyCodes for key events during keypress and keyup. They are different. Also, SlimBrowser with ie will override your key commands if you happen to try to override them yourself (say, by disabling f5 for refresh)
5. Try these, in general.
  • In ie, use line-height to vertically align elements, because vertical-align won't work. Just make line-height the same as height.
  • Always use Regular Expressions whenever possible to parse strings. Or use a stringbuilder that I found, which is extremely fast. (StringBuilder blog coming soon)
  • Enclosures are a wonderful thing. This is also a wonderful resource : A John Resig Book. If you know about Mr R., then you know its at least a book worth reading. I recommend you try to use enclosures when you must load something where, along the way, you will need to access local functions or variables later. Enclosures allow you to addEvents to objects with ease, amongst many other things - they help you make elegant code!
  • Work modularly. To help you work less procedurally and more modularly, try working with the JSON syntax. It is not only a great way to partition your work, it minimizes global variables, a more or less known evil. I also highly recommend this book Javascript: the good parts.
  • Sometimes browsers like IE highlight the screen with dark blue text? That is the selection mechanism. To confuse it, set the focus of any element on the page that can accept focus. Until you understand the bug you have at hand, focus() on an element is a fantastic way to short-circuit the natural browser behavior. Use it sparingly.

More to come.

Sunday, August 24, 2008

Four great puzzles to keep your mind sharp.

Someone I work with likes to do a sudoku puzzle during every lunch. I don't even have to ask him to know that he loves to play them, but also that he likes to keep his mind sharp.

Coding can be quite challenging, and often depletes your energy without you having even to stand up for 8-10 hours (although I do!). When you get stuck or create bugs, it is often because you are too tired or foggy to do it properly.

Aside from a good night's rest... there are a lot of fun ways to keep your mind off your work in the downtime, but also to help maintain that razor edge intelligence I'm sure you bring to work.

If you are anything like me, then your talents are visual-spatial. When you are asked a question, you have to create the scenario in your head first, before you can answer. This kind of thinking is incredibly useful for a Software UI Engineer, but not so much for other vocations. It is this kind of talent that you should keep sharp.

I feel that the puzzles you choose to fill up your free time should reflect your type of cognitive style. Here are three sites (and more) that work really well if your intelligence is primarily visual-spatial. Even if it is not, then you may still enjoy the challenge this proposes... but just be warned... if you are more of a logical or verb-driven thinker then these may drive you crazy!

The original exploding pie game
  • Challenge the computer with three different sized levels, to take control of a board, by adding pie slices to your pies. Sounds a little silly i know... but the pie only describes the shapes of your playing pieces.
  • The game is extremely difficult, employing the absolute depths of your visual-spatial intelligence, planning, strategy and creativity. Part chess, part Stratego, and all the fun of chain-reactions.
  • This is one of the most addictive games I've played, and I really get bored of the typical addictive games. This one has you involved. It does take a little while to understand since the instructions don't begin to cover what is possible.
Combination lock
  • I loved this game because it didn't make me feel like an idiot. When I add or subtract, I have to create pictures of numbers in my head, and this is very slow. So the timer makes it all the more interesting.
Mensa intelligence tests 1-6
  • I am up to puzzle #3 and still working on it. Extremely, extremely, difficult. This is mensa here, so of course its going to be insanely hard. I'm on Puzzle #3 and I'm stumped! What the heck is puzzle #6 like? Still, I enjoyed this thoroughly.
Double Maze
  • Don't let its initial looks fool you - this is a real challenge! It will make you go "doh!"

  • My colleague Matt has a really cool puzzle site with a wide variety of puzzles, from crosswords, to word search to hangman and more. My favorite is Ghost, where you need to play the computer to create words by adding letters. It challenges your vocabulary tremendously.

Friday, August 15, 2008

Javascript Search / Sift Tool v1.0

Javascript Search / Sift Tool v1.0


How to use the demo: You will see various blocks with text. Inside each of these are sets of attributes that you may search on. The datasets behind every div is just below. Have a look and that will give you a sense of how the sift tool works.

So, allow me to give you a couple of starting searches. After looking at the datasets below, type the following. At each step, take note of what the sift tool is doing:

  1. mammal
  2. hit backspace until just "m" of "mammal" remains.
  3. hit the clear button.
  4. now, type "wings+ape" (nothing, but it does find items as you type).
  5. now, change the + to a | (a pipe). Interesting results! Here is where things get fun. You got any field that matched wings and any field that matched ape. So any bird or insect with wings was returned.
  6. now, leave whats in step 5, but anywhere in the search box, type "!" the exclamation point. Everything else is returned.
  7. play around with it.

Water Bear||Insect||Touch||Feet

Download: Version 1

What's coming in version 2:
  1. Support for buckets of objects
  2. Support for keeping track of counts of what remains
  3. Support for search convenience buttons

About the sift tool and logic:

Sifting is a little different than searching. Just a little. I called this "search / sift" so web searches would find it. Nobody is looking for "sift". With sifting, all of the data is already available in memory, be it a whole bunch of P tags, divs or whatnot. In this blog, I use the words "sift" and "search" interchangeably even though this really does "sift". I have 10 years of saying "search" so its hard not to say it.

I was recently challenged with developing a UI that returned a sizable amount of searchable data, on the order of say, 600 items, each with 10 searchable parameters, giving us 6,000 pieces of data.

While this is not, on the whole, a lot of information... there are plenty of uses for such an application when the lists are finite and not generated by users (but even then this can be modified to suit such a purpose).

I'll assume you know how to develop interfaces, and will also assume that you have a text box somewhere. My examples will be written using mootools v1.11, but really there are only a couple of moo-related features I'm using. It won't take much to move this to version 1.2.

Overview of interface:
  • Supports OR with "|" pipe.
  • Supports AND with "+" plus.
  • Supports NOT with "!" exclamation point.
  • Searches are always wildcards
  • Allows several ways to search: by enter key, by a search button and by searching while the user types. Although the code supports all three... My example shows the "search while you type method".
  • Searches are easy to customize, and have the option of returning a value or not.
  • Note: You cannot do And with Or in the same sift.
Overview of code:
  • For our purposes, I am coding using JSON, with mootools framework, and have segmented my methods inside of an "app" variable, which is the only global variable I need. That is why you will see references to "app".
  • Also, I am not using any enclosures, since I did not find it useful for this task. (beware "overuse of cool techniques").
  • Testing only on IE for the moment (but Firefox for me is always faster here), I've got this optimized to do 6.09 milliseconds per object searched.
  • This was tested on 2.79 Ghz CPU with 2 G ram. The faster the machine that the user sifts with, the faster the sift.

A couple rules beforehand:

  • Don't send an object in the dom to your function or assign it to a variable, since this can cause memory leaks in IE. Instead, just call it by reference.
  • Don't use mootools elements when you are creating them by the hundreds, as the garbage collection utility in mootools simply cannot handle that amount of information and will cause your browser to think its running slow scripts when onUnload() is called.
  • Don't forget commas at the end of every function in JSON, but not the last function. leave that comma-less. Since my code is broken up, I've taken them out. See the js file for the entire structure.

I apologize for the formatting issues below. This html editor keeps eating up my pre tags. For a good look at the code, just download it here: Download: Version 1

Step 1, setting up the tools :

  • setupSiftTool. I call this when the view comes into focus the first time. This could be your enclosure if you wanted.
  • I set up my box called "siftBox" by finding it in the DOM by reference. In this case, I did not inject it into the DOM but i could have. You can easily just add the events to your text box old-school style if you want.
  • "clearButton" is a button right next to the search box. This does exactly what you think it does.
  • cArray is a shadow array. It is there because of the fact that it is always faster to iterate an array in memory then it is to comb the DOM. We will use this to keep track of what has already been found so that the search gets faster the more you search.

initialize : function(){
this.arrayOfObjects = $$(".siftItem");
$each(this.arrayOfObjects, function(item, i){
item["data"] = $A(item.getAttribute("data").split("||"));

setupSiftTool : function(){
Here you can decide, based on the number of expected items how you want the
search to be triggered. I like to use a search box when the data set gets to large,
which means the user has to hit enter or click the box.
Until that time, I let the search work continuously as they fire the keyup event.
You can use if(event.keyCode === 13) to ensure it happens with enter key.
$("siftBox").addEvent('keyup', function(event){
$('siftBox').value = "";
this.cArray = [];

Step 2, the iterator :

  • You'll notice here how I partition my logic. All methods should be tight, small, and serve a particular purpose. Like this blog, I keep things short and sweet if I can.
  • captureKeys: responsible for iterating over a set of objects, and this is where I assume you are in-memory. I call it simply, arrayOfObjects
  • forEach is a mootools paradigm equal to a loop over an array. It is bound to "this", or app.
  • testFailAttribute is coming in step 3. This is the core logic.
  • If you want to clean up this code so that it doesn't call the same logic in both the if and the else statement, then go ahead. I have it this way for clarity.
  • Note: arrayOfObjects I assume you will build up yourself. In my case, I do it by iterating over the dom to find Divs. These are all Divs.
  • this.Tm, a test-match boolean. Explanation in step 3.

captureKeys : function(){
app.arrayOfObjects.forEach(function(obj, index){
return false;
app.cArray[app.cArray.length] =;
app.cArray.remove(; = (window.ie6) ? "inline" : "block"; // ensures a fix to ie6 margin impl.
this.tM = null;
this.isAnd = -1;
this.isOr = -1;
this.isNot = -1
this.firstStyle = "";
this.secondStyle = "";
this.returnNeg = false;
this.returnPos = true;

Step 3, the core logic:

  • testFailAttribute. Here you are trying to see if an object does *not* match.
  • this.Tm, a test-match boolean. We use this to ensure that we're not calling the first section of testFailAttribute every time the user searches.
  • isAnd and isOr tell us the jist of what the user is trying to do. At this time, I'm not letting them mix the two.
  • doShowObj is an associative attribute, one that tracks the lifecycle of the object. The reason this is here is so that the UI can search as the user types. In this case, I want to use the enter key, but it supports searching while typing as well.
  • testFailMatch is a list of items that the conditions must meet or the test fails.
  • escapeReqExp comes from mootools framework. You'll need to be careful not to process certain characters.

testFailAttribute : function(obj,box){
this.firstStyle = "inline";
this.secondStyle = "none";
this.returnNeg = false;
this.returnPos = true;
this.isNot = $(box).value.indexOf("!");
this.isAnd = $(box).value.indexOf("+");
this.isOr = $(box).value.indexOf("|"); //must be one or the other.
if(this.isOr === -1) this.tM = $(box).value.toLowerCase().split(/\+/g);
if(this.isAnd === -1) this.tM = $(box).value.toLowerCase().split(/\|/g);
if(this.isOr !== -1 && this.isAnd !== -1) return;
obj["doShowObj"] = 0;
this.tM.forEach(function(m, index){
index = index+1;
m = m.escapeRegExp();
if(this.isOr !== -1){
if(index === 1 && obj["doShowObj"] > 0) obj["doShowObj"]--;
if(obj["doShowObj"] > 0) obj["doShowObj"]--;
if(this.isNot !== -1){
this.firstStyle = "none";
this.secondStyle = "inline";
this.returnPos = false;
this.returnNeg = true;
if(this.isOr === -1){
if(obj["doShowObj"] === this.tM.length){ = this.firstStyle;
return this.returnNeg;
}else{ = this.secondStyle;
return this.returnPos;
if(this.isOr !== -1){
if(obj["doShowObj"] > 0){ = this.firstStyle;
return this.returnNeg;
}else{ = this.secondStyle;
return this.returnPos;

Step 4, the attributes to sift on:

  • testFailMatch. This is a list of attributes on the object itself (in my case, dom attribtues added to the div.) I cut it down to one, but just add as many as you want with "&&".
  • Here you can be creative. If you want the sift to eliminate items based on lets say, a displayName, then add that. But you can be clever about it and add convenience for the user, by also adding other attributes. Lets say you have a dataType attribute. If the user searches for "date" you can surprise them by returning anything with "date" in the name, or any item that is a date dataType, even if "date" is not in the name.

testFailMatch : function(obj,testMatch){
testMatch = testMatch.replace("!","");
if(!(obj["data"][0].toLowerCase().test(testMatch)) && !(obj["data"][1].toLowerCase().test(testMatch)) && !(obj["data"][2].toLowerCase().test(testMatch)) && !(obj["data"][3].toLowerCase().test(testMatch))){
return true; // meaning, if the item passes none of these tests, hide it an add it to the array.
return false;

The Ui Guy

Since this is my first post, I guess an introduction is in order. My name is Ari, and I have been a user interface engineer for 10 years now, for enterprise and web.

I registered a few domain names to start a company a few years ago, but then decided not to bother. So, the domain names "", "", and "" all will link to this blog.

It may seem lazy for me to be using blogger, seeing that I have done software and websites for a living, but thats the reason why at the moment I don't want to bother. I'm too focused on my career and don't have the time to put into it. I currently manage my art website, Headcircus and that is enough for me.

I plan on blogging about my experiences over the past 10 years, and that may be better than full-fledged articles.

So, your probably thinking "The" Ui guy? What arrogance.

Truth be told, at the time "" was already taken, and same here for So thats what I have. It really should be "A Ui guy", but that doesn't ring as nice.

So what do I have to offer in this vast sea of blogs? A lot if you are interested in the front end of software development, especially in the User Interface arena.

And yes, I always write in small, easily digestible paragraphs, and I wish the world would do the same. Nothing says "stumble" or "back button" more than a menacing block of text.

On to the blog!