ATG Parameter Names

Often in ATG form handler or droplet code one finds code like this:

public static final String OUTPUT = "output";

You can take advantage of ATG’s ParameterName class to represent any parameter name. From the ATG 2006.3 API Reference:

A ParameterName object can represent any parameter name used in Dynamo. Use this class when building your own droplets to create unique parameter names. The parameter names will then be stored in a global hashtable keyed by strings. Using this class allows the parameters of a droplet to be publicly available as well as enforcing good coding standards whereby the parameter name string only appears once in the java code.

Throughout ATG’s public source you can see that many parameter names have already been defined. For brevity sake I have omitted the “public final static” prefix.

ParameterName ARRAY = ParameterName.getParameterName("array");
ParameterName DEBUG = ParameterName.getParameterName("debug");
ParameterName DEFAULT = ParameterName.getParameterName("default");
ParameterName ELEMENT_NAME = ParameterName.getParameterName("elementName");
ParameterName EMPTY = ParameterName.getParameterName("empty");
ParameterName EQUAL = ParameterName.getParameterName("equal");
ParameterName GREATERTHAN = ParameterName.getParameterName("greaterthan");
ParameterName INDEX_NAME = ParameterName.getParameterName("indexName");
ParameterName IN_URL = ParameterName.getParameterName("inUrl");
ParameterName LESSTHAN = ParameterName.getParameterName("lessthan");
ParameterName NONCOMPARABLE = ParameterName.getParameterName("noncomparable");
ParameterName NON_SECURE_URL = ParameterName.getParameterName("nonSecureUrl");
ParameterName OBJ1 = ParameterName.getParameterName("obj1");
ParameterName OBJ2 = ParameterName.getParameterName("obj2");
ParameterName OUTPUT = ParameterName.getParameterName("output");
ParameterName OUTPUT_END = ParameterName.getParameterName("outputEnd");
ParameterName OUTPUT_START = ParameterName.getParameterName("outputStart");
ParameterName PATH = ParameterName.getParameterName("path");
ParameterName REVERSE_ORDER = ParameterName.getParameterName("reverseOrder");
ParameterName SECURE_URL = ParameterName.getParameterName("secureUrl");
ParameterName SORT_PROPERTIES = ParameterName.getParameterName("sortProperties");
ParameterName TRUE  = ParameterName.getParameterName("true");
ParameterName UNSET = ParameterName.getParameterName("unset");
ParameterName VALUE = ParameterName.getParameterName("value");
ParameterName CURRENCY_PARAM = ParameterName.getParameterName("currency");
ParameterName EURO_SYMBOL_PARAM = ParameterName.getParameterName("euroSymbol");
ParameterName LOCALE_PARAM = ParameterName.getParameterName("locale");
ParameterName TARGET_LOCALE_PARAM = ParameterName.getParameterName("targetLocale");
ParameterName YEN_SYMBOL_PARAM = ParameterName.getParameterName("yenSymbol");

ATG Consulting Interview

Today I had the most detailed but at same time most interesting ATG consulting interview yet. Here are the questions I was asked with answers when appropriate in italics.

  1. Which versions of ATG have you worked with?
  2. What parts of ATG’s stack have you worked with?
  3. How do you compare ATG with Ruby on Rails?
  4. What is Nucleus?
  5. What is the ATG Repository?
  6. When creating form handlers typically what ATG base class do you extend? GenericFormHandler.java
  7. When creating droplets what ATG base class do you extend? DynamoServlet.java
  8. What form handlers and methods do you use during checkout? ShoppingCartFormHandler, numerous handlers like handleMoveToConfirm, etc.
  9. What does a user typically see during checkout? Add to shopping cart, login, billing and shipping address, payment, confirm, confirmation, email confirmation, shipped email.
  10. How do you compare strings in Java? If String a = “hello” and String b= “hello” what is a == b? True, a and b both reference the same constant string.

In another interview I was asked these questions.

  1. What is HTTP? How does it work?
  2. If HTTP is stateless then how does a web application maintain state.

