This is another boring tip in case you have to construct a form to send to Rails, and I’m sure it’s documented everywhere:

Rails-generated checkboxes return a value of 1 when they’re clicked. That is, the parameters will contain the name of the checkbox and a value 1. But the way checkboxes work is they’re either on or … they’re not included in the parameters. They don’t get sent as “off” or “0″. So the thing to realize is that the Rails-generated checkbox is accompanied by a generated hidden field with the same name as the checkbox and a value of 0. Apparently, if there are two identical names submitted in a form the first one takes priority. Who knew?

So you would do something like this with Ext JS:

new Ext.form.Checkbox({ name : "profile[licensed_realtor]", inputValue : "1",
            id : 'js_profile_licensed_realtor_field', fieldLabel : "Licensed Realtor",
            checked : <%= @user.profile.licensed_realtor == true ? "true" : "false" %> }),
        new Ext.form.Hidden({ name : "profile[licensed_realtor]", value : "0" })

This is, uh, a technical post.

Probably there are others who want to do the same somewhat senseless thing: use Ext to do form validation while keeping a boring non-Ajax post-and-response. The bottom line is that Ext favors doing it the Ajax way, and the Ajax way isn’t that hard to set up with Rails (just handle the form submission as normal but return JSON or XML to signal success or failure). But if you’re like me and working on a deadline, there can be a cognitive burden to switching to Ajax posting that you might want to avoid. Paradoxically, you might find yourself wasting a lot of time trying to figure out how to do it the “old-fashioned” way. Well, here’s one working standard-submission Signup Form, with fancy validations and all the kinks worked out.

Here’s the top half of the file users/new.html.erb, which is nearly the same as the code generated by restful-authentication:

<% @user.password = @user.password_confirmation = nil %>
<%= error_messages_for :user %>
<div id="no-js-form">
    <% form_for :user, :url => users_path, :html => {:id => "signup-form"} do |f| -%>
    <p>
        <label for="login">
            Real Name
        </label>
        <br/>
        <%= f.text_field :name, :id => "signup_name_field" %>
    </p>
    <p>
        <label for="login">
            User Name
        </label>
        <br/>
        <%= f.text_field :login, :id => "signup_login_field" %>
    </p>
    <p>
        <label for="email">
            Email
        </label>
        <br/>
        <%= f.text_field :email, :id => "signup_email_field" %>
    </p>
    <p>
        <label for="password">
            Password
        </label>
        <br/>
        <%= f.password_field :password, :id => "signup_password_field" %>
    </p>
    <p>
        <label for="password_confirmation">
            Confirm Password
        </label>
        <br/>
        <%= f.password_field :password_confirmation, :id => "signup_password_confirmation_field" %>
    </p>
    <p>
        <label for="password_confirmation">
            Role
        </label>
        <br/>
        <%= f.select :role, [["consumer","consumer"],["vendor","vendor"]], :id => "signup_role_field" %>
    </p>
    <p>
        <%= submit_tag 'Sign up', :id => "signup_submit_button" %>
    </p>
    <% end -%>
</div>
<div id="js-form-panel">
</div>

The only differences are a div wrapping the form (”no-js-form”) and the “js-form-panel” at the end. You’re going to laugh at me, but this form is buzzword-friendly; it’s unobtrusive in an ugly way. If javascript is turned on, the form will work, and the following will fail:

<script type="text/javascript">
    /* 
     Thanks to:
     http://www.extjswithrails.com/2008_03_01_archive.html for standardSubmit tip (hard to find!)
     http://extjs.com/forum/showthread.php?t=23068 for password confirmation
     Anyone else I stole semantics from
     */
    // Look, I'm copying over the authenticity token to send in the JS-generated form. LOL!
    var authenticity_token = document['forms'][0]['authenticity_token'].value;
 
    Ext.onReady(function(){
        $('no-js-form').hide();
 
        var myForm;
 
        function submitHandler(){
            form = myForm.getForm();
            form_as_dom = form.getEl().dom;
            form_as_dom.action = form.url;
            form_as_dom.submit();
        }
        myForm = new Ext.form.FormPanel({
            monitorValid: true,
            standardSubmit: true,
            url: "/users",
            applyTo: "js-form-panel",
            title: "Signup as a New User",
            width: 310,
            autoHeight: true,
            items: [new Ext.form.TextField({
                allowBlank: false,
                msgTarget: 'side',
                name: "user[name]",
                id: 'js_signup_name_field',
                fieldLabel: "Real Name"
            }), new Ext.form.TextField({
                allowBlank: false,
                vtype: 'alphanum',
                msgTarget: 'side',
                name: "user[login]",
                id: 'js_signup_login_field',
                fieldLabel: "Username"
            }), new Ext.form.TextField({
                allowBlank: false,
                vtype: 'email',
                msgTarget: 'side',
                name: "user[email]",
                id: 'js_signup_email_field',
                fieldLabel: "Email"
            }), new Ext.form.TextField({
                allowBlank: false,
                inputType: 'password',
                vType: 'password',
                msgTarget: 'side',
                name: "user[password]",
                id: 'js_signup_password_field',
                fieldLabel: "Password"
            }), new Ext.form.TextField({
                fieldLabel: "Password Confirm:",
                allowBlank: false,
                inputType: 'password',
                name: "user[password_confirmation]",
                initialPasswordField: 'signup_password_field',
                vType: 'password',
                msgTarget: 'side',
                id: 'js_signup_password_confirmation_field',
                fieldLabel: "Confirm Password",
                validator: function(value){
                    return (value == document.getElementById("js_signup_password_field").value) 
|| "Your passwords do not match";
                }
            }), new Ext.form.Hidden({
                name: "authenticity_token",
                value: authenticity_token
            }), new Ext.form.Hidden({
                name: "user[role]",
                value: "consumer"
            }), ],
            buttons: [{
                handler: submitHandler,
                text: "Signup",
                formBind: true
            }]
        });
 
    });
 
</script>

The noteworthy steps are: first, I hide the ‘no-js-form’, then I copy the authenticity_token that gets generated by a rails form to put in the js-generated form. Then, standardSubmit : true is the config option that makes a FormPanel not submit as an XmlHttpRequest. The funny code in the submitHandler is getting the underlying form object and calling submit on it, but as I write this it doesn’t make sense why both would be necessary. Finally, formbind : true causes the submit button to be deactivated while there are failing validations, and there’s some handy code for making sure that the password_confirmation matches password (totally lifted from somewhere else, see above).

I’m going to share some wonderful things with you now. I’ve saved them up, although my one reader has probably seen them all through my del.icio.us account.

I think Christopher Hitchens getting waterboarded is fairly noteworthy.

Zadie Smith writes about Kafka again. Funny story about this. I was reading the article, and the writer noted that Women are snares which lie in wait for men on all sides, in order to drag them into the merely finite is a “perfectly ordinary expression of misogyny, dispiriting in a mind that more often took the less-traveled path.” I was already annoyed with the article on a number of counts (it’s titled “F.Kafka, Everyman”) and I thought, I bet the author’s a woman. When I scrolled to the top and saw who it was, I thought, “well she makes some good points”. So, there.1

This article made the rounds on the aggregator blogs. There’s a passage that ends “She had scratched through her skull during the night—and all the way into her brain,” that made it like a story from Scary Stories to Tell in the Dark. Some people have called bullshit on it, but who cares?

This video will also scare the hell out of you. Look at the debate in the comments about whether it’s basically a snuff film.

Have you seen Quest for Fire? My god, it’s a French-Canadian movie about cavemen trying to get their fire back. It has authentic made-up cavemen dialogue in several languages and no subtitles. So awesome.

I like to corner people and tell them about the bonobos. This video will change your life. The thesis at the beginning of the video sounds ridiculous, but let it sink in a little before you reject it.

This video about a weird subculture in Japan will also change your life. There’s a tremendous surprise about halfway through. This video isn’t exactly eye-opening, but it brings you up to speed on something you might not have wanted to know about.

The second video here has become a local meme for Amy and I, along with the lines from this (an old thing that we just discovered). Huh??? What???

Technology Crisis I and II are just about the best free music you’ll ever get. It’s music written for an imaginary video game.

Anyway, I have a lot of this stuff. I estimate about 40% of my brain is made out of this crap.

