Using the bundled fields library

Torro Forms includes a reusable field library, which is part of the plugin library bundled. That library is used for all areas that include several fields to specify behavior, such as:

  • the plugin’s settings screen
  • metaboxes in the form edit view
  • elements in the form builder
  • the submission edit view

Leveraging a single library in all these locations makes it very easy to extend them, since they use a common foundation. If you wanna add fields to any of them, you simply need to hook into the relevant filter, through which the field definition is passed, and add the definition for your custom fields. Validation, sanitization and persistence is then handled for you automatically.

How to modify fields for a certain area

Here is a simple example which adds a single checkbox field to the “Form Behavior” section of the plugin’s settings screen.

function myplugin_add_settings_fields( $fields ) {
	$field['my_custom_field'] = array(
		'section'     => 'form_behavior',
		'type'        => 'checkbox',
		'label'       => __( 'Enable my custom field behavior?', 'myplugin' ),
		'default'     => false,
	);

	return $field;
}
add_filter( 'torro_settings_fields', 'myplugin_add_settings_fields' );

As you can see, fields are defined in an associative array, where each key is the identifier of a field and its value is another associative array with that field’s definition. So all you need to learn in order to extend the available fields displayed and handled for an area of the plugin is which arguments are available and which values they accept.

Available arguments for a field

Global arguments

The following arguments are available for every field, regardless of the field type. Below the following list you’ll find information about additional arguments which only apply to specific types.

  • type (string) – Type of the field. Must be the identifier of one of the available field types. Here are the types available out-of-the-box:
    • text (a regular text input field; this is the default value)
    • email (an email input field)
    • url (a URL input field)
    • textarea (a textarea field)
    • wysiwyg (a textarea using the default WordPress visual editor)
    • number (a number input field)
    • range (a range slider input field)
    • checkbox (a single checkbox toggle)
    • select (a dropdown to select a single choice)
    • multiselect (a dropdown to select one or more choices)
    • radio (a group of radio buttons to select a single choice)
    • multibox (a group of checkboxes to select one or more choices)
    • autocomplete (a text input field with autocomplete functionality using the REST API)
    • datetime (an input field for a date, a time or both combined)
    • color (a color picker)
    • media (a media picker to specify a file using the media library)
    • map (a map picker to specify an address or geocoordinates using Google Maps)
    • group (a collection of multiple fields of the above being combined, where all values will be stored in one associative array)
  • label (string) – Label for the field. Default is an empty string.
  • description (string) – Description for the field. Default is an empty string.
  • section (string) – Identifier of a section the field should be part of. How fields of a section are displayed and which sections are available depends on the area for which the fields are being defined. In some cases, for example in the settings screen, you can also filter the sections available to add your own. There are also cases where sections are not used at all, in which case this argument is not used. Default is an empty string.
  • default (mixed) – Default value for the field. The value you provide should be valid for the type of field you picked. For example, a string in case of a text field, a float or integer in case of a number field, or an array of strings in case of a multiselect field. Default is null, which will fall back to the default value which makes sense for the field type specified.
  • validate (callable) – Custom validation callback. In most cases, you don’t need to provide one as all types already have their own default validation, for example to ensure a number field only accepts integer/float values within its boundaries or to ensure a select field only accepts one of the choices that are actually available. Default null, which falls back to the default callback for the field type.
  • input_classes (array) – Array of additional CSS classes to provide for the field control itself. Classes plugin-lib-control and plugin-lib-{$type}-control are always rendered by default. Default empty array.
  • label_classes (array) – Array of additional CSS classes to provide for the field label. A class plugin-lib-label is always rendered by default. Default empty array.
  • wrap_classes (array) – Array of additional CSS classes to provide for the field wrapping element. A class plugin-lib-wrap is always rendered by default. Default empty array.
  • display (boolean) – Whether to display the field. If not, it is included in the markup, but hidden. Default is boolean true. If it is hidden, its required argument is ignored (since it wouldn’t make sense to require a hidden field to have content).
  • required (boolean) – Whether this field is required. If true, it must not be empty when submitted. Default is boolean false.
  • before (callable|string) – Extra content to render before the field control, either as a callback echoing it or as a plain HTML string. Default null.
  • after (callable|string) – Extra content to render after the field control, either as a callback echoing it or as a plain HTML string. Default null.
  • repeatable (boolean|integer) – Whether to make this field repeatable. A repeatable field always includes a button to add more instances of the control. Values specified are always stored together as an array. Instead of providing a boolean, you may also specify an integer greater than 0 to limit the maximum amount of fields to this number. Default is a boolean false.

Out of the above arguments, you should commonly provide at least type and label, and also section if the area where you define the field for uses sections. All other fields, including those below, should be provided as necessary. Note that repeatable currently does not work with fields specified for an element in the form builder.