Submitting an ATG Form Using a Text Link

It has always bedeviled me how to submit an ATG form using a text link. I have asked many people about this but no one seems to know. Finally with the help of ATG support I figured it out.

Below is a simple example of how to do it. The trick is the hidden submit input which triggers ATG to call the handleSubmit method of the form handler.

<%@ taglib uri="/dspTaglib" prefix="dsp"%>

<dsp:page>

<script>
  function submit(form) {
    form.submit();
  }
</script>

<dsp:form action="<%=request.getRequestURI()%>" method="post" name="testForm">

  Foo: <dsp:input type="text" bean="TestFormHandler.foo"/>

  <p><a href="javascript:submit(document.testForm)">Submit</a>

  <dsp:input type="hidden" bean="TestFormHandler.submit" value="Submit"/>

</dsp:form>

</dsp:page>

You can also invoke the JavaScript like this:

  <p><a href="#" onclick="submit(document.testForm); return false;">Submit</a>

Forwarding instead of Redirecting in Form Handlers

Typically how an ATG form handler handles form submissions is that if the form submission has any errors it redirects to an error or failure URL, otherwise it redirects to the success URL. It does this when you call the form handler’s method checkFormRedirect.

However by redirecting you are creating a new request and you will lose all the information in the current request. If you want to keep them you can do this by forward instead of redirecting.

To specify that a form handler use forward instead of redirect you can either

  1. set the request parameter “atg.formHandlerUseForwards” to “true” (case insensitive) OR
  2. set the boolean property useForwards to true, either in the properties file of the form handler or using a hidden input in the JSP/JHTML form

None of this as far as I can tell is documented, probably because instead of using forwards ATG would probably prefer developers make a form handler session scoped if information needs to be preserved over multiple requests. Regardless this is all documented in the source code for atg.droplet.GenericFormHandler which is available in the ATG install location under DAS/src/Java/.

Note that if you call the response’s method sendLocalRedirect you bypass the flexibility of possibly using forwards. Instead it is preferable to call the form handler’s method redirectOrForward.

ATG forms do not work if action is an HTML page

When creating forms that are to interact with ATG form handlers, one cannot use an HTML page as the action. If one does then the ATG form handler will not be invoked.

For example, this form will not invoke the ATG form handler.

<form name="test" action="test.html" method="get">
  Name: <input type="text" bean="/TestFormHandler.name">
  <p><input type="submit" bean="/TestFormHandler.submit">
</form>

However this form will.

<form name="test" action="test.jhtml" method="get">
  Name: <input type="text" bean="/TestFormHandler.name">
  <p><input type="submit" bean="/TestFormHandler.submit">
</form>

Internet Explorer form does not invoke ATG handler

In Internet Explorer if you have a form that has only a single line text input and if you press Enter to submit the form instead of pressing the submit button then the ATG handler for this form will not be invoked. Instead the form will act like a regular HTML form.

To get around this problem on Internet Explorer one must explicitly call the handler using a hidden input tag.

Here is an example of a simple form that illustrates this problem. The action of this form is to go to wrong.jhtml but if the ATG handler is invoked then the request is redirected to right.jhtml.

<form name="test" action="wrong.jhtml" method="get">
  Name: <input type="text" bean="/TestFormHandler.name">
  <p><input type="submit" bean="/TestFormHandler.submit">
</form>

Here is a screenshot of this form.

test form with only one input field

When I press Enter I go to the wrong page, i.e. wrong.jhtml, because the handler is not invoked.

example of a form working incorrectly

When I press the Submit button I go to the right page, i.e. right.jhtml, because the handler is invoked.

example of a form working correctly

To fix this I add this line within the form of testForm.jhtml.

  <input type="hidden" bean="/TestFormHandler.submit">

I also add this getter, which does nothing and may not be necessary for later versions of ATG, in the form handler.

  public String getSubmit() { return null; }

After doing this when I press Enter I go to the right page.

Note that with a form that has more than one input field this is not a problem.

test form with two input fields

The source for this example can be downloaded here.