Monday, June 11, 2012

Making Prettier Forms: Converting Checkboxes into Images

A couple weekends ago I went to the Big Design Conference in Dallas (recap coming soon), and I always come back inspired to help the user’s experience with the applications I write. One of the things mentioned (several times) was making forms simpler. Basically, you don’t have to make the end-user feel like they’re filling out a form. There are ways to make it seem less intimidating. One way is to swap out the typically hard-to-click checkbox or radio button with an image. It gives the user a larger click area and it looks nice…at least in my opinion.

Basically, I’m helping a friend with a small project, and the image below is what I wanted to create.

image

If you buy Stephen Anderson's book "Seductive Interaction Design", you will see a similar form to the one above...primarily just the name and contact info stuff. By the way, I definitely recommend this book.

As you can see, the “Select Classification” is not your typical radio button setup. I googled for a bit if there was already a jQuery plugin to do this type of thing and came up empty. I’m sure you almighty readers know of one, but I couldn’t find it…so I made one.

So far I’ve tested it in Firefox, IE9, Chrome, and JAWS, and it works pretty good in all of them. The way I set it up to work is based on the input and label. So you’d have the most accessible standard markup with your preferred styles for the label, and that’s how you get the effect shown above. I think it’s probably better said with code:

So it looks like a pretty typical setup so far, right? You have an input with a label. To make it more accessible, you wrap it with a fieldset and give it a legend. The primary reason you’d do this is to give screen readers some context. If you don’t need to worry about that, you could just as easy wrap it all with a div. You’re going to want to wrap it so your jQuery selector is more precise. After you markup the form, you just add the following JavaScript.

Now you’re all wired up, and you just add in your styles to whichever stylesheet classes you specified. The default stylesheet class names I specified are:

  • .Selected-Checkbox – this class is added to the label after it has been clicked
  • .Checkbox-in-focus – this class is added to the label when the checkbox/radio button is in focus

If you’re not sure the plugin is working properly, you can put it in “testMode”, like this:

$('#classification_radio_wrapper label').checkMate({testMode: true });

If you need to override my default class names, you can do that too by specifying class or focusClass in the options. I might rename class to selectedClass in the near future.

Please leave a comment if you have any questions or feedback.

The source code is available on github at https://github.com/derans/checkMate

The demo is located on 1pg.it at http://1pg.it/v9etvtn5 (also on github as the example.htm file)



Shout it

kick it on DotNetKicks.com

Tuesday, May 22, 2012

File Icons using CSS Selectors

This post is for a friend that was asking how to easily show icons with different file extensions. What I’ve setup are some styles that can just be copied over to any stylesheet and used.

I converted the icons downloadable at famfamfam.com to base64 and placed them in the styles. Without further ado, here they are:

These are all the basic file types I could think of and obviously you could add more to the list. I also added the with-icon, but this could be easily removed so it applies to all your hrefs all the time. There are a couple “special” styles at the bottom of the list for email and http links that use the ~=, which means starts with. All the rest of the styles work off the $= selector, which means ends with. To give the same icon to multiple file types, you just separate the selector with a comma.

In order to use these styles, you just do this:


This ends up looking like this:

links_with_icons

kick it on DotNetKicks.com

Wednesday, May 09, 2012

Testing for StructureMap Default Instances

Have you ever received the good ole “No Default Instance defined for PluginFamily”? error while using StructureMap? I thought I’d share a quick test you can write to catch this error before you deploy the bug. This test is particularly useful when you mostly depend on the default conventions.

In the example provided, I’ll be verifying that I can get a default instance of all my controllers. So I’ve setup 5 controllers and 2 have constructors with some type of dependency.

Something like this:

So now I can setup my test, which looks like this:


If you’re not familiar with TestCaseSource, I blogged about it a few weeks ago on the Headspring blog, so you can read about it there. The test queries the assembly containing HomeController for all types that are a subclass of Controller and are not abstract. After it gets the type, it tries to get an instance of it from the object factory. If it fails, the test fails with what specifically it couldn’t return and which controller couldn’t be instantiated.

Here’s what the test looks like when they all pass:

CropperCapture[7]

Here’s what the tests look like when the two with dependencies fails:

CropperCapture[8]

