I’ve been a hobbyist programmer since I got my first computer in 1984 or so. I greatly enjoy it and I’m terrible at it.

I mainly use JS to create utilities for myself that take me 1,000 hours to write and save me a lifetime of 45 seconds. I like Javascript for tawdry reasons: It’s straightforward, there’s a huge collection of libraries, any question I might ever have has already been asked and answered at StackOverflow, and I get to see the results immediately on screen. It’s of course also useful for the various bush league Web sites I occasionally have to put up (e.g., Everyday Chaos). Also, jQuery makes dumb HTML (DOM) work easy.

But here’s the but…

But, ECMA is taking JS in a terrible direction: it’s turning it professional, what with the arrow functions and the promises, etc. If you’re a hobbyist who enjoys programming for the logic of it, the new stuff in JS hides that logic on behalf of things I happen not to care about like elegance, consistency, and concision.

Now, I know that I don’t have to use the new stuff. But in fact I do, because the community I rely on to answer my questions — basically StackOverflow — increasingly is answering with the new stuff.

There’s a reason JS became the most used language on the planet: not only can you do webby stuff with it, it has a pretty linear learning curve. Now I literally feel like I’m in danger of losing “View Source” from my browser … literally because while I can view the source, increasingly I can’t understand it.

I’m going to lose this argument. I already have lost it. I should lose it. My position is wrong. I know that. Nevertheless, I stand firmly on the wrong side of history as I declare in my lonely, quavering voice: Keep. JavaScript. Dumb.

I’m more surprised than proud that I got this to work, but here’s some JavaScript that slides down a box when the user scrolls an alphabetized table and slides that box back up once the user stops. While the user continues scroll up or down the page, the box displays the first letter of the row at the top. When the user stops scrolling for about a tenth of a second, the box goes away.

Note that when I say that “I got this to work,” what I really mean is that I successfully copy-and-pasted code from StackOverflow into the part of my script that runs when the script is first loaded. And when I say “JavaScript” I really mean “JavaScript using the jQuery library along with the Visible plugin that I think I actually don’t need but I couldn’t get jQuery’s is(":visible") to work the way I thought it should.

So here’s an annotated walkthrough of the embarrassing code.

The first part notices the scrolling, shows the box, and fills it with the first letter of the relevant column of the table the page is displaying. (Thank you, Stackoverflow!)

The second part comes from another StackOverflow question. It notices when someone has stopped scrolling for 0.15 seconds and hides the block displaying the letter. And, yes, it could probably be combined with the first bit.

This is amateurish hackery. I understand that. But I’m an amateur. I’m not writing production code. I don’t have to worry about performance: this code works fine for scrolling 350 rows of a text-only table, but might crap out with 1,000 lines or 5,000 lines. At least it works fine so far. On the current versions of Chrome and Firefox. Under a waxing moon. I understand that I can get this far only because millions of real developers have posted their own code, and answered questions from fools like me. My hat is off to you.

For your copying-and-pasting convenience, here’s the code in copy-able form. (Click on the “Toggle line numbers” button on the bottom.)

1

var mywindow = $(window); // get the window within which

2

// the page is being displayed

3

var mypos = mywindow.scrollTop();

4

var newscroll;

5

// add a function that’s called whenever the window is scrolled

6

