true false maybe

tom longson’s blog on software, design, and user experience

My wife’s bakery for cupcakes in san francisco has gotten a TON of press recently. I even was quoted in the Wall Street Journal!

As you might know I’m a designer and developer, and for the first time in my life i’m thinking about kids. Partly because I’m on the cusp of turning 30, and in a stable relationship, but also because right now I’m babysitting a toddler. He’s really cool, and extremely curious.

In exploring his environment around the home where he lives, there are places and things he manages to get to that are clearly new for him. I had the idea of turning one of those push lights into something more interesting, like make it light up and make a noise, and put them all over your house, encouraging exploration, but in the *right* places. At least, I would since I grew up being uncoordinated, and I’d want my kid to be able to literally be able to crawl up the walls.

What do you think?

The Locker ProjectSo installing Locker can be a bit of a bear, so I put together this howto since my laptop got stolen last week, and I had a brand spanking new macbook pro to try out locker from the very start. With this guide, using OSX, you could install Locker for yourself at this very early stage to try it out.

Start by getting Git

Git is used to get Locker. It’s also used to contribute to locker. Git is great. Go get git.

http://code.google.com/p/git-osx-installer/downloads/list?can=3&q=&sort=-uploaded&colspec=Filename+Summary+Uploaded+Size+DownloadCount

Get XCode (Developer Tools)

Go to the Apple Store, search for “Xcode”, download. This is needed for compiling Node.js. It was $5.00. I remember this being free before the App Store…. >:(

Download Node.js

http://nodejs.org/#download

I grabbed the tgz.

curl -o node.tgz http://nodejs.org/dist/node-v0.4.7.tar.gz

cd node-v0.4.7/

So I read README.md. Looks like the usual drill of ./configure; make; make install.


./configure
make

Some warnings about directory not found for option ‘-Lusr/local/lib’. Hopefully that won’t stop me.

Going to try make test to test to see if it works as the node guys expect node to.

make test

Crap, one of the test failed… “simple/test-http-dns-fail” my node doesn’t ever fail, so this will be irrelevant (j/k).


make install

Eep

Cannot create folder
'/usr/local/include/node/' (original error: [Errno 13] Permission denied: '/usr/local/include')

Lets do that with sudo, if it works for sandwiches…

Yay! ‘install’ finished successfully (0.256s)

Ok, NPM now.

This is for node packages. Yummy yummy nodey packages.

curl -o install_npm.sh http://npmjs.org/install.sh
sudo sh install_npm.sh


Okay, now we can install Locker!

git clone https://github.com/LockerProject/Locker.git
cd Locker

Yay, downloaded (cloned) it directly from github.com. Now I have my own personal Locker platform to run with.

We need to set it up though…

npm install
python setupEnv.py

Okay, nothing fishy there…


node lockerd.js

Hot damn, it’s up! Now to go to http://localhost:8042 to access it with Chrome.

Here’s a picture of a kitty to show you how I feel:

kitteh

I ran into a problem with some legacy code which looked like this:

Delete

And the corresponding function:

function doDelete() {
    var submitForm = function() {
        document.forms[1].method="POST";
	document.forms[1].action="myThing.do?dispatch=delete";
        document.form[1].submit();
    }
    var messageBoxConfig = {
		message:"Are you sure you want to delete?",
		title:"Confirm",
		style:YUI.widget.MessageBox.STYLES.CONFIRM,
		buttons:YUI.widget.MessageBox.BUTTONS.YESNO,
		callback:submitForm
    };
    YUI.widget.MessageBox.show(messageBoxConfig);
}

Inline onclick handler aside (again legacy code), IE6 would submit the form without causing a page refresh. The form would submit transparently, leaving the user on the same page, which meant the backend wouldn’t have a chance to update the page with the results of the action. Firefox on the other hand, had no trouble submitting the form as I would expect.

In order to get IE6 to behave correctly, I had to use a setTimeout 0 in order to defer the action, and get IE6 to execute it.

function doDelete() {
    var submitForm = function() {
        document.forms[1].method="POST";
	document.forms[1].action="myThing.do?dispatch=delete";
        setTimeout(function() {
            document.form[1].submit();
        },0);
    }
    var messageBoxConfig = {
		message:"Are you sure you want to delete?",
		title:"Confirm",
		style:YUI.widget.MessageBox.STYLES.CONFIRM,
		buttons:YUI.widget.MessageBox.BUTTONS.YESNO,
		callback:submitForm
    };
    YUI.widget.MessageBox.show(messageBoxConfig);
}

From what I understand, Internet Explorer 6 has issues with submitting from an onclick event in an anchor, although when I remove the MessageBox code, it worked as expected again (without the setTimeout). Some people have reported onmousedown instead of onclick gets IE6 to work correctly. Possibly the default behavior of the anchor is causing it to break? Nevertheless, using timers to queue the submit action makes it work properly regardless of the browser. Will update this post if I find out more!

Related posts:

iphone wine app

I’m really pleased to announce that Andrew, Anna, and my iPhone Wine App, Fine Local Wine is live on the app store. It’s my first push into real mobile development, and I’m really proud of what we’ve accomplished. This app uses Fine Local Wine‘s website as the backend, and reuses much of Gaia iPhone GPS‘s framework on the mobile frontend.

My aim is to do more development, and rebuild the backend with Pinax to allow more user input into what wineries are in our database, and allow people to rate and review the ones that are.

Would love to hear your feedback. If you leave me a comment I’ll give you a promo code so you can try the app out yourself for free :-)

