usable in any place a human can be used

20091020

deleting a record

I've been working on a side project in my spare time, what little there is, and its come time to work on the UI, which is one of my favorite things to do, but one of the hardest things to get right.

Trying to decide amongst the various ways to delete something, trying to create a user experience that will be pleasant and not knock you out of your workflow. Here are the various methods I've been mulling over with lists of pro's and con's, and because I'm super nice, some javascript code that implements them.

All of the methods I'm going to go over rely on some backend handler that will be communicated with asynchronously to do the heavy lifting of performing the actual delete. The code could be simplified (in some cases greatly) by using jQuery or some other javascript framework, but in the interest of not being dependent on any particular framework, I wrote the code as straight javascript.

All the code depends on two helper methods

 
/**
 * Finds the nearest ancestor of an element with a given tag name
 * @param elem [HTML Element] element to find the ancestor for
 * @param tag [String] tag name to look up
 * @return elem [HTML Element | null] null if can't be found
 */
function get_parent(elem, tag) {
  if(elem == null || elem.tagName.toUpperCase() == tag.toUpperCase()) {
    return elem;
  }
  return get_parent(elem.parentNode, tag);
}
 
/**
 * Removes a row when given any node within the row or the row itself
 * @param row [HTML Element] row node or any child node of row node
 */
function remove_row(row) {
  row = get_parent(row, "tr");
  var parent = row.parentNode;
  parent.removeChild(row);
}

Method 1: Simple delete

Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete
  function simple_delete(lnk) {
    remove_row(lnk);
  }
Pros Cons
Extremely Simple Easy to accidentally delete something
  Very little feedback

Method 2: Confirm Delete

Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete
  function confirm_delete(lnk) {
    if(confirm("Really Delete?")) {
      remove_row(lnk);
    }
  }
Pros Cons
No accidental deletes Breaks flow
Easy cross browser implementation Annoying, focus steal, mousing

Method 3: Double-click Delete

Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete
  var dblclk_delete_state = null;
  function dblclk_delete(lnk, which) {
    //Hide everything first
    for(var i = 1; i <= 3; ++i) {
      var msg = document.getElementById('dblclk_confirm_' + i);
      if(msg) {
        msg.style.display = 'none';
      }
    }
  
    if(dblclk_delete_state == which) {
      remove_row(lnk);
      //No need to clear state, but it can't hurt
      dblclk_delete_state = null;
    } else {
      dblclk_delete_state = which;
      document.getElementById('dblclk_confirm_' + which).style.display = 'block';
    }
  }
Pros Cons
Easy deletes Some people double-click out of habit
Confirm before delete Double clicks avoid confirmation

Method 4: Binary Delete

Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete
//Yes link simply calls remove_row(this)

//This function is called by the delete link and the No link
function binary_message(which) {
  var msg = document.getElementById('binary_confirm_' + which);
  if(msg) {
    if(msg.style.display == 'none') {
      msg.style.display = 'block';
    } else {
      msg.style.display = 'none'; 
    }
  }
}
Pros Cons
No accidental deletes Breaks flow (less)
Can be prettied up with qTip Clicking delete after message appears should perform what action?

Method 5: Binary Modified

Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete
  //Yes simply calls remove_row(this); like in the non-modified version

  //delete link calls this function
  function modified_open(which) {
    modified_state(which, 'block');
  }
 
  //No link calls this function
  function modified_close(which) {
    modified_state(which, 'none');
  }

  //Helper function 
  function modified_state(which, disp) {
    document.getElementById('modified_confirm_' + which).style.display = disp;
  }
Pros Cons
No accidental deletes Breaks flow (less)
Also can be made pretty  
Better (?) delete link behavior  

So those are the various methods I'm mulling over now, also whether a delete should remove the row or simply gray it out, should you be able to undo a delete, all kinds of questions. These have serious consequences for my application and are quite outside of the scope of this already way too long post. I think I like Method 4 or 5 the best, can't decide which. Which do you like, is there something that I missed?

Code is hacked together example code, real code will be nicer, possibly even a jQuery plugin

deleting a record


I've been working on a side project in my spare time, what little there is, and its come time to work on the UI, which is one of my favorite things to do, but one of the hardest things to get right.


Trying to decide amongst the various ways to delete something, trying to create a user experience that will be pleasant and not knock you out of your workflow. Here are the various methods I've been mulling over with lists of pro's and con's, and because I'm super nice, some javascript code that implements them.


All of the methods I'm going to go over rely on some backend handler that will be communicated with asynchronously to do the heavy lifting of performing the actual delete. The code could be simplified (in some cases greatly) by using jQuery or some other javascript framework, but in the interest of not being dependent on any particular framework, I wrote the code as straight javascript.


All the code depends on two helper methods




/**
* Finds the nearest ancestor of an element with a given tag name
* @param elem [HTML Element] element to find the ancestor for
* @param tag [String] tag name to look up
* @return elem [HTML Element | null] null if can't be found
*/
function get_parent(elem, tag) {
if(elem == null || elem.tagName.toUpperCase() == tag.toUpperCase()) {
return elem;
}
return get_parent(elem.parentNode, tag);
}

/**
* Removes a row when given any node within the row or the row itself
* @param row [HTML Element] row node or any child node of row node
*/
function remove_row(row) {
row = get_parent(row, "tr");
var parent = row.parentNode;
parent.removeChild(row);
}

Method 1: Simple delete
























Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete


[javascript]
function simple_delete(lnk) {
remove_row(lnk);
}
[/javascript]













Pros Cons
Extremely Simple Easy to accidentally delete something
  Very little feedback


Method 2: Confirm Delete
























Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete



function confirm_delete(lnk) {
if(confirm("Really Delete?")) {
remove_row(lnk);
}
}














Pros Cons
No accidental deletes Breaks flow
Easy cross browser implementation Annoying, focus steal, mousing


Method 3: Double-click Delete



























Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete



var dblclk_delete_state = null;
function dblclk_delete(lnk, which) {
//Hide everything first
for(var i = 1; i <= 3; ++i) {
var msg = document.getElementById('dblclk_confirm_' + i);
if(msg) {
msg.style.display = 'none';
}
}

if(dblclk_delete_state == which) {
remove_row(lnk);
//No need to clear state, but it can't hurt
dblclk_delete_state = null;
} else {
dblclk_delete_state = which;
document.getElementById('dblclk_confirm_' + which).style.display = 'block';
}
}














Pros Cons
Easy deletes Some people double-click out of habit
Confirm before delete Double clicks avoid confirmation


Method 4: Binary Delete



























Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete



//Yes link simply calls remove_row(this)

//This function is called by the delete link and the No link
function binary_message(which) {
var msg = document.getElementById('binary_confirm_' + which);
if(msg) {
if(msg.style.display == 'none') {
msg.style.display = 'block';
} else {
msg.style.display = 'none';
}
}
}














Pros Cons
No accidental deletes Breaks flow (less)
Can be prettied up with qTip Clicking delete after message appears should perform what action?


Method 5: Binary Modified



























Name Age Delete
Amy 24 delete
Matt 23 delete
Zeke 32 delete



//Yes simply calls remove_row(this); like in the non-modified version

//delete link calls this function
function modified_open(which) {
modified_state(which, 'block');
}

//No link calls this function
function modified_close(which) {
modified_state(which, 'none');
}

//Helper function
function modified_state(which, disp) {
document.getElementById('modified_confirm_' + which).style.display = disp;
}


















Pros Cons
No accidental deletes Breaks flow (less)
Also can be made pretty  
Better (?) delete link behavior  



So those are the various methods I'm mulling over now, also whether a delete should remove the row or simply gray it out, should you be able to undo a delete, all kinds of questions. These have serious consequences for my application and are quite outside of the scope of this already way too long post. I think I like Method 4 or 5 the best, can't decide which. Which do you like, is there something that I missed?


Code is hacked together example code, real code will be nicer, possibly even a jQuery plugin

20091019

tool roundup

