# Monday, 17 January 2011

One can never know as much as a team knows. Learning from others is a wonderful team and individual trait.


About a year ago our team was working on an intranet project. As the lead developer and I discussed the features needed, we decided to handle some tasks on the front end with jQuery. Neither one of us had much experience with jQuery and we had a tight deadline to meet. 

The Bad & The Ugly

Since we were really under the gun we split up the work and I tackled the client side jQuery. Warning – Avert eyes now if you wish not to see be subjected to ugly code!

var Editor1 = '#Editor1';
var Editor1CountLimit = 5000
var Editor1InfoArea = '#Info';

var WhyThisStratArea = '#txtVchWhyThisStrategicArea';
var WhyThisStratAreaCountLimit = 500;
var WhyThisStratAreaInfoArea = '#txtVchWhyThisStrategicAreaInfo';

var ProgramDescriptionArea = '#txtVchProgramDescription';
var ProgramDescriptionAreaCountLimit = 1000;
var ProgramDescriptionAreaInfoArea = '#txtVchProgramDescriptionInfo';

var Activity = '#txtVchActivity';
var ActivityCountLimit = 3000;
var ActivityInfoArea = '#txtVchActivityInfo';

var OtherInfo = '#txtVchOtherInfo';
var OtherInfoCountLimit = 1000;
var OtherInfoArea = '#txtVchOtherInfoInfo';

var OutcomeMandated = '#txtvchOutcomeMandated';
var OutcomeMandatedCountLimit = 1000;
var OutcomeMandatedArea = '#txtvchOutcomeMandatedInfo';

var ServiceLevelMandated = '#txtVchServiceLevelMandated';
var ServiceLevelMandatedCountLimit = 1000;
var ServiceLevelMandatedArea = '#txtVchServiceLevelMandatedInfo';

var ChangeInLevelofService = '#txtvchChangeInLevelofService';
var ChangeInLevelofServiceCountLimit = 1000;
var ChangeInLevelofServiceArea = '#txtvchChangeInLevelofServiceInfo';

