0

I have an form in a block with ajax submission. The block view code calls drupal_get_form, adds some other info, uses a custom theme tpl to create the block.

I want to replace the form in the block with a thank you message after successful submission.

AJAX works: The ajax on the submit element of the form means that a custom ajax callback can replace the entire form with another themed chunk, passing in the form values received by the form so they can be merged in the thank you template. This works well because the ajax function has access to the form_state.

But what if AJAX is unavailable on the client? Then the normal form submit happens and the block view function just gets a blank form.

So how can my block view function get hold of the submitted values to feed them into the thank you template?

Edit: messy work-arounds

  1. I could just access $_POST but that's nasty and unvalidated! yuk

  2. In the submit handler I can copy the $form_state['values'] variable to a superglobal, and check for that.

5
  • $form_state['foo'] = 'bar'; $form_state['rebuild'] = TRUE; in a submit handler then check for $form_state['foo'] in the form build function?
    – Clive
    Jul 18 '14 at 9:51
  • @Clive thanks, but it's the code outside the form builder that needs to know the values. i.e. other content on the page is going to change as the result of filling in the form. Jul 18 '14 at 10:02
  • You shouldn't make that rely on the form then - set a state variable somewhere (session/database/whatever) in your submit handler, and read from that in the block function. Forms are intentionally isolated so their logic doesn't bleed out where it's not wanted.
    – Clive
    Jul 18 '14 at 10:09
  • I think that's what I've done with workaround (2)? It's not the logic I want to interfere with, I just want the form to be able to provide variable outputs. Jul 18 '14 at 10:10
  • That's what I mean, forms aren't supposed to provide return values to the rest of the request; they're supposed to accept some input, process it, and then get out of the way (this is the reason you can't find an easy way to get access to $form_state['values']; they're not supposed to be available outside the context of a form build). I wouldn't class setting a state variable as a 'workaround', I'd consider that to be the correct approach
    – Clive
    Jul 18 '14 at 10:13
1

I realise this is an old question but: drupal_get_form() is mostly a wrapper for drupal_build_form(), and (the docs say) is intended to be used "instead of drupal_build_form() when $form_state is not needed", with the implication that if $form_state is needed, it's OK to go straight to drupal_build_form().

The only extra bit drupal_get_form does is assemble a 'build_info' array in the $form_state, so instead of (e.g.) $block['content']['form'] = drupal_get_form('myform_name', $arg);, you could do something like this:

  $form_state = array();
  $form_state['build_info']['args'][] = $arg;
  $block['content']['form'] = drupal_build_form('myform_name', $form_state);

You should find your $form_state variable is now populated as it would be if you were operating inside the form building function, including any $form_state['values'] or $form_state['input'] in the event that your form is being rebuilt.

1
  • 1
    I've not tested this, but TBH it was 4 years ago I posted this question and this looks right to me. So thanks! Oct 14 '18 at 11:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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