Surfin’ no more.

RSS has had a profound affect on the way I use the web. I check my subscriptions using PulpFiction a couple of times a day, occasionally adding new feeds that I find there, but I rarely surf any more. Safari’s running pretty much all the time – I develop web based applications after all – but It’s not getting the workout it used to.

Using WebObjects DirectActions – pt. 2

At the conclusion of part one of this mini-series we had successfully configured a WebObjects application to accept DirectActions, had written a simple DirectAction method, and created a WOHyperlink to trigger it. Now it’s time to look at some of the common additional requirements you might encounter. As I mentioned last time they are:

  1. Passing parameters to our action
  2. Accessing a database with our action
  3. Invoking or using a Session with our action

Each of these will take a little work to get through, so I’m going to tackle them in several separate posts. Today we will look at passing parameters to our actions. We are going to extend the examples we used last time so fire up your IDE (Eclipse I hope) and lets get started.

Passing parameters to a DirectAction

Being able to trigger an action based on the URL is fun and all, but often we will want to do more. More? what could we possibly want that is more? Well submitting a form to a direct action URL might be nice, or passing a value to the next page for display or to modify its behaviour would be cool too.

To get this to work we have a number of issues to cover:

  1. Handling parameters in our action
  2. Passing a single parameter to our action
  3. Passing multiple parameters to our action

1. Handling parameters in our action

The first thing we are going to tackle is to get our DirectAction to handle parameters attached to our URL. Our DirectAction class has access to a WORequest object through the request() method. The WORequest contains a bunch of information about the current request, including any form values – which is how we will be passing values into our DA’s. These can be accessed through the following methods:

  • formValues()
  • formValuesForKey(String aKey)
  • formValueForKey(String aKey)

I suggest you take a look at the documentation for WORequest for more information but here is a brief summary of what they do:

  • formValues – returns an NSDictionary with all of the form values. The names are represented as the NSDictionary keys each with an NSArray containing its value(s).
  • formValuesForKey – returns an NSArray of the form value(s) that match a given name (key).
  • formValueForKey – returns an Object that is one of the value(s) that matches a given name (key).

Note: formValues() and formValuesForKey(String aKey) will return NSArray’s of values. This is because multiple form values can be associated with any given name (key). The NSArrays returned are sorted in no particular order – be warned.

Similarly, the Object returned by formValueForKey(String aKey) will be arbitrarily chosen from the NSArray of returned values – only use this method if you can be assured that there is only one value for each key (or don’t care which value you receive).

Lets extend the helloWorld example from last time to see how this works. Open your project and modify the helloWorld method in the DirectAction.class so it looks like this:

public WOActionResults helloWorldAction() {
	// Using formValues()
	NSDictionary dict = this.request().formValues();
	System.out.println("Form Values for request: " + dict);
	WOComponent page = pageWithName("Main");
	page.takeValueForKey("Hello World", "myDisplayString");
	return page;
}

Granted, this is not awe inspiring code, but it will help us to explore the next section.

2. Passing a single parameter to our action

Build the application and run it. If you are working on the project we built last time your web browser should open a new page with a single link. Click on the link to get to the Hello World page. You should see something like this in your console:

Form Values for request: {}

Which is understandable, as we haven’t supplied any values. Let’s change that. Append the following to the current URL "?=thisIsATest" so it looks like this:

http://STD_WEBO_URL/Test.woa/wa/helloWorld?=thisIsATest

The STD_WEBO_URL will look something like: "localhost:55555/cgi-bin/WebObjects/" it’s abbreviated for brevity… and to make it shorter too.

Hit return to submit the modified URL and you should see this in the console:

Form Values for request: { = ("thisIsATest"); }

Because we did not append a key-value pair to the URL, our resulting dictionary is missing the key. This is fine if we don’t need to uniquely identify our values. If we are just passing one value, we can retrieve it using formValueForKey("").

3. Passing multiple parameters to our action

Having one value is rare, in my experience, so lets look at identifying our value with a key. Appending a key to the URL is easy, the resulting URL will look like this:

http://STD_WEBO_URL/Test.woa/wa/helloWorld?aKey=thisIsATest

Submitting this URL to our application should give us this in the console:

Form Values for request: {aKey = ("thisIsATest"); }

We can explicitly retrieve this value using formValueForKey("aKey").

Finally, lets look at sending multiple key-value pairs. Simply append additional pairs (key1=value1) separated by an & symbol:

http://STD_WEBO_URL/Test.woa/wa/helloWorld?key1=value1&key2=value2

This URL should give us the following in the console:

Form Values for request: {key1 = ("value1"); key2 = ("value2"); }

Again, using formValueForKey("keyN") will allow us to get each of these values from the request.

You should now have a pretty good idea of how a simple DirectAction works, and how values are encoded into the URL. However, it would be nice if we could get the URLs without having to enter them by hand. So, next time we’ll look at generating the DirectAction URLs by using the bindings on WebObjects WODynamicElements.

Swansea Figure Skating Association

I built a little website for the Swansea Figure Skating Association last year. This is a local volunteer group that runs figure skating classes at the outdoor rink in Rennie Park. This entry is for Google, since for some reason, Google has forgotten they exists.

So if you are looking for figure skating lessons for your self or your children, in Bloor West Village, the Swansea Figure Skating Association may be for you.

:-)

Raccoon proofing your Green Bin

According to the City of Toronto our new Green Bins are as Raccoon proof as possible. Obviously they’ve never met our neighbourhood raccoons (genius IQ’s I guess).

After cleaning up our back porch a couple of times, I decided a quick trip to Home Depot was in order

Raccoons usually like to tip things over, this gives them more leverage as they pry on the latch or lid. So I mounted a couple of brackets on the porch railing to suspend the bin a couple of inches off the ground. The bin is not very heavy, but this seems to prevent the little rascals from tipping it over.

Green bin hanger detail

Next, I needed a way to prevent them from opening the bin as the built in latch proved to be little or no deterrent. My first attempt was to wrap a bungie cord around the bin holding the latch closed – this was not good enough however, and they defeated it easily. Something stronger was required. The picture below shows my final solution.

Green bin latch detail

A 1/4″ eye bolt through the side of the bin, and a carabiner that clips through it and the existing latch makes it impossible for them to undo the latch and lift the lid, yet is still fairly easy to undo and open when filling. It has survived a couple of nights with a full load of decomposing goo, so I’m tentatively calling it a success.

Note: It is important to remember to unlatch the carabiner when putting the bin out for collection, otherwise its [stinky] contents will be left behind.