When Ajax goes wrong

So I’ve been migrating the about-me widget over to the new widget API in WordPress 2.8.2+ for the past week and I’ve not been having fun.

Actually I’ve had the majority of the widget done, and simplified for more than half that time, but I’ve been struggling with one issue since; how to get the rich text from the tinyMCE instance into the textarea on form submit so it will be saved. And let me tell you… it’s been a tail of one annoying discovery after another.

First let me say that the new widget API is impressively simple and a breeze to work with, however in many ways it reminds me of the iPhone, fantastic so long as all you need to do is what the original engineers thought you would ever want to do. In other words it has some limitations, and they’re mainly around the wp-admin/widgets.php page itself instead of the api.

Where to start?

Each widget admin form is rendered in it’s own form, fantastic, but the form has no id or name, boo. It took me a ridiculous amount of time to figure out the correct jQuery foo to get the form encompassing the current widget so that I could try and add a submit hook. Which brings us to the next issue, try as I might I could not find a way to actually catch the form submit event and force the tinyMCE widget to copy the html to the textarea. I soon discovered that this was because the form is never action submited, in fact the widgets admin page wires the ajax request to the onclick event of the save button. That’s right, rather than adding an onsubmit event handler to catch the form and ajax-ify it, they use an onclick event. If they’d actually used the form submit event then the tinyMCE auto detection would have worked on it’s own.

So as it stands we have a whole bunch of html foms with no id’s or names, which are ajax-submitted by an onclick event of the button. Not the best way to do it, but workable. So the next step is to register an onclick event hook on the button using jQuery and just force the tinyMCE.triggerSave() call in there.

Nope. That won’t work either, since jQuery fires all the click event’s asynchronously and the generic form submission click event is bound before my custom event. There is no way in jQuery to reorder the event bindings, you can only unbind them and add your own. Dirty, dirty, dirty.

I’m going to digress now to talk about Anthem.Net, an ajax library that knew how to integrate on both the client and server. Anthem did ajax exactly as I’d expected it above, it caught the form submit event, built an asynch request, fired it off and then updated the page with the new content. This conversion of a .net form postback concept to an ajax mechanism was named a callback in Anthem terminology, and Anthem provided a way to catch the event on both the client and server. On the client side it provided another event called onprecallback (or similarly named), which would allow the developer to hook in any client side code that needed to be run before the form was submitted. I was sorely missing this feature while working on this widget.

So now to the widget, what I have to do is unbind the save button’s click event, bind my own event that does the tinyMCE.triggerSave() call and manually call whatever functions it was that the save button’s click event was meant to call.

Not a clean solution at all, but it works

0 Responses to “When Ajax goes wrong”


  • No Comments

Leave a Reply