---

  1. To get this, you have to understand that Zadie Smith and Kafka and the intersection of the two have been key influences throughout my 20s. [back]

Continuing with the theme of wholesome outdoor athletic activities, Amy and I went to see the Pittsburgh Passion playoff game on Saturday night. It was fun; there was a good crowd; the tickets were $5. The Passion have gone undefeated this season, and tonight we saw why. When we left at half-time (it was raining) it was something like 37-6 against Orlando (final 41-6).

My homework assignment for the DC folks (I guess for next year): go see a DC Divas game, and keep track of the next Passion vs. Divas game, so we can get together and I can be conflicted.

Amy and I rode our bikes in Critical Mass for Pittsburgh, which I didn’t realize is a monthly thing. We didn’t know what to expect at all, but it turned out to be a very mellow and pleasant affair. Some of the regulars were making fun of a “competing” ride called Critical Manners1, where the pack doesn’t blow through red lights and even rides in a single file. We were also dismayed when we arrived at the meeting place that it didn’t seem like the mass was nearly large enough; it would be a sub-critical mass, a fizz-out. But when everyone got on their bikes and swarmed out it seemed like the pack magically grew to something like 150-200 bikes. Then everyone just sort of ghosted along at a leisurely pace with some quiet talking and not much yelling in a loop around the Oakland area. Since it was a Friday at 6PM, there weren’t even that many cars to inconvenience.

Of course, the 200~ person pack would take a long time to cross an intersection and stopping for the red lights would have broken it up, so that’s where the bad-boy behavior comes in. Even this was pretty civilized. At each intersection, if the light was red the front of the pack would wait, but then the whole pack would pass through. A couple bikes would park in front of the cross-street, just looking at the waiting cars and smiling. So we did see one guy in a white SUV try to muscle his way past the “guards”, but the cyclist just slid his bike under the SUV’s wheel and suddenly there were a couple cyclists talking to the driver.

Okay, so the cool part was when the pack climbed up Craig St. toward Bigelow, which is a kind of highway on a height that drops down like a rollercoaster into either Bloomfield (a residential neighborhood) or downtown. This is a main commuter avenue for getting across Pittsburgh’s East Side, and normally it would be iffy to ride with the cars there. This is where we had a line of cars backed up behind the pack, probably fairly annoyed for the 15 minutes that we held them up for. The point wasn’t to hold up the cars, even though I didn’t feel too bad about it. A lot of people make hellish 2+-hour commutes to and from Pittsburgh, just because they can’t imagine actually living in the city. Some of those people are the same drivers who act squirrelly around bikers, tailgating because they’re afraid to pass, or freaking out when you pause to turn in the left-turn lane.

Anyway, it turned out that it’s just really nice to own the road for awhile, and especially a privileged car commuter road like Bigelow. There’s a weird little sliver of a park (”Frank Curto Park”) that’s up on this inaccessible ridge by Bigelow that thousands of car commuters pass every day. Nobody goes to Frank Curto park, not even by car. Driving past you sometimes see a flock of geese turkeys2 and wonder how they got there. We rode past that (but we could have stopped) and then the entire pack bombed down through the long descent to downtown, with the sun starting to set and all of Pittsburgh below us. That was a nice experience, seeing how all the people dealt with the descent, because each person is focused on controlling his bike and enjoying the speed and wind. So it was a solitary meditative moment enabled by this group activity and effort. The whole time this is going on there was a rear guard which was probably putting on the brakes to keep the pack from getting too compressed and which was dealing with the annoyed motorists and an advance guard that had to open up the traffic when we got to the bottom of the hill, so there was also a sense that you were being given a gift of being able to enjoy this descent.

The pack rode around downtown a bit and ended up at Three Rivers state park where there’s a big fountain with a circular ring around it that some used as a velodrome. By that time the sun was really red. After that, everyone dispersed; it seemed like it was your job to find your own way home. I knew where the path was, just not how to get to its entrance from the park, so we had a short adventure with a densely wooded unofficial path before we figured out the proper way to get back home. Between the Critical Mass ride and the ride back we probably did 9-10 miles.

Anyways, so that’s the problem with the Critical Manners concept. Especially damning to me is the single-file line rule. The whole unpleasantness between cars and bikes is that cars get anxious when they can’t go 30 miles per hour, even when they’re just racing to the next red light and even when a bike is going 10+ miles per hour. The other lane’s taken and here’s this guy just toodling along on his bike in front of you, and oh! it’s just so frustrating. Making them wait is the quasi-political statement that says, we let you drive those things that poison our air and boil the planet, you don’t let us use this asphalt that we pay for.

---

  1. In the article about a San Francisco Critical Manners, there are 16 participants mentioned [back]
  2. Amy reminded me that it was turkeys, not geese. Turkeys is weird, geese not so much. Also, apparently the group word for turkeys is “rafter”? link [back]

Amy and I were sitting in an airport waiting for a flight. I said, “I should have been a pilot.” Amy asked me why. Really, it was just something to say; I was briefly imagining my alternate life in which I was an airline pilot. Instead of explaining the details of the fantasy (get to fly around the world, chicks dig on you, etc.) I said: “So I could fly far away from you.” See, it was funny to say because I didn’t mean it, and because this is so obviously a terrible thing to say to anyone, let alone your girlfriend. Oh, we had a good laugh.

Amy suggested that there could be an entire children’s book based on this premise:

  • I wish I were an astronaut… so that I could escape to another planet
  • I wish I were a deep sea diver… so that I could go to the bottom of the ocean and be alone
  • I wish I worked at night… so that I’d never see you
  • I wish I were an explorer in foreign lands… so that we’d lose contact
  • I wish I were a time traveler… so I could travel to before you were born… or after you died

Try this with your loved ones, the next time you’re feeling grumpy, or simply want to make an impression.

Pale bearded guy wants girl. His woman-savvy friend advises him to ditch the beard and get a suntan. “She’ll look at you in a totally new light, man. She’ll be all, who’s this guy?” Guy takes his advice and lays in the sun. Music montage, natch. Then we see him shaving his beard off, with the lather. With great satisfaction he wipes off the last lather and dries his face. We see him step out the door into the light. His face is evenly bronzed… except for the entire lower half, pitifully white, minus a small tanned crescent above his chin!1

---

  1. I had a mild form of this. I thought it was razor burn until I realized with horror what had happened. [back]

Is it bad that I really like this lyric? You kind of have to hear it. From Close Edge:

I’m Mos Definite, not think so
Flood ya city with the black ink flow
And my crew ain’t scared to let them things go
So, stop with the nonsense, like he conscious
I’m just alright dawg, I’m doin’ great dawg
I don’t play games so I don’t playa hate y’all
Get it straight or get the fuck up out my face dawg
I’m like the second plane that made the tower’s face off
That shit that let you know it’s really not a game dawg1

Your grind and my grind ain’t the same dawg
2

I think this is appropriate. While I was in Hawaii I went to the Pearl Harbor memorial, where you stand on a platform above the sunken USS Arizona with its 900+ interred corpses. Before you go out to the platform you watch a video that details the sequence of events. The tone of the video is mournful, but it never goes so far as to condemn the Japanese for the attack, only reminding the viewer that they were an Axis power. Yamamoto is treated as a figure like Robert E. Lee, personally against the war but determined to make the best military showing. Then when the attack happens, you feel a chill: so many ships in so little time, and there’s video of the Arizona exploding. Basically, because this was an attack on a military base, it’s possible to experience this event first objectively as awesome (deinos3), then parochially (and humanely) as dastardly, tragic, sad, etc. Anyways, I figure Mos Def’s figure is precise here. I remember on September 11, someone told me that a plane had crashed into one of the Twin Towers, and I assumed that he was talking about some freakish accident. It was only when I heard about the second plane, and then the collapses, that I knew it really wasn’t a game.

---

  1. The heavy repetition (e.g., dawg, dawg, dawg, dawg, and -ow for six couplets at the beginning) works IMO. [back]
  2. The other stuff going on in the song is interesting too. He’s saying that he’s not a gangsta rapper but he’s not going to criticize those who are. I like the poetic conflation in hip-hop. His “grind” is and isn’t the same as drug-dealing. It’s like the different accounts of gangsta on Damn, It Feels Good to be a Gangsta, one of which describes the President of the United States as a gangsta. Then, the main idea of Mos Def’s song is that he’s “close to the edge”, not of flipping out and killing someone, but he’s paying attention to what’s happening on the margin of society. [back]
  3. It’s a cranky prescriptivist cliche to remind people that something that is awesome, like an “awesome god”, is something that is terrifying to behold.[back]

I’m going to try to sound more like Andy Rooney1 up here on this blog. Also, how about I indicate when the boooring technical notes begin and end with technical and interesting.

This is one of my favorite xkcd comics. It really speaks to my experience. Usually I can pull away before I’ve finished registering for comments. Sometimes I’m halfway through a closely reasoned argument when I realize how perfectly pointless and non-personal-goal-advancing my actions are. Then, in the worst case scenario, there I am mixing it up with the other comment-warriors. Here’s me windmilling my way through a post about dolphin killing on Japanprobe. This used to be the url for a pitched brawl in which I interjected a few uninformed comments. Etcetera.

Anyway, I thought I’d write this post at a more meta level to dissuade myself from commenting elsewhere. So here goes (technical):

Have you ever noticed that Objective-C is really, really weird? Like, they just took all the C- and C++- style conventions and changed them? Me too. And on top of that it’s compiled and you do memory management and the engineers make APIs that have objects called NSCamelCasedFactoryMethodObjectFacilitator2. Okay, so then someone makes a script-y dynamic thing for managing the Objective-C stuff, good idea. And when designing this scripting interface they make the following language syntax design decisions:

Finally, the instruction separator is a dot, like in English sentences:
myString := ‘hello’.

The following example shows how to send a message to an object:
myString class

See, this is funny, because it’s completely different from every other programming language3. That is all.

Umm, but there is a somewhat interesting take-away. Both Apple and Microsoft have designed really sucky APIs (in terms of intuitability rather than functionality) , compared to which GTK is fairly sane (it gets a bit clunky when dealing with “GtkIter” operations). But the MacOS developers follow Apple’s improvements of this API, cooing over the increased simplicity afforded by the new NSMakesYourToastRegistry. It’s the same with new C#/ Windows API developments. So (this is actually the interesting part) the lesson is that when people work within a “closed” development system, they lose their sense about good and bad design!4

Here’s the idea. Closed development systems don’t get good feedback and don’t have good change mechanisms, so even very good engineers (probably Apple’s are some of the best) end up working in the dark a little. It gets all culty, because there’s an elect that makes the design decisions and a laity that passively learns the new scripture. And everyone’s straining so hard to understand what the design class hath laid down that they’re no longer perceiving the design objectively. And proprietary lock-in helps, because it leads to fatalism (”what can I do, switch to Windows?”). There are all these weird little island communities where the natives are effectively locked-in to a platform because they’ve already invested the energy to understand its weird design. This isn’t even necessarily a proprietary vs. opensource thing. There are strange over-designed opensource projects that aren’t particularly open because of this class division (and most opensource projects rely on only 1-3 main contributors, it seems). All I’m saying is that bad APIs / development languages happen when designers aren’t being influenced in the right way by the end-user developers, and I’m speculating that this has to do with particular attitudes and processes associated with proprietary code and also a kind of design elitism. I mean, doesn’t Objective-C code (as code) suck?

---

  1. I include this link because I think this already marginal reference will become incomprehensible in ten years.[back]
  2. Yeah, I’ve got their number all right.[back]
  3. Actually, these are pretty interesting design decisions. The := assignment syntax is wack, but probably necessary for named arguments or something. The dot on the end is okay, but you’re moving the OO-messaging operator into the generally useless semicolon position. By using the space for messaging, you’re now saying “subject verbs(args)” instead of “subject.verb object, args” (in Ruby you can omit the parens for a function). [back]
  4. So I sort of believe that. Mainly I’m bitter because I can’t get some code to work on MacOS.[back]

An instance of obsessive behavior: trying out various Wordpress themes, tweaking the CSS to look right, making sure the code highlighting is the same color as my gvim theme. Perhaps for hours. This by way of giving myself permission to stop.

« Previous Entries