Skip to content

Dynamic lists fields

Aurovrata V edited this page Sep 12, 2021 · 2 revisions

The plugin introduces the concept of dynamic lists fields and instantiates a dynamic-dropdown and dynamic-checkbox tag fields to overcome the CF7 plugin's flaws when building fields with lists of options, namely the fact that all the options have to be hardcoded into the form design, making large lists cumbersome to maintain and prone to errors. Furthermore, the dynamic list concept leverages the WordPress framework CMS data management which should be the way to maintain any option lists.

Dynamic dropdown (dynamic-select tag)

this builds an HTML select field which itself can be converted into a Hybrid HTML Dropdown field (fully theme-able with CSS) or a JQuery Select2 field which has its own powerful api as well.

Dynamic checkbox (dynamic-checkbox)

The dynamic checkbox field tag allows to build a list of checbox (or radio) fields. These can be converted into a Hybrid dropdown. This field accepts multi-level nesting.

Custom dynamic lists

other dynamic lists can be instantiated and leverage the dynamic list building functionality, which are

Dynamic list sources

It gives you 3 possible options to create/maintain a list,

Taxonomy lists

You can create a new list which is stored as a taxonomy on your site and you can edit the terms from the form editor 'Information' metabox located at the top right corner of the page. Each term you add in the taxonomy will be listed in your dropdown. This functionality was introduced because CF7 dropdown fields are not easy to maintain within a form, prone to errors. dynamic list

Posts title list

You can instead chose existing post titles as your list options. This allows for much richer data constructs on your site. This is useful if you have a form with users need to select options that represent custom-posts in your site. You can further reduce the posts to be displayed by selecting terms from one of its associated taxonomy. In this example I wish to display a dropdown with a list forms from which a user can register form, but I have differentiated my forms between partial forms which are used to build final forms. dynamic list

Custom list

The last option is to create your own custom list by using a filter hook and programmatically passing a list of option_value=>option_text pairs to load in your form. This is especially useful if you to filter dropdown options according to a particular user or some other function.

Registering custom lists

it is possible to register a custom list, allowing a developer to create their own HTML field structure while leveraging the powerful list source selection offered by the dynamic list framework built into the plugin.

Register your field tag

The dynamic list functionality is exposed by the class CF7SG_Dynamic_list (file: includes/class-cf7sg-dynamic-list.php) using filter and action hooks. The first step is to register a new field tag that will be displayed on the form editor,

require_once plugin_dir_path() . 'cf7-grid-layout/includes/class-cf7sg-dynamic-list.php';

add_action('cf7sg_register_dynamic_lists', 'cf7sg_create_my_custom_dynamic_tag');
function cf7sg_create_my_custom_dynamic_tag(){
  $dl = CF7SG_Dynamic_List::get_instances('my_dynamic_tag'); //it will create a CF7 tag [my_dynamic_tag ...]
  if(false === $dl){ //check if instance in memory.
    //create a new instance
    $dl = new CF7SG_Dynamic_List('dynamic_select',__( 'dynamic-dropdown', 'cf7-grid-layout' ));
    $dl->set_styles(array( //list of style $attributes=>$labels
        $attribute_1=>$label_1 //labels can be HTML.
      ),array( //additional attributes for above declared attributes
        $attribute_1=>array(
          $for_attribute_1=>array(
            'label'=> 'some text or HTML',
            'attrs'=>'disabled' //additional HTML attributes to include in the HTML checkbox field.
          )
        )
      ));
    $dl->set_others_extras(array( //extra attributes for the field tag
        'multiple'=> '<a target="_blank" href="https://www.w3schools.com/tags/att_select_multiple.asp"> Enable multiple selection</a>'
      ));
  }
}

The above field registration will determine the admin tag builder form layout/parameters as well as the attributes included in the field tag that a user can choose to customise the field parametrisation.

To understand the code, you can view the 2 registrations of the dynamic dropdown and dynamic checkbox fields included in the plugin at the bottom of the file includes/class-cf7sg-dynamic-list.php.

You have 4 aspects of the registration which will control the tag builder form parameters.

  1. The field style - set using the method set_styles(array(), array()), it takes 2 arrays. The first one includes the various styles you want your user to be able to select form the builder (in the case of the dynamic dropdown 2 styles are offered, the default HTML select field the JQuery Select2). This first array expects the attribute=>label pair. The label can be plain text or HTML such as link to an external page. The 2nd array allows for further options on a given style. For example, the dynamic dropdown Select2 style can take an additional (optional) tags attribute to further customise the select2 field. This is passed in the 2nd array using the correspoing select2 style attribute in the first array,
