A Better Date Picker in Angular.js

<h3 id="update-march-14th-2015">UPDATE (March 14th, 2015)</h3> <p>When I first wrote this library, I didn&rsquo;t have a great understanding of the <a href="https://docs.angularjs.org/api/ng/type/ngModel.NgModelController">ngModelController API</a>, nor good directive design. So I wouldn&rsquo;t recommend this library anymore. I started on a replacement library <a href="https://github.com/adamalbrecht/angular-date-picker-polyfill">here</a>, though it&rsquo;s not quite ready for production use.</p> <p><hr></p> <p>I wasn&rsquo;t particularly happy with any of the datepicker directives out there for Angular.js, so I decided to build one myself. I did it out of a need on my current project but also because I wanted to learn the ins and outs of directives. You can find the library <a href="https://github.com/adamalbrecht/ngQuickDate">on Github</a>.</p> <p></p> <h3 id="requirements">Requirements:</h3> <ul> <li><p>Easy to use via the keyboard. I hate when I&rsquo;m using a form-centric application and there&rsquo;s one particular field that I can&rsquo;t just tab through.</p></li> <li><p>No dependencies (besides angular). Many of the existing datepicker directives are just jQuery widgets that are made to work with Angular. I wanted to build something from scrath in the &ldquo;angular way&rdquo;.</p></li> <li><p>Very configurable. If it&rsquo;s not totally required, make it optional.</p></li> <li><p>Lightweight styling that can be easily overridden. Too many front-end libraries assume you&rsquo;re using bootstrap or a particular icon font. I actually am using bootstrap for my project, but I don&rsquo;t want it to be forced on anyone.</p></li> </ul> <h3 id="the-end-result">The End Result:</h3> <p>After a few hours hacking here and there for a couple weeks, I have something fairly stable that I&rsquo;m calling <a href="https://github.com/adamalbrecht/ngQuickDate">ngQuickDate</a>. It is built with Coffeescript, meets all my requirements, is fairly well tested using <a href="http://pivotal.github.io/jasmine/">jasmine</a>, and works pretty damn well if you ask me. Unfortunately, there were quite a few breaking changes in the recent 1.2 release of Angular, so currently it only works with 1.0.8. I&rsquo;ll be releasing a 1.2 compatible version shortly.</p> <h3 id="lessons-learned">Lessons Learned:</h3> <p>If you really want to understand the amazing directive system in Angular, building a datepicker or another similarly-complex UI widget is a great way to go about it. I had to go through a number of iterations before it felt right, but I learned a lot in the process. A few things to keep in mind:</p> <ul> <li><p>Learn what&rsquo;s already built into angular before you pull in any 3rd-party libraries. For example, I didn&rsquo;t realize at first that I could use filters in my javascript code (as opposed to just in templates), so I was using another library to format dates.</p></li> <li><p>Take the time to provide some decent configuration for your directive. Angular provides a nice way to set the original default settings using a <a href="http://docs.angularjs.org/api/AUTO.$provide#methods_provider">&lsquo;provider&rsquo;</a>.</p></li> <li><p>Make 3rd-party libraries optional by providing basic functionality without them, and extended functionality with them. In ngQuickDate, you can configure it to work with a library like <a href="http://sugarjs.com">Sugar.js</a> for enhanced date parsing, but it&rsquo;s not required.</p></li> <li><p>Use <a href="http://smacss.com/">SMACSS</a> or a similarly modular system for writing your directive&rsquo;s CSS. By doing this, you&rsquo;re much less likely to use conflicting class names, you&rsquo;ll write more efficient CSS, and make it easier to re-style.</p></li> <li><p>Stick to the tools you know and love if it will help your project. I started out with the intention of doing it in plain Javascript and CSS so I wouldn&rsquo;t turn off any developers out there unfamiliar with Coffeescript or any of the CSS pre-processors. But writing Coffeescript is just so much more fun the end-result is much more succinct and readable.</p></li> </ul>