Here’s a detailed view of one of the error messages:

CropperCapture[9]

Notice it says IAuthenticationService and it failed on the AccountController, so we know exactly where to start looking. The only other thing I probably need to mention is the TestBase, which contains the StructureMap initialization. You could simply register your StructureMap registry file there. Here’s what the example looks like:

If anyone has any suggestions on how to improve the test or if StructureMap already has a test built-in that I’m not familiar with, please share.

kick it on DotNetKicks.com

Tuesday, April 03, 2012

Generic L2S Repository

I’m sure you’re all tired of me blogging about L2S, but I still like it. It’s just so simple and easy to use. Obviously with .net 4.0, the big issues with L2S seem to be resolved. Alongside l2sprof, LINQ to SQL can be very effective. Anyhow, I thought I’d share a simple generic repository I made.

Here's how you'd use the repository. Basically, you just pass in the DataContext you want to use and then call the method needed. As usual, please let me know if you see any improvements that can be made or if you have any questions.

kick it on DotNetKicks.com

Monday, March 12, 2012

Refactoring with LINQ

So my little brother sent over the code below last week and asked me if there was a better way to do it. When I first read through it I was thinking…I can’t believe people still use the good ole to/from listbox style UI. I don’t remember the last time I had to write this code, but I’m pretty sure it was prior to LINQ.

So here’s what I came up with in my response using LINQ.

Basically I was able to get rid of all the for loops, sorting, adding items, and most importantly, the new version is more readable.

Shout it

kick it on DotNetKicks.com

Sunday, March 04, 2012

Create an ActionLink without Magic Strings

Updated: 3/7/2011

So it’s been a while. I have a new job working for Headspring in Austin, which is one of the reasons I haven’t blogged in a while. It’s tough moving and re-adjusting to a new area and job, but Austin is great and Headspring is terrific. I started blogging on the Headspring site too. I’m trying to alternate weeks for posting, so we’ll see how that goes. (also fyi, Headspring is hiring)

On to the good stuff, I started playing with an HtmlHelper extension to rid a project of magic strings for action links. It was definitely more tricky than I originally thought, but I have a first attempt ready to share. Here’s the code:

@(Html.ActionLinkFor<HomeController>(a=>a.Contact(Model), "Contact"
, new Dictionary<string, object>{{"style","color: #f90;background:#000"}})) <br />

@(
Html.ActionLinkFor<MainControllerController>(a=>a.Index(), "Main Home"))<br/>

@(Html.ActionLinkFor<HomeController>(a=>a.Index(), "Home")) <br />

@(Html.ActionLinkFor<HomeController>(a=>a.AnotherTest(new SampleModel{Id=5555
, Name =
"Just a test", Address = "123 Main"}), "Another Test"))<br/>

@(Html.ActionLinkFor<HomeController>(a=>a.TestYetAnother(new SampleModel{Id=12345678
, Name =
"Just another test yet"}), "Yet Another Test"))