'select2'=>array(
   'tags'=>array(
     'label'=> '<a target="_blank" href="https://select2.org/tagging">'.__('Enable user options','cf7-grid-layout').'</a>',
     'attrs'=>'disabled'
   )
)

the style attributes in the first array are rendered as radio fields, the user can select only 1 such style. The style attribute is setup as a class in the CF7 tag, eg class:select2. So are the additional attributes for each style, eg class:select2 class:tags for the select2 style.

the additional attributes in the 2nd array are rendered as checkboxes and expect an array with a label and optional attrs which can be a string of attributes to be added to the HTML checkbox, eg disabled checked.

  1. Field's extra options - set using the set_others_extras(array( )) method, it allows you to set additional attributes to parametrise the field tag. In the example above, the attribute multiple allows a user to parametrise the field to accept multiple selections. The extra option attributes are passed as is to the tag field, eg [dynamic_select fiel-name class:select2 multiple]

  2. Limiting extra options to single selection - set using the method set_others_extras_radio(), which forces the rendering of each extra option as radio fields.

  3. Enable nesting of lists - set using the method allow_nesting(). Nesting in the dynamic dropdown field is by default disabled due to the limitations of the HTML <select/> field, however, this is enabled in the dynamic checkbox registration and allows for hierarchical representation of taxonomy lists.

Register additional script/style sources

When a form is saved in teh admin editor, the following filter is fired,

add_filter('cf7sg_save_dynamic_list_form_classes', 'save_dynamic_list_form_classes',10,3);
/*
 * these classes are passed in a front-end action hook when the form is being loaded on a page, 
 * allowing you to enqueue the required sources for this form.
 * @param Array $form_classes is an array of classes to be added to the Smart Grid HTML form wrapper element.
 * @param WPCF7_Tag $tag is the dynamic field tag used in the current form.
 */
function save_dynamic_list_form_classes($form_classes, $tag, $form_id){
  //use the $tag classes and other attributes to determine how the tag is parametrised and which classes to add to the form.
  return $form_classes;
}

to see an example of this, see the method save_dynamic_list_form_classes() in the file admin/class-cf7-grid-layout-admin.php.

Build the HTML field

on the front-end, the dynamic field HTML structure is built by hooking the following filter,

/*
* in the case of the registration of 'my_dynamic_tag' field,
* @param String $html html to filter.
* @param Array $attrs array of attribute key=>value pairs to be included in the html element tag.
* @param Array $options array of value=>label pairs  of options.
* @param Array $other_attrs array of other attributes in tag field as $attr=>true.
* @param mixed $selected a string or an array of values that are pre-selected.
* @return String an html string representing the input field to a=be added to the field wrapper and into the form.
*/
add_filter('cf7sg_my_dynamic_tag_html_field','', 10,5);
function build_my_dynamic_tag_field( $html, $attrs, $options, $other_attrs, $selected){
  return $html;
}

to see an example, see the method build_dynamic_checkbox_field() in the file: public/class-cf7-grid-layout-public.php.

Register your extra resources

it is important to register any extra resources (wp_register_scruipt / wp_register_style) prior to enqueue-ing them at the time of form display when the form classes are available to determine which resource needs to be enqueued. This is because the point of execution of the form display is too late to enqueue resources that have been pre-registered. It is therefore important to register all possible resources (scripts and stylesheets) that any form may require.

add_action('smart_grid_register_scripts', 'register_dynamic_list_scripts', 10,2);
* @param Boolean $airplane if airplane mode is on, do not load remote scripts/styles.
  * @param String $min set to '.min' by default, empty if in WP_DEBUG mode.
function register_dynamic_list_scripts($airplane, $min){
}

to see an example, see the method register_dynamic_list_scripts() in the file: public/class-cf7-grid-layout-public.php.

Enqueue the required resources

finally when the current form is being displayed (by the CF7 plugin), the smart grid enhances the form with its own HTML wrapper and additional resources. It fires an action for other plugins to hook and enqueue their resources based on the form classes registered when the form was last saved in the admin editor.

add_action('smart_grid_enqueue_scripts', '',10,3);
/*
* @param String $cf7_key unique key to identify the form.
* @param Array $atts an array of attributes passed in the CF7 shortcode, including the form id.
* @param Array $classes an array of classes registered for this form.
*/
function enqueue_dynamic_list_resources($cf7_key, $atts, $classes){
}

to see an example of this, see the anonymous function in the method register_dynamic_list_scripts() in the file: public/class-cf7-grid-layout-public.php.