Reputation: 5533
Been struggling with this for a couple days now. Here's the set up - I have a parent page "support.php" there are tabs, and when you click a tab it brings in the appropriate form via ajax. (the relevant code for each section:)
form input's on the AJAX page
<input type="text" class="numbers" name="captchaImage" id="SupportNumbers" size="6" value="" readonly>
<input type="text" class="numbers" name="SupportMath" id="SupportMath" size="6" maxlength="6" tabindex="9">
The parent page - support.php calls for "validation.js" which is my jQuery.validate script.
...
SupportMath: {
required: true,
equal: "<?php echo $randomNumTotal; ?>"
}
There is a .get command on the parent page for a file "random.php"
$.get('PHP/random.php', function (data){
$("#SupportNumbers").val(data);
});
<?php
$randomNum = rand(0,9);
$randomNum2 = rand(0,9);
echo $randomNum ."+". $randomNum2;
$randomNumTotal = $randomNum + $randomNum2;
?>
which generates two random numbers so you can add them together. The validation checks to make sure the two numbers that are generated are added correctly. I just can't seem to get all these pieces to use the same numbers, i can get the text box "SupportNumbers" to populate with two random numbers say "2 + 5" but when I enter "7" into "#SupportMath" it displays the error msg. It should be $randomNumTotal but I can't get that to the page, and have the validation script check against that. HELP.
I realize this is clear as mud so ill try and explain more I have 5 forms on my support page. To reduce the chaos, I have them in a vertical tab set. I don't want my js validation script on the page and I don't want all 5 forms hidden/displayed on the page due to some issues we've had with some bots. So my solution was to bring in the forms with AJAX (done) and just link to the validation script (done) all is good except for our "random math captcha" I can put it in a file and use the ".get" command to populate the box that holds the two random math questions, but can't get the answer to validate. Hope this helps, code below.
Upvotes: 1
Views: 1568
Reputation: 31173
EXPLANATION: ( step by step )
<input type="hidden" name="math" id="math"/>
this field is needed since you are using a readonly
field, now the readonly
fields are not submitted...by forms, this way we have the one shown to user and another one hidden, this one will be submitted;#math
value that is a string
ex: 5+2
so we need to transform this into two int
and sum it.SUM
against the user input #SupportMath
PHP ( that check the match against... )
if ( isset($_POST['post']) ) {
$math = explode('+',trim($_POST['math']));
$sum = ( (int)$math[0] + (int)$math[1] );
$message = 'error';
if ( (int)$sum === (int)$_POST['SupportMath'] ) {
$message = 'success';
}
echo $message;
}
jQuery ( pseudo code...)
$(function() {
$.get('random.php',function(data) {
$("#SupportNumbers,#math").val(data);
});
$('#form').submit(function(e) {
e.preventDefault();
var query = $(this).serialize();
$.ajax({
type: "POST",
url: "post.php",
data: "post=post&" + query,
success: function(msg) {
if (msg.indexOf('success') == -1) {
alert('error');
} else {
alert('cURL');
}
}
});
});
});
HTML
<input type="text" class="numbers" name="captchaImage" id="SupportNumbers" size="6" readonly>
<input type="hidden" name="math" id="math"/>
<input type="text" class="numbers" name="SupportMath" id="SupportMath" size="6" maxlength="6" tabindex="9">
Upvotes: 2
Reputation: 101614
Here's a self-sufficient version of what I was referring to.
<?php
session_start();
if (isset($_GET['validate']))
{
$passed = (session_is_registered('validate') && (int)$_GET['validate'] == $_SESSION['validate']);
header('Content-Type: application/json');
echo sprintf('{"validation":"%s"}', $passed?'OK':'FAIL');
exit;
}
function generate_check()
{
// generate a result (incompleted)
$result = Array(
'num1' => rand(0,10), // first random number
'num2' => rand(0,10), // second random number
'problem' => null, // actual math problem
'answer' => null // the answer
);
// random method
switch (rand(0,999) % 3)
{
case 0: // addition
$result['problem'] = sprintf('%d + %d',$result['num1'],$result['num2']);
$result['answer'] = $result['num1'] + $result['num2'];
break;
case 1: // subtraction
$result['problem'] = sprintf('%d - %d',$result['num1'],$result['num2']);
$result['answer'] = $result['num1'] - $result['num2'];
break;
case 2: // multiplication
$result['problem'] = sprintf('%d * %d',$result['num1'],$result['num2']);
$result['answer'] = $result['num1'] * $result['num2'];
break;
}
return $result;
}
$check = generate_check();
session_register('validate');
$_SESSION['validate'] = $check['answer'];
?>
<html>
<head>
<title>Sample Validation</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<Script type="text/javascript">
$(function(){
$('#check').click(function(){
$('#result').css('color','').text('Checking...');
$.getJSON('<?php echo $_SERVER['PHP_SELF']; ?>',{'validate':$('#answer').val(),'_':(new Date()).toString()},function(data){
if (data.validation=='OK')
$('#result').css('color','green').text('PASSED!');
else
$('#result').css('color','red').text('FAILED!');
});
});
});
</script>
</head>
<body>
<p>What is <b><?php echo $check['problem']; ?></b>?</p>
<input type="text" name="answer" id="answer" /><input id="check" type="button" value="Check" />
<p id="result"></p>
<br /><br />
<form action="<?php echo $_SERVER['PHP_SELF']; ?>"><input type="submit" value="New problem" /></form>
</body>
</html>
Upvotes: 1
Reputation: 12870
I used to do pages like this until I found this wonderful inline Jquery validator You simply add a class with relevant information to your form objects and it does the rest. There's no need to fool around with redirecting or sessions for that matter. I've had it in production on about 25 sites for nearly a year without any issues whatsoever.
Edit: looks like you're trying to do a Captcha of sorts, maybe? Perhaps look at ReCaptcha which not only verifies a user is correct, but also helps improve OCR. Alternatively, you could do a slidelock
As we say in my shop, "No reason to go off and write a minivan...."
Upvotes: 0