As I Drink This Beer

A dystopian “control” society based on distraction. Remember, in Brave New World it’s entertainment, in Brazil it’s bureaucracy and prolishness, in 1984 it’s fear and propaganda… but distraction as such is something different. You set your mind to do something and you get distracted, you forget to do it, you forget that you even wanted to do it. The political control is that you can only do what is programmed for you to do. The closest literary example I can think of is the thought-suppressing bells in Harrison Bergeron. GTD is about programming steps for yourself to do in the absence of a continuous memory, while any decent employer can provide you with a constant feed of Microsoft Exchange tasks to complete. I once read a cool story about a  guy with progressive alzheimer’s who programmed a computer to give him tasks and look out for his welfare after his mind went; it’s in this collection somewhere. Anyway, the genius of such a regime would be that it would sustain the illusion of purposive activity. It’s becoming more and more clear to me that we need to defend ourselves against our primate nature.

2008

You can’t really tell from this blog what I’ve been doing in the past year (or in previous years, either). Partly this is due to a congenital habit of not discussing anything that is directly relevant to my life. To know what’s going on you have to read the lacunae–if I’m not discussing it, it must be important to me1. The most prolific periods in this blog are from times when I wasn’t doing anything meaningful (and hating it). The recent long stretches of silence are due to an abundance of positive forward motion. The truth is, 2008 was a good year for me. Indeed, probably the most pressing dissatisfaction (and there are always dissatisfactions, c’est la vie) is the lack of reflection in my present mode. This makes me think about a Zadie Smith statement that she writes mainly so that she won’t sleepwalk through life. Yeah, let’s not do that. Anway, let me tell you about some major unannounced features of my current life.

First, I am 28. I am okay with this, really. Although I do think of January 13 as the starter’s pistol on a 2-year mad dash toward 30. Expect some erratic behavior  between now and then as I attempt to fill the waning years of my 20′s with value-added experiences.

Second, I am a graduate student. This is something that I’ve actually been doing since November of 2007. I am getting a Master’s in Philosophy at Duquesne University in Pittsburgh. This implies that I am living in Pittsburgh. Duquesne’s is a “Continental” program. If you don’t know what this means, in a Continental program it is possible and even common to say something that sounds and may actually be insane and have everyone nod. I’ve taken 9 classes so far. 3 more and a language to go. Most of them have been really great.

  • Fall ’07: Freud, Aristotle Metaphysics, Hegel Science of Logic
  • Spring ’08: Hegel & Shakespeare, Husserl Ideas I, Nietzsche
  • Fall ’08: Deleuze A Thousand Plateaus, Sartre B&N, Heidegger Contributions of Philosophy
  • Spring ’09: Contemporary Political Philosophy, Early Modern Political Philosophy

I’m re-reading Leviathan! I’m reading about Rawls!

Third, I am living in Pittsburgh. In fact, I have been in Pittsburgh for more than 2 years now!2 When I first got to Pittsburgh two years ago in January I was involved in a longish and dispiriting job hunt that ended with me joining a temp agency and doing some truly dull data entry. After the summer I got paid for a while to program in Ruby on Rails, then didn’t work in Spring ’08. The whole of the summer was taken up with an increasingly desperate and focused job hunt for a real, honest-to-god programmer job, which I landed in August! Also, randomly: Amy and I visited Hawaii in July.

Fourth, I am a software developer. I get up at 6:30 in the morning and go off to work as a web developer until 5 PM (well, I’m on salary, so this isn’t always true). My classes are all scheduled from 6-8:40PM. It could be concluded that I am following a course of study that is unified by the principle (or business rule, if you like), occurs after 5PM. This would be an ungenerous conclusion. The language I program in is PHP3. This is funny, because I actually hate PHP as a language (I’m a Ruby man). I like programming, though. I really like being a professional. After a post-collegiate career that has consisted almost uniformly of unchallenging, dull, hateful jobs I have a true appreciation for a job wherein I show up, devise technical solutions to interesting problems and then collect a reasonable salary for the work I do. And if I go straight from reworking the logic of the site “shopping cart” to a discussion of the Deleuzo-Guattarian “Body Without Organs”, that is the price of this lifestyle that I’ve chosen.

Fifth, other things I should mention:

  • I am paying down my credit card
  • I own a Playstation 3 and have completed Fallout 3
  • I watch too many movies
  • I hardly ever read any more and know this is bad. I like Murakami and graphic novels by Yoshihiro Tatsumi.
  • I have a nuanced but nonetheless loyal attitude toward open source

---

  1. I’ve long thought of this as the Kafka principle; Kafka never mentions God, Judaism or German ideology in his stories, which is how we know that he is preoccupied with these topics[back]
  2. I probably have a better internal map of Pittsburgh than I do of DC, because I’ve navigated a great deal of Pittsburgh’s east side by bike, whereas I seem to only know DC as a sliver of NW and a network of Metro stations.  [back]
  3. Primarily; web development is actually a combination of SQL, HTML, javascript and CSS and a server language[back]

Weird Spam

I actually wrote this a couple of months ago, but I was too shy to post it then.

I get the occasional weird spam mails that are sent to the alexandria-list-owner and I’m not sure if I can safely spam them in Gmail, so I end up reading a lot of interesting spam1. Most of the spam are about penis enlargement and viagra and are notable mainly for the creative euphemisms employed and the awesome shame tactics. Every once in a while I’ll open my inbox to something like this:

Stop being the weakling you are today.

Ouch. More recently, the spam has been related to fictional future events, apparently part of the Storm Worm, which Bruce Sterling has been following pretty closely. For example, I’ll get one that says:

Terrible earthquake devastated Beijing

with text “A new deadly catastrophe in China”. If you click through there will be a link to see videos, and this link will contain an .exe, which is how the worm spreads. The link, btw, is to an IP address which makes me wonder if the worm contains a small web server serving from a computer’s dynamic IP (cuz that would be smart).

Anyway, I got this new one today that struck me with its laughably hostile tone. It’s very rude and obscene, which is why I’m linking to the image. In other words, it’s NSFW: link. Tell me it doesn’t make you laugh a little with its absurdity.

---

  1. Obviously, I could have it not show up in my inbox, so I must have some purely sociological interest in it [back]

Idea Quickie: Event Wiki Site

Okay, so events are past public occurrences that get a URL. E.g., “a man who was wearing a gaudy green coat and playing a ukelele that disturbed people in the cafe at X.” In the case of crimes, these events would be linked to a crime report. But mostly the wiki page for an “event” would be for people to share an account about it, put a picture or video to it, etc. And there could be an interface that would essentially try to pinpoint events as an intersection between a timespan and a location. So this could really involve a Google maps mashup with two controls, an area box selector and a timerange selector. These would bring in sub- or dependent events from any larger set of events affecting the area. So for example, “the car crash at 6:15pm outside of the music festival venue (which occurred all day)” could coexist with the nearby event “woman who flashed traffic at 6:15pm outside of the music festival venue…”. Something like that. It would be a system that could report on mundane “shared urban events” or on crimes or on historical incidents. The main user story would be something like “I saw something remarkable today and wondered if others saw it and knew more about it; I went to the URL and shared a detail that only I noticed.” This is something that happens with local or topical blogs where an entry will become the canonical comment point for a public event, with the blog entry itself being updated through the incorporation of information from the comments.

Another City Story

I was at the local PNC Bank to deposit a paycheck, and I was writing out a deposit slip.  A woman said loudly to the bank teller something like, “I wish she’d just had the heart attack then!” and the teller demurred, “well…” “I have to laugh just so I don’t cry,” the woman explained, and walked away from the teller. In line behind her was a man pushing a baby carriage. “I have to stay away from you because you’re too cute!” the woman said to the baby in the baby carriage. The father smiled. Everyone looked at the baby (it was cute). The woman stood there for a second and said, “Yeah, I have to stay away from you so you won’t get what I’ve got.” She walked a few steps toward the door and turned, “No, wouldn’t want you to get what I’ve got.” A few more steps. “No, nobody wants what I’ve got.” Finally, she turned and as she was walking out the door, started to sing, “♫Nobody wants what I’ve got…♪“. I started laughing along with the young woman standing next to me.

My Ubuntu Setup

Update: It was cute to have the two articles together, but this will be better for googleability and notwastingtimeability. Added information about typing breaks and getting Twhirl.

This is also booring, but might be vaguely useful for someone out there.

I’ve set up Ubuntu so many times that I’ve put down some deep neural pathways for how to do it. So here goes. These are all commands I type right after the first login:

General Users

# I add this line to /etc/apt/sources.list or through "Software Sources" to get most recent gnome-do:
# deb http://ppa.launchpad.net/do-core/ubuntu hardy main
sudo apt-get install liferea pidgin-libnotify gnome-do gnome-do-plugins gmail-notify cheese glipper

Liferea is a decent feed reader1. In preferences I turn off the notification icon and click “Show the items of all child feeds…”. After setting up Pidgin I turn on the libnotify plugin and “Psychic mode”. libnotify gives you nice popups and psychic mode tells you when someone’s about to IM you, so you can log out quickly :) . Gnome-Do is pretty useful once you force yourself to use it (by default, it’s activated with super+space). You should enable most of the official plugins (click the corner down arrow and preferences) and teach yourself to keep tabbing to the more advanced options for an action. Gmail-notify is better than the Pidgin notifications IMO. Cheese is a Photobooth clone. Glipper is a more advanced clipboard. Add it as an applet to a dock (it’s called Clipboard Manager).

I have to add pidgin, gmail-notify and gnome-do to my startup session in Preferences -> Sessions. To my mind, this is clearly the most user-unfriendly but necessary step in the Gnome desktop experience. I should be able to right-click on the application in the dock to add it and each application should offer to do this for me, and I definitely shouldn’t have to type the correct application name (twice) to add it to an inscrutable list.

For Firefox, I install Firebug (a developer thing) and Delicious Bookmarks, and I hit YouTube to let the browser download Flash for me.

None of the native Twitter clients seem to work particularly well, so I’ve been using Twhirl with Adobe Air. Air is easy enough to install, just chmod +x the bin file and run it (you could also right-click it and change permissions to “read and write” for owner). You have to download Twhirl through the Manual Installation link.

One nice feature that’s a bit hidden away is Preferences -> Keyboard -> Typing Break2 for avoiding RSI/maintaining sanity.

The rest of these steps probably don’t apply to you.

Macbook Stuff

# Add this to /etc/apt/sources.list to get macbook stuff
# deb http://ppa.launchpad.net/mactel-support/ubuntu hardy main
 
# More configuration options for the touchpad
sudo apt-get install gsynaptics
 
# I install these for the isight and a weird problem with numlock staying on, respectively
sudo apt-get install isight-firmware-tools mactel-support-fnmode-fix
# Eh, I still get the numlock problem. Numlock goes on when I unplug my USB mouse?

I need to replace the relevant section in /etc/X11/xorg.conf to get two-finger right-click on my touchpad:

Section "InputDevice"
	Identifier	"Synaptics Touchpad"
	Driver		"synaptics"
	Option		"SendCoreEvents"	"true"
	Option		"Device"		"/dev/psaux"
	Option		"Protocol"		"auto-dev"
	Option		"HorizEdgeScroll"	"0"
	Option "FingerLow" "20"
	Option "FingerHigh" "30"
	Option "MaxTapTime" "150"
	Option "MaxTapMove" "90"
	Option "MaxDoubleTapTime" "180"
	Option "VertScrollDelta" "15"
	Option "VertTwoFingerScroll" "true"
	Option "FastTaps" "true"
	Option "TapButton2" "3"
	Option "TapButton3" "4"
	Option "SHMConfig" "true"
EndSection

Development Stuff

# Get vim and a friendly IRC client
sudo apt-get install xchat-gnome vim-full vim-gtk vim-ruby vim-python
 
# These give you most of the build requirements for your system
sudo apt-get install build-essential gnome-devel
 
# Probably will need these too
sudo apt-get install git-core bzr subversion mysql-server-5.0 apache2

FWIW, I set terminal profile to grey on black, with about 80% transparency.

Ruby Stuff

sudo apt-get install ruby ruby1.8-dev rdoc irb

Despite the fact that it’s essential for doing anything with Ruby, Rubygems is still packaged improperly on Ubuntu as of Hardy (it will work now but gem executables aren’t installed or chmod’ed or something). It’s still the best bet to build it from the most recent source from here.

wget http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz # e.g.
tar xvzf rubygems-1.2.0.tgz # again, e.g.
cd rubygem-1.2.0
sudo ruby setup.rb install
# For some reason, it's gem1.8 and not gem anymore. Let's fix that.
sudo ln -s /usr/bin/gem1.8 /usr/local/bin/gem
sudo gem install rails # say; do a new bash if it doesn't work

Actually, you want to use utility_belt in irb:

sudo gem install utility_belt

and create a file ~/.irbrc:

IRB.conf[:PROMPT_MODE] = :SIMPLE
require 'rubygems'
require 'utility_belt'

---

  1. although I’ve switched to Google Reader now that I have to juggle machines at work and home. [back]
  2. I set “Allow postponing of breaks” so I can click “postpone break” every three minutes for sometimes an hour. It’s a nice diagnostic for internet addiction. [back]

A Crash

This will be booring.

On Sunday I sat down to do some coding work that I had been procrastinating on1. Computer booted up, I logged in…and it hung. Did the ctrl-shift-backspace thing, but the screen just displayed what looked like memory codes and some failure messages.  Restarted a couple times and decided that my system was completely borked.

Grabbed two Ubuntu CDs off the top of my huge pile of burned but unlabeled CDs. The first CD I put in was for 6.10 and was the text installer. Now every time I restarted I was forced to boot from this CD because of my stupid-ass hardware… a Macbook that I only run Ubuntu on2 ; I couldn’t eject the CD using the keyboard key while in the text installer. After too much time figured out that the rescue mode worked and I could use the `eject` command on the drive (I found out later you can just hold down the touchpad button and hit the eject key on boot-up). In any case, with both CDs I was seeing the same strange behavior: a message that my system clock was set to Jan 1, 2001 and failures to install completely.

Oh, long tedious story short, first I thought it was the RAM, so I bought a new 1GB stick, then I thought it was the harddrive (but really I thought it was the motherboard, because of the clock thing), so I bought a notebook harddrive that had the wrong connectors. So as a totally random troubleshooting step, I burned a new copy of 8.04.1 and tried installing it3.  When the system started, I got the clock error but everything else worked. On the second startup I didn’t even get the clock error.

There is no lesson from this story4. Okay, there is a lesson: troubleshooting is hard, and if you really want to do it well, make a grid and work your hypotheses methodically. If I had done this I might have fixed my system on the first night instead of on the third day. The end result of my ordeal is that I have an extra 500MB memory, a scratched and scuffed Macbook interior, fewer screws on the exterior, and no idea whether my problem was software or hardware related. I basically expect my laptop to burst into flames at any moment.

---

  1. I don’t know if you procrastinate on or procrastinate about. I don’t even know how to ask Google the question. [back]
  2. I used to be able to dual-boot it with MacOS and it was pretty nice, but for some reason I nuked that partitition and I haven’t been able to reinstall from the CD. [back]
  3. The key was walking away once the install started and coming back after an hour, clearly. [back]
  4. I like to bug Amy by sententiously declaring, “I think we’ve all learned a valuable lesson today,” whenever one of us, usually me, does something stupid. [back]

King of the Set: Zombies

For no particular reason I’ve grouped a bunch of movies I’ve seen fairly recently (all in the last year, most in the last few months) into sets of three. Here’s the first set. Zombies!

I watched 3 zombie films recently:

  • Day of the Dead (2008 remake)
  • Diary of the Dead (George Romero)
  • 30 Days of Night

Diary of the Dead

Diary of the Dead was just okay. The idea of this movie is that it’s Cloverfield with zombies (Cloverfield, if you’ll recall, was Blair Witch Project with Godzilla). As with Cloverfield, this is going to be an extremely difficult conceit to pull off believably. The conceit is updated somewhat cleverly with the idea that the raw footage has been edited and produced in order to be as scary as possible. Also, there are two cameras that sometimes record each other, and there are montage intermissions and monologues by the documentary’s producer. George Romero wants to make the movie about the impossibility of neutral observation and the desire to record events in order to insulate yourself from true horror. The recurring phrase in the movie is “If it’s not caught on camera, it didn’t happen,” and there’s an idea that guns and cameras both “shoot” people. Anyway, George Romero is a very hamfisted director, and so the final result can’t be completely satisfying, especially the very last stupid scene. I liked this movie so much better than Land of the Dead, though, which felt like it was an episode of Buffy the Vampire Slayer (not a good thing in this case).

Day of the Dead (2008)

Day of the dead was a nothing film; I thought it would be an entertaining remake of the original Day of the Dead, since the remake of Dawn of the Dead was pretty good. They even tried to dupe me into thinking that Ving Rhames was somehow playing his character from Dawn of the Dead. He’s not that guy and he dies early on. This was a dumb movie because people would turn into zombies through an extremely fake-looking and over-the-top CG transformation and then they were “fast zombies” (in Diary of the Dead a character complains about the fast zombies unleashed by 28 Days Later, something like “they’re the resurrected dead! They lurch!”1 ). There were a couple somewhat decent scenes, but overall this movie was made just to take my $12.

King of the Set: 30 Days of Night

Waitaminute! 30 Days of Night isn’t a zombie film! Oh, but it is. In fact, it is by far the best zombie film I’ve ever seen. Let me explain. You see, zombie films in my book aren’t necessarily about zombies, if zombies are narrowly defined as “the living undead”. The zombies in 28 Days Later don’t meet this standard, nor do the zombies in I am Legend (in both, the zombies are “the living unwell”). However, both are clearly zombie films. Also, the presence of “the living undead” doesn’t necessarily make for a zombie film (for example, see the truly shitty The Killing Box, about lame supernatural zombies and the American Civil War). Finally, it could be argued that Hotel Rwanda is a zombie film, because zombie films are at heart about the small group defending against a dehumanized and murderous mob.

Thus, the biggest problem with saying that 30 Days of Night is a zombie film is that the danger comes from outside the community, not that the monsters are vampires. I took this as a creative twist on the genre, though. The general form of the zombie film is: the collapse of normal society by “zombie” epidemic; the creation of the ad hoc social unit (usually a multicultural “family”); the defense against the zombies, either successful or unsuccessful, depending on how dysfunctional the social unit is. Other sub-motifs are: competing social units (usually military ones) can be monstrous too, and, the attempt to wall yourself in will ultimately fail, usually because of human weakness or folly.

What I liked about 30 Days of Night was that the typical middle action of the zombie film gets derailed by the ferocity of the initial vampire attack (really quite scary). Instead of manning the barricades and getting whittled down, or assembling impromptu weapons which prove insufficient, the handful of survivors go and hide in an attic for a couple weeks. It’s clear that they don’t stand a chance against the vampires. There’s even a scene where Josh Hartnett burns one of the vampires with a sun lamp, and you think they’ll learn to fight back now, but the vampires just go and shut off the generator. Another thing that subverts the typical zombie film story is that the vampires are very animalistic and it’s unclear how intelligent they are. The vampires look and sound like birds or rats and their cruelty seems to be due to a total lack of connection with humans (the leader does give us some creepy vampire philosophy in what sounds like Russian, e.g, “They [the humans] believe the most ridiculous things”, but mostly the vampires screech and hiss at each other). What’s scary about this is that the vampires’ intelligence doesn’t mean that they are in a moral relationship with the humans, because they appear to belong to a different, perhaps superior, species.

30 Days is also extremely stylish. It’s based on a graphic novel, and on the second viewing I realized that most of the shots are static, like: shot of someone’s face; shot of the room; shot of something in someone’s hand. As with 300, it seems to have benefited from being well-storyboarded. The acting is good, too. This is a great horror movie, but also an interesting, well-made movie in its own right.

---

  1. A note about fast zombies: fast zombies seem to be the product of the disappointment over the failure of a peaceful world order to arise after the end of the Cold War. In George Romero’s original movies the slow zombies are representative of ideological squares, consumer drones and other mechanical, mindless types (this is why military types and racist Good Old Boys are considered to be equivalent to the zombies in the movies). The Rage zombies in 28 Days Later represent a more total social disruption that has a fast, explosive quality, like the Rwanda genocide (Jared Diamond suggests it may have been as much a grab for neighbors’ land as about anything else) or massive terrorist attacks (this is more explicit in 28 Weeks Later, where the American military is “just as bad” as the zombies). Fast zombies are about a kind of epidemic of social distrust based on pressurized social conditions (food scarcity, war, immigration) that has a tendency to explode and wipe out the liberal social gains. Or something. [back]
  2. Movies are $1 from the Redbox vending machine at the grocery store [back]

About Rails Checkboxes

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" })

Rails and Ext non-Ajax Signup Form with Password Confirmation

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).