Tuesday, November 25, 2014

Creating Responsive Tables


When building a responsive website where the main responsibility is to display data in tables, one needs to put some thought into how to present this data on smaller screens. Tables are, of course, as wide as the number of data columns, so this presents some challenges with how to display it when the view width is limited.

Using Bootstrap's table-responsive

Bootstrap's table-responsive class offers one solution, where the table is given a horizontal scrollbar. This is not ideal as it requires the user to scroll the table to see all the data in a row. This can be done by touching the table but this is not obvious and some users may think they need to use the scrollbar. This then reduces usability when there are more than a few rows in the table - the user would scroll to the bottom of the table before scrolling horizontally, leading to some frustrating vertical scrolling if the data they are looking at is back up at the top of the table.

Rotating the Data

The following is an alternative approach. The idea is to "rotate" the data so that columns become rows and rows become collections of rows. So this table:



Looks like this on a smaller screen:


Achieving this with CSS poses a couple of challenges. How do you lay out table header cells vertically, and flow the data cells in this way? Well obviously you can't, so you need to employ a couple of tricks.

The first thing to do is set up a simple table. It can use the bootstrap table class as well as our custom responsive-table class (note  this is different to the bootstrap table-responsive class).

<table class="table responsive-table">
   
<thead>
   
<tr>
       
<th>Number</th>
       
<th>First Name</th>
       
<th>Last Name</th>
       
<th>Address</th>
       
<th>Points</th>
   
</tr>
   
</thead>
   
<tbody>
   
<tr>
       
<td data-content="Number">1</td>
       
<td data-content="First Name">Sam</td>
       
<td data-content="Last Name">Smith</td>
       
<td data-content="Address">12 Smith Road</td>
       
<td data-content="Points">87</td>
   
</tr>
   
<tr>
       
<td data-content="Number">2</td>
       
<td data-content="First Name">Bob</td>
       
<td data-content="Last Name">Jones</td>
       
<td data-content="Address">99 Angle Street</td>
       
<td data-content="Points">43</td>
   
</tr>
   
<tr>
       
<td data-content="Number">3</td>
       
<td data-content="First Name">Terrence</td>
       
<td data-content="Last Name">Rogers</td>
       
<td data-content="Address">999 Letsby Avenue</td>
       
<td data-content="Points">85</td>
   
</tr>
   
<tr>
       
<td data-content="Number">4</td>
       
<td data-content="First Name">Lawrence</td>
       
<td data-content="Last Name">Burnfish</td>
       
<td data-content="Address">69 The Matrix</td>
       
<td data-content="Points">0</td>
   
</tr>
   
</tbody>
</table>

Of course in a real scenario, this data would be dynamic.

Note the use of the data attribute. We'll get to that shortly. Otherwise this is a basic table. No css is required for the full screen version, unless you want to add some formatting, as this is handled by bootstrap's table class.

The CSS

It's in the media query where the magic happens. You will need to decide on your breakpoint size depending on the expected minimum width of the table, which might depend on the number of columns, and width of the data. For this example, we'll set the breakpoint to 600 pixels.

@media only screen and (max-width: 600px) {
   
.responsive-table {
       
border-top: 1px solid #ccc;
   
}
   
   
.responsive-table th,
   
.responsive-table thead{
       
display: none;
   
}

    .responsive-table, .responsive-table tbody, .responsive-table tr, .responsive-table td {
       
display: block;
   
}
 
   
.responsive-table tr {
       
border-bottom: 1px solid #ccc; 
   
}
 
   
.responsive-table td {
        /* important to override bootstrap */
        padding-left: 50% !important;
       
border-top: 0 !important;       
        text-align: left;
       
position: relative;
       
border-bottom: 0;      
   
}
 
   
/* Now like a table header */
   
.responsive-table td:before {      
       
font-weight: bold;
       
font-size: 0.85em;       
       
position: absolute;
       
margin-left: -50%;
       
width: 50%;
       
white-space: nowrap;
       
content: attr(data-content);
   
}
}

Setting the display property of the tr and td elements to block forces the cells to flow vertically.

.responsive-table, .responsive-table tbody, .responsive-table tr, .responsive-table td {
       
display: block;
   
}

Each cell has left padding of 50% which matches the width and negative margin-left of our td:before pseudo element:

margin-left: -50%;       
width: 50%;

To display the table headers we're hiding the actual th elements and using the value of the data-content attribute of each table cell. This is done using the td:before pseudo element and by setting the content css property using attr(data-content).

.responsive-table td:before {      
       
font-weight: bold;
       
font-size: 0.85em;       
       
position: absolute;
       
margin-left: -50%;
       
width: 50%;
       
white-space: nowrap;
       
content: attr(data-content);
   
}

The beauty of using the data-* attribute is that you can set these in the html to something dynamic such a javascript or @razor variable. As they will be the same for each row, this  means they can be set within the loop which displays the rows.

Presentation

We're hiding the borders on the table cells and setting a border-bottom on the table rows, so that our data is neatly separated into a collection of rows.  Notice the table itself has a top border, just to frame it.

Browser compatibility

As this trick uses media queries, and media queries only work in IE9+, we only need to ensure the other features work in IE9+. (Below this the table will not refactor when the screen shrinks anyway).  Content, data-*, and pseudo elements all work in ie9, but unfortunately negative margins don't, and combined with position:absolute, which is essential, this causes a pretty significant issue.  




Of course this only becomes a problem when an IE9 user (currently about 2% globally) reduces their browser window, and won't be a problem on actual mobile devices which this technique is targetted for, so it's up to you whether you decide to mitigate this by putting the media query into a conditional statement.

