my current Work Stack

  • Ruby
  • Mongo
  • Titanium
  • Rails/Sinatra
  • Shoulda/Factory Girl
  • jQuery
  • Capistrano
  • Passenger
  • Apache.Nginx
  • Heroku
  • Nodejs
My Play List
last edited 10.08.2010

here's all my posts so far

04/11 Managing Development or Sometimes work gets in the way of work
12/21 Git Stash: For when your boss|clients|life priorities change
12/09 Picker Fields in Titanium
11/30 An Update on Raphael JS and Charts
10/08 How to make a Native App Form that doesn't suck with Titanium
09/23 Notification Subscriptions in Gowalla
09/21 Developing an API in Rails
08/26 I was promised Event Driven APIs and hoverboards. Where are my hoverboards?
08/14 A Node.js wrapper for Gowalla
08/09 Phusion Passenger Tweaking: Apache stuck in Sending(W)
06/28 HTML 5 is here and breaking old hacks we should have never done!
06/26 Simple PDFkit example in Rails 3
06/23 Raphael.serialize
06/12 Serializing RaphaelJS
06/11 Rails 3 beta4 destroyed my Tie Fighter
05/21 Rails 3 and Shoulda
05/13 Using yaml to configure default options for Paperclip
05/07 It's OK to not be pretentious
04/23 Snippet #1
04/21 I Need Closure
04/16 The Good and Bad of Github
04/08 Fun with Beards, or at least mine

here's some tweets I made

what would You look like with my beard?

upload an image to put a beard on it
you can drag the beard and even resize it
Hi!
I'm Jonathan, a web developer in Austin, TX. I'm into fun apps, Ruby, programming creatively, TDD, and one line code challenges.

Here's the last thing I wrote on here:

Managing Development or Sometimes work gets in the way of work

I haven't posted in a long time. Luckily, it's not because I haven't been learning anything, it's just that most of the things I've been learning aren't as programming related as they are "business tech" related.

Your company grows and you start spending time making phone calls, collaborating with partners, talking with users, writing documentation, etc.

So instead of coding snippets I want to talk about coding in a fast paced environment, especially when you have a lot more to do than just code.

I am managing development at a startup, so this is also my intended audience. Also, I screw up all the time.

  1. Set small goals in short timeframes

    Big vague goals are difficult to accomplish and difficult to break into chunks to assign to different people. I also find that checking things off builds morale for everyone invested in the code. We do everything in two week sprints and plan the week every Monday.

  2. Set a whole lot of them way in the future

    Today you should know what you are going to do in six weeks. Even though the goals themselves are small, they should reach far into the future.

  3. Don't be afraid to change them

    Understand that you don't really know what you are going to do in six weeks. Things come up: opportunities that take precedence or failures in ideas or technologies. Things change and so do you.

  4. Don't be afraid to never to do some of them

    You will not and should not complete all of the goals. They are set far into the future to give you direction now. But by the time you get there, they will change. Your job is to make the best ones, the ones that will move your company forward, emerge.

  5. Know your coders

    You need to know your coders and their strengths and weaknesses. Not just what they are good at coding, but also what motivates them, what environment is best for them, when do they do their best work. Also, understand what part of coding they love, and what they hate. And if they don't love any of it, get rid of them. :)

  6. Trust your coders
    If you learn to trust your coders based on their strengths and weaknesses, your tech will make progress much more quickly. Assign tasks and let them do them. Or better, yet, allow them to choose tasks. But you have to trust that they will choose the right one for them and that they will do it.

  7. Don't trust their code (or yours)

    Because we all make mistakes and their code is your responsibility. Take the time to code review, have them refactor if required, make small tweaks yourself but use them as teaching opportunities. Oh, and most of all: AUTOMATED TESTS

  8. Limit your scheduled phone calls to either 1 per day, or all of them in one day.

    Phone calls kill. You're no good before them and no good after them. And no one is any good during them. I prefer the one per day method, just knowing that an hour of my day will be phone calls with partners or support. Then I plan accordingly.

  9. Figure out what time of day is best for certain tasks and schedule around that

    This really goes for anything you do in your life. When are you best at exercising, reading books, spending time with your family? I know in the morning I'm easily distracted, so that's when I schedule calls, do email and write documentation. In the afternoon I can creatively solve all of the world's complex problems and hunt down the most deceptive bugs. Late at night, though, I can hunker down and churn out millions of lines of rote code. You might be completely the opposite.

Comments

Git Stash: For when your boss|clients|life priorities change

I discovered git stash awhile ago and have gotten a lot of use out of it.

Basically, it takes your working changes and stashes them somewhere, reverting back to the HEAD. You can retrieve those changes later like they never went away. This allows you to change branches when you want without committing things.

Since you can have lots of stashes and refer to them by name, you can also try one solution, benchmark it, then try a different one and in the end, only apply the best one.

I've been using it this way for awhile, but today I discovered git stash branch which lets you move your stash to a new branch.

Today I was asked to roll back all my working changes for a release, but keep those changes for the next release. Our priorities changed. In the past I would have done a commit, then made a branch, then rolled back a commit. But with git stash branch I just typed:

1
2
git stash
git stash branch <newbranchname>

Done.

Comments

Picker Fields in Titanium

I see a lot of questions in the Titanium Developer Forum about hiding the Keyboard when you click a text field. Typically you want to bring a Picker up when you do this.

Almost every response says "Just blur the field in a focus handler" While I guess this "works" you can still see the keyboard slide in and out. Especially on the iPhone 3G and OG.

I present a better way.

