Retrieving form values during intial form rendering
I'm really stumped with what I thought would be a simple thing, and I'm finally asking for some help. This is in Drupal 5. I have a form that is *not* node-related, that needs to be able to do the equivalent of a preview, in that it needs to be rendered with its default values being the fields from its previous submission. Sounds simple, right? Here's what's happening, though: My form gets built fine during HTTP GET, with #default_value being set appropriately. The user submits the form, and $_POST gets the right data. That data is passed to hook_form_validate() and then to hook_form_submit(). So far, so good. But when I get to hook_form(), the $_POST is no longer set, because of the drupal_goto() that results from hook_form_submit(). So I wondered, "Where does my data get stored?" Apparently, I wondered this like everyone else, because the Forms API handbook page says: "The practical upshot to this is that many developers immediately find themselves asking the question of "where does my data get stored?". The answer is simply that it doesn't. You put your $form data together, perhaps loading your object from the database and filling in #default_values, the form builder then checks this against what was posted." Loading from the database isn't an option, because these happen to be search parameters that aren't stored in the database. Most of the extant Drupal code I looked at for an example doesn't apply to my situation, because they all use $node->foo to store their data. My module is managing an app-specific table that isn't connected with nodes in any way, and the particular form in question is a query rather than data entry, so I don't have a table where I can put the data. Now, I think I can probably solve this using $_SESSION, but that seems so... inelegant. I've got to believe someone has solved this before, and that there is a "Drupally-correct" standard way to do what I need to do, which is simply to have a form that defaults to its previous values each time it's rendered after a POST operation (but not a GET). Can anyone tell me what I'm overlooking, or point me toward one of your own modules that does this that would serve as an example? Many thanks. Scott -- ------------------------------------------------------------------------------ Scott Courtney | "I don't mind Microsoft making money. I mind them scott@4th.com | having a bad operating system." -- Linus Torvalds http://4th.com/ | ("The Rebel Code," NY Times, 21 February 1999) | PGP Public Key at http://4th.com/keys/scott.pubkey
I think you want to research '#button' and '#after_build'. '#button' will send you form values without a full submission. '#after_build' will allow you to do something with the built values (node.module uses #after_build to prepend the rendered preview version) You may have to supply a '#name' element for your button so that it doesn't get stuck in 'op'. I'm a little rusty on that point. Cheers, -Mark On 3/30/07, Syscrusher <syscrusher@4th.com> wrote:
I'm really stumped with what I thought would be a simple thing, and I'm finally asking for some help. This is in Drupal 5.
I have a form that is *not* node-related, that needs to be able to do the equivalent of a preview, in that it needs to be rendered with its default values being the fields from its previous submission. Sounds simple, right?
Here's what's happening, though: My form gets built fine during HTTP GET, with #default_value being set appropriately. The user submits the form, and $_POST gets the right data. That data is passed to hook_form_validate() and then to hook_form_submit(). So far, so good.
But when I get to hook_form(), the $_POST is no longer set, because of the drupal_goto() that results from hook_form_submit(). So I wondered, "Where does my data get stored?" Apparently, I wondered this like everyone else, because the Forms API handbook page says:
"The practical upshot to this is that many developers immediately find themselves asking the question of "where does my data get stored?". The answer is simply that it doesn't. You put your $form data together, perhaps loading your object from the database and filling in #default_values, the form builder then checks this against what was posted."
Loading from the database isn't an option, because these happen to be search parameters that aren't stored in the database. Most of the extant Drupal code I looked at for an example doesn't apply to my situation, because they all use $node->foo to store their data. My module is managing an app-specific table that isn't connected with nodes in any way, and the particular form in question is a query rather than data entry, so I don't have a table where I can put the data.
Now, I think I can probably solve this using $_SESSION, but that seems so... inelegant. I've got to believe someone has solved this before, and that there is a "Drupally-correct" standard way to do what I need to do, which is simply to have a form that defaults to its previous values each time it's rendered after a POST operation (but not a GET).
Can anyone tell me what I'm overlooking, or point me toward one of your own modules that does this that would serve as an example?
Many thanks.
Scott
-- ------------------------------------------------------------------------------ Scott Courtney | "I don't mind Microsoft making money. I mind them scott@4th.com | having a bad operating system." -- Linus Torvalds http://4th.com/ | ("The Rebel Code," NY Times, 21 February 1999) | PGP Public Key at http://4th.com/keys/scott.pubkey
On Friday 30 March 2007 18:19, Mark Fredrickson wrote:
I think you want to research '#button' and '#after_build'. '#button' will send you form values without a full submission. '#after_build' will allow you to do something with the built values (node.module uses #after_build to prepend the rendered preview version)
You may have to supply a '#name' element for your button so that it doesn't get stuck in 'op'. I'm a little rusty on that point.
And on Friday 30 March 2007 18:28, Peter Wolanin wrote:
I'll agree with Mark here- I've used this trick a few times.
Take a look at how node previews are generated.
And now I will write.... File this under, "Boy do I feel stooopid now." You guys are right, though slightly off on syntax. It's working now. For the benefit of anyone else who's as dumb as me, here's the solution: All I needed to do was change '#type' => 'submit' to '#type' => 'button' in my form array declaration. That's basically it. I also simplified my life by declaring the $form_values parameter, needed by my hook_form() function, directly into the menu, as in: function mymodule_menu($may_cache) { global $form_values; if ($may_cache) { $items = array(); $items[] = array( 'path' => 'mymodule', 'callback' => 'mymodule_page', 'callback arguments' => $form_values, 'access' => user_access('access genealogy'), 'title' => t('Genealogy'), ); ...etc.... return $items; } function mymodule_page($form_values=array()) { // Generate my page $html = drupal_get_form('mymodule_query', $form_values); } And finally... function mymodule_query_form($form_values=array()) { $form = array( 'first_name' => array( '#type' => 'textfield', '#title' => t('First name'), '#size' => 40, ), 'dosearch' => array( '#type' => 'button', '#value' => t('Search'), ), ); return $form; } I believe Mark is correct about the need for '#name' to be added to the button, but I haven't tried that part yet. I've done that in another module, and Mark's recollection matches mine. But the main thing I couldn't get working, namely the redisplay of the values, works now for all field types. Right now I have only the one button, so the '#name' business to tell "which" button isn't an issue for me yet. Incidentally, looking at node.module for its preview was the first thing I thought of, but that code's execution flow is pretty complex with all the foo_invoke_foo() calls, database loads, and such that don't apply to what I'm doing. I totally overlooked the simple notion of using a non-submit button to inhibit the call to hook_submit(), but that was the key! Thanks very much, Gentlemen, for the right answer and the quick reply. I'm trying to get some Drupal coding done while I'm out of town, and having this answer tonight will let me make more progress tomorrow during a no-Internet daytime commitment. Many thanks! Scott -- ------------------------------------------------------------------------------- Syscrusher (Scott Courtney) Drupal page: http://drupal.org/user/9184 syscrusher at 4th dot com Home page: http://4th.com/
participants (2)
-
Mark Fredrickson -
Syscrusher