Additional arguments for specific field types

  • choices (array) – Associative array of $value => $label pairs to select from. Default empty array. Can be specified for the following types:
    • select
    • multiselect
    • radio
    • multibox
  • optgroups (array) – Associative array of $optgroup_slug => $optgroup_data pairs, where $optgroup_data is another associative array with the following required arguments:
    • label (string) – Optgroup label. Default empty string.
    • choices (array) – Associative array of $value => $label pairs to actually select from. Default empty array.

    Make sure to only specify either choices or optgroups. The latter can be specified for the following types:

    • select
    • multiselect
  • min (float|integer|string) – Minimum value allowed. Should be a float or integer for numeric fields, or a ‘Y-m-d H:i:s’ datetime string for datetime fields. Can be provided for the following types:
    • number
    • range
    • datetime
  • max (float|integer|string) – Maximum value allowed. Should be a float or integer for numeric fields, or a ‘Y-m-d H:i:s’ datetime string for datetime fields. Can be provided for the following types:
    • number
    • range
    • datetime
  • step (float|integer) – Numeric step values should be divisible by. If this is an integer, it will furthermore store the values as an integer instead of a float. Can be provided for the following types:
    • number
    • range
  • store (string) – How to store the value provided. This must be one of a few predefined values depending on the type. Should be provided for the following types:
    • datetime (must be one of ‘date’, ‘time’ or the default ‘datetime’)
    • media (must be one of ‘url’ or the default ‘id’)
    • map (must be one of ‘coords’ or the default ‘address’)
  • wpautop (boolean) – Whether to run editor content through wpautop(). Default is false. Can be provided for the following type:
    • wysiwyg
  • media_buttons (boolean) – Whether to display media buttons above the editor. Default is false. Can be provided for the following type:
    • wysiwyg
  • button_mode (string) – Mode to display editor buttons in. Either ‘regular’ for buttons like in the post editor, or ‘simple’ for a simplified set of buttons, like in the editor within the text widget. Default is ‘regular’. Can be provided for the following type:
    • wysiwyg
  • autocomplete (array) – Associative array of autocomplete options. Should have the following keys:
    • rest_placeholder_search_route (string) – Relative URL to the endpoint including a %search% placeholder that will contain the entered value from the autocomplete field. The endpoint should return multiple objects, each including a value to store in the database and a label to display in the autocomplete field. Default is wp/v2/posts?search=%search%.
    • rest_placeholder_label_route (string) – Relative URL to the endpoint including a %value% placeholder that will contain the stored value from the database. The endpoint should return one object including the label to display in the autocomplete field. Default is wp/v2/posts/%value%.
    • value_generator (string) – Path to the property in each object that holds the value to store in the database. Default is %id%.
    • label_generator (string) – Path to the property in each object that holds the label to display in the autocomplete field. Default is %title.rendered%.

    Can be provided for the following type:

    • autocomplete
  • fields (array) – Array of sub-field definitions for a group of fields. Should look exactly like a regular array of field definitions, except that you never need to provide a section here. Furthermore, inner fields specified here cannot be repeatable, and you cannot put a group within another group. Default is an empty array.

Field Dependencies

While the field arguments above are sufficient for most use-cases, an additional feature of the library included is that fields registered together, i.e. being part of the same field definitions array can include dependencies to each other. You can for example show or hide a field, change the description or even the selectable choices, all depending on another field’s value. Dependencies are specified in a dependencies field argument, which is an array one or more dependencies, which themselves are associative arrays of dependency definition, with the following arguments being required:

  • prop (string) – Property of the field that is modified by this dependency. Any main property can be specified. Common values include ‘display’, ‘choices’, ‘label’ or ‘description’.
  • callback (string) – Name of a registered callback that contains the actual logic to determine the value to set prop to. The callbacks available out-of-the-box are ‘get_data_by_condition_true’, ‘get_data_by_condition_false’, ‘get_data_by_condition_greater_than’, ‘get_data_by_condition_lower_than’, ‘get_data_by_map’ and ‘get_data_by_named_map’. Additional callbacks must be registered for both PHP and JavaScript – the first being used on the server, the second being used for live handling on the client. In PHP, the plugin_lib_dependency_resolver_callbacks filter can be used to add $callback_name => $callback pairs; in JavaScript, the pluginLibFieldsAPIDependencyCallbacks event on the document node can be used, which is passed the dependency resolver on which you can call the addCallback( callbackName, callback ) method.
  • fields (array) – List of field identifiers whose values prop depends on. At least one must be given. How the values are handled is determined by the logic in callback.
  • args (array) – Additional arguments to pass to callback as $arg => $arg_value pairs. Having those arguments allows to make the available callbacks more flexible.

The callback variants in both PHP and JavaScript receive the prop as first parameter, the field values as $field_identifier => $field_value as second parameter and args as third parameter. The PHP callback must then run the necessary logic and return the result value to set prop to. In JavaScript, since the callback may run asynchronously, it receives an additional callback as fourth parameter which at the end must be called with the result value to set prop to as sole parameter.