First, create your Picker and the view, and provide a toolbar to cancel or choose your selection.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var pickerView = Titanium.UI.createView({
  height:260,
  bottom:-260
});
var cancel =  Titanium.UI.createButton({
  title:'Cancel',
  style:Titanium.UI.iPhone.SystemButtonStyle.BORDERED
});
cancel.addEventListener('click',function() {
  pickerView.animate(slide_out);
});
 
var done =  Titanium.UI.createButton({
  title:'Done',
  style: Titanium.UI.iPhone.SystemButtonStyle.DONE
});
done.addEventListener('click', function(event) {
  specialField.text = picker.getSelectedRow(0).title;
  specialField.color = "#333333"; // no more hint text
  pickerView.animate(slide_out);
});
 
var spacer =  Titanium.UI.createButton({
  systemButton: Titanium.UI.iPhone.SystemButton.FLEXIBLE_SPACE
});
 
var toolbar =  Titanium.UI.createToolbar({
  height: 43,
  top: 0,
  items:[cancel,spacer,done]
});
pickerView.add(toolbar);
window.add(pickerView); // do this last or set a z-index

You probably already had something similar to slide in when the textField was focused. Notice I didn't put the picker in this example.

Now comes the key part. Make a view and a label that look like a textField. Luckily, Titanium (or javascript really) lets you assign random attributes to an existing object. (OK, so it's really an associate array but we're going to use Object Notation so it looks like a traditional attribute)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

var specialFieldView = Ti.UI.createView({
  borderColor: "#a6a6a6",
  top: 240,
  width: 260,
  height: 40
});
var specialField = Ti.UI.createLabel({
  color: "#bbb",
  left: 10,
  width: 260,
  height: 40,
  text: "Choose Special Thing", // used like hint text
  font: {fontSize: 16, fontWeight: "normal"}
});
specialFieldView.add(specialField);

specialFieldView.addEventListener('click', function(event) {
  pickerView.animate(slide_in);
});

So the key now is to just make the View and Label combination look like your Text Fields. It's pretty easy to do. If you want to use Hint Text, just make sure to change the text color to something darker once the value is set.

Comments

An Update on Raphael JS and Charts

I've been a fan of Raphael JS for a long time. It's a javascript vector graphic library that (IMHO) blows canvas stuff away. Canvas definitely has its uses, but most of the stuff I see being done in canvas can be done more easily and more efficiently in SVG.

For a couple of years I've been using the Google Charts API. I've never been a fan of Flash graphs unless you need the bells and whistles of interactivity and zooming. So I've generally stuck with Google. However, I've never been pleased with the look and feel, and building URLs feels a little odd sometimes.

In comes Raphael Charts, or gRaphaƫl. It's simply a plugin for raphael from the creators of raphael. The demos are beautiful and they offer basic levels of interactivity with very little effort. And importantly; no Flash.

I had the pleasure of using it this evening and roughly clocked 6 minutes from the time I entered the raphael URL to the time my first pie chart was finished.

Here's some quick sample code in haml

1
2
3
4
#chart
:javascript
  var r = Raphael(document.getElementById("chart"));
  r.g.piechart(120, 120, 100, [#{@game.results.collect{|r| r.winnings}.join(",")}]);

Comments

How to make a Native App Form that doesn't suck with Titanium

Some things are much more difficult to do in a native app than on the web. But forms are not one of them. Both iOS and Android give us simple tools to make form interaction nice and easy.

Unfortunately the Titanium docs make it almost impossible to figure out. Don't get me wrong, the docs are great, and the Kitchen Sink app they supply covers 80% of the things you can do. But making a nice form was somehow left off.

In particular, I was looking to make a form with sections that are stacked together, had a hint and no label, and led you from field to field. After tons of searching docs, Q&A and googling, I did it.

I'll show you the code first and then go through it.

This is in a file I called login.js that is called by a window.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
var window = Ti.UI.currentWindow;
var loginField = Ti.UI.createTextField({
  value:'',
  width:300,
  height: 40,
  left: 5,
  hintText: 'Username',
  returnKeyType:Titanium.UI.RETURNKEY_NEXT,
  borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE
});

var passwordField = Ti.UI.createTextField({
  value:'',
  height: 40,
  passwordMask: true,
  hintText: 'Password',
  width:300,
  left: 5,
  borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
  returnKeyType:Titanium.UI.RETURNKEY_DONE
});

loginField.addEventListener('return', function(event) {
  passwordField.focus();
});

passwordField.addEventListener('return', function(event) {
  // submit your form here
});

var table = Ti.UI.createTableView({
  style: Ti.UI.iPhone.TableViewStyle.GROUPED,
  rowHeight: 40
});

var section = Ti.UI.createTableViewSection({headerTitle: "Sign in"});
    
var row = Ti.UI.createTableViewRow();
row.add(loginField);
row.hasChild = false;
row.className = "field";
section.add(row);

var prow = Ti.UI.createTableViewRow();
prow.add(passwordField);
prow.hasChild = false;
prow.className = "field";
section.add(prow);
table.setData([section]);

window.add(table);

It's pretty simple really.

The first part creates a username and password field. The key parts here are:

1
2
3
hintText: "Username",
returnKeyType:Titanium.UI.RETURNKEY_NEXT,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE

  • hintText adds the helper text so you don't need a label.
  • returnKeyType basically changes the text on the input keyboard return key.
  • borderStyle we set to none so that we can let the table view handle the borders.

In the next part we set event listeners for when that return key is pressed. We can auto forward the user to the next field using .focus();

Next we create a table that is GROUPED, add our inputs to simple rows and put them in the table. Make sure the row height is the same as the input height so that the rows appear to be the inputs.

Here's the result:

Comments