As a programmer I'm often asked to do what lots of programmers have to do, think about and analyze a completely conceptual structure. Programs can build up massive structures, the computer is more than happy to allow you to create a hash of trees of lists of objects with properties that are hashes of trees of lists of objects with properties that are... and so on and so forth. That is one of the great strengths of programming, but also one of the greatest challenges.

At the end of the day the computer only has one data structure, a memory address. It's just one big long row of memory that we can store stuff in, the rest is all conceptual framework we build on top of it. To deal with these complexities we build tools and abstractions, I want to talk about some of my favorite tools, and find out about some of yours.

I was recently given the task of fixing up a workflow, there are many entries in a database table somewhere where each entry represents a part of a path through the workflow. So an entry might define that from the put on socks state you could move to the put on shoes state. Having a vast number of these states and a whole bunch of paths between them, it became difficult to think about the way the system worked, so I created a visualization.

This looks complex, and it is, but it is a much better reference when working with this particular part of the system than looking at the database table and trying to assemble parts of it in my brain as the situation demands. So how did I create this diagram

Diagrammr one of the coolest on-line tools I've ever encountered. It's free, it's fast, and it works really well. I just entered a bunch of fragments into a text box like this

  • ds to dc
  • dc to ta
  • dc to tr
  • tr to dc

And after adding quite a few more, this fun diagram popped out, quick and easy.

This diagram was fairly straightforward, the boxes are just simple states, but when I need a more full bodied solution, I use Dia. Let's run down the checklist here, free, yes, lightweight, yes, intuitive, yes, awesome, yes.

Dia is also cross-platform, super bonus, and it has figure sets for almost any kind of diagram you would want to make. One of the best things about Dia is that the images are intelligent objects, double click on a table in a schema diagram and it brings up a dialog to enter column information. Double click a class in an inheritance document and it brings up a dialog to add members, functions, and hierarchy information. Dia also lets you easily export to several different file formats including but not limited to

  • Native Dia Diagram File (.dia)
  • HP Graphics Language (.hpgl, .plt)
  • Portable Network Graphic (.png)
  • Scalable Vector Graphic (.svg)
  • Visio XML Format (.vdx)
  • Windows Meta File (.wmf)
  • XSL Transformation Filter (.code)

Last but not least is my all purpose tool, the number one go to when the chips are down, Graph Paper. It is fair to say that I love graph paper. It is by far the most useful tool to have around. Is there anything graph paper can't do, lets look.

  • Write beautifully in horizontal and vertical orientations... check
  • Allow for monospaced fonts... check
  • Ad hoc tables... check
  • Impromptu graphs... check
  • Arrow support... check
  • Runs linux... soon (I'm sure someone's working on it)

These are some of my favorite tools, with them no data structure frightens me, no data set is too formidable, order can be brought to chaos. What are some of your favorite tools?



tool roundup

As a programmer I'm often asked to do what lots of programmers have to do, think about and analyze a completely conceptual structure. Programs can build up massive structures, the computer is more than happy to allow you to create a hash of trees of lists of objects with properties that are hashes of trees of lists of objects with properties that are... and so on and so forth. That is one of the great strengths of programming, but also one of the greatest challenges.


At the end of the day the computer only has one data structure, a memory address. It's just one big long row of memory that we can store stuff in, the rest is all conceptual framework we build on top of it. To deal with these complexities we build tools and abstractions, I want to talk about some of my favorite tools, and find out about some of yours.


I was recently given the task of fixing up a workflow, there are many entries in a database table somewhere where each entry represents a part of a path through the workflow. So an entry might define that from the put on socks state you could move to the put on shoes state. Having a vast number of these states and a whole bunch of paths between them, it became difficult to think about the way the system worked, so I created a visualization.





This looks complex, and it is, but it is a much better reference when working with this particular part of the system than looking at the database table and trying to assemble parts of it in my brain as the situation demands. So how did I create this diagram


Diagrammr one of the coolest on-line tools I've ever encountered. It's free, it's fast, and it works really well. I just entered a bunch of fragments into a text box like this



  • ds to dc

  • dc to ta

  • dc to tr

  • tr to dc


And after adding quite a few more, this fun diagram popped out, quick and easy.


This diagram was fairly straightforward, the boxes are just simple states, but when I need a more full bodied solution, I use Dia. Let's run down the checklist here, free, yes, lightweight, yes, intuitive, yes, awesome, yes.





Dia is also cross-platform, super bonus, and it has figure sets for almost any kind of diagram you would want to make. One of the best things about Dia is that the images are intelligent objects, double click on a table in a schema diagram and it brings up a dialog to enter column information. Double click a class in an inheritance document and it brings up a dialog to add members, functions, and hierarchy information. Dia also lets you easily export to several different file formats including but not limited to



  • Native Dia Diagram File (.dia)

  • HP Graphics Language (.hpgl, .plt)

  • Portable Network Graphic (.png)

  • Scalable Vector Graphic (.svg)

  • Visio XML Format (.vdx)

  • Windows Meta File (.wmf)

  • XSL Transformation Filter (.code)



Last but not least is my all purpose tool, the number one go to when the chips are down, Graph Paper. It is fair to say that I love graph paper. It is by far the most useful tool to have around. Is there anything graph paper can't do, lets look.



  • Write beautifully in horizontal and vertical orientations... check

  • Allow for monospaced fonts... check

  • Ad hoc tables... check

  • Impromptu graphs... check

  • Arrow support... check

  • Runs linux... soon (I'm sure someone's working on it)


These are some of my favorite tools, with them no data structure frightens me, no data set is too formidable, order can be brought to chaos. What are some of your favorite tools?



20091016

the blog experiment

So as you know, since you are reading this blog currently, I have a blog now. Welcome to 2002, Matt, everyone has a blog these days. Now that its been running for two weeks I wanted to do a meta-post about my blog.

I have a wide array of interests, from video games to progressive politics to linguistics. I decided though that I wanted to write a technology blog to increase my professional stature on the cybernets. It hasn't always been easy, some days I've had little inspiration in the technology part of my life, but something burning in the politics part of my brain. I strive though to keep this blog about programming and software and sometimes rage filled rants. When I started this blog I came up with a strategy for how I wished to drive traffic to the blog.

  • Post everyday - When people can reliably expect some new content they will come and look for it or set up a feed reader to your site. The Daily WTF posts something everyday, and although most days I read the story with a "meh" I still come back every time the lunch whistle blows.
  • More than words - I wanted to avoid the wall of text, breaking up posts with a related image, code snippet, or youtube embed makes that post more memorable and more valuable.
  • Shameless self-promotion - Every post I write is followed up with a tweet, shouting to my co-workers about how great I am telling them to read my post, texting people, shining a special "Matt-signal" into the perpetually overcast Columbus sky
The Good:
  • I have had a few neat things happen so far, I've gotten comments from people I know and respect Rick, Jeremiah, etc. and somewhat more exciting, comments from random people I don't know.
  • Knowing that I need to produce content has had my creative brain juices flowing, it has spurred me to learn about ruby, powershell, and lisp.
  • Wanting to produce quality content has caused me to dig deeper into things than I normally would have, leading to more learning, and bonus for you, better content
  • Launched my first self-designed website and had somewhere to brag about it
The Bad:
  • Writing a post everyday is hard, even when I have an idea, doing the research, linking things up nicely, and trying to write something that people will want to read is a daunting task.
  • Failed to get anyone to join up with my I'll pimp your site if you pimp mine old school 1990's style blog-ring (I really only tweeted this once so its not like I tried very hard)
  • Scant feedback. Sometimes starting up a blog is a lot like shouting into the darkness, it is very exciting to get a comment on a post, even when its someone disagreeing with you, at least you know someone's reading.

So I'm going to keep on keeping on, I'm going to post something everyday, I've got 4 or 5 posts saved up for a series I'm hoping to publish soon. The blog has been a positive thing for me, it has kept me learning, communicating, and creating.

Let me know what you think about the blog, the good, the bad, and the ugly. I'm going to keep up with my post a day schedule for a while longer, so check back in daily or follow my blog to get a little sliver of goodness everyday.

Post a day doesn't include weekends, people have better things to do on the weekends than read blog posts, like program lisp

the blog experiment


