This site is a self-contained low down on what's going on in my life, what I'm working on, what I'm thinking about, and how I'm feeling about life in general.
Wednesday, 02 July 2008
I've been working on version 2 of the iPhone version of my blog. I love writing webapps for a device like the iPhone because your code is so much more direct and streamlined with out all that cross browser malarkey.
I've used the sliding tab interface that I've described in a previous post. It's a bit shaker but I'm going to work on optimizing it somewhat. Also, search, comments, categories, tags and progressive article loading have yet to be implemented.
On a side note I was really happy to have found the blog of Sacha Chua, an IBM web 2.0 specialist and evangelist. I love reading her posts, they're always engaging and insightful, and I'm supprised she hasn't featured on "a list apart yet.
Tuesday, 24 June 2008

Always trying to do something to stimulate the grey cells, I have started applying the slide demo I developed a few weeks ago to a calendar object. I'm going to be using it in a personal application I'm developing to help track my finances (The green box denotes a bit, should be red).
Â
The screenshot is in fact just a fireworks mockup. When it's finished I'm going to integrate it into the blog navigation, sweet.
Thursday, 19 June 2008
I’ve been trying to create two webparts that communicate with each other in SharePoint. Looking around the web there are a number of good examples of how to create an asp.net 2.0 webpart that communicates with another but there are a couple of things that they don’t tell you.
If you want your webparts to be able to talk to each other, you have to develop them in the same project in Visual Studio, otherwise they won’t compile. Sounds obvious enough but no-one ever actually says to do this.
Once you’ve built the provider webpart, simply add a new webpart into the solution explorer and off you go.
Another thing that is never covered for SharePoint is how to link the webparts once they’ve been developed. Firstly, click edit page, and then click the edit button on either the provider or the consumer webpart.

From here you will see connections, select send ... to, or get ... from, depending on which webpart you’re looking at. Once this relationship has been established, your webparts should communicate perfectly.
Monday, 16 June 2008
Wednesday, 11 June 2008
It's been hard to find time to get much done this week outside of work, what with rugby and spending time with Michael and Lisa, but the ideas and output are still trickling through.
Every time I look at the v3 design for Digita Solutions, I come up against the same brick wall, what do we want to offer. I keep bouncing off the web design question, do we? don't we?
It's very frustrating not having the confidence in yourself to commit to an area of the business, my initial fears were over making it pay, but I think if the quality is there then you make it pay through competitive charging for the product, but not selling yourself short.
I really do believe that once we've finished the products we have in development then we'll have the capital to start looking at different services like web design.
I'm planning something revolving around a photo gallery Silverlight application, and also setting this blog software up to post to multiple blogs simultaneously. With dual posting I can post items of consequence to other sites I maintain such as the digita solutions site. Would be great to do it form a single admin suite.
After I was deeply disappointed with the shortages of Wii's when they first came out, a few years on we've finally bought one. Lisa want's a Wii fit, which frustratingly are in as short supply as the Wii's were. Very frustrating that Nintendo seem to want to create demand for the product even greater by not supplying in sufficient quantities, and then we end up with a situation like this, where hoarders buy up a large volume of the item and sell for £120 plus on eBay. Rediculous profiteering.
I've got dentist Friday, argh, no fillings please.
It's been a slow week, but looks like things will really pick up tomorrow, may be a late night on the cards, I stayed on a little tonight, but the flexi will be useful for a long lunch in town next week I'm sure.
Monday, 09 June 2008
I've been looking at evvective and stylish ways to show off room bookings and came up with this.

The room list is static, while the internal content slides smoothly based on the timeframe selected.
I didn't use a framework, instead coding this myself.
As such I haven't had time to streamline the code yet (as usual) but it's free to use if anyone wants it.
All that's missing is adding your own code to reflect the bookings.
The full source code is available here.
Saturday, 31 May 2008

