Table of Contents Previous Section

Action Methods

An action method is a method you associate with a user action-for instance, clicking a submit button, an active image, or a hyperlink. To associate your method to a user action, you map it to a dynamic element that has an attribute named action. (In the examples just given, the dynamic elements associated with the user actions are WOSubmitButton, WOActiveImage, or WOHyperlink.) When the user performs the associated action, your method is invoked.

For example, in the HelloWorld example application (in <DocRoot>/WebObjects/Examples/WebScript/HelloWorld, where <DocRoot> is your web server's document root), the submit button is mapped to a method named sayHello in the Main component. When users see this page, they type in a name and click the button. This initiates the application's request-response loop, and sayHello is invoked.

Action methods take no arguments and return a page (component) that will be packaged with an HTTP response. For example, the sayHello method creates a new page named Hello and sends that page the name the user has typed into the text field.

//WebScript HelloWorld Main.wos
- sayHello
{
id nextPage;
nextPage = [WOApp pageWithName:@"Hello"];
[nextPage setVisitorName:visitorName];
return nextPage;
}
If you're programming in Java, you can look at the HelloWorldJava example, which is identical to HelloWorld but written in Java. Its sayHello method looks like this:

//Java HelloWorld Main.java
public Component sayHello() {
Hello nextPage = (Hello)application().pageWithName("Hello");
nextPage.setVisitorName(visitorName);
return nextPage;
}
In this example, the component Main is used to generate the page that handles the user request, and the component Hello generates the page that represents the response. Main is the request component or the request page, and Hello is the response component or the response page.

It's common for action methods to determine the response page based on user input. For example, the following action method returns an error page if the user has entered an invalid part number (stored in the variable partnumber); otherwise, it returns an inventory summary:

// WebScript example
- showPart {
id errorPage;
id inventoryPage;

if ([self isValidPartNumber:partnumber]) {
errorPage = [[self application] pageWithName:@"Error"];
[errorPage setErrorMessage:@"Invalid part number %@.",
partnumber];
return errorPage;
}
inventoryPage = [[self application] pageWithName:@"Inventory"];
[inventoryPage setPartNumber:partnumber];
return inventoryPage;
}
// Java example
public Component showPart() {
Error errorPage;
Inventory inventoryPage;

if (isValidPartNumber(partNumber)) {
errorPage = (Error)application().pageWithName("Error");
errorPage.setErrorMessage("Invalid part number " +
partnumber);
return errorPage;
}
inventoryPage = (Inventory)
application().pageWithName("Inventory");
inventoryPage.setPartNumber(partnumber);
return inventoryPage;
}
Action methods don't have to return a new page. They can instead direct the application to use the request page as the response page by returning nil (null in Java). For example, in the Visitors application, the recordMe action method in the Main page records the name of the last visitor, clears the text field, and redraws itself:

// WebScript Visitors Main.wos
- recordMe
{
if ([aName length]) {
[[self application] setLastVisitor:aName];
[self setAName:@""]; // clear the text field
}
}
// Java Visitors Main.java
public Component recordMe
{
if (aName.length != 0) {
((Application)application()).setLastVisitor(aName);
aName = ""; // clear the text field
}
return null;
}
Note: Always return nil (null) in an action method instead of returning self (this). Returning nil uses the request component as the response component. Returning self uses the current component as the response component. At first glance, these two return values seem to do the same thing. However, if the action method is in a component that's nested inside of the request component, a return value of self will make the application try to use the nested component, which represents only a portion of the page, as the response component. This, most likely, is not what you want. Therefore, it is safer to always return nil.

Table of Contents Next Section