Today I had the chance to mess around a bit more with the marvellous Prototype Javascript framework which in my opinion just keeps getting better and better. It makes me wish I had started using it 18 months ago when I first started getting (back) into Javascript and this thing called AJAX, it would have saved me a lot of head – and heart – ache. I’d highly recommend it.
However there’s one problem. And that’s tied to the fact that the vast majority of work I do is with databases, and therefore that means recordsets. A recordset, in case you didn’t know, is just a collection of records from a database. Say, a list of the details of all the users with a security level of ‘Administrator’. So, of course, I’m looping those records in PHP or ASP and outputting the result. So far so good. But what if I want to attach Javascript functions to each record, for example toggling a ‘more details’ section?
What I’d traditionally have to do is find out the records I’m going to be printing out, set up some kind of listener for each one at the top of the page, then print the recordset further down. That means two loops. Let me explain, in psuedo-code:
// Get all the users with a type of 'Administrator'
$recordset = $database->getRecordset("All users who are Administrators");
// Loop all the records
for each $user in $recordset {
// print each users name
print $user["name"];
// print a hidden area with further details on this user
print "";
// print a few more details about the user
print $user["email"]
print $user["phone"]
// end the hidden area
print "";
What I want to do is place a Javascript listener for each username so when it is clicked the hidden area is shown for that area. Of course, using Prototype and all the other Javascript frameworks I’ve seen, you have to add a separate listener for each thing you want to listen for. That makes sense.
However the difficulty is that I need to know about all the usernames at the top of the pge, where I can create my Javascript and put it in the head section, but often I don’t open the database until further down. Yes, I know, I know, doing it all as objects sorts this problem out, but that’s not always practical for older projects.
What I need is a method in Prototype that will allow me to listen for elements with attributes like what I want. In my example (using real code this time) I could create the following using my server-side code:
User 1
user1@email.com, 11111</p>
User 2
user2@email.com, 22222</p>
User 3
user3@email.com, 33333</p>
Then I would set my Javascript code to look for all elements with and ID like ‘user-[whatever]’ and set a listener for each element it finds. Like this:
// Loop all elements with ID like 'user-' then any series of numbers, using regular expression syntax
for (var i=0; i // get the value from the ([0-9]*) section for this element
var thisId = document.getElementsByIdLike('user-([0-9]*)')[i][0];
// for each element found set a listener using Prototype
Event.observe(document.getElementsByIdLike('user-([0-9]*)')[i].id, 'click', toggleDetails, false);
}
It’s a bit rough-and-ready (what else do you expect from me?) but I think this function would be really useful. Does anyone else agree? Does anyone else get what I’m on about?
The other thing I’ve been using today is JSON, a really lightweight way of transferring data about. It’s as easy as pie to parse it using Javascript, and makes a big step forward from my usual blunderbuss method of returning chunks of HTML from AJAX calls. Maybe this goes to prove I’m moving on in my geekdom. I’ll leave it up to you to decide whether that’s a good thing.