Creating Custom Fields in Node Forms to Control User Input

Sometimes you want to customize your node forms because end users are entering erroneous data. One situation that happens a lot is a field that you usually don't need any data entered but people do because the field is displayed.

Let's say you have a node type called listings for storing business listings and each has an address. Some businesses have multiple listings, one for each address. So to differentiate them, we use a field called location name. The problem is that users will enter a location name even though its not required and the business only has a single location. A simple way to fix this specific issue would be to create a checkbox above the location name field titled "This business has multiple locations.". When the user checks the checkbox, only then will it display the location name field.

Let's dive in to some code in our custom module to create our custom field:

<?php
/**
* Implementation of hook_form_alter
*/
function mymodule_form_listing_node_form_alter(&$form, &$form_state, $form_id) {

  // only display location name field if custom checkbox is checked
  $form['field_location_name_display'] = array(
    '#type' => 'checkbox',
    '#title' => t('This business has multiple locations.'),
    '#default_value' => (isset($form['field_location_name']['und'][0]['value']['#default_value']) ? 1 : 0),
  );

  $form['field_location_name']['#states'] = array(
    'visible' => array(
      ':input[name="field_location_name_display"]' => array('checked' => TRUE),
    ),
  );

}

In the above function, we alter the node form for the listing node type. I created a new checkbox form field that will toggle the display of my existing field called field_location_name. I've altered the field_location_name to add a new attribute called #states that adds JavaScript to the element to determine whether or not its displayed.

The only thing left to do is to make sure my new checkbox field displays right above the location name field. I usually like to use Display Suite for form layout which gives you fine grain control over the look of your forms. However, it won't display your custom field in Display Suite by default. This is where the Renderable Elements module is really useful. Once this module is installed, you can add your custom form field as a renderable element and it will display in the manage fields display with all your other fields