# choices

Use choices in conjunction with the boolean, checkbox, and select fields to define the choices that a user will see. The choices array should be an array of objects with label and value properties. value is what winds up in the database, label is what the user sees.

# showFields

The showFields sub-option can be used to show and hide other fields based on the choice that was made. This is a very powerful way to make forms more user-friendly.

# boolean Example

{
  type: 'boolean',
  name: 'housing',
  label: 'Do you require housing?',
  mandatory: 'Sorry, you need to have housing!',
  choices: [
    {
      value: true,
      showFields: [
        'dormPreference', 'vegetarian'
      ]
    }
  ]
}

When "Yes" is selected, the value becomes true, and the fields named dormPreference and vegetarian will be visible. At all other times they will not be.

# checkboxes Example

{
  type: 'checkboxes',
  name: 'preferences',
  label: 'Preferences (check one or more)',
  choices: [
    {
      label: 'Big',
      value: 'big'
    },
    {
      label: 'Friendly',
      value: 'friendly',
      showFields: [ 'friends' ]
    },
    {
      label: 'Furry',
      value: 'furry'
    }
  ]
}

In this example, the value of the preferences property of the data object will be an array of strings. Each string is the name property of a choice that was checked. If no boxes are checked, the value is an empty array.

When "Friendly" is one of the selected checkboxes, the field named friends becomes visible. Otherwise that field is hidden.

# select Example

{
  type: 'select',
  name: 'housing',
  label: 'Where will you be staying?',
  choices: [
    {
      label: 'On Campus',
      value: 'on-campus',
      showFields: [
        'accessible', 'vegetarian'
      ]
    },
    {
      label: 'Off Campus',
      value: 'off-campus'
    }
  ]
}

When the "On Campus" choice is selected, the schema fields named accessible and vegetarian will be visible. At all other times they will not be.

A cursor filter method is added automatically for all fields of type select. This means joins to pieces containing a select type field can be filtered by the field's value;

{
  name: '_post',
  type: 'joinByOne',
  filters: {
    postType: 'event',
  }
}

# readOnlyFields

The readOnlyFields sub-option can be used to convert other schema fields on the page to read only based on the choice that was made. This can be useful to let the user know that choices have been made in other form fields, but these fields cannot be changed. This is slightly different from showFields where the user will not know that those choices have been made for them since the fields will never be revealed.

If the field being made non-editable does not have a default value set through the def option, no value is returned for the field. If any schema field is required, it must either have a default value or be edited to contain a value before making it read-only.

# boolean Example

{
  type: 'boolean',
  name: 'housing',
  label: 'Do you require housing?',
  choices: [
    {
      value: false,
      readOnlyFields: [
        'dormPreference',
        'mealPlan'
      ]
    },
    {
      value: true,
      readOnlyFields: [
        'dailyParkingPlan'
      ]
    }
  ]
}

In this case, if the user selects "No" then both the dormPreference and mealPlan fields will no longer be editable, while the dailyParkingPlan field can still be edited. Selecting "Yes" will toggle which fields can be edited, but all fields will remain visible regardless of choice.

# checkboxes Example

{
  type: 'checkboxes',
  name: 'preferences',
  label: 'What fields should be non-editable? (check one or more)',
  choices: [
    {
      label: 'Colors',
      value: 'colors',
      readOnlyFields: [
        'hoverColor',
        'activeColor'
      ]
    },
    {
      label: 'Fonts',
      value: 'fonts',
      readOnlyFields: [
        'paragraphFont',
        'headingFont'
      ]
    }
  ]
}

In this case you can make the color fields, font fields, or both read-only.

A similiar example could be made for a select field where either the color fields or the font fields could be made non-editable, but not both.

# Fetching choices dynamically from APIs

What if the choices change and can't be hardcoded in your code? You can fetch them dynamically.

First, set the choices option to the name of a method in your module. Pass a string, the name of the method — do not pass a function.

Second, implement that function to take a single (req) argument and return an array of choices in the usual format. You may use an async function, or return a promise that will resolve to the array. That means you can reach out to APIs using modules like axios or request-promise.

It is usually a good idea to perform at least short-term caching in your choices method, in order to limit the impact on performance when editing.