I have a custom module (entitled ta_module) : in the user registration form, it hides the e-mail field, and add a custom field where user have to enter what's before @ and then choose his e-mail domain name between the one proposed in a list next to it.

Here's the code :


 * Implementation of hook_form_alter()
function ta_module_form_alter(&$form, &$form_state, $form_id) {

   // If the form is the user_register form
    if ($form_id == 'user_register_form') {
        // Attach our custom validation function as the first validation function
        array_unshift($form['#validate'], '_ta_module_user_validate');
        // Hide the email address field
        $form['account']['mail']['#type'] = 'hidden';
        // Give the email address field a random default value (in this case a random number and a timestamp)
        // as we cannot unset it due to Drupal's validation rules
        $form['account']['mail']['#default_value'] = rand(1111, 9999) . '@' .time() . '.com';
        // Add our new text entry field
        $form['mail_first'] = array(
      '#type' => 'textfield',
      '#title' => t('Email address'),
      '#default_value' => '',
      '#size' => 35,
      '#maxlength' => 64,
      '#required' => TRUE,
        // Add our select list of possible email domain values
        $form['mail_last'] = array(
      '#type' => 'select',
      '#title' => 'Domaine',
      '#title_display' => 'before',
      '#options' => array(
              // These are the possible email address domains
              'myentreprise.net' => '@myentreprise.net',
              'myentreprise.com' => '@myentreprise.com',
      '#default_value' => 'myentreprise.net',
      '#required' => TRUE,

 * Function to piece together our email address
function _ta_module_user_validate(&$form, &$form_state) {
    // If our two form elements have values
    if (!empty($form_state['values']['mail_first']) && !empty($form_state['values']['mail_last'])) {
        // Set the email address to the correct value
        $form_state['complete form']['account']['mail']['#value'] = $form_state['input']['mail_first'] . '@' . $form_state['input']['mail_last'];

(see This Q/A for more infos).

All appear quite brightly, but when the user click on "create a new account", the user is created but the last function of my module doesn't work : the e-mail finally saved is the default value (something like 0129[email protected]) instead of the two pieces joined together...

HOW TO FIX THIS : Thus how to assign to mail the value of mail-first + mail-last ?

/!\ I'm working on Drupal 7, so I think it's an issue of uncorrect variables...

Thks for reading ! ;)

2 Answers 2


If you need to set the value for the form field used to contain the email address, then you should use code similar to the following one:

function _ta_module_user_validate(&$form, &$form_state) {
  if (!empty($form_state['values']['mail_first']) && !empty($form_state['values']['mail_last'])) {
    form_set_value($form['account']['mail'], $form_state['values']['mail_first'] . '@' . $form_state['values']['mail_last'], $form_state);

As an example of how form_set_value() is used, see system_site_information_settings_validate(), which contains the following code:

// Check for empty front page path.
if (empty($form_state['values']['site_frontpage'])) {
  // Set to default "node".
  form_set_value($form['front_page']['site_frontpage'], 'node', $form_state);
else {
  // Get the normal path of the front page.
  form_set_value($form['front_page']['site_frontpage'], drupal_get_normal_path($form_state['values']['site_frontpage']), $form_state);

Instead of

$form_state['complete form']['account']['mail']['#value'] = $form_state['input']['mail_first'] . '@' . $form_state['input']['mail_last'];

Try using the form_set_value() function. Documentation says:

Use this function to change the submitted value of a form element in a form validation function, so that the changed value persists in $form_state through to the submission handlers.

  • Ok, thks! So I put something like : form_set_value($form_state['mail'], $form_state['input']['mail_first'].$form_state['input']['mail_last'], $form_state); OR form_set_value($element['#mail'], $form_state['input']['mail_first'].$form_state['input']['mail_last'], $form_state); ???
    – nyoz
    Jun 22, 2011 at 20:26
  • 1
    Please see the form_set_value() documentation as I've never had to use the function myself. And don't forget to concatenate your '@' sign to the email string.
    – nmc
    Jun 22, 2011 at 20:40
  • I've tried both after reading the documentation. But the two times I got the following error : Notice : Undefined variable: element dans _ta_module_user_validate() (line 49 in /**DRUPAL_ROOT**/sites/all/modules/ta_module/ta_module.module). Recoverable fatal error : Argument 2 passed to drupal_array_set_nested_value() must be an array, null given, called in /homepages/19/d362299801/htdocs/technomaide/includes/form.inc on line 2393 and defined dans drupal_array_set_nested_value() (ligne 6263 dans /homepages/19/d362299801/htdocs/technomaide/includes/common.inc).
    – nyoz
    Jun 22, 2011 at 22:59

Your Answer

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

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