<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>isambard &#187; interface design</title>
	<atom:link href="http://isambard.com.au/blog/tag/interface-design/feed/" rel="self" type="application/rss+xml" />
	<link>http://isambard.com.au/blog</link>
	<description>musings on information design and architecture</description>
	<lastBuildDate>Sun, 13 May 2012 23:38:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Sharing a Calendar in Sharepoint 2007 &#8211; Part II</title>
		<link>http://isambard.com.au/blog/2011/05/19/sharing-a-calendar-in-sharepoint-2007-part-ii/</link>
		<comments>http://isambard.com.au/blog/2011/05/19/sharing-a-calendar-in-sharepoint-2007-part-ii/#comments</comments>
		<pubDate>Thu, 19 May 2011 04:45:25 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Techniques]]></category>
		<category><![CDATA[interface design]]></category>
		<category><![CDATA[Sharepoint]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=653</guid>
		<description><![CDATA[Earlier I wrote about how you can use XML+XSL to get around the limitation in Sharepoint 2007 of sharing calendars across multiple sites. This technique stores your events as XML and allows you to publish entries wherever and however you wish. This article expands that earlier introduction with some tips and tricks we collating when [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://isambard.com.au/blog/2011/01/10/sharing-a-calendar-in-sharepoint-2007/">Earlier</a> I wrote about how you can use XML+XSL to get around the limitation in Sharepoint 2007 of sharing calendars across multiple sites.  This technique stores your events as XML and allows you to publish entries wherever and however you wish.</p>
<p>This article expands that earlier introduction with some tips and tricks we collating when implementing this for one client:</p>
<ul>
<li>working outside Sharepoint</li>
<li>presenting a URL</li>
<li>sorting items</li>
<li>grouping items</li>
<li>showing a message if a filter set is empty</li>
</ul>
<p>Note:  You can <a href="http://isambard.com.au/blog/wp-content/uploads/2011/05/calendar-v2.zip">download sample XML and XSL</a> here.  These files show all the techniques described in this article.</p>
<table>
<tbody>
<tr>
<td><a href="http://isambard.com.au/blog/wp-content/uploads/2011/05/image-xml.png"><img class="alignnone size-thumbnail wp-image-660" title="image-xml" src="http://isambard.com.au/blog/wp-content/uploads/2011/05/image-xml-150x150.png" alt="" width="150" height="150" /></a></td>
<td><a href="http://isambard.com.au/blog/wp-content/uploads/2011/05/image-filter.png"><img class="alignnone size-thumbnail wp-image-661" title="image-filter" src="http://isambard.com.au/blog/wp-content/uploads/2011/05/image-filter-150x150.png" alt="" width="150" height="150" /></a></td>
<td><a href="http://isambard.com.au/blog/wp-content/uploads/2011/05/image-group.png"><img class="alignnone size-thumbnail wp-image-662" title="image-group" src="http://isambard.com.au/blog/wp-content/uploads/2011/05/image-group-150x150.png" alt="" width="150" height="150" /></a></td>
</tr>
<tr>
<td>the original XML</td>
<td>filtered view</td>
<td>grouped view</td>
</tr>
</tbody>
</table>
<p><span id="more-653"></span></p>
<h2>Working outside SharePoint</h2>
<p>It can be painful to develop your XML/XSL solution in Sharepoint because of the need to upload new versions (or edit webparts), then refresh to see the results, or lack thereof.  Easier to work outside and just upload when done.</p>
<p>To link your XML and XSL outside SharePoint edit your XML file to include a link to your XSL file:</p>
<pre>&lt;!--?xml version="1.0" encoding="utf-8"?--&gt;
<strong>&lt;!--?xml-stylesheet type="text/xsl" href="calendar.xsl"?--&gt;</strong>
....</pre>
<p>Now when you open your XML file in a browser it will use your XSL to present.</p>
<p>Save your XLS as a file with a name to match the XML link and you&#8217;re nearly there.  The only other change you may need to make is to extend your XSL so it generates a full webpage, not just a fragment.</p>
<p>For example our standard calendar presentation XSL generates a paragraph:</p>
<pre>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
&lt;xsl:template match="calendar"&gt;
&lt;p&gt;
&lt;xsl:for-each select="event[program='Leadership Foundations']"&gt;
...
&lt;/xsl:for-each&gt;
&lt;/p&gt;
&lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;</pre>
<p>To work outside SharePoint it needs to generate a proper page; make it do so by simply adding HTML and BODY tags:</p>
<pre>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
&lt;xsl:template match="calendar"&gt;
<strong>&lt;html&gt;</strong>
<strong>&lt;body&gt;</strong>
&lt;p&gt;
&lt;xsl:for-each select="event[program='Leadership Foundations']"&gt;
...
&lt;/xsl:for-each&gt;
&lt;/p&gt;
<strong>&lt;body&gt;</strong>
<strong>&lt;html&gt;</strong>
&lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;</pre>
<p>Just remember to remove these bonus lines when re-inserting into your SharePoint site.</p>
<h2>Presenting a URL</h2>
<p>If one element you&#8217;re recorded in your XML is a URL then chances are you&#8217;ll want to use XSL to convert that into a link.  And the obvious approach you&#8217;d think would be the simplest:</p>
<pre>&lt;a href='&lt;xsl:value-of select="link"&gt;'&gt;link text&lt;/a&gt;</pre>
<p>Other than the issue over nested quotes, all looks pretty straightforward.  Except it doesn&#8217;t work.</p>
<p>The solution is to use a different format for the URL selection:</p>
<pre>&lt;a href="{link}"&gt;link text&lt;/a&gt;</pre>
<p>Now it works fine.</p>
<h2>Sorting items</h2>
<p>One feature we wanted to implement was the automatic sorting of results.  This meant anyone maintaining the master XML list did not need to worry about where to add individual items to preserve their order.  They could just add anywhere in the file and be confident they&#8217;d appear in the correct sequence when displayed.</p>
<p>To sort results, add the <code>&lt;xsl:sort&gt;</code> command as the first element within your  loop. For example to sort by a date element:</p>
<pre>&lt;xsl:for-each select="event"&gt;
    &lt;xsl:sort select="date" /&gt;
    ...
&lt;/xsl:for-each&gt;</pre>
<p>Check <a href="www.w3schools.com/xsl/el_sort.asp">W3Schools</a> if wanting to do something more complicated than an ascending text order.</p>
<p>As you can see from this example, what we were wanting to search on were dates.  And early on we&#8217;d decided that users would enter dates in &#8220;human&#8221; format (ie &#8217;23 May 2011&#8243;, not 20110523).   One issue we had on sorting dates was the chestnut of how to sort &#8220;2 May 2011&#8243; to appear before &#8220;15 May 2011&#8243;.  Our solution was to require all dates in the XML to be two characters (&#8220;02 May 2011&#8243; not &#8220;2 May 2011&#8243;) and then use XSL to remove the ugly leading zero when displayed.  The code to remove that zero is straightforward:</p>
<pre>&lt;xsl:choose&gt;
    &lt;xsl:when test="substring(date,1,1)=0"&gt;
         &lt;xsl:value-of select="substring(date,2)" /&gt;
    &lt;xsl:otherwise&gt;
&lt;/xsl:choose&gt;</pre>
<p>You have to use the <code>&lt;xsl:choose&gt;</code> construct because while XSL does have an IF statement (not surprisingly <code>&lt;xsl:if&gt;</code>), it does not have an equivalent ELSE.</p>
<p>Note:  The alternative would be to define the date in a nice sortable format (I vote for YYYYMMDD).  And then use similar XSL transformations to present in a more readable format.  Either way you&#8217;re putting some overhead on the user.  We stuck with this simple approach because it was (a) less user effort and (b) allowed a wider range of dates to be acceptable.  For example we had some programs that only specified a month.  Sorting this way meant we could accept &#8220;May 2011&#8243; as a valid date.</p>
<h2>Grouping items</h2>
<p>Now this I thought would be easy. Since we&#8217;re working on a calendar, let&#8217;s group entries according to the month.  ie:</p>
<p>April 2011<br />
- This course (12 April, London)<br />
- That course (19 April, Helsinki)<br />
May 2011<br />
- That course (2 May, Romford)<br />
- The other course (30 May, Malaka)</p>
<p>After several false starts, all roads do eventually lead to a fabled Meunchian method.  Trouble is, even after building it, I&#8217;ve no idea how it works.  Of all the articles uncovered to try and explain it, <a href="docstore.mik.ua/orelly/xml/xslt/ch06_02.htm">this one came closest</a>.  Cut&amp;paste their approach (or <a href="http://isambard.com.au/blog/wp-content/uploads/2011/05/calendar-v2.zip">our example</a> using it) and you should be able to get it to work.</p>
<h2>Showing a message if the filter set is empty</h2>
<p>In the <a href="http://isambard.com.au/blog/2011/01/10/sharing-a-calendar-in-sharepoint-2007/">first article</a> we covered how simple it is to present a subset of your entries. However once implemented we discovered we needed to address the situation where a subset was empty.  Rather than just showing a blank list we wanted to show a messsage directing the visitor to other sources.</p>
<p>Simplest way to implement this is to repeat the same filter query used to generate the subset. Just place within a COUNT() and use as a test:</p>
<pre>&lt;xsl:choose&gt;
     &lt;xsl:when test="count(event[program='First Program']) &gt; 0"&gt;

          &lt;xsl:for-each select="event[program='First Program']"&gt;
          ...
          &lt;/xsl:for-each&gt;

     &lt;/xsl:when&gt;
     &lt;xsl:otherwise&gt;
          &lt;xsl:text&gt;No events recorded for this program.&lt;/xsl:text&gt;
     &lt;/xsl:otherwise&gt;
&lt;/xsl:choose&gt;</pre>
<p>Only potential issue may be around your formatting.  Be mindful of where your layout tags appear depending on which data is presented.</p>
<h2>Conclusion</h2>
<p>With just these techniques you can present and manipulate your content in quite ingenious ways.  Just good luck trying to understand the Muench.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2011%2F05%2F19%2Fsharing-a-calendar-in-sharepoint-2007-part-ii%2F&amp;title=Sharing%20a%20Calendar%20in%20Sharepoint%202007%20%E2%80%93%20Part%20II" id="wpa2a_2"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2011/05/19/sharing-a-calendar-in-sharepoint-2007-part-ii/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>UI Rule #47 &#8211; Don&#8217;t Make Up Words</title>
		<link>http://isambard.com.au/blog/2011/01/21/ui-rule-47-dont-make-up-words/</link>
		<comments>http://isambard.com.au/blog/2011/01/21/ui-rule-47-dont-make-up-words/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 03:04:17 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Techniques]]></category>
		<category><![CDATA[interface design]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=644</guid>
		<description><![CDATA[Found the following beauty when on Youtube: You shouldn&#8217;t have to invent your own language (&#8220;Favorited?&#8221;) to make your UI work.]]></description>
			<content:encoded><![CDATA[<p>Found the following beauty when on Youtube:</p>
<p><a href="http://isambard.com.au/blog/wp-content/uploads/2011/01/favorited.png"><img class="alignright size-full wp-image-645" title="favorited" src="http://isambard.com.au/blog/wp-content/uploads/2011/01/favorited.png" alt="" width="268" height="149" /></a></p>
<p>You shouldn&#8217;t have to invent your own language (&#8220;Favorited?&#8221;) to make your UI work.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2011%2F01%2F21%2Fui-rule-47-dont-make-up-words%2F&amp;title=UI%20Rule%20%2347%20%E2%80%93%20Don%E2%80%99t%20Make%20Up%20Words" id="wpa2a_4"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2011/01/21/ui-rule-47-dont-make-up-words/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sharing a calendar in Sharepoint 2007</title>
		<link>http://isambard.com.au/blog/2011/01/10/sharing-a-calendar-in-sharepoint-2007/</link>
		<comments>http://isambard.com.au/blog/2011/01/10/sharing-a-calendar-in-sharepoint-2007/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 05:40:47 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Techniques]]></category>
		<category><![CDATA[interface design]]></category>
		<category><![CDATA[Sharepoint]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=577</guid>
		<description><![CDATA[One of the most annoying omissions in Sharepoint 2007 is the inability to share calendars between sites and subsites: maintain a master calendar and view it (or part of it) in a subsite, or maintain a calendar in the subsite and &#8220;roll it up&#8221; with other subsite calendars to a master view in the main [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most annoying omissions in Sharepoint 2007 is the inability to share calendars between sites and subsites:</p>
<ul>
<li>maintain a master calendar and view it (or part of it) in a subsite, or</li>
<li>maintain a calendar in the subsite and &#8220;roll it up&#8221; with other subsite calendars to a master view in the main site.</li>
</ul>
<p>Apparently this is rectified in Sharepoint 2010 but if you&#8217;re unable to upgrade, and aren&#8217;t allowed to build your own webparts, you&#8217;ve to look elsewhere for a solution:</p>
<ul>
<li>use a 3rd party webpart (can recommend the <a href="http://store.bamboosolutions.com/sharepoint-calendar-plus-web-part.aspx">Bamboo Solutions</a> offering having used it elsewhere), or</li>
<li>hacking together via the page viewer webpart (I never got this to work but your mileage may vary)</li>
</ul>
<p>However this article describes a 3rd option we implemented which met the requirement by not using calendars at all.  Instead we used XML.<br />
<span id="more-577"></span></p>
<h2>An XML solution in three parts</h2>
<p>The XML solution allows a single, master, calendar to be published in multiple subsites, optionally filtering entries to particular subsets.  To implement you need three elements:</p>
<ol>
<li>source calendar (in XML, not a SharePoint calendar)</li>
<li>presentation/design code (XSL), and</li>
<li>webpart that links the above two together on your site.</li>
</ol>
<p><a href="http://isambard.com.au/blog/wp-content/uploads/2011/01/SharePoint-CalendarList.png"><img src="http://isambard.com.au/blog/wp-content/uploads/2011/01/SharePoint-CalendarList-300x249.png" alt="" title="SharePoint-CalendarList" width="300" height="249" class="alignright size-medium wp-image-605" /></a>Without advanced CSS skills this won&#8217;t get you much more than an event list on any site.  But if that&#8217;s all you want, and more important is the ability to reproduce that one list on multiple sites, then this approach might work for you.</p>
<h2>Source calendar (XML)</h2>
<p>In XML a calendar is simply a series of events, with varying parameters that include a date and a name, collected in a parent element.  For our basic implementation we ended up with just that:</p>
<pre>&lt;calendar&gt;
 &lt;event&gt;
  &lt;date&gt;12 August 2011&lt;/date&gt;
  &lt;title&gt;Integration testing starts&lt;/title&gt;
 &lt;/event&gt;
 &lt;event&gt;
  &lt;date&gt;23 November 2011&lt;/date&gt;
  &lt;title&gt;Integration testing ends&lt;/title&gt;
 &lt;/event&gt;
 ...
&lt;/calendar&gt;</pre>
<p>To make it valid just add a definition on the first line:</p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;</pre>
<p>From this basis you can obviously add whatever other values you want to note for each event.  For example if you want to present or filter by project, or responsibility, just add appropriate values to the XML.</p>
<h2>presentation/design code (XSL)</h2>
<p>The XSL code is what converts your XML into HTML that can be presented on your Sharepoint page.  With the simple calendar schema adopted here this is only a few lines.</p>
<p>First set the scene:</p>
<pre> &lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
 &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

 ...

 &lt;/xsl:stylesheet&gt;</pre>
<p>Then add the XSL proper inside the above framework.  The following code will first match our calendar parent element using <code>template-match</code>, before traversing each of our events by using a <code>for-each</code> loop.</p>
<pre> &lt;xsl:template match="CALENDAR"&gt;
  &lt;table border="0"&gt;
    &lt;xsl:for-each select="EVENT"&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;xsl:value-of select="title" /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;xsl:value-of select="date" /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/xsl:for-each&gt;
  &lt;/table&gt;
&lt;/xsl:template&gt;</pre>
<p>This code puts each event (the &#8220;EVENT&#8221; elements) into a separate row in a table, with two event values &#8220;title&#8221; and &#8220;date&#8221; presented in separate columns.</p>
<p>This code gives you the basic framework for manipulating your XML.  However XSL, and HTML/CSS are must more powerful than this example demonstrates.  Feel free to research further on how to leverage this approach to really fine-tune the delivery of your calendar data.</p>
<p>For now, however, I will describe one of the most common XSL functions you&#8217;ll want in this solution: the ability to present a subset of your calendar entries based on a parameter recorded with each event.</p>
<h3>Filtering records</h3>
<p>In XSL you filter records by adding a comparison operator to your <code>for-each</code> statement. For example, if we add a &#8220;project&#8221; attribute to our events, the code to filter to a specific project is a simple change to the <code>for-each</code> command:</p>
<pre> &lt;xsl:for-each select="EVENT[project='Project A']"&gt;</pre>
<p>This will now only list events that are for &#8220;Project A&#8221;.  And how do you get entries to be categorised as &#8220;Project A&#8221; &#8211; just add to the XML:</p>
<pre>&lt;calendar&gt;
 &lt;event&gt;
  &lt;project&gt;Project A&lt;/date&gt;
  &lt;date&gt;12 August 2011&lt;/date&gt;
  &lt;title&gt;Integration testing starts&lt;/title&gt;
 &lt;/event&gt;
 &lt;event&gt;
  &lt;project&gt;Project B&lt;/date&gt;
  &lt;date&gt;23 November 2011&lt;/date&gt;
  &lt;title&gt;Integration testing ends&lt;/title&gt;
 &lt;/event&gt;
 ...
&lt;/calendar&gt;</pre>
<h2>Linking webpart</h2>
<p><a href="http://isambard.com.au/blog/wp-content/uploads/2011/01/SharePoint-EditXMLWebPart.png"><img src="http://isambard.com.au/blog/wp-content/uploads/2011/01/SharePoint-EditXMLWebPart-209x300.png" alt="" title="SharePoint-EditXMLWebPart" width="209" height="300" class="alignright size-medium wp-image-607" /></a>To pull the XML and XSL together on your Sharepoint page, add an XML Webpart.</p>
<p>In this webpart you simply specify the XML and XSL you need to use.  You can enter your details directly into the webpart (which negates the whole sharing theme for the XML, and can cause consistency issues with the XSL).  Or you can link to external files.  With the advantage that those files can exist anywhere in your site architecture.
</pre>
<h2>Conclusion</h2>
<p>Using XML to share a single calendar is not for everybody.  It's harder to maintain the entries, and the presentation is never going to be sexy.  But as a quick way to stop yourself repeating yourself, it's worth considering.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2011%2F01%2F10%2Fsharing-a-calendar-in-sharepoint-2007%2F&amp;title=Sharing%20a%20calendar%20in%20Sharepoint%202007" id="wpa2a_6"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2011/01/10/sharing-a-calendar-in-sharepoint-2007/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rounding error</title>
		<link>http://isambard.com.au/blog/2010/11/27/rounding-error/</link>
		<comments>http://isambard.com.au/blog/2010/11/27/rounding-error/#comments</comments>
		<pubDate>Sat, 27 Nov 2010 05:15:39 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Techniques]]></category>
		<category><![CDATA[interface design]]></category>
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=505</guid>
		<description><![CDATA[Check out my average score from some elearning I had to complete recently for surf lifesaving: Just one more correct answer and I may have got my average up to 94.52631578947369%!! To be fair, at least they did not need 14 decimal places to tell me how long the course took.]]></description>
			<content:encoded><![CDATA[<p>Check out my average score from some elearning I had to complete recently for surf lifesaving:</p>
<p><a href="http://isambard.com.au/blog/wp-content/uploads/2010/11/round-error.png"><img src="http://isambard.com.au/blog/wp-content/uploads/2010/11/round-error.png" alt="" title="round-error" width="510" height="341" class="alignnone size-full wp-image-506" /></a></p>
<p>Just one more correct answer and I may have got my average up to 94.52631578947369%!!</p>
<p>To be fair, at least they did not need 14 decimal places to tell me how long the course took.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2010%2F11%2F27%2Frounding-error%2F&amp;title=Rounding%20error" id="wpa2a_8"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2010/11/27/rounding-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stop this UI Madness: Confirming visible fields</title>
		<link>http://isambard.com.au/blog/2010/10/23/stop-this-ui-madness-confirming-visible-fields/</link>
		<comments>http://isambard.com.au/blog/2010/10/23/stop-this-ui-madness-confirming-visible-fields/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 22:52:30 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Techniques]]></category>
		<category><![CDATA[interface design]]></category>
		<category><![CDATA[usability]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=408</guid>
		<description><![CDATA[Enough people.    Please stop building forms where I&#8217;m asked to confirm a field I can see quite clearly.  Like this example: Or here&#8217;s another example. Which shows right and wrong use of duplicated fields and (horror or horrors) disables cut&#038;paste. The only requirement for a confirmation field is when entering a value that is [...]]]></description>
			<content:encoded><![CDATA[<p>Enough people.    Please stop building forms where I&#8217;m asked to confirm a field I can see quite clearly.  Like this example:<br />
<a href="http://isambard.com.au/blog/wp-content/uploads/2010/11/confirm-email.png.png"><img class="aligncenter size-full wp-image-409" title="confirm-email.png" src="http://isambard.com.au/blog/wp-content/uploads/2010/11/confirm-email.png.png" alt="" width="420" height="124" /></a></p>
<p>Or here&#8217;s another example.  Which shows right and wrong use of duplicated fields and (horror or horrors) disables cut&#038;paste.</p>
<p><a href="http://isambard.com.au/blog/wp-content/uploads/2010/10/repeat-email.png"><img src="http://isambard.com.au/blog/wp-content/uploads/2010/10/repeat-email.png" alt="" title="repeat-email" width="397" height="184" class="aligncenter size-full wp-image-459" /></a></p>
<p>The only requirement for a confirmation field is when entering a value that is not visible, i.e. a password.  For anything else I can see the value I&#8217;ve typed and &#8220;confirm&#8221; it&#8217;s correct without retyping.  Don&#8217;t make me repeat myself.</p>
<p>If worried about validity, beef up your error-checking.  Don&#8217;t delay me with pointless re-typing (or more usually, cut&amp;pasting).</p>
<p>And another thing.  While making me repeat myself is bad enough, making me repeat myself and then disabling cut&amp;paste in the repeated field gets you your own special corner of hell.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2010%2F10%2F23%2Fstop-this-ui-madness-confirming-visible-fields%2F&amp;title=Stop%20this%20UI%20Madness%3A%20Confirming%20visible%20fields" id="wpa2a_10"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2010/10/23/stop-this-ui-madness-confirming-visible-fields/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UI Design (and the World Cup)</title>
		<link>http://isambard.com.au/blog/2010/06/09/ui-design-and-the-world-cup/</link>
		<comments>http://isambard.com.au/blog/2010/06/09/ui-design-and-the-world-cup/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 04:43:04 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Uncategorised]]></category>
		<category><![CDATA[interface design]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=284</guid>
		<description><![CDATA[In a shameless attempt to link work with the greatest sporting event in the world, the following site has one of the most impressive World Cup Calendars seen in a long time. http://www.marca.com/deporte/futbol/mundial/sudafrica-2010/calendario-english.html Takes a certain streak of creativity to build a calendar outside the usually rectangular.]]></description>
			<content:encoded><![CDATA[<p>In a shameless attempt to link work with the greatest sporting event in the world, the following site has one of the most impressive World Cup Calendars seen in a long time.</p>
<p><a href="http://www.marca.com/deporte/futbol/mundial/sudafrica-2010/calendario-english.html">http://www.marca.com/deporte/futbol/mundial/sudafrica-2010/calendario-english.html</a></p>
<p>Takes a certain streak of creativity to build a calendar outside the usually rectangular.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2010%2F06%2F09%2Fui-design-and-the-world-cup%2F&amp;title=UI%20Design%20%28and%20the%20World%20Cup%29" id="wpa2a_12"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2010/06/09/ui-design-and-the-world-cup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Managing timezones with PHP and Javascript</title>
		<link>http://isambard.com.au/blog/2009/12/10/managing-timezones-with-php-and-javascript/</link>
		<comments>http://isambard.com.au/blog/2009/12/10/managing-timezones-with-php-and-javascript/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 06:45:37 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Techniques]]></category>
		<category><![CDATA[interface design]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web 2.0]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=685</guid>
		<description><![CDATA[In a current project we need to keep a log of all activities and present that log to the users. And once we start needing to tell users about times we raise the whole spectre of timezones. After some heated design discussions we narrowed our requirements to needing to provide a choice of two possible [...]]]></description>
			<content:encoded><![CDATA[<p>In a current project we need to keep a log of all activities and present that log to the users. And once we start needing to tell users about times we raise the whole spectre of timezones.</p>
<p>After some heated design discussions we narrowed our requirements to needing to provide a choice of two possible display formats for users.</p>
<ol>
<li>show all activities in (my) local time eg if I&#8217;m in Melbourne, show all activities in Melbourne time, even if not completed in Melbourne</li>
<li>show all activities in (their) local time &#8211; what we called &#8220;original&#8221; time eg if I&#8217;m in Melbourne, show all activities completed in Sydney in their original Sydney time, show all activities completed in Perth in their original Perth time.</li>
</ol>
<p>For the latter format to make sense we agreed to add a timezone code to indicate where we were at the time. For convenience these were all given as time +/- UTC. Eg 4:23PM (UTC +11).</p>
<h2>implementation &#8211; capturing activity times</h2>
<p>To allow us to manipulate activity times after recording them we need to record two bits of information:</p>
<ul>
<li>time completed</li>
<li>timezone completed in</li>
</ul>
<p>Our decision for those two was to record the time in UTC and then for the timezone simply record the difference from UTC for the timezone where the activity was completed. That way we knew that whatever we did on display we had a consistent and understandable set of times in the database.</p>
<p>For example, I&#8217;m in Sydney (current timezone is UTC+11). An activity I complete at 4pm is recorded in the database as:</p>
<ul>
<li>completion time: 5am that morning (4pm converted to UTC)</li>
<li>completion timezone: UTC+11</li>
</ul>
<h2>getting the timezone the activity was completed in</h2>
<p>Getting the timezone is easy, and requires a few lines of Javascript added to the client where the activity is completed. So we can get the value to the server to manipulate and record in the database we pass it back to the server as a hidden form variable on our login page.</p>
<p>The magic function we need is <strong>getTimezoneOffset</strong>. This returns the number of minutes ahead/behind of GMT for the current user. For reasons that become clear when we start looking at presenting dates we convert it to seconds. And for reasons that are lost to us we need to negate the value because it returns the offset the wrong way around. Eg if the client is currently one hour ahead of UTC, getTimezoneOffset returns -60.</p>
<p>Putting all that together adds the following to our login page:</p>
<pre>&lt;script language="JavaScript"&gt; 
   var d = new Date(); 
   var offset = 0 - (d.getTimezoneOffset() * 60); 
   document.write ("&lt;input type='hidden' name='offset' value = '" + offset + "' /&gt;")
&lt;/script&gt;</pre>
<p>We added that code to the login form. That way we can capture it once and store as a session variable to use when recording all subsequent activities for that user in the same session.</p>
<h2>getting the UTC time the activity was completed at</h2>
<p>In getting the time an action was completed we can either take the client time or server time. Doesn&#8217;t really matter (if both are confidently accurate) since we&#8217;ll convert either to UTC.</p>
<p>For simplicity we chose to work from the server time. In PHP we can get the UTC of the current server time in 2 lines:</p>
<pre>$timestamp = time();   
$timestampUTC = $timestamp - date("Z", $timestamp);</pre>
<p>The &#8220;Z&#8221; option for Date returns the offset to UTC in seconds based on the server&#8217;s current timezone. And since timestamps simply count seconds it&#8217;s simple to add/remove our conversion factor.</p>
<blockquote><p>You&#8217;ll have noticed there are a few config requirements if this approach is going to work. We were able to rely on these being true in our case but you&#8217;ll need to check for your own implementation:</p>
<ul>
<li>Javascript enabled on the client</li>
<li>correct time (and timezone) set on the client</li>
<li>correct time (and timezone) set on the server</li>
</ul>
<p>If you cannot rely on any of these then you&#8217;ve a few changes to make!</p></blockquote>
<h2>displaying times</h2>
<p>With our activity recorded in the database as UTC it is a simple task to convert to the display times we require. To provide a different display format, we simply need to choose which offset we apply to the UTC time recorded in the database.</p>
<h2>local time</h2>
<p>This is the easiest to generate. Simply update the recorded UTC time with the current UTC offset of the client that we captured when they logged in. Since we converted that value to seconds when uploading we simply add it to the UTC timestamp from the server:</p>
<pre>$timeLocal = $timeUTC + $_SESSION['offsetClient']; 
$timeLocalDisplay = date("D d M Y H:i:s", $timeLocal);</pre>
<h2>original time</h2>
<p>For original time we just need to apply the offset originally recorded in the database, and then tweak the presentation of the timezone to something legible.</p>
<pre>$timeOriginal = $timeUTC + $offsetActivity  //both from the DB
$timeOriginalDisplay = date("D d M Y H:i:s", $timeOriginal);
if ($offsetActivity == 0) { 
   $timeOriginalDisplay .= " (UTC)"; 
} else { 
   if ($offsetActivity &gt; 0) {   
      $timeOriginalDisplay .= " (UTC +" . ($offsetActivity/3600) . ")"; 
   } else {   
      $timeOriginalDisplay .= " (UTC -" . ($offsetActivity/3600) . ")"; 
   } 
}</pre>
<p>That code gives us a date like &#8220;Mon 23 Jun 2006 12:23:45 (UTC +7)&#8221;.</p>
<p>A third option (that we did not implement) was to give the timezone as relative to our own. Eg if we&#8217;re at &#8220;UTC+4&#8243; the previous date would be &#8220;Mon 23 Jun 2006 12:23:45 (+3)&#8221;. This format would be easy to calculate as we already have our current timezone recorded as a session variable after login. However no-one really wanted it (or could agree how to present it) so the idea was dropped.</p>
<h2>conclusion</h2>
<p>So far this design has handled all the requirements we&#8217;ve thrown at it. Only changes we made after implementation was to move some of the display conversion code into mySQL so our queries return the dates in the formats we require. Otherwise, all works well.</p>
<h2>What&#8217;s missing?</h2>
<p>There is one glaring whole in the design and that is the ugliness called daylight saving. It becomes an issue if displaying local times. Our design converts the original activity time to the local time based on the current difference between local time and UTC. But if we&#8217;ve moved in or out of daylight savings (so the relative difference now is different to what it was then) our calculation will be out.</p>
<p>To manage that we need to know whether we, locally, were in/out of daylight savings when the activity was completed, and whether we are in/out of daylight savings now. Achievable but a not insignificant piece of work. The client agreed and thus we decided to ignore this issue reasoning:</p>
<ul>
<li>a max of one hour out is liveable, and</li>
<li>the issue is consistent (meaning a series of activities reported in local time will still present in the correct order, even if for a period of time they are all 1 hour too early/late)</li>
</ul>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2009%2F12%2F10%2Fmanaging-timezones-with-php-and-javascript%2F&amp;title=Managing%20timezones%20with%20PHP%20and%20Javascript" id="wpa2a_14"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2009/12/10/managing-timezones-with-php-and-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quote of the week (19 October)</title>
		<link>http://isambard.com.au/blog/2009/10/19/185/</link>
		<comments>http://isambard.com.au/blog/2009/10/19/185/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 20:48:53 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Quote of the Week]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[interface design]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=185</guid>
		<description><![CDATA[From Antoine de Saint-Exupéry. A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.]]></description>
			<content:encoded><![CDATA[<p>From <a href="http://en.wikipedia.org/wiki/Antoine_de_Saint_Exup%C3%A9ry">Antoine de Saint-Exupéry</a>.</p>
<p>A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2009%2F10%2F19%2F185%2F&amp;title=Quote%20of%20the%20week%20%2819%20October%29" id="wpa2a_16"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2009/10/19/185/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quote of the week (5 October)</title>
		<link>http://isambard.com.au/blog/2009/10/05/quote-of-the-week-5-october/</link>
		<comments>http://isambard.com.au/blog/2009/10/05/quote-of-the-week-5-october/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 21:59:48 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Quote of the Week]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[interface design]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=175</guid>
		<description><![CDATA[From Charles E. Phillips (president of Oracle): Whenever two or more databases get together, it&#8217;s like people… it&#8217;s only a matter of time before they start to disagree.]]></description>
			<content:encoded><![CDATA[<p>From <a href="http://en.wikipedia.org/wiki/Charles_Phillips_(businessman)">Charles E. Phillips</a> (president of Oracle):</p>
<p>Whenever two or more databases get together, it&#8217;s like people… it&#8217;s only a matter of time before they start to disagree.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2009%2F10%2F05%2Fquote-of-the-week-5-october%2F&amp;title=Quote%20of%20the%20week%20%285%20October%29" id="wpa2a_18"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2009/10/05/quote-of-the-week-5-october/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Application design is like recording a cover version of a song</title>
		<link>http://isambard.com.au/blog/2009/10/04/application-design-is-like-recording-a-cover-version/</link>
		<comments>http://isambard.com.au/blog/2009/10/04/application-design-is-like-recording-a-cover-version/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 00:56:58 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Uncategorised]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[interface design]]></category>

		<guid isPermaLink="false">http://isambard.com.au/blog/?p=177</guid>
		<description><![CDATA[Let&#8217;s face it. 99% of our design effort is spent on developing applications that already exist in some form or another. We work continuously to build a better mousetrap, not invent some fundamentally unique and novel way to catch rodents. This is not to belittle the difference we make but to recognise we stand on [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s face it. 99% of our design effort is spent on developing applications that already exist in some form or another. We work continuously to build a better mousetrap, not invent some fundamentally unique and novel way to catch rodents.</p>
<p>This is not to belittle the difference we make but to recognise we stand on existing shoulders. Or if we don&#8217;t, that our users do and will judge our efforts (fairly or unfairly) against those pre-existing expectations about what our [insert class of application here] application should look and feel like.</p>
<p>This need to try and marry those conflicting needs of &#8220;identifying with the original&#8221; and &#8220;being different&#8221; led me to compare the whole application design issue with music, in particular cover versions. Here&#8217;s another area where you are developing something that has both to be distinctive (and your own) while still recognising the essence of what came before.</p>
<h2>what makes a good cover?</h2>
<p>So what makes a good cover version? And what can that tell us about application development? Probably two conflicting goals:</p>
<ol>
<li>be true to the original, but</li>
<li>add your own individuality.</li>
</ol>
<p>Also hidden before the above two is &#8220;choose a good song to start with&#8221;.  For software development that means picking an application that people are going to want to &#8220;listen&#8221; to.  Your application version of a cover of the Macarena might not get the audience you would like, no matter how hard you work.</p>
<p><strong>Be true</strong><br />
At some level each song (and therefore each application) has an underlying essence.  Any to-do list manager needs to cover fundamentals like adding/removing items from a list.  Any photo library needs to be able to add tags to photos to classify them, etc.  The trick is to use the concept of the cover song to uncover what is the essential for your new version. What needs to exist for your users to recognise this as one of the type? And importantly for them not to dismiss it for missing something fundamental?</p>
<p>In looking for original applications you can start to diverge from the whole &#8220;application = cover song&#8221; metaphor, since with applications it is possible for what is considered the original to change.  In music the original version of Tainted Love will always be by Gloria Jones, nomatter how many people have (a) never heard of it or (b) prefer Soft Cell&#8217;s version anyway.  With applications what is considered original can vary, with first versions disappearing from view (Visicalc anyone?).  In fact it&#8217;s probably more accurate to talk less of the original application and instead talk of the definitive or archetype.  And recognise that it can change.  For example 5 years ago the original/definitive social website you&#8217;d need to study would have been mySpace.  Now it&#8217;s Facebook.  Unless you&#8217;re in Brazil where it&#8217;s Orkut (thanks <a href="http://www.oxyweb.co.uk/blog/2008/10/19/oct-2008-update-world-map-of-social-networks-around-the-world/">Oxyweb</a>).</p>
<p>In some domains, there might not be an obvious original.  In such cases the essence may be determined by reviewing multiple examples and drawing out the commonalities.  And in that regard you&#8217;re moving towards the same approach as per the backs of most software packages, each with their feature lists comparing themselves (favourably of course) with the competitors.</p>
<h2>Be individual</h2>
<p>So once you&#8217;ve determined your original, and confirmed what features/functions are needed to be true to that original, now is the time to add your own spin.  To add your personal creativity.  To make the cover version.</p>
<p>And like musicians you&#8217;ll play to your strengths.  In the same way that a Metallica cover of White Christmas is likely to include a few guitars, so a cover of the to-do list manager you create will reflect your own preferences in design, usability and approach.  As long as the underlying essence remains evident, go for it.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fisambard.com.au%2Fblog%2F2009%2F10%2F04%2Fapplication-design-is-like-recording-a-cover-version%2F&amp;title=Application%20design%20is%20like%20recording%20a%20cover%20version%20of%20a%20song" id="wpa2a_20"><img src="http://isambard.com.au/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://isambard.com.au/blog/2009/10/04/application-design-is-like-recording-a-cover-version/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