November 16, 2010

Looking for a good vineyard?

fine local wine

I recently wrote a service to help people find vineyards, such as napa valley wineries. Each vineyard has a closeup satellite map, which can be really beautiful, like in the case of Petroni Vineyards.

It’s written with GeoDjango with Postgres/PostGIS as the backend, and Google Maps and jQuery on the frontend. I did the design and development, and Ruth Johnson did some of the copy, including this page on New York Vineyards. I’m hoping to have more content on the site soon.

Hope you enjoy! Please leave me a comment if there are any features you would like.

September 21, 2010

Walabs.com Dead Labrador Puppy

walabs-sick-labrador-puppy

My brother bought a Labrador retriever puppy from Jim Young of Walabs in Onalaska, Washington. One week later it was dead.

The vets said the cause of the puppy’s death was likely to do with the breeding program by Jim Young, and by his own accords was underweight and not thriving.

Did Walabs.com offer an apology? A refund? No. Jim Young accused my brother and his girlfriend of doing something wrong, and was hostile. They have since received emails from other people who have bought sick puppies from Walabs’s puppy mill, unfortunately. This post is a warning to future dog lovers who may be looking into buying a puppy from this breeder.

If you have had a similar experience, please leave a comment so others can see. Thank you.

I’ve been expanding my library recently, and I wanted to share a list of some advanced JavaScript books I’ve picked up:

If you’re totally new, these probably aren’t the best books to dive into, but I still recommend picking up JavaScript: The Good Parts. It’s amazing reading, really gave me a much better understanding of the language, and incredibly dense.

Demo: PubSub in jQuery

Recently I did a post on Data Binding in JavaScript using the YUI3 Library as my base. h3 and MikeInVB wanted to see it in jQuery, so I rewrote it and it turns out is a great example of PubSub (publish / subscribe) for jQuery.

For this example, we’re using an object named DB, which is short for DataBind. Basically it’s an object with getters and setters.

  var DB = function (data) {
      this._d = null;

      this.set = function (data) {
           this._d = data;
      };

      this.get = function () {
          return this._d;
      };

      this.set(data);
  };

Really, this is just an abstracted way to store data. To create an instance of it, set it and get the value back, we would do something like:

var myData = new DB();
myData.set("We can't fight in here, this is a war room!");
console.log(myData.get();) // "We can't fight in here, this is a war room!"