The HTML equivalent of an Anderson Shelter, a meta tag that makes IE8 render websites in an IE7 compatibility mode, has been released by Microsofts Nick MacKechnie in his blog this week.
I'm not sure whether I should say "thanks for the heads up" or "why the hell should I have to?". I mean, my site is standards based, I specify my doctype, and there should only be one way of displaying that document.
So yet again, after spending years slowly adopting web standards, Microsoft has yet again come out with a version of internet explorer that adds their stubborn feature set, prioritised above features that make it easier for developers to develop cross-browser compatible sites.
I really did think that this was Microsofts chance to build on the progress they had made with IE7, but no such luck. A couple of months ago I tried out IE8, and when I hit IBM's W3 intranet, All I got was a little blue bar at the top of the page, and nothing else. The majority of sites I've looked at with IE8 do not handle well, so this meta tag is going to be compulsary.
Perhaps Microsoft should absorb the cost that will be incurred by local business to have this line of code inserted into every page of their website, there bust be billions of pages of markup that will require changing, so profitable times ahead for web developers.
Saturday, 31 May 2008
With the summer spluttering into action slowly, I felt like redesigning the site slightly.
I say slightly, the redesign was the first job, I'm also going to be adding a few new features:
I want to add a personal status to my site. But more than just listing things I'm doing or have done, I want to break it down by location (Home, Work, In-Laws, Mums etc.) and I want to create a timeline view for the week, month etc.
I will also be adding a featured article flag to my posts to make it easier to find recent how-to's etc.
Just a small addition to let me add some greater detail to article lists such as most read posts etc.
All in all not really any ground breaking changes happening, but I want to keep the site evolving at some pace. Now I'm off to overheat in the garden.
Friday, 30 May 2008
I can honestly say that writing a .net 2.0 webpart for sharepoint 2007, that has the sole function of reading data from a database, has been the hardest thing I've ever done in my life!
It took me 14 hours through a combination of trail and error to get it working, finding very few resources online, and not being able to use the coveted visual tools available to asp.net developers. Anyway, I got there, and I'll share how with you.
To start with, the tools used. I'm using visual studio 2005, and have the wsssdk installed, the sharepoint 2007 sdk, and the wss 3.0 extenders for Visual Studio 2005.
Start up Visual Studio and create a new webpart. It'll be called webpart1 by default, lets leave it at that for now. First off, right click the project in the solution explorer, and click add reference. Scroll down and select System.Data. Once you've added this we're ready to begin.
Now, make your code look like this:
using System;
using System.Runtime.InteropServices;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Serialization;
using System.Data;
using System.Data.SqlClient;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
namespace WebPart1
{
   [Guid("493c926d-f885-4965-b72d-ee18e0292630")]
   public class WebPart1 : Microsoft.SharePoint.WebPartPages.WebPart
   {
       private string _sqlStatement = "SELECT * from tblTest";
       [WebBrowsable(true),
       Personalizable(PersonalizationScope.Shared),
       WebDisplayName("SQL Statement"),
       WebDescription("Query to return a set of data")]
       public string SQLstatement
       {
           get { return _sqlStatement; }
           set { _sqlStatement = value; }
       }
       protected override void CreateChildControls()
       {
           if (string.IsNullOrEmpty(SQLstatement)
|| !SQLstatement.ToUpper().TrimStart().StartsWith("SELECT")
|| SQLstatement.Contains(";"))
           {
               Literal lit = new Literal();
               lit.Text = "Only single SELECT statement allowed"; Controls.Add(lit); return;
           }
           DataGrid grid = new DataGrid();
          Â
           //Attempt connection
           try
           {
              Â
               using (SqlConnection conn = new SqlConnection("server=SP-TEST\\databasearea; Initial Catalog=spTest; User ID=sharepoint; Password=password; Trusted_connection=yes;"))
               {
                   SqlCommand cmd = new SqlCommand(SQLstatement, conn);
                   conn.Open();
                   SqlDataReader reader = cmd.ExecuteReader();
                   grid.DataSource = reader;
                   grid.AutoGenerateColumns = true;
                   grid.DataBind();
                   reader.Close();
                   conn.Close();
               } Controls.Add(grid);
           }
           catch (Exception exp)
           {
               Literal errMessage = new Literal();
               errMessage.Text = exp.ToString();
               Controls.Add(errMessage);
           }
       }
   }
}
Now just build the control and your webpart should be working well. Lets take a look at some of the key parts.
private string _sqlStatement = "SELECT * from tblTest";
       [WebBrowsable(true),
       Personalizable(PersonalizationScope.Shared),
       WebDisplayName("SQL Statement"),
       WebDescription("Query to return a set of data")]
       public string SQLstatement
       {
           get { return _sqlStatement; }
           set { _sqlStatement = value; }
       }