Wrapping text in titles

Watch out for cell titles with more than one word. These could wrap when the screen size is reduced and will wrap onto the next line if you have white-space set to normal in the td:before css. One way around this is to make your table cell heights 2em or more, although this obviously means all sub-rows will be double height even when there isn't a large title.

Conclusion

Refactoring tables to display vertially can be a very useful alternative technique for presenting wide tables on smaller devices. The technique may require tailoring to your specific data shape and presentation requirements, but overall the tables are easy to read and interact with.


Resources

Monday, November 03, 2014

Creating Value: The Key to Innovation


Creating is to bring about something new. The act of creating involves integrating two or more concepts together to create a new idea.

Value is typically that which adds value to one’s life, whether that be an individual, a group, or the whole of society. Values are benefits, improvements, they alleviate suffering, reduce cost, increase availability.

So how do we go about Creating Values?

You don’t need to be creative to create values. But you do need to utilize certain skills.

Given that Values are that which add benefits to one’s life, in order to create them, we must understand human needs.

Understanding Human Needs

To do this, simply Observe. Watch the world, and pay special attention to where people are happy or unhappy. Figuring out what makes them happy or unhappy is a key to creating new values. Try and find out what are the influences that affect happiness.

Also look at cost, efficiency, functionality and availability. Given that these criteria affect happiness, think about how can they be improved.  Many new values are simply existing values that have been improved. In fact, nearly all of them are. Again, creating involves integrating two or more concepts into a new idea. You will see this to be true when you start creating values by making improvements to what already exists. All you need to do is to take an existing concept and improve it by applying another.

Take the iPhone as an example. Apple didn’t invent the phone from nothing, they just improved on it by applying another, already existing concept to it – the touch screen. They then improved it even further by making it dual touch, and even further still by developing killer software. This multi-layering of improvements is perhaps the secret to their success – most new ideas are only single improvements of existing concepts.

Understand Human Responses

As well as looking at the status quo, pay attention to how individuals and society respond to changes. This information should be in abundance, given that the world is currently changing so fast and that this change is accelerating.

How people respond to change is very revealing. It shows how people really think, how they let their emotions, their desires, their hopes and their fears dictate their actions. It is their emotions which reveal what they value. Knowing what they value will enable you to create new value for them and improve their lives.

Engage

Of course you are a human too. So engage with others. Live your life alongside others and learn what makes you tick as well. You are the person to whom you are closest, so you have the unique privilege of seeing the innermost desires and emotions of yourself. Yes you are different from others, but humans share many common ideals, hopes and fears. Compare yours with others to help you figure out how can I improve this? How can I get more from the world and benefit myself? The answers will point you in the direction of how to create more for others and this is the nature of Creating Values.

Document Human Needs and Behavior

Humans are complicated and their behavior is not always predictable. However, when you understand human needs, you will be see patterns emerge. It is important to keep a record of these patterns not only to help yourself remember but so that this data can be analysed. This documentation will help you formulate a plan to create values based on human responses and needs.

Create Values Based on Your Observations

Design

When you figure out what makes people tick, how they respond to the environment, what drives them and what they see as benefits, you can begin the task of creating new values to take advantage of this knowledge. The first step, like it should be in all acts of creation, is deliberate design.

Design is about customizing an idea to meet certain needs. Often these needs might be aesthetic, and this can be very important, especially if your chosen field of value creation is artistic. But aesthetics are more of a “want” than a “need”. They are still important, especially with regards to improving culture, marketability, and sometimes usability, but they are not the focus of this article.

From a business/technological point of view, design needs to give most consideration to functionality. This is the attribute that will lend itself most to fulfilling human need. Functionality is the essence of a creation, its purpose, its reason for existing. Functionality should solve some human need, and that should be the focus of your design.

Work to incorporate some level of functionality into your created values – functionality that fulfills a human need. It should improve on a current concept in one or more areas. The more the better, but you may find that each improvement is the basis for a new tree of ideas – and every route can be followed to create numerous values.

Just remember the most important aspect of design and constantly ask yourself – how does this fulfill human needs?

Create

The often missed step of value creation is the act of creation itself. Turning the idea into a physical reality is perhaps more important than the idea itself. Many people have ideas, but until this idea is turned into reality – it is nothing more than an electrical signal that will disappear when you die. It does not have any effect on humanity, it will not improve anyone’s life, and it will not provide you with any income. Thoughts are nothing without actions.

Even designs drawn on a page are nothing until they are made into something real, because the design itself has no purpose, no impact.

Only when something is built in real life do you find out if it really works – and what its consequences will be. For every value creating action comes a seemingly infinite tree of implications, it’s impossible to know how your creations will impact everybody, and what effects they will have on the world.

This is our purpose, it's what gives life meaning. Your creations open the doors to other creators to build on your creations. Every creation is a combination of two or more existing concepts – therefore – your new concept will become one of the concepts in a whole new creation.

It is an exciting and noble route to prosperity.

Tuesday, October 21, 2014

5 Reasons you should start doing code reviews

  1. It will help catch quality issues earlier, another perspective on your code might reveal possible bugs
  2. It will help you be more aware of other work going on
  3. It will increase the quality of your coding practices
  4. You will learn from other people's perspectives on your code
  5. You will learn by looking at other people's code
    Books are made better by editors. Coders are made better by pair programming and code reviews. - Scott Hanselman
    Why not add Code Reviews to your Definition of Done today?