mywindow.scroll(function () {

7

newscroll = mywindow.scrollTop(); // the scroll bar indicator’s

8

// vertical position

9

// Go through the rows of the table to find the one currently at the top.

Because I don’t actually enjoy watching football, during the Pats vs. Broncs game on Sunday I transposed the Oscar™ nominations into a JSON file. I did this very badly, but I did it. If you look at it, you’ll see just how badly I misunderstand JSON on some really basic levels.

Why JSON™? Because it’s an easy format for inputting data into JavaScript™ or many other languages. It’s also human-readable, if you have a good brain for indents. (This is very different from having many indents in your brain, which is one reason I don’t particularly like to watch football™, even with the helmets and rules, etc.)

Anyway, JSON puts data into key:value™ pairs, and lets you nest them into sets. So, you might have a keyword such as “category” that would have values such as “Best Picture™” and “Supporting Actress™.” Within a category you might have a set of keywords such as “film_title” and “person” with the appropriate keywords.

JSON is such a popular way of packaging up data for transport over the Web™ that many (most? all?) major languages have built-in functions for transmuting it into data that the language can easily navigate.

So, why bother putting the Oscar™ nomination info into JSON? In case someone wants to write an app that uses that info. For example, if you wanted to create your own Oscar™ score sheet or, to be honest, entry tickets for your office pool, you could write a little script and output it exactly as you’d like. (Or you could just google™ for someone else’s Oscar™ pool sheet.) (I also posted a terrible little PHP script™ that does just that.)

Suppose you’re using the Dropbox API to let a user choose a file from her Dropbox folder and open it in your application. Dropbox provides a convenient widget — the Chooser — you can more or less just drop into your Web page. But…suppose you want to find out the path of an item that a user opens. For example, you want to know not only that the user has opened “testfile.txt” but that it’s “Dropbox/testfolder/TestA/testfile.txt”. The chooser only tells you the link is something like:

https://www.dropbox.com/s/lry43krhdskl0bxeiv/testfile.txt?dl=1

Figuring out how to get that path information took me /for/ev/er. I know it shouldn’t have, but it did. So, here’s how I’m doing it. (As always, please try not to laugh at my efforts at coding. I am an amateur. I suck. Ok?) (I owe thanks to Andrew Twyman at Dropbox who went out of his way to help me. Thanks, Andrew! And none of this is his fault.)

The way to get the path is explained in Dropbox’s API documentation, but that documentation assumes I know more than I do. Dropbox also provides an API Explorer that lets you try out queries and shows you the code behind them. Very helpful, but not quite helpful enough for the likes of me, because I need to know what the actual PHP or JavaScript code is. (It’d be easier if I knew Python. Someday.)

So, here’s roughly how I got it working. I’m going to skip some of the preliminaries because I went through them in a prior post: how to register an app with Dropbox so you can embed the Dropbox Chooser that lets users browse their Dropbox folders and download a file.

That prior post included code that initializes the Chooser. I want to add a single line to it so we can get the pathname of the downloaded document:

1

var opts= {

2

success: function(files) {

3

var filename = files[0].link;

4

filename = filename.replace(“dl=0″,”dl=1”);

5

$(“#filenamediv”).text(files[0].name);

6

alert(filename);

7

$.ajax({

8

url: “./php/downloadDropboxContents2.php”,

9

data: {src : filename},

10

success: function(cont){

11

$(“#busy”).show();

12

openOpmlFile_File(filename);

13

$(“#busy”).hide();

14

setCookie(“lastfile”,”/php/currentFile/” + filename);

15

getDropboxPath(filename);

16

},

17

error: function(e){

18

alert(e.responseText);

19

}

20

});

21

},

22

multiselect: false,

23

extensions: [‘.opml’],

24

linkType: “download”

25

};

26

var button = Dropbox.createChooseButton(opts);

27

document.getElementById(“uploadDB”).appendChild(button);

When a user chooses a file from Chooser, the “success” function that starts on line 10 is invoked. That function is passed information about the files that have been opened by the user in an array, but since I’m only allowing users to open one file at a time, the information is always going to be in the first and only element of that array. That information includes something called “link,” which is a link to the file that does not include the path information. So, in line 15 — the only new line — we’re going to pass that link to a function that will get that elusive path.

This is another AJAX call; it too assumes that you’ve included jQuery. (See the prior post.)

Now, how does this work. Well, I’m not entirely sure. But it’s sending a request to the Dropbox API. It’s doing this as a standard http web call, which means (I think) that you have to include metadata that web servers expect when you’re using http. (I could be wrong about this.) So, in line 6 you tell it that you are expecting to get JSON back, not a standard Web page. (JSON is a standard way of encoding human-readable, multipart information.)

In line 8 you’re constructing the URL you’re going to send your request to. Everything up to the question mark is simply the URL of the Dropbox API for getting metadata about a link. After the question mark you’re telling it that you’re authorized to make this request, which requites getting an authorization code from Dropbox. I’m probably cheating by using the one that the API Explorer gives you, but it works for now so I’ll worry about that when it breaks, which will probably be the next time I use it. Anyway, you need to insert your authorization code where it says “insert your authorization code” in all caps.

Line 9: The data is the internal link that the Chooser gave you as the URL of the file the user downloaded. I use JSON.stringify because it didn’t work until I did.

Line 10 is what happens when your query works. You’ll get an object from Dropbox that contains several different pieces of info. You want the one called “path_lower,” presumably because it gives you the path that is lower on the great Tree of Files that is a Dropbox folder. [LATER THAT DAY: Andrew tells me it’s actually called path_lower because it’s the path in all lower case, which is useful because the Dropbox file system is case insensitive. Frankly, I prefer my explanation on poetic grounds, so we’ll have to agree to disagree :)] Line 11 gets that path (cont.path_lower) and pops it into an alert box, which is almost certainly not what you actually want to do with it. But this is a demo.

That’s it. If you have questions, try to find someone who understands this stuff because I got here through many trials and even more errors.

Perhaps you’d like to post to your WordPress blog from an app that isn’t WordPress.

I know I do. I write most of my posts in an editor (javascript + php) I’ve worked on for over ten years. Someday I’ll clean it up and post it at GitHub so you can all have a laugh. Meanwhile, it intermittently loses its ability to post straight to my blog, so I have to copy and paste the text into the WP editor. But I fixed it again today. So, here’s a tutorial for people at my level of non-technicality. (I got huge help from a post at HurricaneSoftware. Thanks!)

First, make sure that the file xmlrpc.php is installed where you’ve installed your WordPress blog software. This file comes from WordPress itself, and it should be there automatically. Check the permissions; I think it should be 644 but I am terrible at permissions.

I run my homegrown editor from my Mac, using the Apache web server that MAMP supplies. That lets me write blog posts even when I’m not online. That means the directory from which I’m running my JavaScript and PHP is on my hard drive. I keep these files in /Applications/MAMP/htdocs/blogdraft/. (Blogdraft is the name of the folder in which my code resides.) To the web server, the address looks like this: /localhost/blogdraft/.

The operative part of this is your PHP file. Create an empty text file and name it, let’s say, postViaXmlrcp.php. For a first pass, it should look like this—and the brunt of this comes straight from HurricaneSoftware:

This PHP script relies upon another one, so you have to load it. “Require_once” will do so, and it will remember that it has done so during a session so you won’t waste computer resources reloading it every time you run this script.

You can get this script here. Right click on that link and choose “Save file as…” or however your browser puts it. Put it in the same directory as your PHP script. Make sure you name it “IXR_Librabry.php.inc.” Set its permissions. (See above.) Then leave it alone.

7

$title=$_REQUEST[‘title’];

8

$body=$_REQUEST[‘body’];

9

$keywords=$_REQUEST[‘tags’];

10

$category=$_REQUEST[‘categoryArray’];

11

$customfields=null;

These lines read data that you’ve sent from the JavaScript that we haven’t written yet. It assigns them to some pretty obviously-named PHP variables.

Notice that we’re doing nothing with the $customfields variable. That’s because I don’t know what to do with it. I would have just deleted that line, but it scares me. And yet fascinates me.

12

$encoding = ini_get(“default_charset”);

13

$title = htmlentities($title,ENT_QUOTES,$encoding);

14

$keywords = htmlentities($keywords,ENT_QUOTES,$encoding);

htmlentities is a PHP function that makes sure that your HTML with all of its weird characters arrive without being translated into something more literal and wrong. Line 12 tells it which character encoding to use. I could have decided on one for you, but instead I’m just using whichever one you already use. We have already established I’m a coward, right?

15

$content = array(

16

‘title’=>$title,

17

‘description’=>$body,

18

‘mt_allow_comments’=>1, // 1 to allow comments

19

‘mt_allow_pings’=>1, // 1 to allow trackbacks

20

‘post_type’=>’post’,

21

‘mt_keywords’=>$keywords,

22

‘categories’=>$category,

23

‘custom_fields’ => array($customfields)

24

);

We are eventually going to be sending all of the content information to WordPress via XMLRPC. This section packs an array (“$content”) with the information XMLRPC needs, attached to the keywords it loves. If you want to argue about it, take it up with XMLRPC.

26

$client = new IXR_Client(‘http://www.yourblog.com/myWP/xmlrpc.php’);

We now create a new client for the IXR script you downloaded. It wants to know where your xmlrpc.php file is, which should be where the rest of your WordPress files are folders are.

27

$username = “your-WP-username”;

28

$password = “your-WP-password”;

Fill in your WordPress username and password.

29

$params = array(0,$username,$password,$content,true); // Last parameter is ‘true’ which means post immediately, to save as draft set it as ‘false’

Now we’re making another array. This one includes the prior array ($content) as well as your username and password. And note the comment. Setting to “draft” is very useful when you’re playing around with these scripts.

This does the deed. No one knows how. If it fails, it’ll pop up the error messages and kill it before it spawns evil. Otherwise, it sends back the message that it posted successfully.

You can test this PHP script by running it in your browser. If you’re running a local web server, you’d enter something like this: /localhost/blogdraft/postViaXmlrcp.php. (That’s assuming you put it in a folder called “blogdraft,” of course.) Check with MAMP or whatever you’re using for your web server for details.

But running this as-is won’t work because it’s expecting the content to be sent to it from the JavaScript we still haven’t written. So, comment out lines #7-11, and insert something like these:

$title=”TEST TITLE”;

$body=”<h1>Hello, world!</h1>”

$keywords=”tag1,tag2″

$category=array(“cat1″,”cat2”);

$customfields=null;

Replace the categories (“cat1”, “cat2”) with the names of categories that you actually use. Also, change “true” to “false” in line #29 so you’ll just produce drafts, not actually publish anything yet.

Now when you run this PHP file in your browser ( /localhost/yourLocalFolder/postViaXmlrcp.php), if should create a draft post. Check via the “All posts” page at your WP administration page to see if the draft got created.

When it’s working, comment out the four lines immediately above and uncomment lines #7-11.

The JavaScript

I’m going to pretend that you have some HTML page that has a text box where you can enter the content of your post, a similar box for entering the title, one for entering tags separated by commas, and checkboxes that list the categories you use. I’ll also assume that you use jQuery. So, your HTML might look soomething like this:

This loads jQuery from Google. Of course you could keep a local copy and include it that way.

8

function postIt(){

9

// get the title

10

var titlecontent = $(“#titlebox”).val();

11

// get the body of the post

12

var bodycontent = $(“#contentbox”).val();

13

// get the tags

14

var tagscontent = $(“#tagsbox”).val();

The postIt function begins by using jQuery to fetch the values entered into the three text areas. (Just in case you don’t know jQuery, “$(“#titlebox”) gets the element with the ID of “titlebox.” And if you don’t want to use jQuery, you can get the same result with: var titlecontent = document.getElementById(‘titlebox’).value.

16

// get an array of all checkboxes in the div

17

var checks = $(“#categories”).find(“input”);

18

// create an empty array

19

var cats = new Array();

20

// go through all the checkboxes

21

for (var i=0; i < checks.length; i++){

22

// is this one checked?

23

if ($(checks[i]).is(‘:checked’)){

24

// if so, then push its value into the array

25

cats.push( $(checks[i]).val() );

26

}

27

}

Creating an array of categories takes a little more work. Line #17 creates an array (“checks”) of all of the checkboxes in the div with the id “categories.” Lines #21-27 look at each of the checkboxes in that array. If line #23 sees that a particular checkbox has in fact been checked, then it puts the value of that checkbox into the created on line #19. (You want the value to be exactly the same as the name of the category in your WordPress installation. Also, remember that the checkbox’s value is not necessarily the same as the text displayed to the user.)

Now we call the PHP script that we created above. We do this via AJAX, using the jQuery syntax, which is much simpler than the native JavaScript way of doing it. Lines #30-40 specify the communication the JavaScript will have with the PHP file.

Line #30: The “POST” here has nothing to do with posting a blog post. It’s stating what sort of transaction we’re about to have with the PHP script.

Line #31: This is the path to the PHP file we’re going to run. If it’s in the same directory as this HTML file, you don’t have to monkey with a path name.

Line #32: We’re going to pass data to the PHP script in the JSON way of expressing data.

Line #33: This creates the JSON we’re going to send. It’s all within curly brackets. There are four phrases, separated by commas. Each phrase consists of a keyword (which you can think of as being like a variable) and a value. We are free to make up whatever keywords we want, so long as those are the keywords we use in the PHP file to fetch the data that they label; see lines #7-10 in the PHP script above.

Line #44: If there is an error in the PHP, it will send back some information. There is also an equivalent “success:” function available. But I’m doing something wrong, because even when the PHP works and the blog gets posted, I still get an error message. If you go back to Line #33 of the PHP, you’ll see that if the PHP succeeds, it sends the message “Article Posted Successfully.” For reasons I don’t understand, that message shows up in the “error:” function of the AJAX. So, I check the message. If it has the word “Successfully” in it, the script alerts the user that the post has been posted. If it does not, on line #39 it posts an error message.

That’s it. If it doesn’t work, it’s because you’re doing something wrong, starting with listening to me. Obviously I can’t help you since I don’t even know how this thing works.

I was writing a long-ish tutorial about how to use LibraryCloud that refers to bunches of Javascript. I wanted a way to refer to that code in the HTML document. So I wrote a converter that turns Javascript code (and maybe others) into HTML tables you can just plunk into your document.

There’s definitely some clunkiness to this. For example, if you click on the “toggle line numbers” button it hides or shows the line numbers for every such table in your document. (I’ll fix this eventually.) By the way, the “Toggle” button is there so your readers can select the code and not get the lline numbers.

Also, in order to get the formatting totally encapsulated within your document, I clunkily add a “<style>” section before each table. I couldn’t figure out any other way to do it without making your HTML document dependent on my server being up.

Much as I love being a hobbyist programmer, it can sometimes be frustrating as all get-out. Sometimes it’s just a bug because I made a dumb error (getting a variable’s scope wrong) or because I made an assumption about how something works (BBedit‘s hex dump does not show you the content of the file on the disk, but of the file in memory, including the line endings it’s transformed). But then there are the frustrations that come from not having the slightest idea of the basics. The worst are the basics that are so basic that the explanations of them assume you already know more than you do.

Welcome to the world of pain known as uploading multiple files using Javascript. For example, suppose you are writing an app that lets users take notes on an article using a plain old text processor. They can then upload those note files to some code that processes them, perhaps turning them into a database. Rather than having users upload one file at a time, you want to let them upload a bunch.

There are plenty of slick, free examples on the Web that provide beautiful front ends for doing this. Many of them I could get to work, but not exactly the way that I wanted. Besides, I was really really really confused about what happened after the front end.

So, after a lot of skullpounding and forehead slapping, here’s a guide. But please take seriously this warning: I barely know what I’m doing, and I’m undoubtedly doing this in the clunkiest fashion possible. I am very likely getting important things wrong. Some of them may be fatal, at least in the programmatic sense. (If you have a correction, please let me know. Note I may fix the code that follows, rather than doing the usual — and proper — Web thing of striking through the errors, etc.) Here goes….

To enable uploads, you’ll be writing code that will live in two places. The user interface code is in the HTML running in the user’s browser. The files are going to be uploaded — copied — to a web server. The code in the browser is going to be Javascript. The code on the server is going to be PHP, because Javascript is for browsers. (Oversimplification noted.) Those two places can be physically the same machine. If you’re using a Mac, a web server comes standard; if you don’t have a web server handy, there are bunches of free ones; that’s beyond the scope of this post.

After experimenting with many of the beautiful packages that are available, I gave up and went with the HTML5 solution. Modern browsers will have no problem with this. If you need to design for the world of old-fashioned browsers, then you need to find a competent explanation. In short: I love you, but go away! (Apparently, if you use the HTML5 solution, it will still be usable in lesser browsers, although it will allow users to select only one file at a time.)

HTML5 makes it ridiculously easy to do the user interface bit: you just tell it you want to allow multiple selections within a file-chooser dialogue. This comes from a post by Tiffany Brown:

This will create an input field that when clicked will launch a file-browsing dialogue box in which the user can select multiple files. It then sends it to the PHP script called “processThem.php” on your server. The two key points to note are that the first line does the work of allowing multiple choices, and the “[]” in the name turns that variable into an array that will pass the entire list of user choices to the PHP script waiting on your server.

Here’s what it looks like, although this particular example won’t actually upload anything:

Now you have to create the “processThem.php” script (or whatever name you’ve specified) on your server. The uploaded files get placed in an array called $_FILES. But, they don’t get stored on the server for long: they are stored in a temporary folder from which they are automatically deleted after a little while. So, you need to process them, and quite possibly move them for permanent storage to a folder of your choosing. Here’s some sample PHP code from an anonymous commenter (“Me”) on the Tiffany Brown post:

In the first few lines, Me does us the favor of providing non-technical explanations of possible errors, so that if something goes wrong, it will be easier to know exactly what it was.

$upload_dir = './tmp/';

Then Me designates a particular folder as the container for the uploaded files. Me chooses one called “tmp” in the same directory as the PHP script. (Make sure you have such a folder and the permissions are set, or, of course, create one with whatever name you’d like.)

$num_files = count($_FILES['upload']['name']);

Then Me gets a count of how many files were uploaded, and stores it in the variable $num_files. You tell that variable that you want the number of files that were included in “upload[]” in the form on your HTML. (You can use whatever name you want on that form, so long as you use the same one in your PHP.)

First the easy parts. The baseline function returns just a file’s name without any path information; we want that because the point of this line is build a path to where the file will be saved in the folder you’ve set up for it. Also, I added the urlencode function in case the name of the file your user uploaded contains spaces or other characters that makes your server barf.

Now consider $_FILES[‘upload’][‘name’][$i]. It’s got those weird bracketed terms because $_FILES is an associative array. You can think of the usual sort of arrays as pairing a value with a number; give the array the number and it returns the value. In an associative array, values are paired with arbitrary keys (i.e., a word); give it the key and it returns the value. Here are the pre-defined keys for the associative array that gets sent to the PHP script when a user uploads files:

name: The file name of the uploaded file

type: Is it an image? A music file? etc.

size: The size in bytes

tmp_name: The crazy-ass name of the copy being stored on the server

error: Any error codes resulting from the upload

So, suppose you’re cycling through the array of uploaded files as in our example, and you want to get the name of the current file (i.e., file $i in the sequence):

$fname = $_FILES['upload']['name'][$i];

The [‘upload’] designates the array of all uploaded files. The [$i] pulls out of that array all of the information about one particular uploaded file, just like with ordinary array. The [‘name’] gets the value associated with that key for that particular file. As $i is incremented, you get the name of each file. If you wanted the crazy-ass temporary name, you would put in tmp_name instead of name, and likewise for the other parameters.

if (!preg_match("/(gif|jpg|jpeg|png)$/",$_FILES['upload']['name'][$i])) {
print "I asked for an image...";
}

Next Me optionally checks the name of the uploaded file for a particular set of extensions in case you want to limit the uploads to images (as in Me’s example) or whatever. Me is using regex to do the work, a function for which I am doomed to a copy-and-paste understanding.

if (@is_uploaded_file($_FILES['upload']['tmp_name'][$i])) {

Next Me does a check to make sure that the file was actually uploaded and is not the result of malicious code. is_uploaded_file is a built-in PHP function. The preceding “@” suppresses error messages; I don’t know why Me did that, but I’m confident it was the right thing to do. While you are debugging, you might want to take the @ out.

move_uploaded_file($_FILES['upload']['tmp_name'][$i], $upload_file)

If the file passes that test, then Me moves it to the folder s/he designated. Note that we’ve already put the pathname to the storage folder into $upload_file.

Obviously, where the script has the comment “Great Success” you would put the code that does what you want to do to the uploaded file. I have added two lines — commented out — that get and print the content of the file; that gets ugly if the file isn’t some type of text file.

So, please let me know what I’ve gotten wrong here. (And maybe sometime I’ll give you some truly embarrassing code for returning the results of the PHP on the page that has the upload form on it.)

Hallelujah! For years — literally years — I’ve been limping along with a blender full of spaghetti to do something that should be really simple: capture control key combos (like CTRL-S or CTRL-I) via Javascript in all the major browsers. I finally found some simple code that seems to work beautifully.

The problem is that the browsers don’t agree about what’s going on when a user presses a control key and another key simultaneously, which is, after all, the usual thing people do with the control key. Some of the browsers think that it’s two events, so you have to record the control keypress, remember it, and treat the next keypress differently. Other browsers think of it as a single keypress that you can just process as a if CTRL-S were a unique key. Then, depending, you may or may not have to nullify the S press. The way I was doing it (cribbed from multiple sources, of course) involved first checking on which browser the Javascript was running in, and then process keystrokes, looking for an initial control press. Pain in the butt, and it was fragile.

I am certain that this is not a problem for actual developers. For example, jquery handles keystrokes, although I had trouble getting it to work (becaues, if it’s not clear, I am a ham-fisted hobbyist who mainly just copies in other people’s code. Thank you, other people!)

First, include jQuery. Place the following into your Javascript the following block. Put it toward the top, and don’t put inside a function. You want it to run whenever your Javascript loads. (Well, you could put it into an initialization function if you want.)

I mentioned to my nephew Joel Weinberger, a CS grad student at UC Berkeley, that I wished the Javascript “split” method took multiple delimiters, and within minutes, he wrote one for me. If you know what I’m talking about, you can click here to get a zip file with the code (including a function as well as a method) and a sample. If you don’t …

[Note: all explanations are approximate.] Javascript comes with a built-in method for converting a string (that is, what normally consists of letters and characters in quotes) into an array (that is, a data structure of numbered elements). So, if you have a string that’s really a list of elements, such as “monday, tuesday, wednesday” or “12-345-6,” the split method will automatically chop it up into an array, using a delimiter of your choice (a comma or a dash in the two examples given). This is very useful.

But suppose you have a string such as this: “beef OR chicken AND duck” You want to be able to chop it up at the ORs and the ANDs, but the split method only lets you specify one delimiter.

Enter Joel. His multiSplit method lets you specify an array of delimiters. It chops up the string and records the phrases and their delimiters. Very handy.

I’m a-lovin’ Marijn Haverbeke’s Eloquent Javascript, an interactive javascript tutorial. It’s clear, nicely written, nice looking, handy (what with its embedded console for trying scripts out), free, and Creative Commons licensed. It’s easily downloadable so you can run/read it even when you don’t have any of that newfangled “broadband” the kids are so excited about.