Basically I have a gigantic form that would be a pain for anyone to have to re-fill. We have to implement reCaptcha to prevent spam bots.
I want to make it so that if the user enters the reCaptcha incorrectly, their form data is not lost.
The form, reCaptcha lib, and reCaptcha initialization code are in their own file titled Application.php
. This form POSTs to application_confirm.php
. application_confirm
includes another file which processes the form data into an email format and sends it to the admin.
Application.php
is required on another php page (ironically also titled application.php -- this is the one the user visits, and then the form html is included from the previously mentioned Application.php via require('content/Application.php')
I don't really know what I need to do to or where I need to place the captcha validity check -- any help much appreciated!
I like to store the $_POST data into a $_SESSION instead of a javascript approach. When the form is submitted, push the $_POST array into a $_SESSION variable. If the recaptcha fails, reload the form with the value from the $_SESSION. When the form is posted successfully, destroy the session so that if they were to return to the form, it isn't autofilled with old information.
<?php
session_start();
$response = recaptcha_check_answer ($privatekey,
$_SERVER["REMOTE_ADDR"],
$_POST["recaptcha_challenge_field"],
$_POST["recaptcha_response_field"]);
if(isset($_POST['submit']) && !$response->is_valid)
{
$_SESSION['form'] = $_POST;
}
else
{
//Handle form processing
}
?>
Set value of input field to value from $_SESSION
<input type="text" name="email" value="<?= $_SESSION['form']['email'] ?>" />
You can use AJAX to send values using the event onsubmit to the form tag to a page that saves the form values into a session
then basically say you had an input with the name of 'FirstName'
<form onsubmitup='PreserverValues();'/>
then basically you change all inputs to
<input type='text' name='FirstName' value='<?php if isset($_SESSION['FirstName']) echo $_SESSION['FirstName']; ?>'/>
localStorage
for this...Requirements
I'm assuming you have jQuery installed. If not, you'll have to include it on your page or rewrite some of the function for basic JavaScript.
I'm also assuming your user is running a relatively new browser (although you can do much the same thing with cookies, explaining how to set that up is another answer of its own) and doesn't have JavaScript disabled.
Preserving the form
First, attach a class of input-to-store
on every input object you wish to store a value for, then when your user presses the submit button, instead of immediately submitting your form, have it first call a function called storeValues()
then submit the form:
function storeValues() {
if(typeof(Storage) !== "undefined") {
localStorage.setItem('preserve', true);
$('.input-to-store').each(function() {
localStorage.setItem($(this).attr('id'), $(this).val());
});
}
}
Note: localStorage
is not universally supported, so this method will only support newer browsers (Firefox 3.5+, Chrome 4+, IE 8+). You may wish to have an else
statement to set these values in cookies if this method isn't supported.
Depending on your form, you may wish to preserve values which aren't stored in the .val()
accessor. In this case, add another class and do an .each()
function on each of those too.
Retrieving values when the form is reloaded
When the form is loaded, check for preserved values. If found, reload your old values into those fields:
if(typeof(Storage) !== "undefined") {
if(localStorage.getItem('preserve') === true) {
localStorage.setItem('preserve', false);
$('.input-to-store').each(function() {
if(value = localStorage.getItem($(this).attr('id')){
$(this).val(value);
}
}
}
}
Clear localStorage
when you're done with it
On your success page (after a successful form submit), you'll want to clear localStorage
to prevent your application from wasting space on the user's HDD:
localStorage.clear();
Hope this helps, haven't tested the syntax but it should give you an idea about how to persist data using localStorage
and get around the dreaded lost form.
This is a working example of a recaptcha preserving form data if reCaptcha fails?
<script type="text/javascript">
var RecaptchaOptions = {
lang: 'en',
theme: 'custom',
custom_theme_widget: 'recaptcha_widget'
};
</script>
<div class="control-group">
<div id="recaptcha_widget" style="display:none">
<input type="text" id="recaptcha_response_field" name="recaptcha_response_field" class="required"/>
<div id="recaptcha_image"></div>
<div class="recaptcha_only_if_incorrect_sol" style="color:red">Incorrect please try again</div>
<div><a href="javascript:Recaptcha.reload()">Get another CAPTCHA code</a></div>
</div>
<script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k=YOURKEY"></script>
<noscript>
<iframe src="http://www.google.com/recaptcha/api/noscript?k=YOURKEY" height="300" width="500" frameborder="0"></iframe><br>
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge">
</noscript>
<?php
require_once('captcha/recaptchalib.php');
$publickey = "YOURKEY"; // you got this from the signup page
echo recaptcha_get_html($publickey);
?>
</div><!-- control grp captcha -->