The code above is what I wanted for the end result. The code below is what makes the code above work.

    public static class HtmlHelperExtensions
{
public static IHtmlString ActionLinkFor<TController>(this HtmlHelper htmlHelper
,
Expression<Func<TController, object>> expression,
string displayText) where TController : Controller
{
return ActionLinkFor(htmlHelper, expression, displayText, null);
}

public static IHtmlString ActionLinkFor<TController>(this HtmlHelper htmlHelper
,
Expression<Func<TController, object>> expression, string displayText
,
IDictionary<string, object> htmlAttributes)
where TController : Controller
{
var method = ((MethodCallExpression)expression.Body).Method;
var actionName = method.Name;
var parameters = method.GetParameters();
var arguments = ((MethodCallExpression)expression.Body).Arguments;

var routeValue = new RouteValueDictionary();
for (int i = 0; i < parameters.Length; i++)
{
if (arguments[i] as MemberExpression != null)
{
var memberExpression = (MemberExpression)arguments[i];
if (memberExpression.Expression as ConstantExpression == null)
AddRouteValuesForMemberExpression((
MemberExpression)arguments[i]
, parameters[i].Name, routeValue);

if (memberExpression.Expression as ConstantExpression != null)
AddRouteValuesForConstantExpression(((
MemberExpression)arguments[i])
, parameters[i].Name, routeValue);
}
if (arguments[i] as MemberInitExpression != null)
AddRouteValuesForMemberInitExpression((
MemberInitExpression)arguments[i]
, routeValue);
if (arguments[i] as MethodCallExpression != null)
AddRouteValuesForMethodCallExpression((
MethodCallExpression)arguments[i]
, parameters[i].Name, routeValue);
}

var controller = typeof(TController).Name;
var controllerName = controller.Remove(controller.LastIndexOf("Controller"));
return htmlHelper.ActionLink(displayText, actionName, controllerName, routeValue, htmlAttributes);
}

private static void AddRouteValuesForMethodCallExpression(MethodCallExpression methodCallExpression
,
string parameterName, RouteValueDictionary routeValue)
{
if (methodCallExpression.Object != null)
{
var value = ((PropertyInfo)((MemberExpression)methodCallExpression.Object).Member)
.GetValue(((
ConstantExpression)((MemberExpression)methodCallExpression.Object)
.Expression).Value,
null);
routeValue.Add(parameterName, value);
}
}

private static void AddRouteValuesForMemberExpression(MemberExpression memberExpression
,
string parameterName, IDictionary<string, object> routeValue)
{
object model;
if (((MemberExpression)memberExpression.Expression).Member is PropertyInfo)
model = ((
PropertyInfo)((MemberExpression)memberExpression.Expression).Member)
.GetValue(((
ConstantExpression)((MemberExpression)memberExpression.Expression)
.Expression).Value,
null);
else
model = ((FieldInfo)((MemberExpression)memberExpression.Expression).Member)
.GetValue(((
ConstantExpression)((MemberExpression)memberExpression.Expression)
.Expression).Value);

foreach (var p in model.GetType().GetProperties())
{
if (p.Name == memberExpression.Member.Name)
{
var value = p.GetValue(model, null);
if (value != null && !routeValue.ContainsKey(p.Name))
routeValue.Add(parameterName, value.ToString());
}
}
}

private static void AddRouteValuesForConstantExpression(MemberExpression memberExpression
,
string parameterName, IDictionary<string, object> routeValue)
{
var properties = ((PropertyInfo)memberExpression.Member)
.GetValue(((
ConstantExpression)memberExpression.Expression).Value, null)
.GetType()
.GetProperties();

foreach (var property in properties)
{
var value = property.GetValue(((PropertyInfo)memberExpression.Member)
.GetValue(((
ConstantExpression)memberExpression.Expression).Value, null), null);

if (value != null)
routeValue.Add(property.Name, value.ToString());
}

if (properties.Length == 0)
{
var value = ((PropertyInfo)memberExpression.Member)
.GetValue(((
ConstantExpression)memberExpression.Expression).Value, null);

if (value != null)
routeValue.Add(parameterName, value.ToString());
}
}

private static void AddRouteValuesForMemberInitExpression(MemberInitExpression memberInitExpression
,
IDictionary<string, object> routeValue)
{
foreach (var p in memberInitExpression.Bindings.Cast<MemberAssignment>())
{
if (p.Expression is ConstantExpression)
{
var value = ((ConstantExpression)p.Expression).Value;
var name = p.Member.Name;
if (value != null)
routeValue.Add(name, value.ToString());
}
if (p.Expression is UnaryExpression)
{
throw new NotImplementedException("Not able to handle UnaryExpressions yet.");
}
}
}
}

Basically the way this thing works is off the Expression<Func<TController, object>> parameter being passed into the ActionLinkFor method. From the expression, you can determine the route values and action name…by doing a lot of manipulation. So, if you would, try this helper out and let me know of any bugs or improvements that can be made.


Shout it

kick it on DotNetKicks.com

Wednesday, November 09, 2011

Refactoring MVC Routes

Some of my team members and myself are participating in the Houston AIR competition this weekend and we are building our project this week. Of course we’ll have to rebuild it from scratch on Saturday, but hopefully it’ll just be a bunch of re-typing and no surprises. Anyhow, one of my duties on the team is to configure MVC and the interfaces we’ll need and all that jazz. So when I went to setup the routes, I was surprised again at how flexible it all is to setup. Typically you can get by with the default route, but not in our case this time. Basically we wanted to have these routes:

/story/give
/story/{id}
/feature/{id}
/prayer/{id}
/{pagename}

By the way, our assigned charity is a church in Houston called the Household of Faith Church - South Acres. At first I had this: (which is TOTALLY RIDCULOUS, but I wanted to see them all)
routes.MapRoute(
"Home",
"",
new { controller = "Main", action = "Home" });

routes.MapRoute(
"GiveStory",
"give/story",
new { controller = "Main", action = "GiveStory" });

routes.MapRoute(
"Feature",
"feature/{id}",
new { controller = "Main", action = "Feature", id=UrlParameter.Optional });

routes.MapRoute(
"Prayer",
"Prayer/{id}",
new { controller = "Main", action = "Prayer", id = UrlParameter.Optional });

routes.MapRoute(
"Story",
"Story/{id}",
new { controller = "Main", action = "Story", id = UrlParameter.Optional });

routes.MapRoute(
"About",
"About",
new { controller = "Main", action = "About"});

routes.MapRoute(
"Directions",
"Directions",
new { controller = "Main", action = "Directions" });

routes.MapRoute(
"SiteMap",
"SiteMap",
new { controller = "Main", action = "SiteMap" });

routes.MapRoute(
"Help",
"Help",
new { controller = "Main", action = "Help" });
I typically setup my routes early on because I usually know what I want the URLs to be and it helps when naming my actions on the controllers. So obvioulsy we only have one controller because it’s not a large site and they all kinda go together, but what’s up with all the actions on the route configuration? Ridiculous right? So let’s get rid of all that mess like this:
routes.MapRoute(
"GiveStory",
"give/story",
new { controller = "Main", action = "GiveStory" });

routes.MapRoute(
"Feature",
"feature/{id}",
new { controller = "Main", action = "Feature", id=UrlParameter.Optional });

routes.MapRoute(
"Prayer",
"Prayer/{id}",
new { controller = "Main", action = "Prayer", id = UrlParameter.Optional });

routes.MapRoute(
"Story",
"Story/{id}",
new { controller = "Main", action = "Story", id = UrlParameter.Optional });

routes.MapRoute(
"Page",
"{viewname}",
new { controller = "Main", action = "GetStatic", viewname = "Home" });
Simple enough right? So I created an action called GetStatic that just accepts the view name for that page. The action looks like this:
public ViewResult GetStatic(string viewname)
{
return View(viewname);
}
Now let’s address the other redundant mess I have here…the {feature/prayer/story}/{id} route. Basically we’re going to do that and add a constraint to the route like this:
routes.MapRoute(
"GiveStory",
"give/story",
new { controller = "Main", action = "GiveStory" });

routes.MapRoute(
"WebSectionRoute",
"{WebType}/{Id}",
new { Controller = "Main", action = "GetWebSection", Id = UrlParameter.Optional }, new {WebType = "Story|Feature|Prayer"});

routes.MapRoute(
"Page",
"{viewname}",
new { controller = "Main", action = "GetStatic", viewname = "Home" });
So what this says is if the WebType contains story/feature/prayer then use this route otherwise keep on going. I can’t express enough the importance of the route order here. It’s an easy thing to miss and I’ve caught the missed order a few times for other developers and myself. Make sur eyou put them in the order they need to be in and not in some random order. Well that’s it. Route configuration refactored and now it doesn’t have any redundant routes.

Thanks for reading!

kick it on DotNetKicks.com

Sunday, October 16, 2011

How to easily turn your L2S objects into interfaces




I know it’s been a while since I posted an actual post, but I think this one will be fun. So let’s get to it…
In one of our recent code reviews, we found several methods that looked almost identical. All of these methods were just for lookup tables that populated a dropdown. So…this is what we did:
We had a repository with something like GetDepartmentList and GetStatusList that looked something like this:
public class SampleRepository : ISampleRepository
    {
        public IList<LookupDepartment> GetDepartmentList()
        {
            using (var dc = new LookupSampleDataContext())
                return dc.LookupDepartments
                                 .Where(x => !x.IsDeleted)
                                 .OrderBy(x=>x.Name)
                                 .ToList();
        }

        public IList<LookupStatus> GetStatusList()
        {
            using (var dc = new LookupSampleDataContext())
                return dc.LookupStatus
                                 .Where(x => !x.IsDeleted)
                                 .OrderBy(x=>x.Status)
                                 .ToList();
        }
    }
