Create A New Field Type In Caldera Forms

A Volcano In The Distance

This tutorial will help you create a plugin that will add a new custom type of field of to Caldera Forms. A custom field add-on is one of twp major types of add-on plugin you might wish to create. The other major type is a custom processor, as explained here.

Please note: This is a tutorial designed for WordPress developers familiar with the basics of plugin development and the plugins API.

Key Concepts

This section explains core concepts of fields. This example code illustrates all of these concepts together:

Field Files

The markup for your field is generated by three files:

  • Front-end – This field is referred to as the field file. It generates the HTML for the front-end view of the form.
    • This file’s path  is defined in the “file” index of field definition (see next section)
    • This is optional. If not used the generic input file is used. That file is a good start point for a custom file, BTW.
    • If uysing the generic input, you almost always have to use the caldera_forms_field_attributes filter.
  • Settings – This file is referred to as the config file. It generates the HTML for the field settings in the form editor.
    • This file’s path is set in the “template” index of the array set in the “setup” index of field definition (see next section).
    • Default configuration options — ID, name, default, etc will be created automatically. This is for settings unique to this field.
    • This file is not optional. If you don’t need it create a file anyway and just open PHP and put a 1 line comment (a totally empty field will trigger WordFence.)
  • Preview – This file generates the preview of the field in the form editor
    • This file’s path is set in the “preview” index of the array set in the “setup” index of field definition (see next section).
    • This file will live update with basic settings.
    • Best thing to do is copy the single line text field’s preview.php.
    • This file is not optional. If you don’t need it create a file anyway and just open PHP and put a 1 line comment (a totally empty field will trigger WordFence.)

Important Filters

  • caldera_forms_get_field_types
    • For a field to be known by Caldera Forms, it must be registered on this filter.
    • To register a field, add it to the array exposed by this filter.
    • The index of the array you use will identify the field.
  • caldera_forms_validate_field_{$field_type}
    • This is optional.
    • For server side validation.
    • The index mentioned above is the $field_type
    • Return a WP_Error to trigger a validation error.
  • caldera_forms_field_attributes
    • This is optional.
    • If you are using the generic input, you must use this or the dynamically named variant for your field.
      • This is important because if your field is “field_slug” but you want the HTML type attribute of your field to be hidden, this filter can change it.
      • See this gist.
    • If you do not use a field HTML generator, this filter isn’t applied.

JavaScript Bindings

If you need to do run some JavaScript, for example a jQuery plugin on the input, instantiating at the document ready event may be insufficient. Keep in mind that if a field is hidden by conditional logic, it is removed from the DOM. When it is added back, the “cf.add” event is triggered using jQuery.trigger(). Field JavaScript should also be instantiated when a page changes — when the “cf.pagenav” event is triggered and when/ if a form is loaded in a modal “cf.modal” event.

Here is a the basics of that:

Targeting Fields

You should never guess the field’s id attribute. It is dynamic. The easiest thing to do is target your fields by class instead. Here is how to add a unique class to your field type when using the caldera_forms_field_attributes filter as described above.

For reference, the HTML id attribute used for a field when rendered is the field’s ID an underscore and the current count of forms on the page. If a user creates a field and its assigned the ID of fld12345 and the form is rendered before any other Caldera Forms, the field’s HTML attribute id will be fld12345_1. If it is the second form on the page the id will be fld12345_2. This is the solution to the problem of not knowing how many times a form is on the page. Don’t futz with this system or other things will break.

Field Change Events

You can use jQuery.change() or similar to bind to field change events. Caldera Forms’ uses a front-end state object CFState to manage field values. It has an events system you can use to bind to changes. This is the most forward-compatible method and this object internalizes a lot of the gotchas that comes with using jQuery.on() and related functions for bindings.

Here is an example where we will bind to the change event of every field that has a the class “field_slug” — as added in the last step.

 

Fun facts:

  • Once you have CF State and id attribute captured in a variables, use state.mutateState( idAttr, 'Hi Zac' ); to change the value.
  • The CFState and CFEvent constructors are in assets/js/state
    • If the caldera_forms_render_assets_minify filter returns true, which it does by default, these files are not loaded, instead assets/build/js/caldera-forms-front.min.js, which contains them is.
    • Debugging is way easier if you return false on that filter 🙂

Building The Plugin

Here are two complete examples of how to build a custom field type in Caldera Forms that you can reference: