By Chris R. Chapman at November 28, 2009 02:38
Filed Under: better practices, scrum, sharepoint

Recently, I was asked to make a return visit to a customer for whom I had built a customized SharePoint web app to do “refresher” round of knowledge transfer to folks who would be entrusted with support and deployment.  It was only for an hour, and in that time I did a soup-to-nuts flyby of the highlights along with some deep-dives into code when asked about particular features.

While describing the schema for an external database we’re using to gather data, one of the attendees asked me why I opted for a single flat-file and not a series of relational tables, etc. as this would alleviate “maintenance headaches” down the road.

I reminded the fellow of the theme (which I had explained in a prior session) that guided my development on this solution :  The simplest thing that worksUsing this as a “knothole” test, I triaged and pared features and design down to keep the project achievable within the 4.5 week timeframe I was alotted.  Had I chosen to modify the schema as he suggested, I’d actually have complicated my solution on the reporting end, which uses a series of pivot charts in Excel connected to the datastore.

(I should also hasten to mention that another influence on my adherence to simplicity for this project was the failure of a similar, prior solution developed by another consultant that ended up gutted and a shadow of its former self because the customer’s support team found it “too complex” and failed to perform as advertised.)

This episode brought to mind a couple of the rules of Unix design philosophy:

2. Rule of Clarity:  Clarity is better than cleverness.

6. Rule of Parsimony:  Write a big program only when it is clear by demonstration that nothing else will do.

Beyond the example of the simple, flat schema for the data store, I employed these rules throughout my design and development of the solution, leveraging as much OOTB functionality from SharePoint as I could and only treading into custom code where I couldn’t avoid it – and even then, using low-impact techniques.

Where I couldn’t build functionality in a reasonable amount of time, I recommended purchasing pre-built web parts.  Where I couldn’t find ready-made web parts for a report user interface, I built one using client-side techniques (HTML + jQuery + AJAX + SharePoint web services) that avoided creating heavy-weight, server-side code.  Where we needed adhoc reporting capabilities because the customer was unsure of how they wanted to drill into data, I recommended using Excel with a SQL connection instead of SQL Server Reporting Services.

Now, I didn’t come to these solutions immediately;  in fact, as I know from years of experience, good design emerges iteratively.  No amount of clever Big Design Up-Front planning ever yields this quality of results.  In-line with just about every engagement I’ve undertaken within MCS, had I stuck to the original plan, I’d have delivered a solution that would have been complex and substantially off-the-mark.  However, by breaking my time down into weekly iterations, I was able (with the customer’s guidance) to zero-in on the highest value features they needed while making key compromises with their blessing.

Thus, a fundamental tool for communicating these design decisions to the customer and garnering their support were my weekly demonstrations each Friday where they could see the working solution come to life and have direct input:  “Yes, I like this;  no, that totally misunderstands what that number is for;  I am disappointed we can’t do this other thing, but I now understand why – maybe we can look at this for v2.00”.

In this way I was able to enforce the Rules of Clarity and Parsimony:  “The simplest thing that works.”

By Chris R. Chapman at November 26, 2009 06:40
Filed Under: javascript, web20

Problem:  You want to render data that’s contained in a Javascript associative array on the client.

Solution:  Use jQuery and Flot, a jQuery charting plug-in.

jQuery is a Javascript library that makes writing client-side code extremely easy and quick through a “shorthand” syntax that is geared toward accessing page DOM elements and actions.  Flot is, according to its developers, an “attractive Javascript plotting library for jQuery”.  Looking over their gallery of samples, I’d have to agree:

1) Obtain jQuery from the jquery.com site and reference into your page:

<script type="text/javascript" src="/Scripts/jquery-1.3.2.min.js" mce_src="/Scripts/jquery-1.3.2.min.js"></script>

2) Obtain Flot from its Google Source repository:  http://code.google.com/p/flot/ and reference into your page. 

There’s a lot of files in there, but the ones you will want to use are jquery.flot.min.js and excanvas.min.js.  Reference these libraries into your page (after copying them into your Scripts folder) as follows:

<script type="text/javascript" src="/Scripts/jquery.flot.min.js" mce_src="/Scripts/jquery.flot.min.js"></script>

<!--[if IE]><script language="javascript" type="text/javascript" src="/Scripts/excanvas.min.js"></script><![endif]-->

Note that the excanvas.min.js library is needed for IE browsers to render the chart because it lacks a native “canvas” object.

3) Add a <DIV> element to the page that will host your chart:

<div id="chartPlaceholder" style="width:600px; height:300px”></div>

Note that the id of the DIV element will be referenced by the Flot code, so name it appropriately to keep your code readable and maintainable.

4) Build an associative array in Javascript to contain your data, eg:

var _dataArray = new Array();

Populate the array accordingly.

5) Create a method to build a Flot bar chart from your associative array data:

  function plotMyChart()

  {

  

      $.plot($("#chartPlaceholder"), [

      {

          data: _dataArray,

          bars: { show: true },

          color: "rgb(131,176,236)"

      }],

      {

          xaxis: {

          ticks: [[0.5, "Q3"], [1.5, "Q6"], [2.5, "Q9"], [3.5, "Q12"],

              [4.5, "Q15"], [5.5, "Q18"], [6.5, "Q21"], [7.5, "Q24"],

              [8.5, "Q27"], [9.5, "Q30"], [10.5, "Q33"], [11.5, "Q36"],

              [12.5, "Q39"], [13.5, "Q42"], [14.5, "Q45"], [15.5, "Q47"]]

          },

          yaxis: {

              tickSize: 5

          }

      }

    );

  

  }

6) Behold your new chart:

Flot_chart

By Chris R. Chapman at November 11, 2009 14:42
Filed Under: .net, asp.net, better practices, moss, sharepoint, software development

A quick reminder:  Say you have a SharePoint Survey List in a site that you want to populate using a console application.  Further, say that said Survey List has an Event Receiver attached to it that needs to pick up settings from the web.config file for the host web app – let’s say a connection string.

You run your console application and notice that nothing is happening – well, something is happening, just not what you intended.  A quick look in the Event Log reveals a bizarre error indicating that an object reference isn’t instantiated and it appears to be originating several lines of code before you make a call to the ConfigurationManager thus:

_connectionString = ConfigurationManager.ConnectionStrings[SQL_CONNECTION_STRING_NAME].ConnectionString;

The line that that is generating the error has nothing whatsoever to do with this line.  It is a puzzling sort of puzzle.

You decide to check first principles and see if you can trigger the event receiver by hitting the list in the browser.  Yup:  Works fine.  So what gives?

Then you remember:  Your console app isn’t running in the same context as the browser app.  Of course it can’t find the <connectionStrings> element – it doesn’t exist as far as it’s concerned.  The called code in the Event Receiver is running blind!

<foreheadSlap> Simply add a {nameOfConsoleApp}.exe.config file local to the console .exe file and stash the configuration settings from the web.config that the called code needs to find. </foreheadSlap>

I knew this, you know.  I was just not thinking clearly while debugging.

About Me

I am a Toronto-based software consultant specializing in SharePoint, .NET technologies and agile/iterative/lean software project management practices.

I am also a former Microsoft Consulting Services (MCS) Consultant with experience providing enterprise customers with subject matter expertise for planning and deploying SharePoint as well as .NET application development best practices.  I am MCAD certified (2006) and earned my Professional Scrum Master I certification in late September 2010, having previously earned my Certified Scrum Master certification in 2006. (What's the difference?)