0

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(&$form_state) {
  return array(
    'foo' => array(
      '#type' => 'textfield',
      '#default_value' => 'foo',
      '#disabled' => true,
    ),
    'submit' => array(
      '#type' => 'submit',
      '#value' => 'Submit',
    )
  );
}

function foo_form_validate($form, &$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.

1 Answer 1

2

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' => array(
      '#type' => 'textfield',
      '#default_value' => 'foo',
      '#disabled' => true,
    ),
    'submit' => array(
      '#type' => 'submit',
      '#value' => 'Submit',
    )
  );
}

function foo_form_validate(&$form, &$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).

6
  • $form is never passed as reference, not even in Drupal 6.
    – avpaderno
    Commented Jun 28, 2013 at 5:15
  • You're right, Drupal isn't. Even $form_state isn't. This is why we are putting a leading & before. Don't get me wrong, I never used the $form as a reference in a validation function before but I was curious and tested it and it worked in D7. So please be more verbose. Your comment isn't getting anywhere. Is it style, performance or what? Since technically it's possible.
    – aaki
    Commented Jun 28, 2013 at 5:27
  • 1
    If you will set #value, user input will get ignored, only what you set in #value will be used from now on. Tested.
    – Mołot
    Commented Jun 28, 2013 at 8:27
  • This is right but since he wants this field to be disabled...
    – aaki
    Commented Jun 28, 2013 at 8:33
  • @aaki According to the Drupal 6 Form API Quickstart Guide, the validation function cannot expect to recieve an argument that can be turned into a reference. Furthermore, there is no guarantee that the form array that is rendered for display to the user is the same as the one that was passed to the validation function (even though in Drupal 6.28 that's pratically the case). I therefore prefer to set the #value property directly in the form builder function. Thanks for hinting me in the right direction.
    – Oswald
    Commented Jun 28, 2013 at 11:33

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.