Asa Williams Ideas and life lessons learned from a comp. scientist

28Dec/110

Url design

Urls are beautiful. You might think I’m a little crazy but hear me out. Most times when going to a site you see a url structure that makes sense. It is something we expect, but never really think about until we see one that doesn’t make sense at all.

 

 

 

Here is one example of a poorly designed url :

http://ecn1.macsales.com/Reviews/Framework.cfm?page=/time_machine/time_machine.html 
(http://www.flickr.com/photos/frankfarm/2204707610/)
 

Looking at it you can tell it has something to do with “time machine”, but other than that you have no idea. Also, since this is on a piece of paper, the user is expected to type this into the address bar. Yeah, good luck with that one! This could have been shortened and formatted to http://macsales.com/time-machine/ to make it more human readable as well as being more memorable and easier to type. Users would be more apt to visiting your site if you make it easier to get there.

So, what makes for good url design? Here are some guiding principles I use in creating urls:

Human Readable

Can someone read it? In the example above, the sub-domain (“ecn1”) isn't a word or a logical abbreviation. I’m definitely not going to remember that. If you think this is bad, some sites take it a step further and add in characters you can neither pronounce nor figure out how to type. But there is also a problem you probably didn't notice right away in the example. They used underscores (“_”) in “time_machine”. This makes it look like there is supposed to be a space between the two words because the default style is to put underlines on links.

Descriptive

I see urls to be like directions and meta data about a destination. Your urls should be describing the content it is going to as well as potentially how to navigate to it through the UI. It is also a good way for users to be able to look at a link and already know what it’s about.

Short

This seems to be fairly obvious. The shorter the url the easier it is to remember, type, and more likely they will go to your site. But, you should not be sacrificing the principles above (readable & descriptive) to achieve even shorter urls. That generally just leads to confusion.

Hackable

What do you mean by hackable? I don’t think I want hackers to mess with my site. No no no. What this means is that the url structure is so obvious that users can navigate somewhere without ever have being there before. For instance, you noticed that when you go to your profile page on site xyz.com that the structure looks like this: xyz.com/username. By knowing this you can go directly to your friends profile page by putting his username instead of yours. By making your urls hackable you have allowed your users faster access to the content they are looking for. Also, you have potential reduced your server load.

Further reading:
http://rield.com/how-to/url-design
http://warpspire.com/posts/url-design/

11Jul/110

Changing css in JavaScript and jQuery : Performance

I was curious about the performance difference between using jQuery's show() and hide() vs. css('display':'block') and css('display':'none'). While searching on the web I found this great jsperf.com test: http://jsperf.com/jquery-show-hide-vs-css-display-none-block/2. This test also brought up another good point. Setting css properties is much faster in pure JavaScript than it is in jQuery.

So, why use jQuery at all for setting css properties? Well, there are a couple benefits to using jQuery.css(): readability, less code, and handing difficult properties like opacity. The only time that would switch to using a pure JavaScript implementation is if it would noticeably improve the performance.

Filed under: Uncategorized No Comments
7Jul/110

Getting Attribute Value Performance

I've seen a lot of jQuery code that does this:

var someVar = $(this).attr('attrName');

but you can just as easily and with less code do this:

var someVar = this.attrName;

The last code snipet has two advantages: it's faster and it's less code. Here is the performance test results jsperf.com/get-attribute-value

10Dec/100

Discover and Share the Best Learning Resources

As a software engineer, hardware hacker, and problem solver I always like learning more about my topics of interest. One of the problems that I have always found was trying to find the best learning materials for learning something new. Also, what resources are people subscribing to (RSS, poscasts, etc.) to stay up to date? You can search the internet and find some pretty good stuff, but sometimes it can take forever. I personally do a search and open up 10-30 tabs of webpages in hopes of finding what I really want. Sometimes you will get lucky and find website that lists all the best resources for X and Y, but again it could be a year old, and in technology terms thats a long time.

To solve this problem two of my friends and I have been creating a site to discover, share, and create the best learning resources. The site is called Pushstack. It is not live yet but if you want an invite go to pushstack.com. You can also follow us on twitter @pushstack and on facebook

Tagged as: No Comments
22Nov/100

Creating a FieldSet Container

The FieldSet container is a standard visual component for HTML and many other visual languages, but not for Flex. I will show you how to create a very basic one in Flex 3.

End Result

This movie requires Flash Player 9

View Source

If you wish to see the entire object's code click the link above.

Adding Children to a Container




    
        
        
    


To allow children components to be added to the FieldSetContainer you need to set a "DefaultProperty" Tag.

FieldSetContainer.as (snippet)

[DefaultProperty("children")]
...
/**
 * Display Children to be added to the Container
 */
private var _childrenChanged:Boolean = false;

private var _children:Array = [];
public function set children(value:*):void
{
    if( value is DisplayObject )
        _children = [ value ];
    else
        _children = value;

    _childrenChanged = true;
    invalidateDisplayList();
}

The string in the tag ("children") is the property that will be set with the DisplayObjects that are inside the FieldSetContainer. Since you can have one or many objects inside this container (DisplayObject or Array of DisplayObjects) we cannot set the data type of the value that is passed in. The '*' allows for all types to be a passed in.

At this point we cannot add the children to the container because the container has not been created yet. The last statement "invalidateDisplayList();" calls the updateDisplayList(unscaledwidth, unscaledheight) method when it is ready ( when everything is created ). We will override this method to be able to add these children to the container.

We first check if the property is changed. Since this method will be called many times not related to the adding of children we do not want to execute this code every time. Looping through the array of children we add each one to the container.

Setting the title string

Like the children and the container the title property will be set before the Label object will be create. We handle setting the text of the label of the title in commitProperties, but we also call invalidateDisplayList(w, h) because the width and height of the titleLabel effects the position of the children and the border. Any time when you need the width and height of the parent container to size or position a object it needs to be done in the updateDisplayList function. To indirectly call this method, you call "invalidateDisplayList();".

protected var titleLabel:Label;

...

/**
 * String to be used as title's text
*/
private var _title:String;
public function set title(value:String):void
{
    if(value != null)
    {
	_title = value;
	dataChanged = true;
        invalidateProperties();
    }
}
...
override protected function commitProperties():void
{
    super.commitProperties();

    if(dataChanged)
    {
        dataChanged = false;
        titleLabel.text = _title;
        invalidateDisplayList();
    }
}
...
override protected function createChildren():void
{
    super.createChildren();

    titleLabel = new Label();
    titleLabel.x = 10;
    titleLabel.y = 0;
    titleLabel.setStyle("color", 0x333333);
    titleLabel.setStyle("paddingRight", 7);
    titleLabel.text = _title;

    addChild(titleLabel);
}

Creating the boarder and children

...

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
    super.updateDisplayList(unscaledWidth, unscaledHeight);

    if(_childrenChanged)
    {
        _childrenChanged = false;

        var index:uint = 1;
        for each(var child:DisplayObject in _children)
        {
            child.y += titleLabel.measuredHeight;
            child.x += 1;
            this.addChildAt(child, index);
            index++;
        }
    }

    createBorders(unscaledWidth, unscaledHeight);
}

protected function createBorders(width:Number, height:Number):void
{
    var borderTopY:uint = titleLabel.height/2;

    this.graphics.clear();
    this.graphics.lineStyle(1, 0x858585);

    this.graphics.moveTo(7, borderTopY);
    this.graphics.lineTo(0, borderTopY);
    this.graphics.lineTo(0, height);
    this.graphics.lineTo(width, height);
    this.graphics.lineTo(width, borderTopY);
    this.graphics.lineTo(titleLabel.x + titleLabel.width - 2, borderTopY);
}

In the updateDisplayList method we will create and position all the children and draw the border. We will start looping over the collection of children at index 1 because the title is at index 0. We also want add the title's height to the y of each child so that it will not overlap the title. In the createBoarders(width, height) method we are creating a boarder line that starts at the vertical center of the title and wraps around the parameter of the container until it reaches the right side of the title label. The "-2" in "titleLabel.x + titleLabel.width - 2" is so the line will always have at least 2 pixels in the direction towards the title.

15Nov/100

Life Lesson for Startups

A great idea was shared in the article, What it Really Means to be a CTO/. What I got from it was this - Hard decisions will have to be made, and when they are you can't just be OK with it, you have to be fully supporting it because you know that it is in the best interest for the company. Putting yourself second, behind the company is very important for its and your success. This is important to keep friction down and cohesiveness of the group tight.

Tagged as: No Comments
15Nov/100

AS3 Performance

http://jacksondunstan.com is a great blog that covers insights into actionscript performance.

5Nov/100

Change in ComboBox Has No Effect in 3.5 SDK

In flex sdk 3.5, when changing the dataProvider of a combobox from one ArrayCollection to another, the new data is not presented in the dropdown list and in the selected item until the user selects one of the items. At this point the most recent data is shown. This bug has already been filed, http://forums.adobe.com/message/2952677

To get around this bug you need to set the combobox.dataProvider and combobox.dropdownlist.dataProvider to the new collection and then combobox.invalidateSize() to set the dropdown's size to be correct.

Filed under: flex No Comments
27Oct/100

Flex MAC address TextInput

This is a basic example of how to use a textinput to format a MAC address like this: ##-##-##-##-##-##-##-##. I would much prefer to just use multiple textinputs, but if your designer says to do it this way, here you go.


MaxChars is set to 23 instead of 16 because you need to account for the dashes and the "restrict" property allows only the characters defined to be entered in the textinput. We are using the "keyUp" event because we need to capture if they hit the backspace button ("change" will not give us this information), which will require different logic.

private function onMacAddressKeyUp(event:KeyboardEvent):void
{
    if(event.keyCode == Keyboard.BACKSPACE)
    {
        if(macAddressTextInput.length % 3 == 2)
            if(macAddressTextInput.text.length != 23)
                macAddressTextInput.text = macAddressTextInput.text.substr(0, macAddressTextInput.text.length-1);
    }
    else if(macAddressTextInput.text.length % 3 == 2)
    {
        macAddressTextInput.text +="-";
        macAddressTextInput.setSelection(macAddressTextInput.text.length, macAddressTextInput.text.length);
    }
}

We are checking for the backspace button hit so that we can check if the next character to be delete was going to be a dash ('-'). If this is true, then remove the next character too. If the user is just entering hex digits and the last one completes the pair then add a dash ('-'). Since we are adding the dash in the code and not by the user we need to set where the cursor should be. If we did not add this last line in we would see a bunch of dashes at the very end.

Filed under: flex, technology No Comments
27Oct/100

Startup: Good Advice

57 Things I've Learned Founding 3 Tech Companies is a great list of things to keep in mind written by Jason Goldberg. Nothing in this list is completely mind blowing or something I have never seen before, but it is always good to have a reminder about some of the more important things when in the grind. One of the points he really drives home by mentioning it many times is the importance of liking the people you work with. These will be your co-founders, investors, mentors, and employees. You better like the people you are going into battle with because you will be spending lots of time with them and it can be a very emotional. You want to be with people you know are going to have your back.