Ben by Ben Jacobs

My own designer line

‘No Wrap’ Plugin for Selectize

Selectize.js is a great jQuery plugin by Brian Reavis to replace the browser’s <select> control. One of the best parts of the project’s design is how everything is structured to be extensible. It’s very easy to write a plugin that modifies core behaviors but without having to touch the core source. This has obvious advantages, since it keeps things lean and makes it possible to configure options based on need.

Out of the box, Selectize does not work very well when the input is narrow but the item is large. In this situation, the control grows taller.

Selectize default on long input

So, I wrote a plugin that takes care of the situation. Here’s a live example:

The plugin is available in my fork of selectize. Once you’ve included the plugin in your page (either through building it into Selectize using grunt --plugins=item_nowrap or by including the javascript and css independently), using it is simple:

1
2
3
$('#select-country').selectize({
  plugins: ['item_nowrap']
});

Talk Like a Pirate Day; or, Decades on the Internet

Avast, me hearties! It’s another “Talk like a pirate day” on internet land. This day is especially important to me because I contributed a tiny bit to its recognition on the internet by writing the Everything2 post about the day. For the uninitiated, Everything2 was a sort of forum crossed with a wiki (all before Wikipedia).

When I was most active on the site, over ten years ago, I was just coming to terms with the reality that I, a high schooler in the Midwestern USA, could type something into my computer and send it out to be read by dozens (thousands?) of people. I didn’t imagine that what I wrote on E2 would be available 11 years later. At the time, I was mostly thrilled that I got four “cool” votes (E2 had a voting system and you could earn reputation for articles).

So, my article remains, even though I abandoned that site years ago. Now, you’re more likely to find my ramblings here or on Twitter. Give me another ten years and I’ll be looking back at my inane tweets.

But, for today, go forth and talk like pirates, ye scurvy dogs!

Original post

Today is the day where instead of saying “hi” you should say “avast ye scurvy knave!” Today is the day when you should start every sentence with “arggg” or “yarrrr.” Today is September 19th, the official “Talk Like a Pirate Day”! My friends and I discovered “Talk Like a Pirate Day” in a newspaper colum written by Dave Barry. Some faithful readers of his column had written Dave Barry to tell him about a holiday they had created. Being a nationally syndicated columist, Dave Barry figured that he had the power to bring this wonderful holiday to the public.

If you need a little help talking like a pirate jump over to Talking like a pirate is fun but annoys people.

Update: server time Friday, September 20, 2002 at 01:17:56

Apparently the inventor of this fine holiday was interviewed on NPR sometime this afternoon. I didn’t have the pleasure of listening to it myself, but one of my faithful pirate maties told me of it.

Yarrrrrrrrrrrg

Google Geocoding Service for AngularJS

A few weeks ago, I was integrating Google Maps into an AngularJS app. I’d done some basic mapping before, but this time I needed to Geocode addresses so that I could put markers on the map based on latitude and longitude. Google provides a Geocoding API that you can access directly through http requests or through a wrapper. Since there’s a convenient Javascript wrapper on the API, I chose to use that. Requests look pretty familiar:

Basic JS request to Geocoding API
1
2
3
4
5
google.geocode({ address: 'My House, in the middle of my street, USA'}, function (result, status) {
    if (status === google.maps.GeocoderStatus.OK) {
        // bingo!
    }
});

Pretty trivial so far.

The challenge I ran into had to do with rate-limiting. Google limits calls to the API to 2,500 requests per day (more if you have a business account). They also limit the frequency of calls, although they don’t say this explicitly in the help documents. Initially, I was trying to geocode about 150 addresses simultaneously with asynchronous calls to the API. After about the first 10, Google would respond with OVER_QUERY_LIMIT.

With this in mind, I came up with three requirements for my service:

  1. That it store results in localStorage so that they would only have to be queried once per client (Google encourages caching the information, as long as you’re only using it with Google Maps).
  2. That it only make one call to the API at a time
  3. That it respond appropriately if it started receiving errors due to rate limits.

You can read the resulting service below. I drew some inspiration from Valentyn Shybanov’s answer to Adding queueing to angulars $http service on StackOverflow. For caching, I used ngStorage, which provides a nice, Angular way to wrap localStorage and sessionStorage.

Blogging With Octopress

I’m switching my blog over to Octopress. I had been using Pelican, but Octopress drew me in with some appealing out of the box features, especially it’s super-simple code highlighting and RSS feeds.

Write something to the console
1
2
3
$(function () {
    console.log('Foobar');
});

Enjoy!

Unpredictable “301 Permanently Moved” in Embedded AngularJS Built With Yeoman

In the past few months, I’ve become a big fan of AngularJS. The data-binding is beautiful. The code is elegant. The community is friendly. It’s pretty easy to go from a complete novice to producing web applications that are useful (especially with the John Lindquist’s videos over at Egghead.io).

Angular, is not w/o it’s challenges, though. I ran into one perplexing but today. I’ve been hacking away at at an Angular application that I started using Yeoman. I build the app using Grunt and deploy it. The deployment itself is within the context of a larger site running a CMS (in this case, Joomla).

The issue: While doing our QA testing, my co-workers and I noticed that the app would sometimes fail to render. It was not throwing any errors. All the Javascript was being loaded correctly. The only thing that was going wrong was the loading the template for the views. In our dev tools, we dug in and found that the template file was getting a 301:

301: Permanently Moved

And further inspection showed that Apache was trying to redirect us. So, when the request was for www.foo.com/views/template.html the response was trying to send us to Location foo.com/views/template.html (notice that ‘www’ has been dropped).

It turns out that the Grunt.js file that got created with Yeoman was including a boilerplate .htaccess along with my app and I was unknowingly distributing it. Removing this from the production server solved the issue. I also modified my Grunt.js file to not copy the .htaccess file in the build process. As a side note, it was pretty easy to find in the .htaccess file where this behavior was coming from.

Now, the oddest part was that this behavior was very intermittent. We observed it in both Firefox and Chrome at different times. Sometimes, rebuilding the app would take care of the problem, and other times it wouldn’t. Clearing the browser cache had no effect.