Community & Support

form API - make element required only if another element is selected

Is this possible through the Drupal form API?

So for example, I have an address form. The postcode field is required unless you select Ireland as your country, then it's optional.

With the Drupal form API, you set what is required and then Drupal renders the form. Is there a way to alter requirements using JavaScript?

Thanks

Comments

Here is one possible way to

Here is one possible way to do this:

<?php
function my_custom_form() {
 
$form = array();
 
$form['country'] = array(
   
'#type' => 'select',
   
'#options' => array('us' => t('USA'), 'ireland' => t('Ireland')),
   
'#title' => t('Country'),
  );
 
$form['postal'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Postal code'),
   
// Don't make this field required. Use the validate hook.
   
'#required' => FALSE,
  );
  return
$form;
}

function
my_custom_form_validate(&$form, &$form_state) {
 
// Validate the postal code is entered when Ireland is not selected.
 
if ($form_state['values']['country'] != 'ireland' && empty(trim($form_state['values']['postal']))) {
   
form_set_error('postal', t('The Postal code is required.'));
  }
}
?>

If you want to add a little Javascript that will add the '*', you can do the following (note that you will still need the validate hook because just putting the '*' in doesn't actually make the field required):

<?php
function my_custom_form() {
 
$form = array();
 
$form['country'] = array(
   
'#type' => 'select',
   
'#options' => array('us' => t('USA'), 'ireland' => t('Ireland')),
   
'#title' => t('Country'),
   
'#attributes' => array('onchange' => 'toggle_required_display();'),
  );
 
$form['postal'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Postal code'),
   
// Don't make this field required. Use the validate hook.
   
'#required' => FALSE,
  );
 
drupal_add_js('function toggle_required_display() {
  if (!$("label[@for=edit-postal] .form-requied").length) {
    $("label[@for=edit-postal]").append(\'<span class="form-required" title="'
. t('This field is required.') .'">*</span>\');
  }
  if ($("#edit-country").val() != "ireland") {
    $("label[@for=edit-postal] .form-requied").show();
  }
  else {
    $("label[@for=edit-postal] .form-requied").hide();
  }
}
toggle_required_display();'
, 'inline');
  return
$form;
}
?>

I didn't test this, so there may be a typo somewhere in the code. I hope not though.

thanks for the detailed

thanks for the detailed response.

This was sort of how I was thinking about doing it, but seeing your code has helped me out in a few areas. The only thing is that I am editing the Ubercart checkout form, so I've got two postcode fields to deal with, plus the form does not use labels.
Oh and also you've got . for concatenation instead of +

The '.' he is using is for

The '.' he is using is for PHP concatenation, so those are correct.

Actually, it should be

Actually, it should be .form-required instead of .form-requied in the selectors.