So as you know, since you are reading this blog currently, I have a blog now. Welcome to 2002, Matt, everyone has a blog these days. Now that its been running for two weeks I wanted to do a meta-post about my blog.


I have a wide array of interests, from video games to progressive politics to linguistics. I decided though that I wanted to write a technology blog to increase my professional stature on the cybernets. It hasn't always been easy, some days I've had little inspiration in the technology part of my life, but something burning in the politics part of my brain. I strive though to keep this blog about programming and software and sometimes rage filled rants. When I started this blog I came up with a strategy for how I wished to drive traffic to the blog.



  • Post everyday - When people can reliably expect some new content they will come and look for it or set up a feed reader to your site. The Daily WTF posts something everyday, and although most days I read the story with a "meh" I still come back every time the lunch whistle blows.

  • More than words - I wanted to avoid the wall of text, breaking up posts with a related image, code snippet, or youtube embed makes that post more memorable and more valuable.

  • Shameless self-promotion - Every post I write is followed up with a tweet, shouting to my co-workers about how great I am telling them to read my post, texting people, shining a special "Matt-signal" into the perpetually overcast Columbus sky


The Good:

  • I have had a few neat things happen so far, I've gotten comments from people I know and respect Rick, Jeremiah, etc. and somewhat more exciting, comments from random people I don't know.

  • Knowing that I need to produce content has had my creative brain juices flowing, it has spurred me to learn about ruby, powershell, and lisp.

  • Wanting to produce quality content has caused me to dig deeper into things than I normally would have, leading to more learning, and bonus for you, better content

  • Launched my first self-designed website and had somewhere to brag about it


The Bad:

  • Writing a post everyday is hard, even when I have an idea, doing the research, linking things up nicely, and trying to write something that people will want to read is a daunting task.

  • Failed to get anyone to join up with my I'll pimp your site if you pimp mine old school 1990's style blog-ring (I really only tweeted this once so its not like I tried very hard)

  • Scant feedback. Sometimes starting up a blog is a lot like shouting into the darkness, it is very exciting to get a comment on a post, even when its someone disagreeing with you, at least you know someone's reading.


So I'm going to keep on keeping on, I'm going to post something everyday, I've got 4 or 5 posts saved up for a series I'm hoping to publish soon. The blog has been a positive thing for me, it has kept me learning, communicating, and creating.


Let me know what you think about the blog, the good, the bad, and the ugly. I'm going to keep up with my post a day schedule for a while longer, so check back in daily or follow my blog to get a little sliver of goodness everyday.


Post a day doesn't include weekends, people have better things to do on the weekends than read blog posts, like program lisp

20091015

you can't understand google wave

Please everyone, just stop. Everyday someone writes a new article about Google Wave. If you are writing a first impressions, explanation, frequently asked questions type of article, go ahead, this rant is not aimed at you. The rest of you people writing reviews, glowing or scathing, you can't understand Google Wave, yet.

Google Wave is big, that's for sure, its got a Federated Protocol and XMPP and PubSub and all kinds of neat technology. It has an interface too, half email, half chat client, half sentient alien technology. The problem with people waxing inanely about what Google Wave will be is that they have their heads up their asses. They don't know, because they can't know.

Let's go back to 1975 and somebody explains the idea of the World Wide Web, they go on and on about HyperText Transfer Protocols and HyperText Markup Language and they show you the first webpage. Imagine that instead of being the tech savvy web surfing person that you are that you have no idea what HyperText or Uniform Resource Locators are, this is where we are at with Google Wave.

The idea behind it is complex, the foundations are new (at least in application) and also very complex, and the future of Google Wave is unknown, more than that it is unknowable. Could Tim Berners-Lee have guessed what we would be doing with his invention today, could he have dreamed of web applications, twitter, social networking. I guess he could have, but it wouldn't have been immediately apparent.

The technology is too new, it could be a new World Wide Web, or it could be a Gopher. We won't know until we see what people create with it. Google has already produced a collaboration tool that looks very promising, and people are already finding surprising ways to use it.

So if you want to vacillate and bloviate about Google Wave continue doing so, I certainly can't stop you, but you might go down in history as the guy who called the internet a fad.