How to display default value of disabled form elements after failed validation? I have a form with some disabled form elements. When the form fails validation and is sent back to the user, the disabled fields are empty. How can I make the disabled fields display the default values that were originally defined in the form?

function foo_form(&amp;$form_state) {
  return array(
    'foo' =&gt; array(
      '#type' =&gt; 'textfield',
      '#default_value' =&gt; 'foo',
      '#disabled' =&gt; true,
    ),
    'submit' =&gt; array(
      '#type' =&gt; 'submit',
      '#value' =&gt; 'Submit',
    )
  );
}

function foo_form_validate($form, &amp;$form_state) {
  form_set_error('submit', 'You cannot submit this form');
}


In this example, when the user presses the Submit button, the expected warning is displayed, but the text field is empty. This is most disturbing for the user, he does not know that all relevant information to process the form are still present.

$form_state['values']['foo'] is empty, but that's expected because disabled HTML elements are not included in the HTTP request that submits the form. Setting $form_state['values']['foo'] to the desired value in the validation function does not help.
The function that builds the form array isn't expecting any params unless you set a param in your hook_menu for instance. Instead you could try to grab the $form variable in the validation handler by reference and setting the value. 

function foo_form() {
  return array(
    'foo' =&gt; array(
      '#type' =&gt; 'textfield',
      '#default_value' =&gt; 'foo',
      '#disabled' =&gt; true,
    ),
    'submit' =&gt; array(
      '#type' =&gt; 'submit',
      '#value' =&gt; 'Submit',
    )
  );
}

function foo_form_validate(&amp;$form, &amp;$form_state) {
  $form['foo']['#value'] = 'bar';
  form_set_error('submit', 'You cannot submit this form');
}


This is untested as I have no running Drupal 6 instance at the moment. But I was able to do so using Drupal 7.

Another approach would be to use #value instead of #default_value since you already got your custom validation handler to put some extra logic in (get rid of the form_state value).