This part sets the SQL query you're about to run.
using (SqlConnection conn = new SqlConnection("server=SP-TEST\\databasearea; Initial Catalog=spTest; User ID=sharepoint; Password=password; Trusted_connection=yes;"))
               {
                   SqlCommand cmd = new SqlCommand(SQLstatement, conn);
                   conn.Open();
                   SqlDataReader reader = cmd.ExecuteReader();
                   grid.DataSource = reader;
                   grid.AutoGenerateColumns = true;
                   grid.DataBind();
                   reader.Close();
                   conn.Close();
               } Controls.Add(grid);
This part connects to the database and displays the results in a data grid. Note the server name SP-TEST\\databasearea has two backslashes, this is to counter the escape effect of a backslash.
So that's it really, tiny bit of code with big implications. Hope it opens some doors for you.
Wednesday, 28 May 2008
Lets get something straight, I hate Microsoft SharePoint.
Not because it's a bad product or it's expensive licensing, it's because I'm a web developer being bullied and backed into a corner by it.
I actually think SharePoint is good for some things, its Active Directory integration, it's ease of use and powerful feature set, but it should know it's place.
Microsoft may lead you to believe that it's all powerful with it's Master Pages and .net 2.0 framework construction, but in truth, it is not a good platform to build custom applications into. Even what should be a no brainer for something so powerful, connecting to an SQL database and returning tabulated data, is an absolute chore of the highest calibre.
I'm tasked with building bespoke solutions for a SharePoint portal, and the only way I can do this is through what are called webparts. These webparts are actually quite powerful, if a little limited, in that to build a multi-page application, you need to build lots of webparts and piece them together in multiple sharepoint pages.
It's a total bind, but I'm warming to them, looking at the positives I can deploy a web part across a huge number of different web portals very quickly, without duplicating any code. That's it for the positives so far, I'll let you know how I get on....
Monday, 26 May 2008
I'm not really used to having bank holidays off. I've always taken them as days in lieu, after all it usually rains anyway. Working for the local authority now, however, means I no longer have the luxury of a quiet day in work and an extra days holiday.
As bank holiday weather goes, today was pretty attrocious. It was blowing a gale when I went shopping with Michael. The struggle I had to get him into a trolley in the middle of a hurricane only bolstered my respect for single parents (Men and Women alike).
The shopping complete I pretty much had an open day. We took it easy, I cooked food and did some cleaning, nothing special, apart from spending some really nice time with Michael and Lisa.
Work-wise, I managed to amalgamate a couple of tutorials into a multi-language asp.net application. This is good because it sets the stage for the VLE I'm writing (or will be once I work out how to install SQL server on vista!).
Monday, 26 May 2008
I thought that a new job and a new baby together would be a clean break all-round. As it turns out it's about the hardest thing I've ever been through, and on top of it all I've got a cold.
But enough moaning, on to some updates.
Firstly, week two at work is over, and things are getting better! More structure, more idea where things are going, more settled and more vision for the future.
On the back of work, I'm learning asp.net, amongst other things. I always knew it would be a huge leap going from asp 3.0 to .net, and there is that ever-present, inherent fear of the unknown to contend with. Now I have no choice but to learn it, and thankfully it's not as hard as I thought. In fact I'm enjoying it, which definitely helps.
Outside of work it's been a tough week. The amount of work that goes into raising a baby is starting to sink in and take its toll, and I'm only doing a quarter of the work (if that). Lisa has been amazing taking care of him, but it's still draining. You just don't have time for anything, and sometimes knowing that just eats away at you, even if you don't have anything to do anyway. I can only update my blog at crazy times of day. It's a tough lifestyle change but I'm getting used to it. Single parents have more than my admiration, they have my vote for sainthood.
The run of failing electrical items has progressed today as I ordered a replacement fridge freezer. The old one doesn't keep milk for more than a couple of days, bugger. That's now the Xbox, the Camcorder, The Tumble dryer, and the washing machine that have bitten the dust recently, as if things weren't strained enough.
Another positive is that I found a little motivation, and a little time to start working on a few project ideas. Unfortunately I have little of both and things haven't worked out very well so far, but progress is progress. I want to build something to help me save money, and will probably make it into a web service, all singing all dancing. I'm also working on a VLE of my own, probably open source. Hopefully it will be my first asp.net project release, although I plan a php version also.
Well the room is starting to rock back and forth which means one thing, need sleep.
Monday, 19 May 2008
From brain surgery to killing someone with your little finger, it's possible to teach yourself anything if you approach it in a structured manner.
My personal experience comes from what I've done in IT and how I've taught myself to do numerous things from 3D Design to PHP Programming. There is a definite and easy structure to follow.
Learning technical subjects in an educational institution occurs as part of a curriculum, nothing more, so the skills you are taught, and hopefully taught well, will no doubt be severely depleted when you actually come to use them. The best time to learn any IT skill is when you need it.
The best learning is born out of necessity, it ensures you're 100% focused on what you're about to learn, and will remember it better because you're putting it straight into practice.
When it's time for you to learn something, and you're going to teach yourself, you need to do some initial homework on the subject. The internet is a great resource for training, but it can be difficult to find consistent material. Personally, I love lynda.com, their training is top notch and the basics are free, which is what you're concerned with at the outset.
Alternatively, find a book that gives a beginners approach to your particular subject. You'll need to ensure you have the fundamentals nailed, this usually only takes a few hours to get through though.
Once you have a foundational understanding of the subject, you need to define what it is you’re trying to do. Once you know what the task is, you need to break it down into real world actions. For illustrative purposes, let’s imagine we’re creating a web application. Firstly, break the project into its high level sections, which may be:
Now pick the area you want to focus on first and break that up into its major parts, lets choose administration:
Again, pick a section and drill down on it, let’s take the add user path. Because this section has tangible flow, with actions and results, we will look at the actions that occur in the flow:
Doing this is half the battle because now you’re in a situation to start programming. For our example, Page 1 requires the creation of a html form. Page 2 requires a database connection, and Page 3 a simple HTML written confirmation of the action.
Because of our analysis, we now have some research to do, how to insert data into the database from a submitted form using x language, how to redirect to another page once that is done.
Most people start their search for answers at Google. Search for what you need rather than how you think it would be written, so if you need to insert into an sql database using asp, search for “Insert into an sql database using asp”. This will yield the results you need. Failing that you could try either Yahoo! or Google answers, although, if you don’t mind paying a small premium, Experts Exchange is always my destination of choice for fast, accurate responses.
Once you’ve complete one task, move through the entire project in this way and take it one step at a time. The old adage of breaking your problems into smaller pieces to make them easier to manage is applicable to most things in life and is just as relevant to programming.
Friday, 25 April 2008
I recently wrote about how to create a bar graph using the <canvas> tag in html. This was more of a theory article, so as promised, here is the substance.