But lets say, we want to subscribe to this data object, and be notified whenever it changes. Instead of polling it and checking to see if the value is the same as last time, we can use jQuery’s custom events to trigger a custom event.

  var DB = function (data) {
      this._d = null;

      this.set = function (data) {
           this._d = data;
           // notify all subscribers when this function is used
           $(this).trigger("change");
      };

      this.get = function () {
          return this._d;
      };

      this.set(data);
  };

Now, we can subscribe to it like this:

$(myData).bind("change", function() {
     alert("The data was changed!");
});

Additionally, we can access that data in our handler:

$(myData).bind("change", function() {
     alert("My data was set to " + myData.get());
});

You can set up any number of subscribers to myData this way now, and they’ll be triggered when that instance is set().

If you want to further improve DB, you can add a function to make it easier to attach change events, jQuery style:

  var DB = function (data) {
      this._d = null;

      this.set = function (data) {
           this._d = data;
           // notify all subscribers when this function is used
           $(this).trigger("change");
      };

      this.get = function () {
          return this._d;
      };

      // shortcut for functions trying to bind to the change custom event
      this.change = function (fn) {
          $(this).bind("change", fn);
      };

      this.set(data);
  };

With our new shortcut, we can subscribe to it like this:

var alexSez = new DB();
alexSez.set("Initiative comes to thems that wait.");
alexSez.change(function() {
    alert("Alex says: '" + myData.get() + "'");
});
alexSex.set("Welly, welly, welly, welly, welly, welly, well. To what do I owe the extreme pleasure of this surprising visit?")
// an alert will come up that says "Alex says: 'Welly, welly, welly, welly, welly, welly, well. To what do I owe the extreme pleasure of this surprising visit?'".

In the same way, you can set up two input boxes to “share” the same value by subscribing to a shared instance of DB like this:



  var myData = new DB();

  var inputs = $("#in1, #in2");
  myData.change(function() {
      inputs.val(myData.get());
  });

  inputs.bind("keyup", function(ev) {
      myData.set($(ev.target).val());
  });

Ta da!

If you’re still interested in PubSub for jQuery, I recommend checking out Jamie Thompson’s example using the $(document) namespace instead of specific object instances, or Peter Higgin’s jQuery.pubsub, which reportedly is significantly faster, although doesn’t allow object specific subscribing.

Demo: PubSub in jQuery

What do you think? Would you do this differently? Leave a comment, I read them all!

See the demo here: Data Binding in JavaScript

Back when I was in Flex land one of the things that I found to be really neat was data binding… you could essentially have widgets that would update if the data updated automagically. I also wanted to take a stab at doing publishing and subscribing in YUI3, so built this an object called DB, which stores data. It can do three things, it can set() data, it can get() data, and it’s an EventTarget, so you can subscribe to it’s change event:

var DB = function (data) {
    this._d = null;

    this.publish("change",{emitFacade: true});

     this.set = function (data) {
         this._d = data;
         this.fire("change");
      };

      this.get = function () {
          return this._d;
      };

      this.set(data);
};
 Y.augment(DB, Y.EventTarget);

And to instantiate an instance of DB you just do var myData = new DB();, and then you can subscribe to it any number of times to be notified when the data has been updated. For example:



var myData = new DB();
var inputs = Y.all("#in1, #in2");
myData.on("change", function() {
    inputs.each(function(node) {
        node.set('value', myData.get());
    });
});

inputs.on("keyup", function(ev) {
    myData.set(ev.currentTarget.get('value'));
});

This code is pretty simple. In YUI3 it creates an instance of DB, which has it’s own private data (unset initially), subscribes to the change event with a function that updates both text inputs on the page if myData gets set(), and then binds to the keyup event on the text inputs to call myData.set() whenever the contents of either text input has something typed into it. This results in a page where both inputs update whenever you type into either one.

See the demo here: Data Binding in JavaScript

Is this useful? Practical? UnJavaScripty? I don’t know, but I’d love to hear what you think ;-)