Creating a Form
You can create a standard HTML form that uses AJAX for validation and error rendering. If you're creating a simple form that doesn't store data, is easily localized, and only requires client-side validation, this type of form is appropriate. You can also create a complex form that stores data, requires server-side validation, and has sophisticated localization requirements. Sophisticated localization can include adding, removing, or rearranging fields in the form or changing the data object you have to store with form data.
If you're creating a complex form, use a B2C Commerce form definition. A form definition results in an in-memory object that persists during the session. You can use this object with various platform features for localization, server-side validation, and data storage.
The following example uses a form definition. The form has a text field to input a nickname, a submit button, and a cancel button. After the form is submitted, another page is rendered that shows the nickname entered in the previous form.
Form Definition
The first thing you create for a form is the form definition. The form definition describes the data you need from the form, the data validation, and the system objects you want to store the data in. This example only has one input field and two buttons. This form doesn't validate or store data permanently.
<?xml version="1.0"?>
<form xmlns="http://www.demandware.com/xml/form/2008-04-19">
<field formid="nickname" label="Nickname:" type="string" mandatory="true" max-length="50" />
<action formid="submit" valid-form="true"/>
<action formid="cancel" valid-form="false"/>
</form>
In-memory form Object
The form definition determines the structure of the in-memory form object. The in-memory form object persists data during the session, unless you explicitly clear the data.
In the Storefront Reference Architecture (SFRA), the first step to create a form is to
create a JSON object to contain the form data. The server.getForm
function uses the form definition to create this object. Data from the form is
accessible in templates using the pdict
variable. However, the form is
available only if the server.getForm
object is passed to the template
by the controller.
Controller to Render the Form
The controller in this example exposes a Start
function that renders an
empty form.
The Start
function sets the actionURL
that's used to
handle the submit action for the form and creates a JSON object based on the form
definition.
SFRAForm.Js
/**
* A simple form controller.
*
*/
'use strict';
var server = require('server');
var URLUtils = require('dw/web/URLUtils');
server.get(
'Start', server.middleware.http, function (req, res, next) {
var actionUrl = URLUtils.url('SFRAFormResult-Show'); //sets the route to call for the form submit action
var SFRAhelloform = server.forms.getForm('SFRAFormDef'); //creates empty JSON object using the form definition
SFRAhelloform.clear();
res.render('SFRAFormTemplate', {
actionUrl: actionUrl,
SFRAhelloform: SFRAhelloform
});
next();
});
module.exports = server.exports();
Form Template
In this example, SFRAFormTemplate.isml
is the empty form rendered for
the user and the SFRAResultTemplate.isml
shows data entered into the
form.
SFRAFormTemplate.isml
The form action uses the actionUrl
property passed to it by the
controller.
The client-side JavaScript and css files are included using the
assets.j
s module.
<!--- TEMPLATENAME: helloform.isml --->
<!--- <isscript>
var assets = require('*/cartridge/scripts/assets.js');
assets.addCss('/css/helloform.css');
assets.addJs('/js/helloform.js'); </isscript>--->
<div class="hero slant-down login-banner">
<h1>SFRA Hello World Form</h1>
</div>
<!--- --->
<div class="card">
<form action="${pdict.actionUrl}" class="login" method="POST"
name="SFRAHelloForm">
<div class="form-group required">
<label> Nickname: </label> <input type="input" id="nickname"
class="form-control" name="nickname">
</div>
<button type="submit" class="btn btn-block btn-primary">Submit</button>
<button type="submit" class="btn btn-block btn-primary">Cancel</button>
</form>
</div>
Controller to Render Form Results
SFRAFormResult.Js
After a form is submitted, data from the form is available as part of the
req.form
property. In the following example, the nickname entered
in the original form is passed to a new template for rendering.
/**
* Handles the simple form rendered by the SFRAForm.js controller.
*
*/
'use strict';
var server = require('server');
var URLUtils = require('dw/web/URLUtils');
server.post('Show', server.middleware.http,
function(req, res, next) {
var nickname = req.form.nickname;
res.render('SFRAResultTemplate', {
nickname : nickname});
next();
});
module.exports = server.exports();
Form Result Template
SFRAResultTemplate.isml
This template prints the form field label and data stored from the form.
<<!--- TEMPLATENAME: SFRAResultTemplate.isml --->
<iscontent type="text/html" charset="UTF-8" compact="true" />
<!doctype html>
<head></head>
<body>
<h1>Hello World Form Result</h1>
<p>Nice to meet you, ${pdict.nickname}.</p>
</body>
</html>
Hiding Form Fields
Most SFRA forms are standard HTML forms, so you can use input
type="hidden"
to hide form fields in templates.
Reusing Form Definitions
The form you create in your template can contain fields from multiple form definitions. The same fields can be reused in other forms as many times as required. This ability can be useful for prepopulating form data that the customer has already entered. For example, address or payment preference data.
Using Form Metadata
You can use the metadata entered for a custom or system object in Business Manager to
determine form definition information. This ability lets you manage data attributes in
one place without having to change code. For example, if you wanted to let merchants
change the labels on form fields, you could include label
as a metadata
attribute and reference it.
Dynamic, Multi-Part, Embedded, or Nested Forms
SFRA doesn't include dynamic forms.
However, if you want to create them, you can use the isdynamicform
tag
to generate dynamic forms. The dynamicform.isml
template and the
dynamicForm.js
script control how code is generated using the
isdynamicform
tag.
SFRA doesn't include multi-part, embedded, or nested forms. We don't recommend them as a best practice.