Start by creating your html body as follows:
<body onload="buildChart();">
<div class="chart">
<div id="label_container" style="position: relative; margin: 20px auto; display: inline-block;">
<canvas id="canvas" width="400" height="200"></canvas>
</div>
</div>
<table id="mydata">
<tr> <th>Customers</th><th>Value</th> </tr>
<tr><td>Design</td> <td>2</td> </tr>
<tr><td>Enquiries</td> <td>5</td> </tr>
<tr><td>Home Screen</td> <td>1</td> </tr>
<tr><td> Navigation</td> <td> 4</td> </tr>
<tr><td> Projects</td> <td> 6</td> </tr>
<tr><td> To-do</td> <td> 9</td> </tr>
</table>
</body>
The table contains the data used to build the chart, this can be built dynamically which is really useful for reports etc.
Now lets start on the javascript to build our chart. Firstly, lets start working with our buildChart function.
function buildChart(){
// source data table and canvas tag
var data_table = document.getElementById('mydata');
var canvas = document.getElementById('canvas');
var td_index = 1; // which TD contains the data
var max_value = 0;
var ySegmentCount = 5;
Here, we've defined our variables for the table, the canvas and specified the column that contains the values for our graph. max_value will be set to the largest of the values, and ySegmentCount contains the number of values to be listed horizontally.
I've defined a fixed pallet for this example, however you can easily adapt this to use a dynamic pallet, I just like to control the colours used.
var myPallet = new Array();
myPallet[0] = "#2A416A";
myPallet[1] = "#39588E";
myPallet[2] = "#4572AD";
myPallet[3] = "#688BC3";
myPallet[4] = "#8EA6D2";
myPallet[5] = "#B2C3DF";
myPallet[6] = "#CCD8EA";
myPallet[7] = "#DDDBFB";
myPallet[8] = "#F0F0F0";
myPallet[9] = "#2A416A";
myPallet[10] = "#39588E";
myPallet[11] = "#4572AD";
myPallet[12] = "#688BC3";
myPallet[13] = "#8EA6D2";
myPallet[14] = "#B2C3DF";
myPallet[15] = "#CCD8EA";
myPallet[16] = "#DDDBFB";
myPallet[17] = "#F0F0F0";
Next we retrieve the chart values and calculate some parameters.
var tds, data = [], color, colors = [], value = 0;
var trs = data_table.getElementsByTagName('tr'); // all TRs
for (var i = 0; i < trs.length; i++) {
tds = trs[i].getElementsByTagName('td'); // all TDs
if (tds.length === 0) continue; // no TDs here, move on
// get the value, update total
value = parseFloat(tds[td_index].innerHTML);
if(value > max_value){ max_value = value; }
data[data.length] = value;
// Assign color
color = myPallet[i];
colors[colors.length] = color; // save for later
trs[i].style.backgroundColor = color; // color this TR
}
var itemCount = trs.length-1;
var yIncrement = max_value / ySegmentCount; //determine increment between y axis increments
var barWidth = (canvas.width - (10 * (itemCount * 2))) / itemCount;
var yIncrementPixels = (canvas.height - (2 * (ySegmentCount * 2))) / ySegmentCount;
We now know how wide to make the bars based on the canvas width and number of items, and also the distance between value markers.
We now need to prepare to draw our bar graph, we start by preparing the variables.
var ctx = canvas.getContext('2d');
var canvas_size = [canvas.width, canvas.height];
var backSoFar = 2;
var ySpanPosition = 0;
var yTotal = max_value;
backSoFar contains the vertical (y) start position of each background block. This starts at 2 to create a slight gap at the top. ySpanPosition contains the vertical position of the span containing the axis value.
Lets render the background.
for(i=0; i<ySegmentCount+1; i++){
if(i==ySegmentCount){
yTotal = canvas.height-8;
var labelContainer = document.getElementById('label_container');
var oSpan = document.createElement('span');
var oLabelText = document.createTextNode('0');
oSpan.setAttribute('style','left: -50px; top: '+yTotal+'px; position: absolute; font-size: 60%; z-index: 100; background: none; width: 45px; display: block; text-align: right;');
oSpan.appendChild(oLabelText);
labelContainer.insertBefore(oSpan, labelContainer.lastChild);
}else{
backSoFar += 2;
ySpanPosition = backSoFar -8;
ctx.fillStyle = '#E7EEF6';
ctx.fillRect(0,backSoFar,canvas.width,yIncrementPixels);
var labelContainer = document.getElementById('label_container');
var oSpan = document.createElement('span');
var oLabelText = document.createTextNode(yTotal.toFixed(2));
//var oLabelText = document.createTextNode('sdfsg');
oSpan.setAttribute('style','left: -50px; top: '+ySpanPosition+'px; position: absolute; font-size: 60%; z-index: 100; background: none; width: 45px; display: block; text-align: right;');
oSpan.appendChild(oLabelText);
labelContainer.insertBefore(oSpan, labelContainer.lastChild);
yTotal += -yIncrement;
backSoFar += yIncrementPixels;
backSoFar += 2;
}
}
Change the value of ctx.fillStyle to set the background colour. Now for our final block for javascript in this function, we render the bars themselves.
var sofar = 0; // keep track of progress
// loop the data[]
for (var piece in data) {
var percentHeight = (data[piece]/max_value)*100;
var pixelHeight = (canvas.height-4)*(percentHeight/100);
var barFloor = canvas.height - pixelHeight; //subtract bar height from canvas height to get ground level;
sofar += 10; //add left margin
//ctx.beginPath();
ctx.fillStyle = colors[piece]; // color
ctx.lineWidth = 4;
ctx.strokeStyle = '#FFF';
ctx.shadowBlur = 3;
ctx.shadowColor = "#999";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.strokeRect(sofar,barFloor,barWidth,pixelHeight);
ctx.shadowBlur = 0;
ctx.shadowColor = "#333";
ctx.fillRect(sofar,barFloor,barWidth,pixelHeight);
//Add labels
var xLabelPosition = sofar;
var yLabelPosition = canvas.height + 10; //add span height
var labelContainer = document.getElementById('label_container');
var oSpan = document.createElement('span');
var oLabelText = document.createTextNode(data[piece]);
//var oLabelText = document.createTextNode('sdfsg');
oSpan.setAttribute('style','left: '+xLabelPosition+'px; top: '+yLabelPosition+'px; position: absolute; font-size: 60%; z-index: 100; background: none; width: '+barWidth.toFixed(0)+'px; display: block; text-align: center;');
oSpan.appendChild(oLabelText);
labelContainer.insertBefore(oSpan, labelContainer.lastChild);
sofar += barWidth;
sofar += 10;
}
}
After calculating the positioning of the bar, we create 2 rectangles, the first is white and has drop shadow, the second is the coloured bar. Then we access the DOM to create the span labels and position them appropriately. The 10 value added to the sofar variable spaces the bars 10 pixels.
Finally, some css to make sure everything displays as required.
canvas { background: #fff; border-bottom: 1px solid #ccc; }
.chart {
position: relative;
display: block;
text-align: center;
background: #FFF;
padding-bottom: 10px;
padding-top: 10px;
}
span { font-family: Arial, Helvetica, sans-serif;}
So there we have it, a low bandwidth bar graph that looks great and is totally dynamic. I haven't had time to make the code as efficient as possible but it definitely does the job. I hope you find this useful.
Monday, 21 April 2008
Web standards is a passion of mine. They are the guidelines set down for a document type, and should be followed. Being a devout standards follower can bring you kudos and appreciation, but your efforts may be let down by the web browser used to view the site.
Poor support for web standards in Internet Explorer mainly, and older versions of Safari, amongst others, means that your site may loose much of it's shape and pizzaz.
Until now, the challenge of the web designer has been to tailor their styles and code to be cross-browser compatible. Ultimately, you may have to reign back some of your design and functionality, sacrificing the overall product, but what if the situation was turned upside down.
Imagine if some of the biggest websites started blocking browsers that would not display their site correctly? It's not unheard of for a site to carry a disclaimer that it will only work properly in Internet Explorer, but you just do not see complete blocking at browser level, and because of this, there is no incentive for Microsoft to release patches for their slightly older browsers (which still dominate the browser demographic).
This type of motion would have to be started by a major site, one that could sway enough opinion and also encourage more users to upgrade, faster than if the smaller sites embarked on such a mission.
Legally, the site ultimately has impunity from prosecution on the grounds of discrimination because the browsers are not technically capable of displaying the content correctly and consitently, and therefore can be blcoked from viewing the content.
Morally, there is always going to be the desire to be open to all, but I think a day will come when major sites will force a browser upgrade before granting access.
Technically, there is a level of satisfaction derived from creating a site that renders near identically on multiple browsers, but the time it takes to achieve this compatibility, and time is money.
Sunday, 13 April 2008
I currently use a rich text editor called Tiny MCE to write the articles for this site. When I started using it, I thought it was the bees knees, but I've come to find it has more than its fair share of drawbacks.
For one, I find myself circumventing it more and more, it strips my code tags, removes / from the beginning of internal links, and completely strips http://www.mattknott.com/ which can be annoying when you are referencing content from multiple locations!
In addition to all of this, I go into html mode a fair bit adding in syntax to try and maintain xhtml 1.0 strict adherence. There has to be an easier way.
This week I'm going to have a stab at a solution based around tag suggestion, similar to the Dreamweaver code editor, triggered by <, a list of tags appears, and refines as I continue to type. Clicking a tag will insert the text I want, the way I want it, including alt tags and title tags for images and links respectively.
I will post an update as to how I get on, as it's going to be a bit of a challenge, but with any luck it'll be something to expand upon in the future.
Sunday, 13 April 2008
I recently wrote about how I'd modified a great example of creating a pie chart using the canvas tag and javascript. I've now written a bar graphing function based on the same principal of dynamically building the chart from tabulated data and building it to the size of the canvas tag.
This will form part of a charting component I'm writing, and although this example only builds a simple bar graph, the finished product will let you compare multiple bar values, plot trend lines, line graphs and scatter graphs. It's just a matter of doing it and making it more flexible.

I'll upload the source code once I've streamilined it a bit, the features are:
Source should be up later in the week, good night all.
Sunday, 13 April 2008
In any information-based website, it's important to remember that people will possibly want to print your information off.Â
This could be for any number of reasons, passing to a friend, saving for your own purposes, or supporting a business case to buy a product.
When they do, they will get a mess, bits of navigation, images, cut off text. The end result is you or your customer lose business, or look unprofessional.
To fix this, use a print stylesheet. A print stylesheet is used only when printing and lets you sweep navigation and other unwanted information under the carpet.

If you're viewing this article on it's own, go to print preview and see what happens. All the navigational elements go and you're left with a nicely formatted document ready to print (Aside from the google ads which I haven't hidden yet).
Creating a print stylesheet should be the last thing you do, that way you're not constantly changing it through the project lifecycle.
When you are ready to implement your stylesheet you can add it in one of two ways. To include the stylesheet using the LINK object:
<link href="css/print.css" rel="stylesheet" type="text/css" media="print" />
Or to use inline styles use:
@media print {
/* style sheet for print goes here */
}
Either way achieves the same result. When compiling your print stylesheet, use display:none; to hide individual elements.Â
Ensure any content containing div's are set to full width so that the full page is utilised.
Finally, consider colours, not all browsers allow background printing, you should bear this in mind. Minimise the use of colours in your page to improve the reproduction on laser printers.
Providing a drastic change from screen to page can set you apart from competitors and give you that slight edge. It's a little detail that can make a big difference.
Friday, 11 April 2008
When building an accessible standards-based website, many developers feel it is sufficient to pass their pages through the w3c page checkers for xhtml etc. It is fairly important for your pages to pass these tests as much as possible, however, I believe that you need to go beyond the standards and look at whether or not your markup is suitable for purpose.
What I mean by this is that you need to look at each element on your rendered webpage and ask yourself if you've used the correct markup to display it. Often, designers will use spans to list items, instead of a list object, or div tags to display tabulated data instead of a table.
Whenever you want to display tabulated data, do not be afraid to use a table. The witch hunts of the CSS revolution focused on the use of tables for page layout and structure, but used correctly they are still the most effective way of displaying your data in a flexible grid layout. The question is are you coding your tables correctly? The traditional method of creating a table was as follows:
<table>
<tr><td>Header 1</td><td>Header 2</td></tr>
<tr><td>Metric 1</td><td>100</td></tr>
<tr><td>Metric 2</td><td>200</td></tr>
<tr><td>Metric 3</td><td>300</td></tr>
</table>
This works, but the best practice for creating data tables is:
<table>
<thead>
<tr><th>Header 1</th><th>Header 2</th></tr>
</thead>
<tbody>
<tr><td>Metric 1</td><td>100</td></tr>
<tr><td>Metric 2</td><td>200</td></tr>
<tr><td>Metric 3</td><td>300</td></tr>
</tbody>
<tfoot>
<tr><td>Total</td><td>600</td></tr>
</tfoot>
</table>
This approach makes your code easier to understand by both screen readers and developers alike, plus when css is turned off, your data retains it's structure.
Â
When you cast a critical eye over your site, you might notice that many of your page elements are actually lists. Site navigation is a list of destinations, likewise site maps are better displayed in a list object, about us pages often list statistics. These are all comment situations where list object should be used but are not.
You can craft an effect top level navigation using an unordered list:
<ul>
<li><a href="home.php">Home</a></li>
<li><a href="blog.php">Blog</a></li>
<li><a href="contact.php">Contact Us</a></li>
<li><a href="links.php">Links</a></li>
</ul>
The magic then happens within the CSS.
ul {
display: block;
width: 100%;
overflow: hidden;
list-style: none;
margin: 0px;
padding: 0px;
}
ul li{
display: block;
float: left;
overflow: hidden;
margin: 2px;
padding: 0px;
}
ul li a:link, ul li a:visited {
display: block;
margin: 0px;
padding: 15px;
}
ul li a:hover {
display: block;
margin: 0px;
padding: 15px;
background-color: #CCC;
}
These are just two common areas of markup that are overlooked, but there are many more, It's worth brushing up on the markup available to you so that you can ensure you always choose the best markup for the purpose.
Friday, 11 April 2008
After spending some time today looking into ways to insert HTML tags into textareas on iPhone, I decided to knock up a quick editor for this site based around the insert at cursor position model as discussed in the previous article.
This post is the first real test of it's function. The biggest problem is scrolling up and down the textarea, it's extremely difficult.
To accentuate the positives however, it can insert the tags I mainly use, such as paragraph, bold, and code. Also it's better than typing it manually. I'm going to try using a two finger scroll to move the textarea.
Roll on firmware 2.0 and the copy and paste feature. For now though, here's how it's done.
function insertAtCursor(myField, myValue) {
if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
}
To call the function, I pass in a reference to my textarea object, followed by the text to insert.
<span onClick="insertAtCursor(document.getElementById('articleBody'), '<p></p>');">P</span>