1

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.

3
  • 1
    Use a $_SESSION variable to hold the result value, then place the two numbers that made the result on the page. When the query is performed, check against your session variable. Commented Feb 24, 2011 at 22:28
  • So if I understand the new question correctly, you have an AJAX script call a PHP file that does two things: creates a math problem and the solution. It returns the problem itself, but "Stores" the answer (at least as long at the page is called). I think your issue is that answer is gone by the time you change contexts (i.e. go from "random.php" back to "validation.js") I'm assuming validation.js is loaded before the ajax is even called, thus you're never going to have aligned numbers without something else used--as I recommended session, but that doesn't appear to be an opt. Commented Feb 25, 2011 at 1:00
  • Yes that is correct. I want to bring in my forms with ajax, have the validation loaded into the parent page and some type of captcha. is this possible? or is there a better solution out there? Commented Feb 25, 2011 at 1:24

3 Answers 3

2

EXPLANATION: ( step by step )

  • we use your method to generate two random number from 1 to 9 at page load
  • we have added an extra input <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;
  • we get the #math value that is a string ex: 5+2 so we need to transform this into two int and sum it.
  • finally we make the check the 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">
Sign up to request clarification or add additional context in comments.

18 Comments

download the source and everything should be clear: ask.altervista.org/demo/php-jquery-validation/… plus in the meanwhile i'm going to expand the exaplanation for you...
@aSeptik - man thanks, I somewhat understand what is going on here. SupportNumbers gets the two random numbers, and "math" also gets the random numbers- why? When I tried this I was trying to put the answer in a hidden input then check SupportMath against it. Unfortunately it was putting the two numbers and the solution in the same box. I'm still not sure how it checks the sum against the two numbers. sorry for being pretty dumb.
what do I need to have in my "post.php" file to make it work? I have it on my server but it returns a 404 on that one..
do you have downloaded the source?
when i click on link it's corrupt. bunch of ascii or some such symbols. I copied the source code, but obviously didn't get your PHP files.
|
1

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>

5 Comments

Brad, thanks for that. If I wasn't submitting the form's via cURL to another domain it would be perfect. I need a solution to exactly what I have above.
Brad - Not sure how I would incorporate that into my jQuery validation, I can get it hacked into my SS val, but not sure about the client. Its pretty sweet though. I really need to get some type of solution working.
@DirtyBirdDesign: What's there to hack? You can compartmentalize it further and make an ajax call to retrieve the problem and set the solution, then make another call to verify. I'll be honest, with what you've provided for explanation and code I'm not 100% sure what you're going for. (little confused by architecture I think)
the "hack" was a reference to my skill level...what you did is awesome. I'm confused too. I'll try and explain in more clarity.
@Brad this is really awesome. I am understanding it a bit more but have questions. I think I'd have to make a "Validator.addMethod" to check the sum against the numbers? I don't know how I would merge this with my current use of jquery .validate.js
0

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...."

1 Comment

I'm using jQuery validation - it just gets muddied up when bringing the forms in via AjAX, having the validation script linked and trying to do the math captcha.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.