<?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>Chris Miller &#187; Web</title>
	<atom:link href="http://chris-miller.org/archives/tag/Web/feed/" rel="self" type="application/rss+xml" />
	<link>http://chris-miller.org</link>
	<description>Life, and how to live it!</description>
	<lastBuildDate>Tue, 24 Jan 2012 14:41:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>JavaScript custom controls</title>
		<link>http://chris-miller.org/archives/2009/02/15/javascript-custom-controls/</link>
		<comments>http://chris-miller.org/archives/2009/02/15/javascript-custom-controls/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 20:19:57 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[HCI]]></category>
		<category><![CDATA[custom controls]]></category>
		<category><![CDATA[interaction]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=185</guid>
		<description><![CDATA[I spend a lot of time writing bespoke content management systems, a lot! I&#8217;m always trying to add some small, lightweight additions to make the user experience a little bit better. One means of doing this is by providing some better custom controls which give good user feedback and emulate similar offline controls. One such [...]]]></description>
			<content:encoded><![CDATA[<p>I spend a lot of time writing bespoke content management systems, a lot!  I&#8217;m always trying to add some small, lightweight additions to make the user experience a little bit better.  One means of doing this is by providing some better custom controls which give good user feedback and emulate similar offline controls.</p>
<p><div id="javascript-custom-controls_figure1" class="wp-caption alignright" style="width: 185px"><img alt="Figure 1: Ordering Control" src="http://chris-miller.org/images/ordering_field.png" title="Ordering Control" width="175" height="26" /><p class="wp-caption-text"><strong>Figure 1</strong>: Ordering Control</p></div>One such control is a linear range control, catchy I know, which allows the user to select a value within a particular range with a given default value.  An example of this may be selecting an ordering value for a blog post, <a href="#javascript-custom-controls_figure1" title="Ordering Control" onmouseover="document.getElementById('javascript-custom-controls_figure1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figure1').style.borderColor = '#d6d6d6';">Figure 1</a>, ranging from say -100 to 100 with a default value of 0.  Posts in our imaginary blog would be ordered by this ordering field ascending with 0 being the default value, resulting in posts being ordered automatically by date.  Rather than using a plain text box to allow the user to enter the ordering value directly, subsequently giving us little or no control over the contents of the field until the form is submitted and no means to convey the nature of the field itself, we can create controls to manipulate the value ourselves.</p>
<p>Creating a custom control allows us to do a number of things that we just cannot do with a normal HTML form element:<br />
<div id="javascript-custom-controls_figures234" class="wp-caption alignright" style="width: 185px"><img id="javascript-custom-controls_figure2" alt="Figure 2: Lower Bounds" src="http://chris-miller.org/images/ordering_field_lower.png" title="Lower Bounds" width="175" height="26" /> <img id="javascript-custom-controls_figure3" alt="Figure 3: Non-Default Value" src="http://chris-miller.org/images/ordering_field_middle.png" title="Non-Default Value" width="175" height="26" /> <img id="javascript-custom-controls_figure4" alt="Figure 4: Upper Bounds" src="http://chris-miller.org/images/ordering_field_upper.png" title="Upper Bounds" width="175" height="26" /><p class="wp-caption-text"><strong>Figures 2, 3 &amp; 4</strong>: Showing lower bounds, non-default value and upper bounds</p></div></p>
<ul>
<li>Display relevant information instead of certain values, such as showing Automatic at 0 in <a href="#javascript-custom-controls_figure1" title="Ordering Control" onmouseover="document.getElementById('javascript-custom-controls_figure1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figure1').style.borderColor = '#d6d6d6';">Figure 1</a></li>
<li>Show when the upper and lower bounds are reached, for example at <a href="#javascript-custom-controls_figure2" title="Lower Limit" onmouseover="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#d6d6d6';">-100</a> and <a href="#javascript-custom-controls_figure4" title="Upper Limit" onmouseover="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#d6d6d6';">100</a> as per our example</li>
<li>Allow the user to reset the value to the default or previous setting</li>
<li>Give some inkling into how the control should be used</li>
</ul>
<p><span id="more-185"></span><br />
<h3>Controls</h3>
<p><div class="wp-caption alignright" style="width: 323px"><img alt="Annotated Ordering Field" src="http://chris-miller.org/images/ordering_field_annotated.png" title="Annotated Ordering Field" width="313" height="63" /><p class="wp-caption-text"><strong>Figure 5</strong>: Annotated Ordering Field</p></div>By using JavaScript <code>onclick</code> or <code>onmousedown</code> events we can manipulate the contents of our ordering field held behind the scenes.  The addition of functions and some variables defining the bounds and the default value of our control then allows us to constrain the upper and lower limits, as we&#8217;ve seen, and to reset the field back to it&#8217;s defaults.  This gives us the following interaction:</p>
<ul>
<li>Previous/Next: update the value of the field to the previous or next value in the range</li>
<li>Reset: reset the value to the pre-defined default value</li>
<li>Display: allow us to display feedback or custom messages based on the value of the field we&#8217;re manipulating</li>
</ul>
<p>This interaction is fairly rudimentary and not very exciting to say the least.  We really want to provide more desktop-like interaction via our own custom controls such as the ability to click-and-hold a button in order to scroll through available values.  With such a control, in the majority of desktop applications, when the button is held the action that button denotes will be repeated after a short delay usually with increasing speed the longer it&#8217;s held.  We can emulate this in JavaScript using a timeout to create the pause and a modifier to decrease the length of this pause and in turn increase the speed with which the actions are executed.</p>
<p><a href="#javascript-custom-controls_snippit1" onmouseover="document.getElementById('javascript-custom-controls_snippit1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_snippit1').style.borderColor = '#d6d6d6';" title="Click-and-hold example">Code Snippit 1</a> contains a brief outline of how to create a mechanism for firing events when a button is held.</p>
<div class="code_header">
<p>
<strong>Code Snippit 1</strong>: Rough JavaScript to deal with the click-and-hold updating mechanism
</p>
<pre class="javascript" name="code" id="javascript-custom-controls_snippit1" >
&lt;script type="text/javascript"&gt;
    var timeout          = 1000;
    var timeout_limit    = 200;
    var timeout_speedup  = 1.5;
    var default          = 0;
    var lower_bounds     = -100;
    var upper_bounds     = 100;

    function setView( str, element ) {
        // Update the ordering element setting the values and
        // icons as necessary
      ...
    }

    function updateVariable() {
        // Update variable
        order        = document.getElementById( "ordering" );
        order_disp   = document.getElementById( "order_disp" );

        // Update variable
        order.value  = order.value + 1;

        // Check Bounds
        if( order.value &gt;= upper_bounds )
            setView( "upper_bounds", order_disp );
        elseif( order.value == default )
            setView( "Default", order_disp );
        else
            setView( "" + order.value, order_disp );

        // Start firing click-and-hold events
        if( timeout &gt; timeout_limit )
            timeout = max( timeout / timeout_speedup, timeout_limit );
        t = setTimeout( updateVariable, timeout );
    }

    function buttonStop( t ) {
        timeout = 1000;
        clearTimeout( t );
    }
&lt;/script&gt;
</pre>
</div>
<p><code>timeout</code> is the time between calling button events, the <code>timeout_speedup</code> modifier is used to recalculate the timeout on each event in order to increase the speed with which the event is fired.  We set a lower limit, <code>timeout_limit</code>, to ensure that the events aren&#8217;t called too quickly to update the display and to give the user time to react once they near their desired value.  A plot of time between ticks against ticks is shown in <a href="#javascript-custom-controls_graph1" onmouseover="document.getElementById('javascript-custom-controls_graph1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_graph1').style.borderColor = '#d6d6d6';" title="Time between ticks vs. Ticks">Graph 1</a>, as you can see it quickly ramps up so <code>timeout</code> is set to the lower limit, much like you would expect from a desktop application&#8217;s click-and-hold button interaction.</p>
<div id="javascript-custom-controls_graph1" class="wp-caption aligncenter" style="width: 551px"><img alt="Timeout vs. Ticks" src="http://chris-miller.org/images/timeout_graph.png" title="Timeout vs. Ticks" width="541" height="250" /><p class="wp-caption-text"><strong>Graph 1</strong>: Timeout vs. Ticks</p></div>
<p><a href="#javascript-custom-controls_snippit2" onmouseover="document.getElementById('javascript-custom-controls_snippit2').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_snippit2').style.borderColor = '#d6d6d6';" title="HTML button">Code Snippit 2</a> shows sample HTML used to create the next button with the appropriate <code>onmousedown</code>, <code>onmouseup</code> and <code>onmouseout</code> JavaScript calls to add the desired functionality to the button.</p>
<div id="javascript-custom-controls_snippit2" class="code_header">
<p>
<strong>Code Snippit 2</strong>: Button calling the events when clicked
</p>
<pre class="html" name="code">
&lt;img
    title="Next" src="images/icons/arrow_right.png" alt="&amp;rarr;"
    <!-- Update the variable and fire click-and-hold events -->
    onmousedown="updateVariable();"
    <!-- Stop the timer if mouse released -->
    onmouseup="buttonStop( t );"
    <!-- Stop the timer if the mouse moves off the control -->
    onmouseout="buttonStop( t );"
/&gt;
</pre>
</div>
<p>We use both <code>onmouseup</code> and <code>onmouseout</code> to ensure that the click-and-hold behavior ceases when the user either releases the mouse button or moves the cursor off the control.</p>
<p><div id="javascript-custom-controls_figure6" class="wp-caption alignright" style="width: 185px"><img alt="Textentry into ordering field" src="http://chris-miller.org/images/ordering_field_textentry.png" title="Textentry into ordering field" width="175" height="36" /><p class="wp-caption-text"><strong>Figure 6</strong>: Textentry into ordering field</p></div>We can extend the custom control even further and give the user a less stringent method of inputting a value by allowing them to type directly into the field in the same manner as the original textbox, <a href="#javascript-custom-controls_figure6" title="Textentry into ordering field" onmouseover="document.getElementById('javascript-custom-controls_figure6').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figure6').style.borderColor = '#d6d6d6';">Figure 6</a>.</p>
<h3>Feedback</h3>
<p>Here&#8217;s where our custom controls can really begin to shine, we can give the user direct feedback in the control that they&#8217;re manipulating in real-time.  Sure we can do this with JavaScript as it stands, but extending beyond the &#8220;red border = wrong&#8221; methodology we can give visual cues to the user to show that they&#8217;re trying to do something thata&#8217;s wrong and what specifically is wrong with what they&#8217;re doing.</p>
<p>Showing the bounds of the field is easy using the visual cues we&#8217;ve detailed in <a href="#javascript-custom-controls_figures234" title="Upper Limit" onmouseover="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#d6d6d6';">Figures 2 &#038; 4</a>.  Other visual cues we can use are that of text/background colouring to show that an error occurred.  We can also, using the same timeout methods used for the click-and-hold interaction, display <em>useful</em> messages to the user for a brief time before correcting their mistakes telling them what they did wrong and why their entries have been changed, <a href="#javascript-custom-controls_figure7" title="Error detection and correction" onmouseover="document.getElementById('javascript-custom-controls_figure7').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figure7').style.borderColor = '#d6d6d6';">Figure 7</a>.</p>
<div id="javascript-custom-controls_figure7" class="wp-caption alignright" style="width: 573px"><img alt="Error detection and correction" src="http://chris-miller.org/images/ordering_field_errorcorrection.png" title="Error detection and correction" width="563" height="36" /><p class="wp-caption-text"><strong>Figure 7</strong>: Error detection and correction</p></div>
<h3 style="margin-top: 10px;">It&#8217;s only an example!</h3>
<p><div class="wp-caption alignright" style="width: 319px"><img alt="Other possible controls?" src="http://chris-miller.org/images/controls_other.png" title="Other possible controls?" width="309" height="59" /><p class="wp-caption-text"><strong>Figure 8</strong>: Other possible controls?</p></div>Of course using such controls for an ordering field is only one example where we can extend upon HTML form elements with this simple control.  This type of control mechanism could be used for <em>any</em> field that has a linear progression in values.  Not only that, you could extend upon the functionality of this example to meet your specific requirements, by wrapping the bounds around to the start, having varying degrees of scale over numerous controls that are swapped in and out for fine or granular interaction or just have it toggle between two set values.</p>
<p>What&#8217;s the point?  There&#8217;s so much we can do nowadays in terms of interaction, even on the web.  Try to add a little bit of interactive zest to your HTML controls, it makes everyone&#8217;s experience that little bit easier and better.</p>
<p>Thanks for reading,<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2009/02/15/javascript-custom-controls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flocking</title>
		<link>http://chris-miller.org/archives/2005/10/21/flocking/</link>
		<comments>http://chris-miller.org/archives/2005/10/21/flocking/#comments</comments>
		<pubDate>Fri, 21 Oct 2005 00:06:38 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Photoblog]]></category>
		<category><![CDATA[del.icio.us]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[Flock]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://chris-miller.org/blog/index.php/archives/2005/10/21/flocking/</guid>
		<description><![CDATA[Flock, a new browsing experience?]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just downloaded and started playing with Flock, a new browser which is integrated with various types of online services like <a title="Flickr" href="http://flickr.com">flickr</a>, <a title="del.icio.us" href="http://del.icio.us">del.icio.us</a> and blogging tools like <a title="WordPress" href="http://wordpress.org">WordPress</a> (I&#8217;m actually writing this through the Flock blogging tool).</p>
<p><span id="more-117"></span>I&#8217;ve only been playing with it for a short while, but my initial impressions are that it&#8217;s pretty damn sweet.</p>
<p>It allows you to post things straight from flickr, downloading your photo stream and showing it to you, so there&#8217;s no need to go to the flickr site and grab the photo url or the code you want to paste into your post, you simply have to drag in the photo!</p>
<div class="center">
<a href="http://flickr.com/photos/86928802@N00/54432252" title="undefined"><img title="Flock Screenshot" src="http://photos28.flickr.com/54432252_778b8b5d91_m.jpg" alt="Flock Screenshot" /></a>
</div>
<p>Anyway, I&#8217;m impressed and you should get yourself a copy to try it out.<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2005/10/21/flocking/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

