jQuery: disable the submit button, but still send the button’s value

Solving the old user-hits-the-submit-button-twice problem is fairly easy using JavaScript and even easier using jQuery. Setting up a sequence like the following is no problem:

  1. User clicks the submit button
  2. Button becomes disabled
  3. The values of the form’s inputs are submitted

My problem is that disabling the submit button causes its value to not submit. Apparently no one else on the planet uses the submit button’s value because none of my Google searches revealed anyone caring about this in the context of using JavaScript to disable the submit button.

No doubt my custom framework could be better designed, but there are a few rare instances when I want to know whether a user submitted a particular form, or even which button in the form they used to fire the submit. If I disable the button, then I don’t get the button’s name/value and thus I lose information about what is happening on the user’s end.

I have two solutions to this problem, the first of which was inspired by Ryan’s comment to my initial draft of this blog entry.

SOLUTION #1: hide the submit button after click

$(document).ready(function() {
  $("input:submit").click(function (event) {
    $(event.target).addClass("Hidden");
    var form = event.target.parentNode;
    var msg = document.createElement("i");
    msg.innerHTML = "PROCESSING...";
    form.insertBefore(msg, event.target.nextSibling);
  });
  $("form").submit(function() {
    $(":submit:not(.Hidden)", this).attr("disabled", "disabled");
  });
});

You will note that I am making use of a CSS class that I’ve called “Hidden”:

.Hidden {
  display: none;
}

Now the sequence of events looks like this:

  1. User clicks the submit button
  2. The click listener runs a function that hides the submit button and replaces it with some italicized PROCESSING… text
  3. The submit listener then disables all other submit buttons
  4. The values of the form’s inputs are submitted, including the newly hidden submit button

SOLUTION #2: copy the name/value to a hidden element

This is my original, hacky solution:

$(document).ready(function() {
  $("input:submit").click(function (event) {
    var $submitName = event.target.name;
    var $submitValue = event.target.value;
    var $form = event.target.parentNode;
    $($form).append("<input type=\"hidden\" name=\"" + $submitName + "\" value=\"" + $submitValue + "\">");
  });
  $("form").submit(function() {
    $(":submit",this).attr("disabled", "disabled");
  });
});

Can you see what horrors I’ve wrought? Now the sequence of events looks like this:

  1. User clicks the submit button
  2. The click listener runs a function that copies the name/value of the clicked submit button to a hidden input which is appended to the form
  3. The submit listener then disables the submit button
  4. The values of the form’s inputs are submitted, including the new hidden input
  5. To the rest of my code, it appears as if the submit button’s name/value came through with everything else

Now don’t be stingy, man. Pass the data, dude.

Posted in HOW-TOs, Programming | 6 Comments

Mirror Dance by Lois McMaster Bujold

Lois McMaster Bujold scored the 1995 Hugo Award for Mirror Dance, one of the many books in her “Vorkosigan Adventures”. I enjoyed this one so much that I’m tempted to explore the rest of the series, but I want to keep my literary train moving.

Mirror Dance centers around the physically stunted Miles Vorkosigan and his psychologically tormented clone, Mark Vorkosigan. The two fight and charm their way through an aggressive stage of political powers using their shared genius and endless ambition. I feel like I’m not doing the plot much justice here… it really is fantastic.

But the real brilliance behind this book is the character construction of Mark, the clone raised from birth to assassinate his “father”. Mark’s internal monologue – the struggle against his demons – is incredible. Being able to create that character and build those thought processes takes quite a lot of skill. My hat is off to Ms. Bujold.

In terms of science fiction, what you’re mainly dealing with is cloning and advanced medicine. There is some FTL travel and futuristic weapons, but scifi technology is not the focus of this book. Maybe you’d consider this a “space opera”, but a great story is a great story no matter how you classify it.

Posted in Books | Leave a comment

Nintendo DS roundup II

Continuing from my first roundup, here is another batch of DS game reviews ordered from best to worst:

Puzzle Quest: Challenge of the Warlords

How does a Bejeweled clone (albeit with a few extra mechanics) keep me interested for scores of hours?

The answer is: By setting it within a rich RPG backdrop.

Although the core puzzle game and its variations did not have me jumping for joy, the RPG aspect kept me riveted. In a traditional turn-based RPG, each battle is sort of like a puzzle anyway – Puzzle Quest simply replaces the combat with Bejeweled. The ability to damage your opponent and cast spells while playing the puzzle certainly doesn’t hurt. This is certainly one of the finest that the DS has to offer.

Chrono Trigger

Ahhh, at last… this is the RPG I’ve been waiting for on the DS. I didn’t play Chrono Trigger when it originally came out on the SNES so this port was more than welcome. Having loved Chrono Cross on the PS1, I was not disappointed by its predecessor.

I did take an odd path through the game… I wound up boarding the “Black Omen” when it first appeared. For awhile I was hacking through really tough encounters, leveling on almost every battle. I finally had the opportunity to warp off the ship and wound up exploring a lot more of the game. However, the Black Omen battles built my party up to the point where there was little challenge in anything else I faced.

The time travel concept in this game is really cool, and Chrono Trigger is full of interesting characters and fanciful places. I’m not a huge fan of “semi-realtime” combat systems, but I did enjoy hacking my through the game’s many battles. I’m not going to hold my breath for another RPG of this caliber on the DS…

Puzzle Quest: Galactrix

Despite one of the best multimedia presentations I’ve seen on the DS, despite a quality story and RPG component, and despite a wealth of additional gameplay elements compared with the first Puzzle Quest, I really didn’t enjoy this game.

I wish that they would replace the whole “puzzle” mechanic with something closer to traditional RPG battles. Perhaps when it comes down to it, I just didn’t like playing their hexagonal puzzle game.

The other problem was performance. The game is constantly loading and saving, each operation taking agonizing seconds. It was hard to get into a groove with these interruptions. Along a similar vein, the puzzle itself hangs up a little bit following each special action. You click to bolster your shields or something, see your shield points increase, click on a hex to make a move, and nothing happens. You have a pause a beat or two for the game to perform some internal upkeep, and then you are allowed to move.

Galactrix presents itself in such an appealing way… I just wish it were as fun to play as it looks and sounds.

Mario & Luigi Partners in Time

Maybe I’ve spent too much time in the Paper Mario genre because I found this game to be kind of ho-hum. Controlling two characters simultaneously and solving puzzles by switching back and forth between the old and young incarnations of the plumbing heroes was interesting, but kind of gimmicky. In the end there just wasn’t enough to keep me coming back for more.

Lock’s Quest

What an annoying, disappointing game this is. A couple of years ago I spent a few weeks addicted to the Desktop Tower Defense flash game and later played a couple of amusing sessions of Defend Your Castle for the Wii. So when I read about Lock’s Quest I figured that I was looking at a slam dunk. After all, how could you go wrong with what is basically an RPG tower defense game?

Well, here’s how you butcher it:

  • Allow only 2-3 minutes to set up your defenses, with no ability to enhance or modify them once the enemies start pouring in
  • Throw in an obnoxious maintenance aspect that has you running back and forth repairing your walls and turrets with tedious “wax-on” motions on the touch screen
  • Break the tower defense model by adding “traps”. I wound up putting up minimal walls/turrets and just layering the ground with as many poison traps as I could – much more effective than building additional structures
  • Include poor character development and a mostly uninteresting storyline

Lock’s Quest had just introduced flying units (which proved to be of little threat) before I decided to give up on this game. I was intrigued to see that there was a multiplayer mode, but the lack of co-op makes me less inclined to try it out. I know I’m being hard on this game… it does have beautiful graphics and a nice interface. Most gaming sites probably give this one an 8, but that’s just not good enough.

Final Fantasy IV

I figured that Final Fantasy would provide me with wholesome RPG goodness, but I found myself slogging through this one. I don’t have much to say about this… I gave it a few hours and didn’t find anything that held my interest.

Anno 1701

This Sim City-style game didn’t do much more for me. Perhaps I’m not a fan of the genre. Also, it looks like crap on the DS.

Posted in Video Games | 2 Comments

Slow printing to Lexmark C522 from OS X 10.4

After a user complained that a 28-page PowerPoint document was taking an hour to print on our networked Lexmark C522, I narrowed the problem down to OS X 10.4 (in my case, 10.4.11).

Solution: use this PPD. In other words:

  1. Save the PPD to your desktop
  2. Go into System Preferences and remove the printer
  3. Add the printer back, specifying the PPD on your desktop as the driver instead of whatever OS X wants to use

My understanding is that the PPD I’ve linked to is supplied by Lexmark – perhaps they simply haven’t updated the 10.4.x driver on their website.

Posted in Hardware, HOW-TOs, OS X | Leave a comment

Using EDID data in xorg.conf

I have two Hanns-G JW199D (19″ 1440×900) LCDs connected to an nVidia GeForce 8400 GS video card. They worked great until I upgraded from openSUSE 10.3 to 11.0; Xorg seemed to have problems configuring the LCD connected to the video card’s VGA port. The image was cropped and at an odd, fuzzy resolution, but the LCD on the DVI port was fine.

I examined /var/log/Xorg.0.log and found this:

(WW) NVIDIA(GPU-0): Unable to read EDID for display device CRT-0

I was fairly certain that this had always been the case, and that the monitor in question was being configured from the “Monitor” and “Modes” sections. But after fooling around with modeline generators and tweaking xorg.conf, I was unable to create a configuration that would give back my 1440×900 display.

Finally I thought, can’t I just apply the EDID data from the working monitor to the problem monitor?

I fired up nvidia-settings and used that to dump a binary copy of the EDID. Then I grabbed read-edid and ran the parse-edid which conveniently generated a “Monitor” section for me. I integrated this output into xorg.conf and I was back in action!

Posted in HOW-TOs, Linux | 1 Comment

Norton Nightmares: Windows cannot connect to the Internet using HTTP, HTTPS, or FTP

The Problem: following a Norton Internet Security uninstall, I could ping IP addresses and hostnames, but not browse to either. Running XP’s Network Diagnostic gave me something like: “Windows cannot connect to the Internet using HTTP, HTTPS, or FTP”. The problem went away when running in Safe Mode.

I tried everything, including:

The Solution: run the Norton Removal Tool.

After 10+ hours of debugging, the problem was that my initial uninstall of Norton Internet Security had left severed limbs of that wretched beast still clawing at the vital organs of the WinXP laptop. I could hardly believe it. I did find Symantec remnants scattered around the system during my trials, but I dutifully removed them all. Yet somewhere, somehow, Norton was still doing what it does best: grinding computers to a halt. Reminds me of a Haiku that a wise man once wrote

Posted in Micro$oft, Rants | Leave a comment

The Ghost Brigades by John Scalzi

UPDATE: removed statements falsely accusing Scalzi of borrowing ideas from Joe Haldeman.

After trying to fight through some tough literary jungle, I was happy to find myself blazing through The Ghost Brigades (2006) by John Scalzi. This book lasted me all of one weekend; it felt really great to be reading voraciously again.

If one were to hybridize Joe Haldeman’s The Forever War and Forever Peace, you might end up with something very much like The Ghost Brigades. However, apparently John Scalzi himself (or someone acting on his behalf) commented on this blog entry to inform me of the coincidental nature of the similarities.

Although I was seeing familiar themes, there are good reasons why I tore through The Ghost Brigades in a couple of sessions; the book is a lot of fun and there is plenty of originality. Cool battles, alien intrigue, manufactured super soldiers, downloaded consciousnesses, interesting characters, and questions about humanity’s future… this book definitely hit my scifi sweet spot.

Posted in Books | 2 Comments

Mac OS X (10.5.6) Spotlight search results are crippled

Open a Finder window, run a search, and you’ll see that the results are presented in three sortable columns: Name, Kind, and Last Opened.

You might expect to be able to adjust those columns to include/exclude whatever file attributes you wish. After all, you can certainly do this when using Finder to browse the file system. What you wouldn’t expect is for Apple, a company known for slick GUIs and user-friendliness, to leave you standing alone on the freezing tundra with your pants around your ankles.

Sorry, I’m not sure why that particular imagery popped into my head.

I won’t spend too much time griping about this because others have already done the work for me:

The take home points are: 1) you cannot customize the search results, 2) “Last Opened” is a silly attribute to use, and 3) no one seems to know when/if Apple is going to correct this usability issue.

I submitted an enhancement request to Apple through their Bug Reporter and I suggest that you do the same. Blogging about the problem also couldn’t hurt.

A competent programmer who is familiar with the software could add customizable columns to the search results in about a day. Maybe figure a few weeks of testing/QA and Apple could push an update out the door. Or maybe this feature will be included in 10.6 as a way to get people to buy Snow Leopard. Either way, it’s a perfect example of the shortcomings of proprietary software.

UPDATE: Apple’s predictable response…

This is a follow up to Bug ID# 6778875. After further investigation it has been determined that this is a known issue, which is currently being investigated by engineering. This issue has been filed in our bug database under the original Bug ID# 5981948. The original bug number being used to track this duplicate issue can be found in the State column, in this format: Duplicate/OrigBug#.

Thank you for submitting this bug report. We truly appreciate your assistance in helping us discover and isolate bugs.

Posted in OS X, Rants | 1 Comment

Software RAID performance on various IDE configurations

I have two 500GB IDE drives that I will use to create a software RAID1 (mirrored) array. How should I connect them to maximize performance?

I’ve used software RAID on my personal file servers for years and ask myself that question every time I make changes. Google has never given me a satisfactory answer, probably because there are so many variables involved that the answer is too system-dependent. Even defining “performance” itself can be a little tricky.

This time I am going to do the work and figure out the best configuration for myself. To start with, here are my system vitals:

  • AMD Athlon XP 1700+, 256MB RAM
  • IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06)
  • Mass storage controller: Promise Technology, Inc. PDC20268 (Ultra100 TX2) (rev 02)
  • openSUSE 11.1, kernel-pae-2.6.27.19-3.2.1
  • RAID1 file system: reiserfs-3.6.19-116.62
  • Two WD5000AAKB HDs (EIDE, 500 GB, 100 MB/s, 16 MB Cache, 7200 RPM)

So here are all the places I could potentially connect the two drives:

IDE slot Abbrev.
Primary master Pri M
Primary slave Pri S
Secondary master Sec M
Secondary slave Sec S
Ultra100 TX2 IDE1 master IDE1 M
Ultra100 TX2 IDE1 slave IDE1 S
Ultra100 TX2 IDE2 master IDE2 M
Ultra100 TX2 IDE2 slave IDE2 S

I used bonnie++ -x 8 -u root and averaged the results to measure performance. I only examined configurations that were interesting to me, excluding “Pri M” because that is the location of the root drive. Here is what I found:

1st HD 2nd HD Write1 (KB/s) Read2 (KB/s) Seeks/s3
IDE1 M IDE1 S 21191 75227 235
IDE1 M IDE2 M 24061 75505 386
IDE1 M Sec M 35582 75802 296
Sec M Sec S 53798 74863 233
Sec M Pri S 75426 75150 396


1 Block Sequential Output (put_block)
2 Block Sequential Input (get_block)
3 Random Seeks (seeks)

The most obvious thing that I glean from this is that writing to the software RAID becomes faster when 1) the drives are on separate channels, and 2) the drives are on the IDE bus instead of the PCI bus. Similarly, random seeks per second improve significantly when the drives are on separate channels. This all makes sense to me – hardware configurations that increase the opportunity for parallel operations are more efficient.

However, there’s one thing I don’t really understand: if the Ultra100 TX2 is capable of the same read performance as the main IDE channels, why is it not capable of the same write performance?

In the end, I think I’ll go with the {Sec M, Sec S} configuration. Here’s why:

  • Although {Sec M, Pri S} offers the best performance, I don’t want to clog up both IDE channels with RAID traffic.
  • Despite this obsessive performance analysis, the server is question is basically just a personal jukebox – I really don’t need screaming speeds.

There. I feel better now.

Posted in Hardware, Linux | 1 Comment

openSUSE 11.1 > Ubuntu 8.04 server

Ubuntu seems like it’s the latest and greatest in the world of Linux distros, but it just didn’t measure up to openSUSE during my install fest last night. I run openSUSE at work so I figured I would get some variety at home by using Ubuntu on my personal file server. I tried installing Ubuntu 8.04 server twice and finally gave up. My gripes:

  • Don’t ask me questions throughout the installation – ask them all up front and then just do it.
  • No, I don’t want to set a special password for MySQL. I don’t want to do it now, nor the subsequent three times you prompt me at various points during the installation.
  • Freezing the system halfway through installation of GRUB is a dealbreaker, namely because I can’t complete the install.

So with some relief I dropped in my openSUSE disc and the install blew through like a breeze. Surely my comfort level with openSUSE helps, but the SuSE brand has been around a long time; it includes all those little fixes and exception handling that are a part of mature software.

Posted in Linux | 2 Comments