$(document).ready(function() {

    ChangeTextOnKeyUp(Editor1, Editor1CountLimit, Editor1InfoArea);

    //change the length when typed in.
    TrackKeyStrokesForTextArea(WhyThisStratArea, WhyThisStratAreaCountLimit, WhyThisStratAreaInfoArea);
    TrackKeyStrokesForTextArea(ProgramDescriptionArea, ProgramDescriptionAreaCountLimit, ProgramDescriptionAreaInfoArea);
    TrackKeyStrokesForTextArea(Activity, ActivityCountLimit, ActivityInfoArea);
    TrackKeyStrokesForTextArea(OtherInfo, OtherInfoCountLimit, OtherInfoArea);
    TrackKeyStrokesForTextArea(OutcomeMandated, OutcomeMandatedCountLimit, OutcomeMandatedArea);
    TrackKeyStrokesForTextArea(ServiceLevelMandated, ServiceLevelMandatedCountLimit, ServiceLevelMandatedArea);
    TrackKeyStrokesForTextArea(ChangeInLevelofService, ChangeInLevelofServiceCountLimit, ChangeInLevelofServiceArea);

    //setup the initial value for a text area...
    $(WhyThisStratAreaInfoArea).html($(WhyThisStratArea).val().length + ' Characters Used');
    $(ProgramDescriptionAreaInfoArea).html($(ProgramDescriptionArea).val().length + ' Characters Used');
    $(ActivityInfoArea).html($(Activity).val().length + ' Characters Used');
    $(OtherInfoArea).html($(OtherInfo).val().length + ' Characters Used');
    $(OutcomeMandatedArea).html($(OutcomeMandated).val().length + ' Characters Used');
    $(ServiceLevelMandatedArea).html($(ServiceLevelMandated).val().length + ' Characters Used');
    $(ChangeInLevelofServiceArea).html($(ChangeInLevelofService).val().length + ' Characters Used');

function ChangeTextOnKeyUp(ctl, limit, info) {

    var editor = $(ctl).contents().find('iframe').eq(1);

    $(editor).load(function() {

        //initial load, set value....
        var txt = $(this).contents().find('body').text();
        $(info).html(txt.length + ' Characters Used');

        //watch cut and paste
        $(this).contents().find('body').bind('cut paste', function(e) {
            var el = $(this);
            setTimeout(function() {
                //use a delay to wait for the text to update....
                var txt = $(el).text();
                if (txt.length > limit) {
                    $(info).html(txt.length + ' Characters Used').css("color", "red");
                else {
                    $(info).html(txt.length + ' Characters Used').css("color", "");
            }, 150);

        //watch key up
        $(this).contents().keyup(function() {

            var txt = $(this).contents().find('body').text();

            if (txt.length > limit) {
                $(info).html(txt.length + ' Characters Used').css("color", "red");
            else {
                $(info).html(txt.length + ' Characters Used').css("color", "");



function TrackKeyStrokesForTextArea(ctl, limit, info) {
    $(ctl).keyup(function() {
        var txt = $(ctl).val();
        if (txt.length > limit)
            $(info).html(txt.length + ' Characters Used').css("color", "red");
            $(info).html(txt.length + ' Characters Used').css("color", "");

    $(ctl).bind('cut paste', function(e) {
        var el = $(this);
        setTimeout(function() {

            var txt = $(el).val();
            if (txt.length > limit) {
                $(info).html(txt.length + ' Characters Used').css("color", "red");
            else {
                $(info).html(txt.length + ' Characters Used').css("color", "");
        }, 150);

function ValidateEditor1Length(source, args) {
    var editor = $(Editor1).contents().find('iframe').eq(1);
    var txt = editor.contents().find('body').text();
    var isValid = txt.length > 0 && txt.length <= Editor1CountLimit;
    args.IsValid = isValid;

function ValidateWhyThisStratAreaLength(source, args) {
    var txt = $(WhyThisStratArea).val();
    var isValid = txt.length > 0 && txt.length <= WhyThisStratAreaCountLimit;
    args.IsValid = isValid;
    /*if (!isValid)

function ValidateProgramDescriptionLength(source, args) {
    var txt = $(ProgramDescriptionArea).val();
    var isValid = txt.length > 0 && txt.length <= ProgramDescriptionAreaCountLimit;
    args.IsValid = isValid;

function ValidateActivityLength(source, args) {
    var txt = $(Activity).val();
    var isValid = txt.length > 0 && txt.length <= ActivityCountLimit;
    args.IsValid = isValid;
function ValidateOtherInfoLength(source, args) {
    var txt = $(OtherInfo).val();
    var isValid = txt.length > 0 && txt.length <= OtherInfoCountLimit;
    args.IsValid = isValid;
function ValidateOutcomeMandatedLength(source, args) {
    var txt = $(OutcomeMandated).val();
    var isValid = txt.length > 0 && txt.length <= OutcomeMandatedCountLimit;
    args.IsValid = isValid;
function ValidateServiceLevelMandatedLength(source, args) {
    var txt = $(ServiceLevelMandated).val();
    var isValid = txt.length > 0 && txt.length <= ServiceLevelMandatedCountLimit;
    args.IsValid = isValid;
function ValidateChangeInLevelofServiceLength(source, args) {
    var txt = $(ChangeInLevelofService).val();
    var isValid = txt.length > 0 && txt.length <= ChangeInLevelofServiceCountLimit;
    args.IsValid = isValid;

Ugly!  Oh ya, we’ve all seen it and we’ve all most assuredly done it at least once. :-)


So what is all this code doing? Basically only three things. It’s setting and tracking the max length allowed in a text area, updating the number of characters typed and showing a message/validating when an entry goes over it’s maximum length.

Why do all this when we can do this with validator controls? We wanted the UI to be more responsive and interactive for the users. We wanted the number of characters along with a warning to the user when they go over the limit before they try to save their work.

Now, I could give every excuse for this horrible looking code. We’ve all been here before.  Not enough time to do it right but we have to get it out the door none-the-less.  I knew the code was bad and could be improved upon.  Still, the code is ugly.

The Good

We had a new team member join our team about four months ago and we happened to be working on this project again.  His jQuery skills brought to bear on this project was just what we needed.

To fix MY monstrosity he created hidden fields tied to the text areas and got rid of the setup variables.  It may sound like we’re swapping one mess for another but it helped greatly in reducing the code needed as well as improved the readability and flow.

<asp:TextBox ID="txtWhyThisStrategicArea" cssClass="spellcheck" runat="server" TextMode="MultiLine"></asp:TextBox>
<input runat="server" type="hidden"  id="txtWhyThisStrategicAreaMaxLength" value="500" />
<input runat="server" type="hidden"  id="txtWhyThisStrategicAreaRequired" value="true" />
// Text field character counter
$('#txtProgramName, #txtWhyThisStrategicArea, #txtContactPerson).each(function () {

    var length = $(this).val().length;
    var limit = $('#' + $(this).attr('id') + 'MaxLength').val();
    var maxInfoArea = $('#' + $(this).attr('id') + 'MaxArea');
    var displayText = ' of ' + limit + '  Characters Used.';

    //set up the initial display
    if (length > limit)
        $(maxInfoArea).html(length + displayText).addClass("warning");
        $(maxInfoArea).html(length + displayText).removeClass("warning");

    //hook the keyup
    $(this).keyup(function () {
        var length = $(this).val().length
        if (length > limit)
            $(maxInfoArea).html(length + displayText).addClass("warning");
            $(maxInfoArea).html(length + displayText).removeClass("warning");


169 lines of code down to 24.  Deleting code, it’s a beautiful thing!

Knowledge, Learning and Sharing – Our Biggest Asset. 

Knowledge and learning are perhaps our biggest asset but are we open to receiving it and sharing it?

I am convinced our attitude in this arena is a huge factor of our success. We never think it’s a bad thing to go get lessons from someone better than us for other activities like learning an instrument.  Why wouldn’t we think the same way in our profession. Do we believe it will make us look weak or expose us in such a way that would jeopardize our job? It’s more dangerous to think this way than it is to actively engage with those better than ourselves to improve.

Stock Photo

Learning from others should be embraced by all.  When we close off our mind to being teachable we will suffer and so will the team.  Contributions from all team members is valuable.  Everyone from the Janitor to the CEO can provide valuable insight.  The more an individual and team thinks and acts like this the more likely they are to grow stronger mentally, improve their technical and social skills, and ultimately help produce better solutions for everyone. 

Happy Coding!

Posted 01.17.2011  #    Comments [2]  | 
# Saturday, 06 November 2010

There are a lot of things that can sink an app but none more visible, yet often overlooked, than a poor user experience.sinking

User Experience Matters

Duh, of course!  Something we all know, right? But do we take care of the UI with the same passion as we do with code?  In order to ensure the user experience remains relevant and a pleasant experience requires refactoring as well.  Like code that can erode over time, the user experience can suffer the same fate.

 The Eroding UI Example

Our team has worked on an application that’s used throughout the organization to enter requests for budget.  The application has gone through several heavy revisions over the past few budget cycles and each time we have had a very tight timeline.  It’s always been a mad rush to make the modifications necessary to accommodate the changes in the process. 

Over time, the UI slowly began to mismatch how the users worked.  The UI grew into a large form and required all the fields to be filled in before a user could save any work.  The nature of how the user worked was very different.

The user process is highly iterative and collaborative within business units who are developing requests.  They often work on one section’s wording over and over until they have it just right and then move to the next section. 

Unfortunately, the UI didn’t handle this well.  Fields that required a lot of text (several paragraphs) were forced into a small text area that had to be scrolled to read.  Users would just print a report to see all the text to get around this.  With all fields being required, users entered garbage/placeholder information into fields in order to save their work.



New ideas were introduced into the process and the application grew.  A few more forms were added.  The flow was changed so that the user was required to enter this information and save it as a separate step from the main form.  The items were required but very much felt like a bolt on and not as important.


An Aside…

Who’s fault is this?  Mine.  It’s the job of the team leader to remove barriers to success and help foster and create situations that lead to success.  It took me a few tries to get us to the point where the team could work their magic properly instead of being hamstrung by constraints that could have been better managed by yours truly. 


This year we took the time to give the application some tender loving care.  The vision was to create logical sections of information.  Maximize space utilization for the sections and move away from strict validation to a routine that would allow saving work anytime while quickly showing what is left to be completed.

The team took the vision and ran with it.



The team created a new navigation section that is very pleasing on the eyes and more visible.  The team nearly eliminated the need to scroll vertically on the page. When scrolling does occur the team floated the navigation so that it will always be at the top of the screen.  The save and cancel operation work on the entire record, versus several forms that required saving separately.  Additionally, the user can save at anytime and reduced the number of absolutely required fields down to two.



The team created tabs to group similar information into sections.  The tabs have an icon representing if that section has been completed or not. 

Additional information is in each tab to help the user.  When a tab has a green check mark the tab includes a message stating it’s complete.


If the tab is incomplete, represented by the yellow warning sign, a message is shown stating what is needed and each element on the form that needs attention has the same warning icon and it’s own message.


With “softer” validation in place the user is able to work on a request in whatever order they need to and with a glance see what is incomplete.  They can also save their work in whatever state they want.  This lends itself well to the iterative drafting process of the initial budget development cycle.

Handling large text needs was simplified by giving them their very own tab.


More obtrusive (yet nice) messaging was added to the system to help ensure the user doesn’t accidently/inadvertently do something.


The real test - What are the users saying?

In the users tests we’ve conducted we received rave reviews.  We have a few weeks to go to finalize the application and go live with the entire user community.  It’s exciting!

It’s coming along great and I am extremely pleased with the team’s redesign and the large undertaking to replace the strict validation with a softer/gentler validation technique to serve the users better.  Kudos to the team!


The UI is not immune to change and requires the same level of care that code does.  The need to develop changes can erode the UI just like code.  The UI requires our attention and needs refactoring as well to stay relevant.

Happy Coding!

Posted 11.06.2010  #    Comments [0]  | 
# Saturday, 26 June 2010

I had the misfortune and pleasure earlier this week to work in an Emergency Operations Center view from my home.  Fire is about 1 mile away.(EOC).  Early Sunday morning the Schultz wildfire broke out and moved extremely quickly towards several communities.  I was amongst 1,000 residents evacuated.  

On Monday, I was called into the EOC to help with information flow to the website and twitter.  Over the next three days I worked a little over 40 hours.  It was exhausting but it was amazing and I am proud to have been of service. 

View from friend's home.  Fire is about 1/2 mile away.



The EOC was a great example of agile even though the team responsible for the EOC didn’t plan with the agile movement in mind.  It reinforced to me that many of the principles in agile can be applied almost anywhere.




Individuals and interactions over processes and tools.
Working software over comprehensive documentation.
Customer collaboration over contract negotiation.
Responding to change over following a plan.

The EOC exemplified the manifesto.  The amount of teamwork and information flow in the room was astounding.  Emergencies rarely follow a plan and as such responding to change is paramount to a great EOC.  This EOC was incredible at adapting versus the blind following of a plan.  Wildfire can be incredibly unpredictable.  Even though the EOC had comprehensive documentation and plans for handling emergencies it clearly valued interactions, collaboration and change over processes, documentation/plans and allowed for teams and individuals to improve upon tasks and adapt to needs quickly.


Our highest priority is to satisfy the customer….

The EOC has many customers, everyone from the public to the people on the ground responding.  The central theme of the EOC was to keep the accurate and timely flow of information at peak performance.  It accomplished this with co-location of personnel, frequent and short team meetings and a constant emphasis on informal communications and information sharing.

Welcome changing requirements, even late in development….

While the EOC has practiced, ran drills, created plans and procedures for execution of an EOC, the ability to adapt was embraced over absolute following of the training and plans.

Deliver working software frequently….

In this case the EOC is delivering information and logistics.  The EOC worked on a constant cycle of information gathering and dissemination.  The EOC every few hours had a short briefing where all of the table/section leaders gave a report to the team and in between there was constant information flow.

Business people and developers must work together daily….

EOCThe EOC was staffed with expertise in each section that focused mainly on their tasks.  Also in the room were sections for leaders who would be the face for the media and citizens.  Additionally, the call center staff were only yards away from the EOC staff.  This allowed for a constant stream of communication at all levels.

The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.

This was perhaps one of the most impressive executions I found in the EOC.  The EOC was staffed EOCwith seven sections, each section was staffed with at least a couple people and as much as six.  Each section was responsible for a general task such as Public Information, Logistics, Operations, Finance, etc.  Each section had a team leader that was responsible for that section.  The interaction between sections was high.  Flip charts, whiteboards abounded along with three projectors displaying relevant but different information.   

At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.

The EOC was extremely concerned with identifying weaknesses and improving them ASAP.  For items that we knew would take longer to correct than the EOC’s existence, the issues and ideas for correction were captured electronically and have been given to staff to work on.

Parting Thoughts:

During the height of operations there were around fifty people in the room.  The energy in the room was high which aided everyone in pushing through long hours and helped keep the room charged.  The dull roar that existed in the room was hardly a distraction as each team was so intent on doing their job well.  Ideas such as co-location and transparent information flow were key to the EOC’s success much like agile proposes.  The organization of each team was self-governing and while overall leadership was provided this leadership did not get in the way of the sections.  The leadership guided and aided in keeping the teams marching forward.

My experience with the EOC was nothing short of amazing.  I feel extremely proud of how the operation center worked and found that many of the ideas and principles held by agile were key in the EOC’s strong success.

Agile | Process | Teams
Posted 06.26.2010  #    Comments [0]  | 
# Saturday, 20 February 2010

This week I dived into two books that are both 100 pages give or take.  Both are fairly easy to get through and are worthy of bookshelf space.  My purpose of reading these was to get a better understanding of two practices of applying Agile principles.  I am an agile rookie who wants to understand/learn about ideas and practices that I could add to my toolkit. 

Agile Software Development With Scrum

This was an easy read especially with it’s case study focus to illustrate the idea or practice.  I felt the “spirit” of agile in the principles and found the practices shown in scrum enlightening. 

I gained a deeper understanding of the how the scrum master facilitates and leads only.  I found it intriguing that the scrum master does not make decisions.   The master is there to coach the team and even though I understood this I didn’t connect the empowerment of the team with the master not making the decisions (A duh moment).  It makes sense that if you want to empower the team to make decisions then you have to give them the power to decide.  I could see the old school mentality in my original thought process. 

The sprint is sacred.  Nothing can/should eek it's way in. This is a big key in ensuring the team stays focused and on task (or should I say feature).  If necessary a sprint can be killed if important enough and restarted with new focus.

The team’s daily stand up are for each other and no one else; not the scrum master, product owner, etc.  A particular story caught my attention on this.  The developers when giving their report were looking at and talking to the scrum master directly.  The meeting degenerated into a project / task status update where the team viewed the scrum master as a classic project manager.  A real test of a good stand up is the team should be looking and talking to each other because they are responsible to each other.  The scrum master is there to observe and if they see something that could use some coaching they should remain silent and look to mentor sometime after but not during the stand up.

Project management is featured based not task based.   Real success is not based on the adherence to a project plan.  It’s based on the delivery of the right features with the right functionality that the customer needs.  That doesn’t mean project management or a plan is thrown out the window.

For anyone trained old school this could be a hard transition and the case studies do a good job of illustrating people who hang on to their old ways and how to remedy the situation.

Lean Software Development

  • Eliminate waste does not mean throw away all documentation.

  • Amplify learning does not mean keep on changing your mind.

  • Decide as late as possible does not mean procrastinate.

  • Deliver as fast as possible does not mean rush and do sloppy work.

  • Empower the team does not mean abandon leadership.

  • Build integrity in does not mean big, upfront design.

  • See the whole does not mean ignore the details.

    These are statements directly from the book.  I can’t think of a better way to summarize this book.  Lean strikes me as less prescriptive in it’s practices than Scrum although I could be wrong on that.  Like the agile manifesto, it gives me guiding principles but at a lower level that one can use to help create practices.

    Both books are an excellent read even if you aren’t interested in applying them.  I can’t see how you won’t come away with a least something to consider for yourself or your team.

    If you are interested in applying these practices both books stressed technical practices as a must. Lean Software Development had very good advice to get started:

    • Start with hygiene. First of all, make sure that you have basic professional software development practices in place: a version-controlled code repository, coding standards, build automation, comprehensive testing, etc.

    A major key to Scrum and/or Lean or any other agile practice is the need for good technical practices.  If you only use Scrum/Lean as yet another project management methodology you are in trouble.

    Above all, each team/environment must adapt for their situation.  These are guiding principles and practices that need real world applied to them.

    As a newbie to agile I am sure I have not understood everything right or deeply enough.  Please let me know what you think.  I like to learn from others!

  • Happy Learning!

    Agile | Books | Lean | Process | Scrum
    Posted 02.20.2010  #    Comments [0]  |