By halloffame on
I'm trying to keep form values intact even on page refresh using $_SESSION variable. I have this to store the info on session:
<?php session_start();
$_SESSION["body"]= "value here";
?>However I cannot figure out what do I put as value other than a static text. What value do I set if I want this to store the field value that the user is typing on the form?
Please advice. Thanks.
Comments
You can't get the form values
You can't get the form values until the user submits the form. If they type something in a field and then hit refresh, it's up to the browser to preserve that info (most modern browsers do). However, if you're trying to make a multi-step form, the Chaos Tools module has an API to help with that.
I'm quite sure that this can
I'm quite sure that this can be done with sessions. Values are being stored in sessions so in case they navigate to other page or refresh the form is still filled with previously input data. I'm able to do it with static value with my code above. I just don't know how to set it dynamically.
I've search the net for this and some people were able to achieve this using
$_POSTor$_GET. I don't know how its supposed to be done the Drupal way. I don't know PHP that much too.I'm able to start a session in my pages with
session_start();. The next step should be storing where I am currently having problem with. Then I was also able to retrieve the information usingecho $_SESSION['body'];*body - Supposedly the field I want to use here.
This should be relatively look simple though. Something like:
$_SESSION[body]= $_POST[body];Well if any of you knows any other way on how to keep form values on refresh (even from anonymous - authenticated state) I would be up for it. As long as I achieve my end goal I don't care what method I'll use. Perhaps cookies? Javascript? I would prefer it through $_SESSION variable though. I got a feeling that I'm on the right track here. I just need to figure out how to store the values.
I'm quite sure that this can
You can't store the user-entered form values until they submit the form. This is PHP, it's server-side only. You can, absolutely, store form values to the session AFTER the form's been submitted (even if it fails validation).
Yes, you essentially want the $_POST values, which in Drupal are duplicated in $form_state['values'] which is what you want to attach to the session, but that's AFTER form submission. As the variable name suggests, it is the $_POSTed values.
You don't need to declare
session_start()you can just add what you want to the $_SESSION directly.Correct, though I would suggest something more like
$_SESSION['form_values'][***FORM ID HERE***]= $form_state['values'];. That way, you'll have a "form_values" array attached to the session, which would be keyed by the form_id which would hold all the values. This way you can easily have values for different forms if you want to without having to worry about them being overridden. Again, this all has to be done AFTER form submission (or more specifically, during a submit handler of the form).As I said in my first post, most modern browsers will remember your form values when you refresh, but I suppose you could ensure this with javascript/cookies. Something like looping through the form fields and saving them to a cookie on page-unload or something. That's a bit out of my realm though personally.
Can I ask for some more detail? What form is this for? A custom form, or an existing Drupal/module-provided form? And why do you need to account for the user refreshing the page in the first place?
Thank you so much for your
Thank you so much for your prompt and detailed input.
I see. I really thought this could be implemented using $_SESSION.
It's a node form for a particular content type.
The Story:
Please don't judge my method. I have a ton of reasons why I resorted to this.
I have a popup iframe for logging in and registering (I don't wanna bore you as to why I resorted to this method instead of ajax or jquery. That would be a long story)
I'm trying to create a workflow where the node form is available to anonymous users. Anon user fills it up then when a user hits up the save button the iframe pops up. They need to login to submit the form. So they login. On successful login I used the onLoad event to close the iframe and refresh the page. The parent page needs to be refreshed to update appropriate content for authenticated users. So the consequence here is.... ofcourse... empty form. After taking so much effort on filling up the form you probably know how would a site user react to this.
This why I need to retain the form values on refresh.
NOTE: I can't do this in any other way. The workflow should be and will be this way. I've got people suggesting me all other stuffs like getting rid of the node form for anon users but this is not an option. So back to my retain-form-values-on-refresh problem.
You can, absolutely, store
Ok I think I'm going to go for this one. I can pass the users to the validation first via Rules before displaying my infamous popup iframe. Can I use the same values I've been trying to use for when the node form is being built to this one? I would really appreciate a walkthough or just some little guidance on this one. Thank you.
Yeah I would suggest adding a
Yeah I would suggest adding a validation handler to the form. This would check if the user is anonymous, and if so, fail validation (after attaching form values to the session), and then reload the form and auto-trigger the popup. Then we can take it from there.
How much experience do you have with module writing?
Experience? Nothing. As in
Experience? Nothing. As in nada. Kaput. Zero. LOL. But I maintained my own module though. A very simple module that I created for my personal use where I could just drop in very simple drupal overrides and you know... the ones where we just 'borrow' from other modules. So that doesn't count. I'm more of a designer than a coder. The fact that I didn't know that $_SESSION doesn't store form values before submitting it already tells a lot about my technical skills.
Anyways! I was able to fail validation upon submission for anonymous user. I post a form error with a link to the login/popup. The form behaves the way it should. You get an error but the fields are still populated. Now a user clicks on the link and logs in. Upon logged in and closing of the popup the user now see this common error we get when we refresh a page with submitted data:
To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier.. Cancel or resend option. User clicks resend then. Great! The page refreshed and user is now logged in and form data did not go anywhere. There is a validation error being displayed though:Validation error, please try again. If this error persists, please contact the site administrator.. No matter how you hit the save button the form now cannot be submitted. Bugger.I think instead of refreshing
I think instead of refreshing the page, you should direct the browser back to the page, if that makes sense. In other words, don't reload it, just send the user to it again with a window.location = '/node/add/whatever' or something. That'll avoid the "Firefox must send information" dialog. Obviously, the form fields will be reset but that's where our session stuff will come into play.
What does your validation function look like? I'm assuming you have one since you said you were able to make it fail for anonymous users..? We can do this whole thing with hook_form_alter() I'm pretty sure, so if you can paste what you have so far I can help you through it. :D
Ok that fixed the firefox
Ok that fixed the firefox dialog problem. Now on to sessions! ;)
I don't have any custom hook_form_alter function at all at the moment because Rules Module can already do everything I want.
So a fresh function would do. I've got nothing.
I don't know how Rules works,
I don't know how Rules works, so I'd suggest adding a hook_form_alter to your custom module... I'm about to leave work right now, but I'll try to hop on when I get home and whip up something you can test out.
edit: work in progress before my ride gets here... just typing out loud here, don't use it yet:
Can we just handle the
Can we just handle the sessions separately? I.E making a new hook_form_alter function for this? The focus right now is to bring all that input form data from anonymous to authenticated back in to the form while moving through pages.
If it helps Rules is like Trigger and Action plus more. You trigger system actions on certain events. In my case I trigger an action when anonymous is submitting the node form. This is the logic --- if anonymous user is submitting a form - return an error. That's just about it. I only have to set 1 condition then fire an action. Then I set the error message to instruct them to login. All can be done within an intuitive UI and no coding AT ALL.
Now lets go back to my first post. We can probably achieve what I want here because we can store the form values now.
This is what I was trying to do earlier. In my page-node-add-ContentType.tpl.php (or any other applicable pages) I would do this to store the value of the form.
Then I'm gonna retrieve it by setting up the default value of the particular field involve with this:
I think this way would be much easier.
Ok thanks for this. I read it
Ok thanks for this. I read it after I posted my reply. I'm up for anything though as long as I will achieve my end goal.
As I said earlier I'm not
Does this apply for all the fields in that particular form? I also have select list and image field in that form.
Sorry I had an itch and I
Sorry I had an itch and I went ahead and try it... It doesn't work. Strangely the title field gets retain though.
Yeah that makes sense. Title
Yeah that makes sense. Title is the only top-level field element, I hadn't traversed yet. Try this out. I tested locally on a relatively complex form and it seems to work pretty well. A couple things I'm unsure of at the moment are:
- It doesn't currently work for a CCK image field.
- I'm not sure if I need to worry about overriding form_build_id and stuff like that but I don't think so because they don't use #default_value.
- I'm sure other bugs will pop up.
I might at some point turn this into its own full-fledged module, but for now you can start with this:
edit: Note that this doesn't take into account the anonymous user-checking aspect. You said you had that implemented already, so I left it out, but it's super super easy to add if you want it here instead.
This is great! It ONLY worked
This is great!
It ONLY worked on body field, title and cck select list though. I'm losing the form values on taxonomy fields and cck text field. :(
Yeah I think that's cuz CCK
Yeah I think that's cuz CCK (and maybe taxonomy too) are attached later in the form building process (in other words, the fields don't exist in the form until after we've looped through and set our values). This can maybe be fixed just by module weighting, but we might have to do the value setting in an after_build function. Still playing around with it, and actually working on making it more flexible as its own module.
Was it stored though?
Was it stored though?
A full pledge module would really be great. This would really be useful to a lot of people as there are no similar modules currently in existence. Can't wait for it! Thank you for walking me through this. I really appreciate it.
Yeah no problem... To answer
Yeah no problem...
To answer your question, yes all form values are stored to the session currently (assuming this module is weighted higher than other modules which use hook_form_alter). But we can accomplish that automatically during the initial install of the module later on. For now I've just set it to 100 manually in my DB, which has fixed some of the values that weren't being applied before.
Currently the only issue is the logic where I'm setting the #default_value. I'll figure it out though. To sum up, yes they are getting stored, it's just the re-setting that's not working for some complex fields.
Still crackin' at it. :D
Ok this is pretty dope. Seems
Ok this is pretty dope.
Seems to be working for everything I tried it with: radios, checkboxes, textfields, textareas, selects, taxonomy, CCK fields (including image fields!).
Still some tweaks to be made for sure, but looking promising!
You can remove the stuff you added to your custom module, and just upload/enable this one: http://www.mediafire.com/?nx4nk8x4zk4pb6q
edit: fixed download link
Pretty dope indeed! You are
Pretty dope indeed! You are an absolute superstar! Give me your paypal.. (LOL. I'm just kidding. I'm broke.)
Anyways, it worked on every node form I have which what I wanted all along but since you are making this a full-pledged module I would suggest a feature where we could choose on what certain forms we want this to activate.
Thanks again.
Yes that's correct. In the
Yes that's correct. In the original examples I was giving you it was specific to a certain node type form. But now it's actually all forms everywhere. And yeah I'm gonna add a settings form where you can put form_id's. Let me know if there are any other bugs or features you'd like.
Uh-oh... I'm getting this
Uh-oh... I'm getting this error on user account edit page.
warning: array_key_exists() [function.array-key-exists]: The second argument should be either an array or an object in D:\xampplite\htdocs\tempsite\sites\all\modules\form_session\form_session.module on line 56.Hmm, I don't see that error.
Hmm, I don't see that error. Do you have any other modules enabled that modify that form?
The error occurs in
The error occurs in /user/uid/edit page not in /node/nid/edit. I don't have any other modules for user edit form.
Yeah I know you said user
Yeah I know you said user page, but I'm not seeing it... Anyway, you can change line 56 from:
<?php if (array_key_exists('#default_value', $form[$element]) && isset($values[$element])) { ?>to:
<?php if (is_array($form[$element]) && array_key_exists('#default_value', $form[$element]) && isset($values[$element])) { ?>That should fix the errors I think.
Heya dude. Just dropping by
Heya dude. Just dropping by to say that I haven't tried this code yet. I'm away and will be back in a couple of days. I will test your module again and report any bugs by then.
Thanks again.
Heya Roper. How's it been?
Heya Roper. How's it been? I'm using this module to a live site for more than two months now without any problem.
Btw, was able to get rid of the error I was talking about above by changing line 56 as per your instruction.
So where we heading now? You turning this into a full-pledged module?
Hi @evilgenius. I've been way
Hi @evilgenius.
I've been way too swamped IRL lately. Keep bugging me about it and I'll get to it at some point in the not-to-distant future. I wanna at least get an admin form where you can configure the form_ids, and also do some code cleanup.
Glad to see it's working out for you in the mean time. :)
Ok thanks dude!
Ok thanks dude!
module or code ?
Hello,
I have been reading your conversation, with highest attention since I am trying to do exactly that!
Unfortunately, the above link for the code is now empty. Could you provide the code? Or have you released an ad-hoc module?
FYI, the workflow I'm trying to do is (D7):
1. user fills in a form
2. on submit => check if user is anonymous.
3. if user is anonymous, a modal form is displayed -I use the 'modal forms' module- to register or login, with the ability to register or login via existing facebook account (but that's another issue!)
4. when user completes registration, the modal window is closed, and the previous/parent page (node form) is reloaded => form data is lost. That is where I would badly need your code: I would like to get fields values -including images- repopulated on the page!
I haven't found a solution so far, so I hope your code would help me out, because I'm stuck right now...
Sure, you can get it here:
Sure, you can get it here: http://www.mediafire.com/?jbjl2pl6cle7tx7
But keep in mind it has seen zero development ever since... In its current state it applies to all forms on the site. Maybe someday I'll get to do something with it.
Also, I don't know if there may be any security implications or anything like that...
Thanks a lot Roper, I will
Thanks a lot Roper, I will try that ASAP :)
Hi Evilgenius, Roper nicely
Hi Evilgenius,
Roper nicely provided me with the code you are using.
Unfortunately, I cannot adapt it to my needs, so I would like to understand more precisely how you used it.
Basically, I understand that you have:
1. anonymous users to fill in a node form
2. then they login or register via a pop-up window (modal window)
3. back to the parent node form, that has been refreshed
- BEFORE: the form data entered by users was lost
- NOW: thanks to Roper's code, the data is stored in the $_session variable, and displayed back into the form even AFTER it has been refreshed.
4. the newly created node is allocated to the authenticated user.
Can you confirm that's the way it's working?
Yes Louis Bob that is
Yes Louis Bob that is correct. Even when you navigate to other pages and when you come back to the form the values are still in tacked.
Make sure you have activated the module in the modules page.
Evilgenius, thank you for
Evilgenius, thank you for your response.
What I don't quite understand is when exactly the module gets triggered, recording the form data into the $_session variable: is it when the user hits the save button? How do you "trick" the save button so that it will process the data (by triggering the module) AND at the same time display a pop-up window to register?
Because for me when I hit the save button, the node gets recorded with author = anonymous. Or if I create a fake save button that will display the registration pop-up, the module is not triggered (form data is lost when parent page is refreshed after user has logged in in the pop-up)...
Sorry to bother you again, but I feel I miss something obvious here ;)
It's been over a year since I
It's been over a year since I implemented this on a friend's site so if memory serves well I think I used the Rules module to help me do the "trick".
See how its done here
I basically created a trigger that when an anonymous user submits certain node type it wouldn't let it go through and will display something else instead.
ok thank you, I'll check that
ok thank you, I'll check that and Rules