Hi drupalists,

we ran into a problem with a custom module which makes heavy usage of the forms-api.

In this module values are checked and eventually modified as the user submits the form. The problem is that the values which are set newly with form_set_value are set only in the case that form_set_error is called in addition. Otherwise there new values are not set.

Is this a regular behaviour or a bug?

Best regards,

Culfin

Comments

culfin’s picture

Priority: Normal » Major

Additional info:
The value (which has to be changed) is being set in the hook_validate method of the form.

bleen’s picture

culfin: ... shouldnt you be doing that sort of change in your form submit function? not your validation function

effulgentsia’s picture

Can you post a simple code example that demonstrates the bug?

webchick’s picture

Status: Active » Postponed (maintainer needs more info)
culfin’s picture

I talked to the module-developer and he pointed out the following:

1. Download the example module at http://drupal.org/project/examples
2. Use the form example.
3. Click on form tutorial.
4. Enter element_validate in the name field
5. Click save.
6. The new value is shown.
7. Now open examples/form_example/form_exampl_tutorial.inc
8. Locate function form_test_element_validate_name
9. Comment out the line form_set_error('');
10. Perform steps 4 & 5. The new value is not shown.

culfin’s picture

Version: 7.0-rc1 » 7.0
Status: Postponed (maintainer needs more info) » Active
bfroehle’s picture

Status: Active » Postponed (maintainer needs more info)

Hi culfin,

Im having trouble following your directions... I'm able to download the example module, enable the form example, and click on element_validate. However in examples/form_example/form_example_tutorial.inc, there is no function called form_test_element_validate_name. There is a function with that name in modules/simpletest/tests/form_test.module... Can you help me out?

But...

I did notice a similar issue in #61856-29: In user.module, trim() user-submitted email address before validation which I can describe how to test... Download and apply the patch in that issue. Assuming you have a user already registered with e-mail address like 'test@localhost', attempt to register a new user with e-mail address ' test@localhost ' (where we've taken the old e-mail address and added some white space on either side). Click submit and you'll get an error that the e-mail address is already registered.

In the validate function for the user registration form, we call form_set_value with the whitespace trimmed version of the e-mail address. However on the page where the duplicate e-mail address error is displayed, the e-mail address still appears with whitespace on both sides.

bfroehle’s picture

Status: Postponed (maintainer needs more info) » Active

Ooopsies! I didn't mean to change the status.

effulgentsia’s picture

Version: 7.0 » 7.x-dev
Status: Active » Closed (works as designed)

As per #7, I'm able to reproduce #5, but not from the Examples module, but rather, by enabling the FormAPI Test module, which is part of core's automated tests, and can be enabled for interactive use by first unhiding the module from the module page (edit modules/simpletest/tests/form_test.info, and put a ; in front of the hidden = TRUE line), and then enable the module from the admin/modules page.

With that module enabled, you can navigate to form-test/validate and perform steps 4 and 5 from comment #5, first without changing any code, and then after commenting out form_set_error(''); from form_test_element_validate_name().

The above is not a bug. The reason why the changed value appears in the first case, and not in the second case, is that when a form is submitted with errors, then Drupal displays the same form, for the user to correct. But when a form is submitted without errors, then Drupal executes the submit handlers, and redirects to a new page, which can either be a totally different page (as specified by $form_state['redirect'], for example, after submitting the node edit form, you are redirected to the node view page), or else can be a fresh copy of the same form (when no $form_state['redirect'] is specified, as in this example). See drupal_redirect_form() for more details.

So, if you take out the form_set_error() in this example, then the form_set_value() still works, and the new value is in $form_state['values'] for when the submit handlers run, but after form processing is complete, you're redirected to a new instance of the form, and this is by design.

In the validate function for the user registration form, we call form_set_value with the whitespace trimmed version of the e-mail address. However on the page where the duplicate e-mail address error is displayed, the e-mail address still appears with whitespace on both sides.

form_set_value() only changes what's in $form_state['values'] for the element. It does not change the value of the element's #value property. The former is used by submit handlers. The latter is used for rendering the form for the user to correct. If you want to change the latter, you can do so with $form['account']['mail']['#value'] = $mail.