Temporary form data storage ... and avoiding validation
I'm using a module-generated form in a mode like a shopping cart, where the user can add data to it, go to other pages, and come back to it, and the data persists. At first I wasn't submitting the data until it was time to complete the process, and so, to persist the data, I was using variable_get/set because without the form being submitted, nothing was being persisted in form_state. However, I've since switched to each of the buttons (return to other pages, update form, submit) causing a submit, with varying logic based on which button was clicked. I discovered (duh!) that variable_set/get was a poor idea, because two users online at the same time end up would get each other's persisted data on the form. So, two questions. Is form_state going to persist the user data for me between form loads, or is there a better method? And I've run into an interesting problem in that the portion of the form with required fields (name, etc) doesn't need to be filled in until the user wants to submit, but of course, that ends up throwing an error when the form is 'submitted' due to one of the other buttons being clicked. Is there a way to have those buttons cause a submit, but bypass validation?
Hmm, to me that sounds like a good use of $_SESSION for storage (as in the cookie), with the advantage that it would persist across site visits, and it only belongs to that user. Nancy ________________________________ From: Jeff Greenberg <jeff@ayendesigns.com> To: development@drupal.org Sent: Tue, August 10, 2010 10:12:49 PM Subject: [development] Temporary form data storage ... and avoiding validation I'm using a module-generated form in a mode like a shopping cart, where the user can add data to it, go to other pages, and come back to it, and the data persists. At first I wasn't submitting the data until it was time to complete the process, and so, to persist the data, I was using variable_get/set because without the form being submitted, nothing was being persisted in form_state. However, I've since switched to each of the buttons (return to other pages, update form, submit) causing a submit, with varying logic based on which button was clicked. I discovered (duh!) that variable_set/get was a poor idea, because two users online at the same time end up would get each other's persisted data on the form. So, two questions. Is form_state going to persist the user data for me between form loads, or is there a better method? And I've run into an interesting problem in that the portion of the form with required fields (name, etc) doesn't need to be filled in until the user wants to submit, but of course, that ends up throwing an error when the form is 'submitted' due to one of the other buttons being clicked. Is there a way to have those buttons cause a submit, but bypass validation?
I think you're right Nancy. I'd had a $_SESSIONectomy and hadn't considered it! Ayen Designs - quality software the first time, every time! -----Original Message----- From: nan wich <nan_wich@bellsouth.net> Sender: development-bounces@drupal.org Date: Tue, 10 Aug 2010 19:20:33 To: <development@drupal.org> Reply-To: development@drupal.org Subject: Re: [development] Temporary form data storage ... and avoiding validation Hmm, to me that sounds like a good use of $_SESSION for storage (as in the cookie), with the advantage that it would persist across site visits, and it only belongs to that user. Nancy ________________________________ From: Jeff Greenberg <jeff@ayendesigns.com> To: development@drupal.org Sent: Tue, August 10, 2010 10:12:49 PM Subject: [development] Temporary form data storage ... and avoiding validation I'm using a module-generated form in a mode like a shopping cart, where the user can add data to it, go to other pages, and come back to it, and the data persists. At first I wasn't submitting the data until it was time to complete the process, and so, to persist the data, I was using variable_get/set because without the form being submitted, nothing was being persisted in form_state. However, I've since switched to each of the buttons (return to other pages, update form, submit) causing a submit, with varying logic based on which button was clicked. I discovered (duh!) that variable_set/get was a poor idea, because two users online at the same time end up would get each other's persisted data on the form. So, two questions. Is form_state going to persist the user data for me between form loads, or is there a better method? And I've run into an interesting problem in that the portion of the form with required fields (name, etc) doesn't need to be filled in until the user wants to submit, but of course, that ends up throwing an error when the form is 'submitted' due to one of the other buttons being clicked. Is there a way to have those buttons cause a submit, but bypass validation?
Le mardi 10 août 2010 à 22:12 -0400, Jeff Greenberg a écrit :
So, two questions. Is form_state going to persist the user data for me between form loads, or is there a better method? And I've run into an interesting problem in that the portion of the form with required fields (name, etc) doesn't need to be filled in until the user wants to submit, but of course, that ends up throwing an error when the form is 'submitted' due to one of the other buttons being clicked. Is there a way to have those buttons cause a submit, but bypass validation?
In order to bypass validation, may be you can remove the required attribute of your form fields, and check for them not be empty in a custom validation handler. You can safely use the form_state array to store your temporary data, but remember that the form cache has only 6 hours to live. I'd create a custom cache table (using the system module table schema definition, with another name), then use it to store my data using each step form submit or validation handler without setting any lifetime. If you create such cache table, it won't be erased by the cron unless you implement the hook_flush_caches() in order to do it. Cache tables are meant to store temporary data which you are be able to rebuild, and can be safely dropped. So, if the data is temporary user input, you can create a cache table and use it with custom queries (not using cache_get() and cache_set()) if you really meant to store this into database, this will allow you to bypass mecanisms such a memcache storage and ensure your data won't be lost. Pierre.
Is form_state going to persist the user data for me between form loads, or is there a better method? ... You can safely use the form_state array to store your temporary data, but remember that the form cache has only 6 hours to live.
The form cache only stores data for a single form submission attempt, bound to form_build_id. Each time the form is built from scratch in a GET request, a new form_build_id is generated, and the form may be cached, but it is not supposed to re-display any previously submitted values that were cached for a different form_build_id. Your shopping cart use-case sounds like $_SESSION or a dedicated table keyed by session ID and uid to me. Also not sure why you want to reinvent the wheel -- doesn't Ubercart or eCommerce or anything else in contrib contain a ready Cart module already? sun
On 08/11/2010 05:29 AM, Daniel F. Kudwien wrote:
Is form_state going to persist the user data for me between form loads, or is there a better method? ... There might be a better method. Some people suggested _SESSION which is pretty handy for little bits of data but I'd checkout ctools' object_cache. Or better yet, since you're creating a form that keeps state, maybe ctools' wizard form generator is what you're looking for. It can do some pretty handy stuff and is well tailored for use with ctools' object_cache. Your shopping cart use-case sounds like $_SESSION or a dedicated table keyed by session ID and uid to me. Also not sure why you want to reinvent the wheel -- doesn't Ubercart or eCommerce or anything else in contrib contain a ready Cart module already?
sun
He did say "like a shopping cart" so I assume it was only an example. Using a prebuilt and tested module is always a big win though. -- James Gilliland
I'll take a look at the form generator, thanks. On 08/11/2010 05:33 PM, James Gilliland wrote:
There might be a better method. Some people suggested _SESSION which is pretty handy for little bits of data but I'd checkout ctools' object_cache. Or better yet, since you're creating a form that keeps state, maybe ctools' wizard form generator is what you're looking for. It can do some pretty handy stuff and is well tailored for use with ctools' object_cache.
As James mentioned, a shopping cart was just an example. The comparison being that the form can be visited many times as the data are gathered. Nothing ends up in the db in this case ... it is sent as an e-mail in the end. On 08/11/2010 06:29 AM, Daniel F. Kudwien wrote:
Your shopping cart use-case sounds like $_SESSION or a dedicated table keyed by session ID and uid to me. Also not sure why you want to reinvent the wheel -- doesn't Ubercart or eCommerce or anything else in contrib contain a ready Cart module already?
sun
participants (6)
-
Daniel F. Kudwien -
James Gilliland -
Jeff Greenberg -
jeff@ayendesigns.com -
nan wich -
Pierre Rineau