npm package: @kbridenhaag/kbridh-form-wizard-controllers
Description: Controllers and models for form wizards
Author: Pandu Supriyono
Latest version: 1.4.0

# Form Wizard Controllers

[![Tests](https://github.com/kbridenhaag/kbridh-form-wizard-controllers/actions/workflows/tests.yaml/badge.svg)](https://github.com/kbridenhaag/kbridh-form-wizard-controllers/actions/workflows/tests.yaml)

A set of helpers for the creation of dynamic, multi-step forms using [hmpo-form-wizard](https://github.com/HMPO/hmpo-form-wizard)

- [Mixins](#mixins)
- [Models](#models)
- [Validators](#validators)

## Mixins

You can use the mixins to extend the default controller exported by hmpo-form-wizard:

```js
const BaseController = require('hmpo-form-wizard').Controller;
const PostcodeLookupMixin = require('form-wizard-controllers).PostcodeLookupMixin;

const PostcodeLookupController = PostcodeLookupMixin(BaseController);
```

You can then use this controller in the wizard's step definitions:

```js
{
'/address': {
  fields: ['address'],
  controller: PostcodeLookupController,
  next: 'confirm-address'
}
```

Currently these mixins are available:

### PostcodeLookupMixin

This mixin uses the [PostcodeLookupModel](#PostcodeLookupModel).
You must provide an API key and a base URL when instantiating the wizard:

```js
const { Router } = require('express');
const wizard = require('hmpo-form-wizard');
const steps = require('./steps');
const fields = require('./fields');

const app = Router();

app.use(wizard(steps, fields, {
    name: 'my-form',
    postcodeLookup: {
      apiKey: 'myApiKey',
      url: 'https://sandbox.postcodeapi.nu/v3/lookup'
    }
}));

module.exports = app;
```

### ParseFormDataMixin

This mixin uses [busboy-body-parser](https://www.npmjs.com/package/busboy-body-parser)
to parse multipart/form-data and put it into req.body. However, you should 
extend this mixin to do something with the uploaded data. It stores the following in your
req.form.values:

```js
fieldName: {
  data: Buffer("raw file data"),
  name: "upload.txt",
  encoding: "utf8",
  mimetype: "text/plain",
  truncated: false
}
```

## SendEmailMixin

This mixin uses [nodemailer](https://www.npmjs.com/package/nodemailer)
to send an email at the saveValues step of a controller.

```js
const { Router } = require('express');
const wizard = require('hmpo-form-wizard');
const nunjucks = require('nunjucks');
const steps = require('./steps');
const fields = require('./fields');

const app = Router();

const nunjucksEnv = nunjucks.configure(['./views'], {
  express: app,
});

app.set('view engine', 'html');
app.set('nunjucksEnv', nunjucksEnv);

app.use(wizard(steps, fields, {
    name: 'my-form'
}));

module.exports = app;
```

And in steps.js you can provide sendOptions to a step definition

```js
const emailerConfig = {
  from: 'sender',
  to: 'recipient',
  subject: 'subject',
  renderer: 'nunjucksEnv',
  template: 'some-template.html',
  context: {
    foo: 'bar',
  },
};

// context can also be grabbed from the request object

emailerConfig.context = (req) => ({
  sessionID: req.sessionID,
});
```

## Models

You can also use pre-defined models for other custom controllers instead.
These are extensions of the remote model found in [hmpo-model](https://github.com/HMPO/hmpo-model).

Currently these models are available:

### PostcodeLookupModel

This model is designed to work with the [Postcode API](https://www.postcodeapi.nu/), which validates and finds
Dutch addresses.

## Validators

This package also includes some validators that come in useful when using our mixins, for example in your
fields definition:

```js
const { mimetype, fileSize } = require('kbridh-form-wizard-controllers').validators;

{
  logo: {
    type: 'file',
    invalidates: ['check-logo'],
    validate: [
      'required',
      {
        fn: mimetype,
        arguments: ['image/png', 'image/jpg', 'image/jpeg']
      },
      {
        fn: fileSize,
        arguments: 5248800
      }
    ]
  }
};
```