Thursday, 31 March 2011

Being too clever with forms

The situation I ran into was with a content type called "document", it's pretty simple: title, description, taxonomy term and a single file upload.

The tricky bit was the taxonomy: each document could belong to a different part of the site (represented by the top level of the taxonomy) let's say SectionA and SectionB, within each of those there'd be subsections: SubA1, SubA2... and SubB1, SubB2 etc.

The first level was selected by the place the document was created - so someone might be in Section A, they create a document - I add the taxonomy term to the URL, like this: node/add/document/X and, in a hook_form_alter(), I use that added value to modify the allowed options in the taxonomy selector to only include the subsections for the section we came from.

Which is fine.

Except when you factor in the file upload. What a file upload does is rebuild the form - which meant my code was getting called again and this was bad. The real code was a bit more complex than I've described here and reloading was very bad - basically it completely wiped out the taxonomy options on the second run through. Which then meant I got validation errors.

The solution is that you have to have some way of noting that you've been here before and not do the changes again. One thing know is that $form_state does not get rewritten so you can store a variable in there marking that you've done the changes already, it should look something like this (using hook_form_FORMID_alter()):

function mymodule_form_myform_alter(&$form, &$form_state) {
  if (isset($form_state['mymodule_myform_processed'])) {
    return;
  }
  $form_state['mymodule_myform_processed'] = TRUE;


  ...the rest of the code...
}

And that does the trick.

No comments: