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.

SFRAFormDef.xml
<?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.js 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.