A Simple Validation Framework with KnockoutJS

11. January 2012 by Tony

In my current side project, I am using KnockoutJS as the “backbone” of the site. I really like how I am able to very easily data-bind certain elements to their equivalent javascript variables without needing to give these elements some reference-able distinction such as an Id. Unfortunately, out of the box KnockoutJS does not offer some sort of validation framework to validate observables. In this post, I hope to show you a simple little framework that I’ve built to help me validate form elements.

Why not just use JQuery Validate?

  • I’d have to wrap all my input elements within a form tag, even if it’s just an AJAX call.
  • Each input element would need a “name” attribute
  • KnockoutJS offers a ViewModel approach, I just want to build a model, and simply check if that model is correct. No $(‘#myForm’).valid() but along the lines of myModel.isValid(). This way I don’t mix in too much HTML-dependent code into my javascript code file. The separation of concerns is beautiful.

The Solution

The validation framework consists of two parts:

  • The validation extensions (using KnockoutJS extenders)
  • A base view model

Validation Extensions

To set up my validation rules, I use KnockoutJS’s extenders to augment our observables with validation properties.

Validation Rules Container
The first extender we’re writing will hold all the validation rules for our given observable.

ko.extenders.validation = function (target, modelValidationContainer) {
    // array of all rules for the given observable
    target.rules = [];

    // check the observable against all attached validators
    target.isValid = function () {
        var validSoFar = true;
        var i = 0;
        while (i < target.rules.length) {
            if (!target.rules[i]()) {
                validSoFar = false;
            }
            i += 1;
        }
        return validSoFar;
    };

    // push valid checking function to the model
    modelValidationContainer.push(target.isValid);

    return target;
}

Important parts of the code include

  1. target.rules = [];

    This will hold all the rules associated with the observable

  2. modelValidationContainer.push(target.isValid);

    This exposes our function that checks if the observable is valid for all rules to the model.

A Validation Rule
Here is a simple (required field) validation rule that can be attached to our container above.

ko.extenders.requiredValidation = function (target, validationMessage) {

    // subobservables that can be bound to HTML elements
    target.displayRequiredError = ko.observable(false);
    target.requiredValidationMessage = ko.observable();

    // The actual validation logic
    var validate = function () {
        if (target() == null || target() == '') {
            target.displayRequiredError(true);
            target.requiredValidationMessage(validationMessage ? validationMessage : "This field is required.");
            return false;
        }
        else {
            target.displayRequiredError(false);
            return true;
        }
    };

    // Add it to our validation rules container
    target.rules.push(validate);

    // Everytime the observable change, validate it
    target.subscribe(validate);

    return target;
}

Important parts:

  1. Subobservables - This is where we can bind HTML elements to various validation intricacies. For example, the
    displayRequiredError

    can be bounded to an html element that is visible dependent on whether or not the observable is valid according to that rule.

  2. Subscription -
    target.subscribe(validate)

    . It's critical that we subscribe our validate method to changes to the observable, so that it may revalidate on the fly.

  3. Rules Container -
    target.rules.push(validate);

    Adding it to our rules container so that the rule's validation logic will be executed when isValid() is called.

The Base Model
One of the primary goals of this solution is to be able to just do

myModel.isValid()

To enable us to do this, we will need some predefined validation rules checking mechanism that validates all observables with their sets of rules. This is something that will be reused over and over again in multiple models, so it is best to create a "base model" from which all viewmodels may "inherit" from.

var BaseModel = function () {
    var self = this;

    this.validationContainers = [];

    // Iterate through the validationContainers of all
    // the observables with validation rules and check
    // validity
    this.isValid = function () {
        var validSoFar = true;
        var i = 0;
        while (i < self.validationContainers.length) {
            if (!self.validationContainers[i]()) {
                validSoFar = false;
            }
            i += 1;
        }
        return validSoFar;
    };
};

And here's a sample ViewModel that inherits from this basemodel

var login = function (baseModel) {
    if (baseModel == null) {
        baseModel = this;
    }

    var self = baseModel;

    self.userName = ko.observable('').extend({ validation: self.validationContainers, requiredValidation: "Username is required." });
    self.password = ko.observable('').extend({ validation: self.validationContainers, requiredValidation: "Password is required." });

    self.login = function () {
        // calling the basemodel's isValid() method
        if (!self.isValid()) {
            console.log('not valid');
        }
        else {
            console.log('valid');
        }
    }

    return baseModel;
};

ko.applyBindings(login(new BaseModel));

* Note that the validation extension has to be first before any rules

And here's a sample binding on the HTML side:

<label>
    Username<br />
    <input type="text" class="full-width" data-bind="value: userName" />
    <span class="error" data-bind="visible: userName.displayRequiredError, text: userName.requiredValidationMessage"></span>
</label>
<label>
    Password<br />
    <input type="password" class="full-width" data-bind="value: password"/>
    <span class="error" data-bind="visible: password.displayRequiredError, text: password.requiredValidationMessage"></span>
</label>

Demo

Here's a working demo!

Tags: , , 1 comment

Performance Tuning GPR using CDN for Common JS files

19. July 2011 by Tony

I decided it was time for me to do some performance tweaking on GPR to not only reduce server load, but to also reduce page load time for better user experiences. The tactic that I will be using today is instead of serving common javascript libraries on my server, I will be referencing publicly available CDN’s. Google’s for Jquery and JqueryUI, and CDNjs.com for Modernizr.

Main Page: http://www.greatphotorace.com
Specific Page: http://www.greatphotorace.com/entries/specifically/ebc9aa39-3841-4b90-ae1d-30ece73c5496

First, let’s take a look at how long it takes to load the two above pages. Keep in mind that I am using loadimpact.com to test how long it takes to load these pages. The originating request is from Sweden, so US users (my main demographic) will experience faster load times (due to lower latencies.) I would like to also not that this is how long it takes to “fully load.” Most browsers will have rendered most of the site before for example, all the images are loaded. So the user may very well see that it only takes 0.5 seconds to get something on the screen.

Before…

Before the optimization:

Main Page: 4.24s
Specific: 2.48s

Main Page Load Time Before OptimizationSpecific Page Load Time Before Optimization

After…

After the optimization:

Main Page: 3.34s (-0.9s)
Specific: 2.12s (0.36s)

Main Page Load Time After OptimizationSpecific Page Load Time After Optimization

Parallelism at its best! Next up, put up the photo entries on a CDN?

Not bad for a relatively quick performance tweak (took me 5 minutes.)

Tags: , Leave a comment

What I am getting out of GreatPhotoRace

06. July 2011 by Tony

In talks with numerous amounts of people, a lot have asked, “what do you hope to get out of GPR?”

Of course it’s all about building a good startup
I want to disrupt the photograph distribution sector. In achieving this goal, I will need to first build a big photographer network, this is what phase 1 of GPR is trying to achieve.

… but most importantly, it’s a test of ability
I know that I can build great sites. But before heading to San Francisco, I want to know what my limitations are. If I were to hire cofounders and employees, I need to know what I need help with and what I’m not good at.

I am hoping to answer these questions:

  • How is my ability to translate user feedback and requests into product decisions? and how quickly can I iterate?
  • How good am I at securing and maintaining key connections (including investors)?
  • How well can I find and secure new customer demographics? How am I measuring conversion and what am I doing to improve them?
  • What is my mental state after certain ups and downs?
  • and most importantly, how business savvy am I? Am I just a code monkey? Can I be an effective decision maker and business leader?

Look out for a followup post before I make the big move to Silicon Valley.

Tags: , , , Leave a comment

GreatPhotoRace UI Demos

19. April 2011 by Tony

Not only do I want GreatPhotoRace to be a purposeful website for photographers of any level to unravel their creative potential, I want the website to be as usable and interactive as possible. So far, there are two neat interactive elements that’s going to be in play at GPR. They are:

  • Lazy Loading of Pictures, so people don’t have to “refresh the browser.” All they have to do is scroll. People don’t read pages, they scan, and they scan really well. This UI element plays on that key notion. See the demo here: http://demos.greatphotorace.com/Default/LazyLoadSlide
  • A tag cloud display. In boosting topics for the subsequent week, I want the users to be able to see at a glance all the tags in a sort of montage’ish view. I want them to be able to play around with the topics, drag it, shoot it directions. It’s a creative, fun, and exploratory process. See the demo here: http://demos.greatphotorace.com/Default/Cloud. Tip: Drag the topics, and double click on them even!

All tutorials for these demos will be posted sometime in the future. More than likely when I have the majority of GPR completed. Stay tuned!

Tags: , , , , Leave a comment

Great Photo Race Designs

13. April 2011 by Tony

General design for GPR has been completed! There might be some future tweaks, but this is generally what it will look like. Check it out below and let me know what you think:

Front Homepage
Photo entry page

Notable UI Elements

  • Lazy loading of photo entries at the bottom.
  • Large number at top right to signify the number of boosts you have remaining

Kudos to Jim D’Amico for the work. He is a genius designer.

Tags: , , , Leave a comment

Snapping to it: An online photography competition

08. April 2011 by Tony

I am an amateur photographer. I like taking pictures of things, post-processing it to add my own “rose-colored lens.” I think it’s fascinating to be able to capture a moment of history, emotions, and cultural contexts. Photography is a very rewarding hobby and when you start getting good at it, you’ll start to see the beauty in all the things around you. But when starting out, you just don’t have this level of appreciation that provides motivation to keep on snapping photos. What’s a good solution to overcoming this hump? Competition. I’m a naturally competitive person and for awhile, I’ve scanned the internet landscape for some sort of regular photography competition. There wasn’t really anything that I’ve found to contain the following features:

  • A regular photo competition with a pre-selected topic
  • Ability to critique photos as they come in, in an organized fashion.
  • A way to “follow” a photographer more easily to see how he/she interprets a several topics.

Sure you may say there are plenty of photography forums out there that hold photography contests. But these photography forums, although very resourceful, aren’t catered for this kind of thing. Think LinkedIn vs Facebook. LinkedIn is more focused on a specific niche.

So introducing….

The Great Photo Race

This is my newest startup and it’s strictly dedicated to competing for the best photo in a pre-selected topic. Here are some of the major features:

  • A weekly competition based on a pre-selected topic.
  • Topics are selected the prior week by internet users through voting
  • An incentive model that distributes $100 per week to the best photos
  • Ability to follow your favorite photographers to see how they interpret certain topics.
  • See all photo entries and all the insightful comments on how it was captured.

More to come, including details on incentive models, designs, and exit strategies (if exiting).

P.S. Shout out to my friend, Jim D’Amico, for the awesome tagline… “Snap to it.”

Tags: , , Leave a comment

Startup Developers includes .NET too

31. March 2011 by Tony

In response to this post by the CEO of Expensify: CEO Friday: Why we don’t hire .NET programmers

As a .NET developer, I am quite insulted.  The CEO of Expensify makes the assertion that all .NET developers are akin to  food service workers found at McDonalds who simply push a couple of flashing buttons and out comes some kind of burger.  He incorrectly believes that the .NET platform (which he incorrectly refers to as a language, and has the audacity to demeaningly call  it dandy) is so entirely inflexible that it can only produce the metaphorical 1.6oz burger and when asked to produce a 1.7oz burger that it is entirely incapable.   I don’t care if he chooses to not hire .NET developers, but when he  publicly posts baseless incorrect reasons why, I find it insulting to not only myself, but to the entire community of very talented and capable .NET developers.

.NET can be as flexible as you want it to be.

Despite what this CEO might say, the .NET framework is one of the most extensible frameworks out there.  If you don’t like the way a certain thing is implemented, feel free to override it or extend it.  Microsoft is not forcing you to use their libraries.  If I decided that I wanted to make a 1.673 oz burger, I damn well can.  I can even dig right into the memory (see C# pointers) if I wanted that much control.  But a lot of times, I don’t want that level of control, because I’m interested in rapid application development (RAD).  I am not interested in a 2-year development plan that involves re-inventing the wheel, but in a 3 to 6-month development plan where I can get things out quickly, get feedback from my audience, improve it, and re-pivot my business model if necessary.

I find it quite funny that Expensify’s CEO incorrectly asserts the inflexibility of the .NET Framework but fails to mention other  RAD frameworks such as CakePHP or Ruby on Rails.

I will admit that Microsoft’s development tools are so damn good that through various UI automation tools, you can create a website without a lot of knowledge of the underpinning technology.  Developers who rely on these tools can be justifiably called code hacks.  But not all .NET developers are code hacks, they can choose to be if they want, or they can dig deeper if so desired, or if business requirements demand it.

What are characteristics of a good developer for startups?

What Expensify’s CEO should instead look for is not so much if a developer knows or prefers .NET over other web technologies, but if he has the following characteristics:

  • Good Problem Solver. First and foremost, he must understand functional/high-level requirements and be able to develop solutions to meet them.  He needs to have a good balance of the forest and the trees to develop custom-tailored solutions to specific problems.  He often says, “I’ll handle it or I’ll figure it out,” but rarely “it’s not do-able.”  He can say “Oh, I can’t get HTML5 canvas to work in IE7, but I can make a fallback solution utilizing the Modernizr library and flash.”  Following into the next point:
  • Understands the limitations of his tools and knows when to look for alternatives. He knows that certain tools have its advantages and disadvantages.  Example:  I like using MSSQL, it’s quite robust, but in terms of cost and horizontal scalability, I might pick a NoSQL implementation such as MongoDb or Cassandra.  I haven’t switched from ASP.NET MVC3 to ROR3.  Why? Because ASP.NET allows me to develop the exact user experience I’m looking for.  I am not willing to change technologies for the sake of change or because it’s trendy or that everyone else is using it.   If it fulfills the business requirements and fulfills it well, there’s no pressing need to change.  I like to be time-efficient like that.
  • Knows when to re-use code and when to write custom code. On the topic of time-efficiency, a good developer knows when he needs to create a custom solution or when to use a pre-existing one.  It really boils down to the question:  Does it fulfill the business/user experience requirement?  No? Then create a custom solution.  A good developer might say, “Well that confirmation box plugin doesn’t work properly in IE7, and it doesn’t allow to me anchor it to another element, so I’m going to write my own implementation.”

Why don’t a lot of startups use the Microsoft stack?

You hear a lot about LAMP (Linux Apache MySql Php) but you don’t  often hear about WISA/WISC (Windows IIS Sql Sever ASP.NET/C#) in the startup community.  I think there are a couple of reasons for this:

  • Microsoft licensing can cost quite a bit.  A Visual Studio 2010 Professional license can run you approximately $799.  For startups, every dollar must be spent efficiently.  If you can program for free on the ROR (Ruby on Rails) platform with free tools, why spend money on licensing similar technology?  Microsoft has a solution for this and it’s called BizSpark.  An example of a startup that used the Bizspark program?  StackOverflow.com, I’m sure most developers have heard of this site.
  • Microsoft is known for enterprise application development, not so much bleeding edge web development.  It certainly does not help Microsoft’s case for creating one of the most horrendous browsers to develop for (IE6).  A lot of people shunned Microsoft for a lack of standards compliance in favor of more open sourced alternatives, like Mozilla Firefox.  This anti-Microsoft sentiment continues and has propagated to other areas of the web.  However, I’ll say that Microsoft has improved tremendously and has embraced more web standards.  For example, in ASP.NET MVC, one of the preloaded libraries in the default application is JQuery.

I hope that Expensify’s CEO has learned a lesson or two from all the comments to his blog post.  In the end, what makes a good developer is not what tool he uses, but his ability to produce regardless of what his tool may be.

Tags: , , , , Leave a comment

Welcome to my blog!

25. March 2011 by Tony

I’ve been inspired of late by several friends and in reading several other blogs online to create my own corner of the web.  I am generally a very private person.  I am also not a terribly good writer.  These two reasons combined led to my initial hesitation in creating my own blog.  Nevertheless, I’ve mustered up the energy and (hopefully) the commitment to maintain a blog.   I want to be a better writer period.  I love discussions and one way for me to get discussions going is to start discussing myself.  I hope that makes sense.  Also, I am more than likely will be taking the GMAT, so this will be a great way to help me prepare.

I’ll be posting about various things centered around web technologies, entrepreneurship, my own life and other’s.  In addition, I’ll be detailing my progress, challenges, and light bulb moments surrounding some of the startups I’m involved in, which are Pivotr, a new way to aggregate content with emphasis placed on relevancy, and Dagree, a twitter meets gallup poll concept.

I am initially setting a goal to post once a week.  Thanks for reading!

Tags: , , , , , , Leave a comment