Aye, good idea, T.
I've been geeking it up a lot lately with all the new MoFo features, though most of them are pretty old hat; taking database records, outputting them, and formatting them with templates.
I did have to get pretty creative for
MoFo Lists, however. It's a big confluence of PHP and JavaScript.
I was going to try to break down the logic of the application step-by-step, but as I started I realized it would be ridiculous to read, and hard to follow, so I'll try to sketch out a somewhat rougher overview...
At one point in the process, I was simply planning to wipe out all related entries everytime someone submitted a list, and then insert whichever ones had been checked. After all, the version being submitted is the latest version, so why not dump the others?
Well, for three reasons: first, unless I checked for the existence of each entry, it'd have duplicates. The way the system works now is that there's a table for movies, and a table which logs movies seen; the "seen" table needs to apply to ALL lists, so it doesn't bother with associating itself with any particular list. Second, I wanted to know when each item was added, and I couldn't wipe everything out each time a new list was submitted without losing that. And third, I wanted to be able to track the addition and removal of items, which you can see on the
list updates page.
So, to do all this, I would need a few things. I already know which items are checked when the list is submitted; that part's easy. But now I need to also know which items were checked when the page first loaded. I need to know for two reasons: so that I can compare this list to the new one, so that I know when someone has UNchecked an item, and so that I can make sure not to delete the items that were checked, and stayed checked.
It breaks down like this:
- Items that were unchecked and stay unchecked, get ignored.
- Items that were unchecked and get checked, are inserted into the "seen" table.
- Items that were checked and stay checked, are excluded from the "delete" list.
- Items that were checked and get unchecked, are added to the delete list/deleted from the "seen" table.
I ended up tracking which items were checked originally upon page load by having hidden fields which share an ID number with them. These are all stored in an array, and when looping through the list upon submission, I use the PHP function array_key_exists() to see if the movie's ID can be found in the array. If it can't, that means it was NOT checked when the page loaded, and I can safely add it to the delete list (just a variable containing ID numbers).
If it CAN find the ID in the array, then, then it was checked to begin with. So, I check it against a copy of the submitted list; if it's not on there, that means it was checked, but was removed; so I add the ID to another variable ($removedmovies) for later, and add it to the aforementioned delete list variable.
After all that, whatever's left can simply be inserted. I added those IDs to another variable ($addedmovies). When I'm done, I insert both $removedmovies and $addedmovies (both comma-delimited) into the updates table.
There's more, but this gives you an idea of all the little details needed to get this sucker working. It looks so very simple at first glance, but it ended up being one of the more involved applications I've written in some time. It's ironic, too, because the intial version was very simple. At first, the movies were just stored as text titles, with duplicates and everything. There was no carryover from one list to another when you checked off a movie that was on both. Changing this fact ultimately complicated everything about the application, but has made it much more robust.
There's some little JavaScript touches, too. For example, when the edit page loads, there's a hidden, empty form field. Everytime an item is checked or unchecked, a JavaScript function is triggered. First, this function checks to see if the item in question has been checked, or unchecked, and switches the CSS classname of the movie title so that it's either plain, or crossed out. Then, it changes the value of the empty form field to "1." This lets the script know that you've made a change -- any change.
The result is that whenever you change lists using the dropdown menu on the right, the script checks to see if the value of the form field is 1 -- if it is, it knows you've checked (or unchecked) something, and asks you if you're sure you want to leave the page without saving your progress. It's a small touch, but these are the kinds of little extras I live for.
Code available upon request if you want it, T. Dunno how useful or interesting it would be, especially to someone who isn't wading knee-deep in it, but it was an interesting project for me for a few reasons. One of which being that it started off as uber-simple, became suddenly and frustratingly complex, but when finished, felt surprisingly elegant. I still think there are some significant inefficiencies in it, but I'm fairly pleased with where it is. There's lots of room for expansion and the like.
What about you, eh? What are you up to, geek-wise?