Problem with jQuery-UI Draggable and Form fields – Solved!

I’ve been using the Draggable functionality of jQuery-UI on a project and ran into a new problem. I needed to add form fields like SELECT and INPUT in my draggable div. Unfortunately, since my container itself is draggable it prevents clicking anything inside the container from being selected so I can’t choose items from the dropdown or focus on the input box to type text.

The solution is rather simple. Just add the appropriate selectors in the cancel option of Draggable. Actually, in my case I’ve migrated to Sortable so I added it there. Now my cancel option looks like: “select, input”. Works like a champ!

Help! Where’s My App Switcher Gesture in Lion?!

I rarely upgrade any OS when it is first released. This was always my practice with Windows, then Linux and now with OS X. So when Lion was released back in the Summer I passed on the chance to be first in line. Then 10.7.1 came out and I still waited. But with the arrival of iOS 5 and iCloud it was time to upgrade in order to take advantage of PhotoStream among other things.

I’m a huge fan of trackpad gestures and so I was pretty happy that Lion expanded the use of gestures, but I was shocked that my most often used gesture from Snow Leopard, the four finger swipe to open the Cmd-Tab application switcher, was gone. Cmd-Tab still opens the old application switcher but the familiar four finger swipe is gone and now there is a three finger swipe that invokes a switch between the new Lion desktops and full screen apps. So unless I run all my apps full screen, the switcher just goes between Dashboard and the main Desktop. Not what I want at all!

After half a week of frustration and searching for a solution I found BetterTouchTool. BTT gives me back everything I lost and more! I left the three-finger swipe alone and now have a four-finger swipe that opens up my long lost Application Switcher. BTT doesn’t stop there, however. It has an advanced application switcher where I can start the swipe and leave one finger on the pad and while still touching the pad, move the cursor to my desired application and then let go of the pad. With a few seconds of training my brain, I now switch applications faster than I ever did under Snow Leopard.

If you’re longing for more out of your trackpad or magic mouse, you must give BetterTouchTool a try. At the very least it restores lost functionality to Lion, but I think you’ll find it adds even more possibilities to gesturing than you had previously imagined.

DropBox vs SugarSync – Or why I’m keeping DropBox

I’ve used DropBox for quite some time now and loved it. When I needed more default storage, however, a friend pointed me in the direction of SugarSync. SugarSync offers a range of different features, but my clear favorite is the ability to flag any folder on my machine as a sync folder. No longer do I have to put my sync files in the DropBox folder, I can sync any of my standard folders and leave them in place.

SugarSync also maintains a distinction between which files came from which of my computers or mobile devices so if I want files specifically from my laptop instead of my desktop the mobile clients show that distinction.

Combine that with a base storage allocation of 5GB and SugarSync looks like the clear winner. Almost.

After two months of using SugarSync I still find myself using DropBox far more often in my day to day routine and there is one simple reason: mobile integration. It seems every app that I care about on my iPad and iPhone allows for DropBox interaction. If I want to work in Office2HD for example or PrintCentral or a myriad of other apps, all of my files have to be in DropBox. For reasons I haven’t explored, SugarSync does not have built-in support in any of the apps I use.

So while it is wonderful to have more storage and sync any folder on my machine, when I want to edit files in my mobile devices DropBox is the go to storage medium. Thus here I am two months later still using DropBox as my mobile storage medium and SugarSync as my cloud backup medium.

Maybe iCloud will change all that but somehow I still think DropBox is going to be my the storage medium of choice for some time to come. We’ll see.

Flash waning, HTML waxing?

Just an example from my own development contracts that Flash apps appear to be on the wane. I spent 3 1/2 years developing a Flash application using Adobe’s Flex technology. The app went live less than a year after we started and we spent the next 2 1/2 years adding features and improving the application. Then in the Fall of 2010 the customer asked how quickly we could rewrite the entire thing in html and javascript!

It took us (me and their own inhouse development staff) three months to rewrite the entire app in html+javascript to a beta version level. One of the key motivations was having a desktop version that worked on the iPad and having a mobile version that shared the same basic codebase as the desktop.

Now that we’re basically finished with the app and polishing the mobile version to work on iOS, Android, etc. it is hard to remember ever using the app in Flex. As much as I hate to admit it, HTML + AJAX has been far faster and less cumbersome to develop for than Flex. We had a very good Flex codebase using very good design patterns. The code was centered around the Cairngorm framework and everything was well modeled in the MVC2 pattern, but in the end, lack of developers with thorough Flex knowledge and desire to have it run on the iPad (and other tablets) drove us to html and javascript.

No looking back now.

Recursive Stored Functions in MySQL

I have only recently started working heavily with stored procedures and functions in MySQL. After years in the Oracle world with advanced stored procedures, functions and packages, I’ve had to come to grips with the shortcomings of MySQL. One of those is recursive functions. MySQL allows recursive stored procedures, but not recursive stored functions. Here is my workaround…

First create your main logic as a stored procedure with an OUT variable:

CREATE PROCEDURE my_recursive_proc(a_some_parameter INTEGER, OUT a_result INTEGER)
    DECLARE v_my_number INTEGER DEFAULT 0;
    -- Have to set max_sp_recursion_depth inside the stored procedure
    SET max_sp_recursion_depth := 20;
    SET v_my_number := v_my_number + a_some_parameter;
    IF v_my_number < 100 THEN
        CALL my_recursive_proc(10, v_my_number);
    END IF;
    SET a_result := v_my_number;

So now I have a recursive procedure that calls itself adding 10 to the initial number until we get to 100. In the real world we'd be doing something serious like descending through related child records until we find some search result. What I really want now is a function I can call in a WHERE clause somewhere.

Here's all we have to do:

CREATE FUNCTION my_recursive_func(a_some_parameter INTEGER)
    CALL my_recursive_proc(a_some_parameter, v_result);
    RETURN v_result;

Now in my SELECT statements I can do:
SELECT * FROM my_table WHERE my_recursive_func(some_column) = 100;

PhoneGap, BlackBerry and Windows 7 – Access Denied!

I have no idea why Windows 7 (and Vista) have decided that an Admin level user is not allowed to write files into Program Files, but apparently Windows knows better than I do what should happen in that folder.

Unfortunately, if you working with PhoneGap and building your app for BlackBerry, the default install locations for the BlackBerry WebWorks Packager is under Program Files and the PhoneGap build scripts copy the compiled COD files into the appropriate simulator folder under the webworks\simpacks folder.

After trying in vain to unset the readonly permissions on the simpacks folder under my normal account (which has admin privileges) I finally tried enabling the administrator account, logging in as administrator and then unsetting readonly on that folder. That didn’t work either. The Administrator user is able to run the build scripts just fine, but when I log out and back in as my normal user the folders are back to read only.

I even tried making my user the owner of those folders (per a blog post somewhere) and that didn’t work either. The PhoneGap build script (and just a regular copy command) get “access denied”.

I finally realize I just needed to run CMD as Administrator and my builds would work. So if you need to run PhoneGap build scripts in Windows 7 as a real user, just launch the Command Prompt as Administrator (right click on the Command Prompt icon and choose Run as Administrator). Now your builds will happily copy the compiled files to the simulator folder under Program Files.

VirtualBox and Ubuntu Hoary Hedgehog

Yes, I know, Hoary Hedgehog has been obsolete for a long time, but there are still customers out there with entrenched installations of the first release of Ubuntu that I have to support. Actually, for some of these customers where the machine is basically a point of sale machine with no internet access, Hedgehog performs just fine and there’s no need to upgrade.

In order to support these customers I needed to set up a test box in VirtualBox to test my updates locally before taking them to the customer. My first attempt on setting up Hedgehog using VirtualBox 4 failed with IO errors during partitioning. The problem is the default setup for a new VirtualBox machine is to use SATA disks and Hedgehog chokes on SATA, at least in VirtualBox. Removing the SATA disk and adding the VDI under the IDE controller worked like a charm.

Hope that helps anyone else still needing to test Hoary Hedgehog installations.

number_format modifier for Template_Lite

Anyone else puzzled why the Template_Lite template engine for PHP does not include a number_format modifier by default? I was. I googled and didn’t find one in my short search so here it is:

function tpl_modifier_number_format($number, $decimals)
		return number_format($number, $decimals);
		return number_format(0, $decimals);

Just save that into the template_lite/plugins folder as modifier.number_format.php and you’re all set. Now you can use this in your templates:


SVN Merging – Update First!

I’m not sure I’ve read this in the official redbean book or not, but in practice I’ve learned that you should always update your SVN tag to the latest version before merging trunk into it. I primarily use Subclipse inside of Eclipse for my SVN work, so this may apply more there, but I always to an SVN update on my tag code before merging the trunk into it.

I would think that merging HEAD of my tag with HEAD of trunk would take care of bringing in the latest code even if the working copy is not updated, but in practice this is not the case. So I always update my working copy to the HEAD of my tag and then merge in the HEAD of trunk.

Hope that helps,


CodeIgniter + qqFileuploader – UPDATED to support IE

I’m using CodeIgniter in a project with the AJAX file uploader qqFileUploader. I wanted my CI controller to handle the upload work for the file uploader instead of a PHP script that lived outside the CI framework. To make this work made a few minor changes to the qq files and I made some changes in CI that force the uploader to always use XHR upload for now and not iframes. Just updated the code to work with iFrames and tested successfully on IE6 and IE8.

Here are the changes:

First, copy the qqfileuploader.php class file to your application/libraries folder. We’ll be loading this as a library in the controller. UPDATE: You’ll want to add a function to the qqFileUploader class in this file. The function will help get the filename for iframe-based uploads. Here is the new function:

public function getFilename() {
$pathinfo = pathinfo($this->file->getName());
$filename = $pathinfo['filename'] . '.' . $pathinfo['extension'];
return $filename;

Second, make a minor change to the qqfileuploader.js javascript file so that it will pass the file information to CI using the CI-style URI instead of with query string parameters:

Find the qq.obj2url function. Comment out these two lines:

? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj())
: encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj)

and in their place put:

? encodeURIComponent(nextObj())
: encodeURIComponent(nextObj)

This just passes the file name of the object to CI and skips the parameter= part. Next find this line:

prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';

and replace it with:

prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '/' : '/';

Lastly find:

uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));

And replace it with:


Now for the CI controller function:

function uploadFile($filename = null) {
// This forces qqfileuploader to AJAX XHR mode

if (!isset($_FILES['qqfile'])) {
$_GET['qqfile'] = $filename;

// list of valid extensions, ex. array("jpeg", "xml", "bmp")
$allowedExtensions = array('jpg','pdf','png','doc','docx','xls','xlsx','png');
// max file size in bytes
$sizeLimit = 2 * 1024 * 1024;

$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);

$result = $uploader->handleUpload('/tmp/', true);

// Check if the filename is empty which it will be for iframe-based uploads
if (empty($filename)) {
$filename = $uploader->getFilename();

if ($result) {
// Get the mime type of the file
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, '/tmp/' . $filename);
$filedata = file_get_contents('/tmp/' . $filename);
// Do something with the file data, like save it to a BLOB or move it somewhere!

if ($result) {
// to pass data through iframe you will need to encode all html tags
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
else {
echo htmlspecialchars(json_encode(array("success" => false)), ENT_NOQUOTES);