Creation of new content type by D7 core is intuitive, fast and nice looking. We don't have to worry about db tables and simple validation. We have widgets, displays, etc. And actually we are building a form (company_node_form).


Custom content type: Company

Field group: Company address (vertical tab)

  • Field (simple text): Street
  • Field (simple text): No.
  • Field (simple text): Zip code
  • Field (simple text): Country

Field group: Company contact (vertical tab)

  • Field (check box): Has phone
  • Field (simple text): Phone
  • Field (check box): Has fax
  • Field (simple text): Fax

Field group: Privacy (vertical tab)

  • Field (check box): Show address
  • Field (check box): Show phone


How to add alternation using custom module "my_module" to provide AJAX behavior while adding or editing content type, i.e. to show "Phone" field only if "Has phone" is checked or show text "Sorry, we don't have authority to add companies from selected country." when UK goes to "Coutry" field?


I know that the above form is very simple to code inside my_module, but I wish to use core node constructor to build that form instead of coding.

4 Answers 4


Your module needs to implement hook_form_alter() to add '#ajax' arrays to the elements that trigger a change in the form. The #ajax elements will include 'wrapper' and 'callback' elements that specify the html ID of the part of the form to replace and a function in your module that returns the part of the form that is being replaced.

For example, if the element 'my-element' should be replaced, add

'#prefix' => '<div id="my-element-id">', 
'#suffix' => '</div>' 

to the form array with key 'my-element'. The element that triggers the replacement will get

'#ajax' => array(
   'wrapper' => 'my-element-id',
   'callback' => 'my_callback',
   'method' => 'replace',

Here is the callback function:

function my_callback($form, &$form_state) {
    return $form['my-element'];

Your hook_form_alter() will hide/show elements and generate your custom messaging depending on $form_state (which it will read when the ajax callback happens).

  • 4
    this is works only on regular form not for a node form
    – sel_space
    Commented Sep 2, 2012 at 20:16

To add this functionality to the node form, use Conditional Fields module - http://drupal.org/project/conditional_fields. You will need to create field dependencies to allow a particular field to show only when the previous field's input meets some criteria.


As @sel_space mentioned hook_form_alter trigger once when builds form at first time. I believe you can use #after_build and add own callback.


For simple Ajax functionality have a look at #states in Form API.

 *  Implements hook_form_alter().
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'MYNODETYPE_node_form') {
    $form['field_telephone_number']['#states'] = array(
      'visible' => array(
        ':input[name="field_has_phone"]' => array('checked' => TRUE),

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.