Note: we do not return L2S objects typically, but to make this example simple, I’m going to pretend that we do.
The first thing we did was changed the type returned by both methods to return ILookupObject instead of the L2S objects…like this:
public class SampleRepository : ISampleRepository
    {
        public IList<ILookupObject> GetDepartmentList()
        {
            using (var dc = new LookupSampleDataContext())
                return dc.LookupDepartments
                                 .Where(x => !x.IsDeleted)
                                 .OrderBy(x=>x.Name)
                                 .Cast<ILookupObject>()
                                 .ToList();
        }

        public IList<ILookupObject> GetStatusList()
        {
            using (var dc = new LookupSampleDataContext())
                return dc.LookupStatus
                                 .Where(x => !x.IsDeleted)
                                 .OrderBy(x=>x.Status)
                                 .Cast<ILookupObject>()
                                 .ToList();
        }
    }
Obviously this cast isn’t going to work so we need to finagle our dbml. It’s easy to extend the L2S objects without modifying the dbml. I actually prefer never to touch the dbml itself unless absolutely necessary because I like to Ctrl+A, del, drag everything back over whenever I want :)
So to extend the classes, we just need to do this:
public partial class LookupDepartment : ILookupObject
    {
        public string DisplayName { get { return Name; } }
    }

    public partial class LookupStatus : ILookupObject
    {
        public string DisplayName { get { return Status;} }
    }
Done.
Now we need to revisit our SampleRepository and extract out all the redundant code so we have something like this:
private static IList<ILookupObject> GetList<T>(Expression<Func<T, object>> orderby) where T : class, ILookupObject
        {
            using (var dc = new LookupSampleDataContext())
                return dc.GetTable<T>()
                                 .Where(x => !x.IsDeleted)
                                 .OrderBy(orderby)
                                 .Cast<ILookupObject>()
                                 .ToList();
        }
All we’ve done is made a generic GetList method that takes in the orderby. You could easily make this not dependent on the datacontext too, but to keep this post simple, we won’t do that now. As you can see, this looks almost exactly like our original method with the exception of dc.GetTable<T>(), which is built-in to the datacontext class. All we need to do is pass it the type so it knows from which table to pull data. It’s actually a pet peeve of mine for a lookup type dropdown to not be ordered, so I’m forcing the orderby method and not giving another option.
The repository looks like this now:
public class RefactoredSampleRepository : ISampleRepository
    {
        private static IList<ILookupObject> GetList<T>(Expression<Func<T, object>> orderby) where T : class, ILookupObject
        {
            using (var dc = new LookupSampleDataContext())
                return dc.GetTable<T>()
                         .Where(x => !x.IsDeleted)
                         .OrderBy(orderby)
                         .Cast<ILookupObject>()
                         .ToList();
        }

        public IList<ILookupObject> GetDepartmentList()
        {
            return GetList<LookupDepartment>(x=>x.Name);
        }

        public IList<ILookupObject> GetStatusList()
        {
            return GetList<LookupStatus>(x=>x.Status);
        }
    }
Nice and pretty…I don’t like the orderby expression here, but I think it’s the best option for now. There is another way, but it jacks up L2S for inserts and updates. So, if you KNOW your not going to ever update or insert a new record for a lookup, then you could do this:
public partial class LookupStatus : ILookupObject
    {
        [Column(Name="Status")]
        public string DisplayName { get; set; }
    }
What this does is maps the DisplayName to the Status column so you could just do .OrderBy(x=>x.DisplayName) instead of passing in the orderby. The reason you have to map the column is because you’ll get a “SQL has no supported translation…” error. You could also just rename the property Status to DisplayName in the dbml file itself.
Also, it’s not recommended that you use multiple datacontexts according to l2sprof, but to make this simple, I did.
So now we can easily bind this to a dropdown via another helper method like this:
public static class extensions
    {
        public static void BindDropDownTo(this DropDownList ddl, IList<ILookupObject> data)
        {
            ddl.DataSource = data;
            ddl.DataTextField = "DisplayName";
            ddl.DataValueField = "ID";
            ddl.DataBind();
        }
    }
So in the UI, we just do this: (if using webforms)
ddlStatus.BindDropDownTo(rep.GetStatusList());
If you’re using MVC, you could create an htmlhelper to do something similar.
Alright, I think that’s it. Please post if you have better methods or have any questions.
Thanks for reading!
Shout it

kick it on DotNetKicks.com

Sunday, October 09, 2011

Can't believe it...

A whole month went by without me realizing that I didn't blog. It's insane to me how fast a month goes by these days. I'm going to have to step up my blogging again.

At least vacation time is coming up soon, so I'll have more free time.

kick it on DotNetKicks.com

Thursday, August 25, 2011

Blogging just to Blog…I mean Styling Tips!




Lately I have not felt like blogging, but I’m committed to at least once a month. I think the primary reason I haven’t felt th need to blog is because I haven’t really spent much time developing lately. I’ve been spending a lot of my time on user experience and interface design.

I thought I’d share a few styling tricks that are too easy not to do because they add a lot to usability.

  1. Changing the style of a row on hover. This allows the end user to easily see which row they’re looking at instead of having to trace the line.

    table tr:hover td {background: #e7e7e7}
  2. Changing the style of an input on focus. This allows the end-user to easily see where they’re at in a form without much thought.

    input:focus {border: solid 1px #f90}
  3. Changing the style of a hyperlink on hover. Granted this one has been around forever, but it’s a great one.

    a:hover {background: #333; color: #fff}

There are most definitely hundreds more, but these are a few of my favorites to use on a project. Also note that they do NOT work in all browsers.

Thanks for reading!

kick it on DotNetKicks.com

Monday, July 18, 2011

Big Design Conference 2011 Recap




Once again I find myself writing a conference recap without notes. Let me go ahead and apologize to all the speakers just in case I leave out something or misunderstood their presentation.

So…this year’s conference wasn’t as good as last year’s to me. I think there are a few reasons…

1. No free donuts (even though I didn’t care for the orange topping last year…I still liked them…I mean, they’re donuts)

2. No free sodas and snacks between sessions. These are important for any successful conference in my opinion :)

3. It wasn’t all new to me…I knew more of what to expect and what people were going to talk about…not the case last year.

As for the presentations, I’m unsure if they were the same or not as good because I lost perspective as a non-conf-rook. Everything last year was new and fresh and this year, not so much. This year’s conference theme was more about all your customer experiences meshing into one big great customer experience via whatever outlet…last year there seemed to be more of a theme on how to leverage the social web. Anyhow, if you’d like to read that recap you can here.

Day 1:

  • Keynote by Gwen Harmon (@ncrmuseum)
    What I took away…
    • Emotional design makes the whole experience almost life haltering, even if temporarily.
    • The National Civil Rights Museum looks like an amazing place to go visit.
    • Engineers are honest to the point of their own death. I had never heard this joke, it was funny.
      • The Joke: an engineer, a lawyer, and a something else(should’ve taken notes) are all on death row via guillotine. The something else is up, they release the blade and it stops…so he’s let off…the lawyer gets up there the blade drops and it stops again…so he’s let off…the engineer has his turn and looks up and says oh I see your problem.
    • The National Civil Rights Museum is looking to do a lot of upgrades, which will make it even more appealing to visit and learn. You can donate now if you’d like to help.
  • Mobile Design at the Speed of Thought by Michael Griffith @crypticdevice
    Prezi Show
    What I took away…
    • Two ways to communicate – talking & drawing (i.e. not reading requirements)
    • Ideas are disposable…we’ll make more!
    • Downloaded the 106 & Park iPhone app. Played with the voting “game”…highest thus far…30 votes
    • Don’t turn a website into an app! An app is a companion to a website.
    • Buy this book…Understanding Comics The Invisible Art by Scott McCloud
      Also…I bought this book…and 5 others…stupid conference making me spend $
  • Designing a Cohesive Customer Experience by Elizabeth Rosenzweig (@elizrosenzweig) and Scott Gunter
    What I took away…
    • Get to sessions on time because standing for an hour kinda sucks
    • With that said, I know they were talking a lot about Ikea…but I missed most of that part…
    • Don’t shop at Pottery Barn because they will stalk you…at least one of the audience members made it sound this way…I believe it
    • Apparently we are capable of cloaking something for 3 nano seconds according to Elizabeth via MSNBC. Read more here if you wish
    • The jist of this one was to make all of your customer experiences aware of each other…if I create a shopping list on kroger.com and it knows which store I shop at…give me my list on my phone by aisle and sort it based on location so I don’t do 18 laps around the store…seriously they should do this…
  • Free Your Mind: Using UX Checklists to Focus on What's Important by Elisa Miller (@elisakm)
    Download Slide Deck
    What I took away…
    • Make good checklists
    • Buy this book - The Checklist Manifesto by Atul Gawande. (Recommended in more than one presentation I attended)
    • I actually started making quite a few checklists today…the most important: Post-Deployment Review Checklist for applications team
  • Forget your MBA: Managing in a Creative Culture by Marcelo Somers (@marcelosomers)
    Download Slide Deck
    What I took away…
    • He’s a finance geek and a machead
    • Companies are alive and they don’t live very long
    • Focus on a few things and do them better than anyone else…Chipotle was his example
    • The market changes…either change with it or die
  • Designing for Disabilities by Sharron Rush (@sharrush)
    What I would’ve taken away…
    • I’ll admit it…I went for a nap over another session…HOWEVER, I would’ve gone to this one. I did stop by their booth because I plan to participate in their airhouston event in October and was looking for more info. I went to her session last year and it was very eye opening. Seriously, I literally just read the description and am very sorry I missed this one. (Sure wish the description had been on some form of program rather than a print out with titles…hint hint!)
  • Closing Keynote by Russ Unger (who needs no introduction apparently, but gets one anyhow cause he’s special) (@russu)
    What I took away…
    • Russ is very happy. (last year he was angry so whatever he’s doing is working apparently)
    • Russ is writing another book with Todd Zaki Warfel. Guerrilla UX Research Methods released November 15, 2011 according to Amazon.com
    • Russ is still funny.
    • Russ grew a “Texas” mustache just for us
    • Russ thinks we should adopt Ice UX Framework…
      • stop collaborate and listen
      • anything less than the best is a felony
      • quick to the point to the point no faking
      • and there may have been others
    • Russ likes a cat named Maru that gets into small boxes…the cat is funny
    • Russ doesn’t know what he does for a living…or maybe people that he is close to don’t know…I don’t remember if he ever actually said
    • Russ is excited to see what we do…I’m curious and a little excited too :)

Day 2:

  • Opening Keynote by Josh Clark (@globalmoxie)
    • I slept in due to lack of description. I need to know what I’m waking up for :)
  • Accelerated Style Sheets: Less Typing, More Style by Wynn Netherland (@pengwynn) and Nathan Smith (@nathansmith)
    • Intended to go to this, but was caught up with packing and checking out of my room
  • Designing for Change and Innovation by Sara Summers (@sarasummers)
    What I took away…
    • She wrote a book. I was going to buy it, but then I saw it was using Expression Blend…
    • Use your conference waiting time to ask people about ideas you have
    • Make a feedback area in the blank walls of the surrounding cubes
    • Walk the dog to think or actually just make time to think – I actually did that this morning on my way into work. I have a 45 minute commute and left the radio off so I could think…it was nice to talk to me.
  • Innovation: Ideas are Just the Beginning by Adam Polansky (@adamtheia)
    Download Slide Deck
    What I took away…
    • An extra 30 minutes to look around…he was a bit quick
    • Innovation = New Combinations (i.e. guy driving thinks “I like listening to radio”…”HEY NOW! I should add a radio in my car!”)
    • Create a list of small bug fixes that can be fixed on your own time…present them…they’ll probably get added to the project list
  • Slay the Legacy Code Beast by Caleb Jenkins (@calebjenkins)
    Download Slide Deck
    What I took away…
    • Caleb is here to help.
    • Caleb looks and talks a LOT like Dane Cook (I think Caleb might be funnier)
    • Caleb references presentations from a year ago (I should’ve gone I guess)
    • Caleb likes to ROOOOAAARRR (or just make monster noises…not sure how to spell what he was doing) and he enjoys audience participation
    • Caleb once worked on a solution with over 68 projects…I think I woulda quit
    • Here’s the jist:
      • Know Your Foe (Legacy Code)
        • Don’t go changing stuff willy nilly
        • Use dependency graphs
      • Create a Safety Net
        • Use Source Control
        • Create Tests
      • Divide and Conquer (pick your battles)
        • The slideshare.net doesn’t do his presentation justice…I mean there was a really nifty split of the screen for this 3rd strategy announcement during his live presentation…it was truly amazing.
    • Caleb will give you credit if he takes one of your pics from flickr…good to know
    • I really enjoyed Caleb’s talk even though I don’t have every day battles with legacy monsters
  • Designing for Awareness by Brian Sullivan (@BrianKSullivan) and Taylor Cowan (@tcowan)
    Download Slide Deck
    What I took away…
    • Attention = Focus
    • Distraction = Disorder
    • Information’s price is attention…don’t be poor on attention
    • Two types of attention…active and passive
    • Do you multi-task? No you don’t.
    • Checklists mentioned again
    • Interruption vs Notification – Very important in design
      • Interruption = Active Awareness (i.e. alert(‘Hey there!’);)
        • Only in emergency or dire situation
      • Notifications = Passive Awareness (i.e. $(‘#thissmallredsquarenotification’).show();)
    • We process 400 billion bits of data per second passively
      • A lot less actively…2,000
  • Progressive Prototyping with HTML5, CSS3, and jQuery by Todd Zaki Warfel (@zakiwarfel)
    Download Slide Deck
    What I took away…
    • Todd likes to cook
    • Todd makes grayscale look sexy
    • Todd does not wireframe…I still do…I prototype too…mostly I wireframe to help me visualize the markup and gen the graphics
      • Todd does this via sketches…I’m not that good
      • I wonder what kind of markers he uses because they look like some awesome colors on his slideshow
    • Todd prefers to fail in a low cost environment…imagine that…
    • Todd lays out the data first…then he styles
    • Todd bragged a lot about not having a single image on his grayscale and it still looking “sexy”
    • Todd then went on about the awesomeness of HTML5
      • Specifically the progress and meter tags, which are pretty freakin sweet
    • Todd gave a heads up about updating your reset.css…I’m glad he did because I have not
    • Todd provides great coverage of CSS3 Selectors…I’ll let you look at his deck…same with his jQuery coverage
    • Todd wrote a book and is working on the one mentioned earlier with Russ Unger…I bought the Prototyping book and am reading it now
  • Mobile & UX by Jared Spool
    Download Slide Deck…OH wait I haven’t received it via email yet…hopefully I emailed them correctly and will get it soon and hopefully I can get permission to share…if not…you shoulda been there :)
    What I took away…
    • Jared is flippin smart.
    • Jared is great at teaching and entertaining…not once did I think, “hey! I’m learning a lot” (I did though)
      • Sturgeon’s Law – 90% of everything is crap. Are you in the 10%?
      • Technology » Features » Experience
        • Jared realizes on an example here that his audience is a young one
      • The Kano Model
        • User Satisfaction by Company Investment
        • Must meet basic expectations (BEs) before excitement generators work
          • When BEs don’t work, you’re just pissing people off
          • With time, delighters become BEs
      • There were 3 questions to see how well formed your team is…but I don’t remember them. Hopefully I get that slide deck soon :)
        What I remember…
        • the vision of the team and their experience with your design
        • how long you spend watching your’s or your competitor’s design
        • have you rewarded failure
    • We are in an immature era, we are learning and the next few years are going to be very exciting and a bit scary if you like your privacy. Seriously…scary.

Books Bought Due to Conference:

Other Stuff

Suggestions for next year

  1. Printed programs with full descriptions of presentations and speakers
  2. Donuts
  3. Snacks
  4. Sodas
  5. Casino night that I know about at least a day or two before the night actually occurs…I would’ve loved to shoot some craps
  6. Donuts
  7. Maybe some bacon??

That about does it. I enjoyed the conference and I’m excited about the user experiences I’ll be creating in the next year. Look forward to next year’s event!

Thanks for reading!

kick it on DotNetKicks.com

Related Posts Plugin for WordPress, Blogger...