Skip to content

AJAX via jQuery in an Objective-C WebObjects app

As with using jQuery for DHTML, this was surprisingly easy. To make it simple to follow along I’ve published the source code to SignUp, a sample app.

SignUp’s default page is comprised of two WebObjects components: Main is the top-level page (including the jQuery script) and SignUpForm implements the form. As described in the previous post on this topic, the form’s email field is only enabled and populated if you tick the ‘contact me’ button.

ScreenShot of SignUp.gswa's main page

We can submit the form via an AJAX request, rather than by making the browser do a full request-response cycle. To do this, install a handler on the form’s submit event that does an AJAX post of the form then cancels the default behaviour.

   var signUpForm = $("#signUpForm");
    signUpForm.submit(function() {
        $.post(signUpForm.prop("action"), signUpForm.serialize(), function(data) {
            $("#formwrapper").html(data);
        });
        return false;
    });

As I’ve said before, I’m a jQuery newbie, there might be an easier way to do the above but this is definitely easy enough. One thing to notice is that the form’s own action is used as the POST URL, meaning that the WebObjects code is still responsible for expressing the control flow through the app.

The handler’s completion function replaces the form’s content with the data it receives from the POST action. That’s going to be another component, specified in the action handler:

- (GSWComponent *)registerInterestAction
{
  GSWRequest *request = [self request];
  [SignUpForm processSignUp: request];
  return [self pageWithName: @"Thanks"];
}

The request object provides access to the form values which are used in the app to populate an Add Person command, which is handled by adding the user’s details to the database. Finally the action handler loads a component called Thanks and returns that, which will replace the form in the web page.

Capture of SignUp.gswa after filling in the form

One thing to notice is that the server side is stateless; unlike many WebObjects apps that use a WOSession subclass (and have fugly URLs incorporating the session ID, if badly configured) everything is done via Direct Actions in this app, there’s no server-side state, and no session should get created. This conveniently avoids a big lock in the WebObjects framework, where the WOApplication instance has to synchronise access to the session table.

A stateless server satisfies one of the REST constraints; obviously we’re also using code-on-demand via JavaScript and have a client–server, layered system. Resources can be cacheable by setting the appropriate HTTP headers, not shown here but certainly doable. The only constraint not satisfied is the uniform interface and even that is partially present as WebObjects is by its very nature a HATEOAS system. Indeed this application arranged to observe HATEOAS by allowing the form object to express its own action URI, rather than “knowing” the form destination in the client code. The only part that’s missing is a resource identification and manipulation interface: instead of POSTing a form as done here a client would PUT a new person.