Forms
DeprecatedAvailable since version 1.0.0
Why is this deprecated?
This API is built for use with JSP which has long since been superseded by HTL as the preferred script language in AEM, therefore the use of this API is discourages as to encourage the use of HTL.
Purpose
Provide an abstraction for managing the submission of statically defined HTML Forms.
How to Use (v1.2.2+)
To create a enable the Forms, create a new sling:OsgiConfig
a OSGi component configuration:
/apps/myapp/config/com.adobe.acs.commons.forms.impl.FormsRouterImpl
The property suffix
will be used to identify and properly route Forms submissions.
The Form API
The Form abstraction is simple development abstraction for transporting data between the browser and AEM. The abstraction is broken into two part:
- The Form (Form.java) which represents the mutable Form state
- The FormHelpers (POST-Redirect-GET or Forward-as-GET) which contain the logic for transporting the Form data and re-constituing the Form on the other side of the HTTP Request.
Limitations
Current limitations of the Forms implmentation include:
- Only supports transport of text/String-based data (No file uploads)
- Multiple form parameters by the same name is not supported. A random value will be selected.
- Multiple forms can exist on a page, however any data in the unsubmitted forms will be lost (unless you’re using XHR POSTs)
The Form
Form is a class that represents HTTP Form submission data, and contains the following data:
- name: the form’s conceptual name; acts as a UID when multiple forms are on a page (ex. login, registration)
- data: which holds submitted form data
- errors: which holds error messaging associated with form field
Form Helpers
Generic Form Helper
FormHelpers interact with Form objects, transporting and re-constuting them on either side of the HTTP Request.
Most of the time the “generic” FormHelper is the better choice. This allows for very easy switching betwen the POST-Redirect-Get and Forward-as-Get implementations.
OR
Forward-as-GET Form Helper
The Forward Form Helper is used when Forms need to redirect (Forward-as-GET) internally to render end state of forms.
Forward Form Helper requests the target resource as an internal Synthetic GET Request, and passes the Form object as a SlingHttpServletRequest attribute.
Key features/use-cases
- Form-payload is too large to be transferred via GET Query Params (to render error page)
- You aren’t uncomfortable exposing for- data as clear text in query params (even though they fall under SSL envelope)
- You don’t mind resubmitting forms when a user clicked “refresh”
- Keeps a “clean” address bar in the browser
POST-Redirect-GET Form Helper
The POST-Redirect-GET (PRG) Form Helper is used when Forms need/can redirect externally (302) to re-render a form or success page.
PRG Form Helper requests the target resource as a 302 Redirect, serialized the Form data as JSON and transports the JSON data as GET Query Parameters. This works well when Form data is under ~2000 characters in total.
Key features/use-cases
- Form-payload is too small-ish (< 2000 chars encoded)
- You like a clean separation between your GET and POST requests
- Don’t mind a messy address bar in the browser (errors are returned to form via GET QPs)
Remember: GET Query Parameters are passed WITHIN the HTTPS envelope, so they are not visible on the wire
Sample Implementation
This example used the PRGFormHelper, however this can easily be swapped out for the ForwardFormHelper;
The normalized FormHelper API that wraps common usecases in .renderForm(..)
and .renderOtherForm(...)
methods.
Generally these methods can be used, and PostRedirectGetFormHelper.sendRedrect(..)
and ForwardAsGetFormHelper.forwardAsGet(..)
can be reserved for unusual use-cases where even more control is required.
demo.jsp
Initialize the Form object with the slingRequest.
This will intelligently look for the Form data from POST Parameters, GET Query Parameters, or HttpServletRequest Attributes depending on the context and FormHelper used.
If the request is a “fresh” request to the page, the form and its errors will be empty.
Changing between Form strategies (PRG vs Fwd-as-GET) is as easy as swapping out the FormHelper as shown below.
Also, don’t forget to make them the same in post.POST.jsp;
IMPORTANT: FormHelper Services should be sync’d between the form rendering JSP and the POST handler JSP.
Set the form to POST back to the component; use formHelper.getAction(..) to add the suffix that is registered with the POST handler. Defaults to /acs/form – can change via OSGi Configuration on:
com.adobe.acs.commons.forms.helpers.impl.PostFormHelperImpl#prop.form-suffix
Optionally pass a second parameter to getAction()
to set the selector used to resolve the script for this POST request. If not provided, defaults to “post” (to resolve to post.POST.jsp).
Useful for multi-page form wizards.
Example: <%= formHelper.getAction(currentPage, "step1") %>
will be handled by /apps/acme/components/demo/step1.POST.jsp
post.POST.jsp
Changing between Form strategies (PostRedirectGet vs ForwardAsGet) is as easy as swapping out the FormHelper as show below. Or for the common case, use generic FormHelper with .renderForm(..)
Choose the return-to-form method based on the Form strategy. You can use PostRedirectGetFormHelper.sendRedirect(..) or ForwardAsGetFormHelper.forwardAsGet(..) variations if the FormHelper.renderForm(..) variations are sufficient (renderForm covers the 80% usecase)
You’ll want to match currentPage/resource/path up to form.getAction(..)
in demo.jsp
Service User
On AEM 6.2 or above, this service uses a Service User for repository access. This user is configured with the expected permissions required, but additional permissions may be required if your repository design deviates from the expected structure.
User name: acs-commons-form-helper-service
ACLs:
- n/a (this user is only necessary for mapping resources)