Edit widgets

This page walks you through all available edit widgets settings.

For an introduction on what widgets are and a comprehensive list of what widgets you'll be able to choose from, check out the previous page: Customize your fields

Text input

Content inputting in its most basic form, the Text input is quite what you will find in most online forms. For more advanced or specialized content types, see the other widgets.


Much like the Text input, the Textarea widget is more appropriate when inputting longer portions of text. To input formatted content, check out the Rich text editor below.

Rich text editor

This widget is what you need when handling formatted text. You will be able to decorate your text in bold, italic and much more.

Price editor

This widget is perfect for editing prices, thanks to a real-time preview of what the formatted number will look like:

To set up your widget:

  • Choose a currency symbol between euros (EUR), dollars (USD) and pounds (GBP)

  • Choose a base: Cents if your values are stored in cents, Unit otherwise

The number formatting is based on your browser's locale, unless you have a specific locale set in your Project settings.

The dropdown is a very powerful and customizable widget. As you would expect, the result will be a dropdown which allows you to choose between several values.

However, you can customize it in the following ways:


Use Static content type if you want to manually enter your content.

Your values should be added manually - as a comma-separated list -, unless you enabled the Alter values option (available in display settings) or if your field is an enum, in which cases you will be able to simply enable/disable values to add them:


Use this option if you want your content to depend dynamically on your data:

Simple mode

In Simple mode, just select which collection you wish to select values from for your dropdown. You can optionally add a filter.

Dynamic mode

In Dynamic mode, values will be fetched from your own API endpoint. Here's an example:

'use strict';
var express = require('express');
var app = express();
var fs = require('fs');

// ...

// You MUST require these files before the default routes.
fs.readdirSync('./decorators/routes').forEach((file) => {
  if (file[0] !== '.') {
    app.use('/forest', require(`./decorators/routes/${file}`));

fs.readdirSync('./routes').forEach((file) => {
  if (file[0] !== '.') {
    app.use('/forest', require('./routes/' + file));

  modelsDir: __dirname + '/models',
  envSecret: process.env.FOREST_ENV_SECRET,
  authSecret: process.env.FOREST_AUTH_SECRET,
  sequelize: require('./models').sequelize

module.exports = app;
// Configure the dropdown in dynamic mode using this path: /forest/orders/shippingStatusOptions
const express = require('express');
const router = express.Router();
const Liana = require('forest-express-sequelize');

// This is a simple case but you can retrieve your data from an external API or using your own logic
const data = [
  'Being processed',
  'Ready for shipping',
  'In transit',

router.get('/orders/shippingStatusOptions', Liana.ensureAuthenticated, (req, res) => {
  res.send({ data });

module.exports = router;

You can add more logic by retrieving the record id or the record type using request.context.record.id, request.context.record.type

In the example below, the dropdown will only suggest status according to the current status of the order.

const express = require('express');
const router = express.Router();
const Liana = require('forest-express-sequelize');
const models = require('../../models');

const STATUS_OPTION_DEFAULT = 'Being processed';
  'Being processed': ['Ready for shipping'],
  'Ready for shipping': ['In transit'],
  'In transit': ['Shipped', 'Failed'],

router.get('/orders/shippingStatusOptions', Liana.ensureAuthenticated, async (req, res) => {
  const { context } = req.query;
  const recordId = context && context.record && context.record.id;

  if (recordId) {
    const order = await models.orders.findById(recordId);
    const currentShippingStatus = order.shippingStatus;
    if (STATUS_TRANSITIONS[currentShippingStatus]) {
      data = STATUS_TRANSITIONS[currentShippingStatus];
  res.send({ data });

module.exports = router;


If your field refers to another collection, the dropdown option will automatically populate the data of that collection. In this example, an order belongs to a product. In order's field settings, you'll find:

While creating a new order, all products are available in the dropdown:

You can also add one or more filters to display only a dataset of the associated collection.

In this case, only Star Wars products will be available in the dropdown:

Say you have a long list of options to choose from. A dropdown becomes a bit cumbersome: this is why we've added this option.

When enabled, the widget becomes an auto-complete input dropdown.

Radio button

The radio button widget works the same way as the dropdown widget: depending on your field type and whether you used the Alter values option (available in display settings), you will have to manually enter your values or simply toggle them.

While editing, the widget will look like this:


The checkboxes widget works the same way as the dropdown widget: depending on your field type and whether you used the Alter values option (available in display settings), you will have to manually enter your values or simply toggle them.

While editing, your widget will look like this:

File picker

Use this widget to upload files (images, pdf,..). This can be done by clicking on the grey rectangle or drag & drop'ing your file in the grey rectangle.


In your field's settings, you may set the following:

  • Specific file extensions: restrict which file types your users may upload

  • Maximum file size: set a maximum weight for your files

  • Prefix: indicate a path to preview your saved files when editing. More on this option here.

Edit tools

The File picker widget looks like this:

When uploading a single image, it allows you to perform 2 basic operations before using this file:

  • Rotate

  • Crop (adjust your image's borders until it fit a desired area)

Upload multiple files at once

For fields accepting multiple files, a new setting is available: setting a maximum number of files.

When uploading multiple files at once, your widget will look like this. Note that uploading multiple files at once will prevent you from using the rotate and crop features.

In the above picture, the Use these files button will become available after removing the first file by clicking the red cross icon.

Large files upload

If you need to upload large files, you may need to add some code to allow it. Check out this paragraph.

Date picker

Use this widget if your content is a date.

Depending on your field type, this might be a Dateonly picker widget.

Color picker

Use this widget if your content is a color.

JSON editor

Use this widget to handle JSON content.


This widget allows you to benefit from Google Places's address autocompletion.

The full address will be put in a single field (in our above example: description)

User dropdown

This widget allows you to input the email address of a user of the current project. You may search for a user using their firstname, lastname or email address.

The user can then be efficiently displayed using the User display widget. Both widgets work together to make record assignment easily achievable.

Last updated