Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have installed hCaptcha into my contact form and it works fine (email is sent only after captcha is checked/validated, but how do I stop the page from refreshing on Submit if captcha is not checked/validated because all fields value disappear and that is bad for user? Does someone know how I can stop this and just have a popup/text near the captcha to let the user know that is required.

Thank you!

What I have tried:

PHP
<?php
if(isset($_POST['submit'])):
    if(isset($_POST['h-captcha-response']) && !empty($_POST['h-captcha-response'])):
        // get verify response
        $data = array(
          'secret' => "code",
          'response' => $_POST['h-captcha-response']
            
          ));

        $verify = curl_init();
        curl_setopt($verify, CURLOPT_URL,   "https://hcaptcha.com/siteverify");
        curl_setopt($verify, CURLOPT_POST, true);
        curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
        $verifyResponse = curl_exec($verify);        
    $responseData = json_decode($verifyResponse);    
        if($responseData->success):
      //contact form submission code
    $email_to = "email";
    $email_subject = "title;
    $ip_address=$_SERVER['REMOTE_ADDR'];$geopluginURL='http://www.geoplugin.net/php.gp?ip='.$ip_address;$addrDetailsArr=unserialize(file_get_contents($geopluginURL));
    $country=$addrDetailsArr['geoplugin_countryName'];


     $name = $_POST['name']; // required
    $where = $_POST['where']; 
    $email_from = $_POST['email']; // required
    $message = $_POST['message']; // required
    $newsletter = $_POST['newsletter']; 
    $hcaptcha = $_POST['h-captcha']; // required
 
    $email_message = "Form details below.<br/><br/><br/>\n\n";
 
     
    function clean_string($string) {
      $bad = array("content-type","bcc:","to:","cc:","href");
      return str_replace($bad,"",$string);
    } 
     
    $email_message .= "IP: ".clean_string($ip_address)."<br/><br/>\n\n";
    $email_message .= "Country: ".clean_string($country)."<br/><br/><br/>\n\n";
    $email_message .= "Name: ".clean_string($name)."<br/><br/>\n\n";
    $email_message .= "Heard from: ".clean_string($where)."<br/><br/>\n\n";
    $email_message .= "Email: ".clean_string($email_from)."<br/><br/>\n\n";
    $email_message .= "Newsletter: ".clean_string($newsletter)."<br/><br/>\n";
    $email_message .= "Message: ".clean_string($message)."<br/><br/>\n";

      // Always set content-type when sending HTML email
      $headers = "MIME-Version: 1.0" . "\r\n";
      $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
      // More headers
      $headers .= 'From:'.$name.' <'.$email.'>' . "\r\n";
      //send email
@mail($email_to, $email_subject, $email_message, $headers);
    $succMsg = header("location:/contact-thank-you");
        endif;
    endif;
endif;
?>


HTML
 <form method="post"  id="contactform" 
name="contactform" action="/contact">
                     <div class="textbox-1"><label 
                     for="name">Your Name *</label>
                        <input class="textbox" type="text" 
                        name="name" title="" 
                           oninvalid="this.setCustomValidity
                           ('Please Enter Your Name')"
                           oninput="setCustomValidity('')" 
                           required>
                     </div>
                     <div class="textbox-1">
                     <label for="email">Your Email *</label>
                        <input class="textbox" 
                        type="email" name="email" title=""
                           oninvalid="this.setCustomValidity
                           ('Please Enter a Valid Email Address')"
                           oninput="setCustomValidity('')" 
                           required>
                     </div>
                     <label>How did you hear about us? 
                     (Not necessary, but we appreciate the 
                     effort.)</label>
                     <select name="where" class="dropdown" 
                     id="where" title="">
                        <option value="-">
                        Click to Choose...</option>
                        <option value="Google Search"> 
                        Google Search </option>
                        <option value="Bing Search"> 
                        Bing Search </option>
                        <option value="Other Search Engine"> 
                        Other Search Engine </option>
                        <option value="Social Media"> 
                        Social Media </option>
                        <option value="Blog"> Blog </option>
                        <option value="Q&A Websites"> 
                        Q&A Websites </option>
                        <option value="Forum"> Forum </option>
                        <option value="Recommendation"> 
                        Recommendation </option>
                        <option value="Other"> Other 
                        </option>
                     </select>
                     <br/><br/>
                     <label for="message">Your Message 
                     *</label>
                     <textarea name="message" 
                     class="textarea" type="textarea" title="" 
                        oninvalid="this.setCustomValidity
                        ('Please Enter Your Message')"
                        oninput="setCustomValidity('')" 
                           required>
                  </textarea>
                     <br/><br/>
                     <label class="container">
                     <input type="checkbox"  value=""
                        oninvalid="this.setCustomValidity
                        ('Please indicate that you have read and 
                          accept our Terms of Use and Privacy Policy 
                          agreements.')"
                        oninput="setCustomValidity('')" required>
                     </input>
                     <span> I have read and accept the <a 
                     class="content-link2" href="/terms"
                     >Terms of Use</a> and 
                     <a class="content-link2" 
                     href="/privacy">Privacy Policy</a> 
                     agreements. *</span>
                     
                     </label>
                     <label class="container">
                     <input type="checkbox" name="newsletter" 
                     id="newsletter" value="yes">
                     <span>I want to receive e-mails 
                     about limited-time special offers.</span>
                     
                     </label>
                     <div class="clr"></div>
                     <br/>
                   <div class="h-captcha" data-sitekey="code" 
                   ></div>
                   
                     <div class="bot-cont"><button 
                     type="submit" name="submit" class="submit_button" 
                     value="Submit">SUBMIT 
                     MESSAGE</button></div>
                     <br/><br/>
                  </form>
Posted
Updated 13-Sep-23 4:50am
v4

Quote:
all fields value disappear and that is bad for user
A classic XY problem[^]; rather than asking how to fix the actual problem, you ask us how to fix the proposed solution to the problem that you've already decided upon.

If you could validate the CAPTCHA on the client-side, that that would render it worse than useless. The spam-bots you're trying to stop would simply repeatedly call the API to validate their response, whereas the poor regular users would be stuck trying to decipher some obfuscated hieroglyphics, or work out whether a picture of a traffic light counts as a traffic light whilst René Magritte[^] spins ever faster in his grave.

Instead, what you need to do is preserve the user input when the form is shown again. For example:
PHP
<input class="textbox" type="text" name="name" title="" 
    value="<?php if(isset($_POST['name'])) echo $_POST['name'];?>"
    oninvalid="this.setCustomValidity('Please Enter Your Name')"
    oninput="setCustomValidity('')" required>
 
Share this answer
 
Comments
Andre Oosthuizen 29-Aug-23 9:24am    
Actually a better pointer into a solution than mine!
vlad10 29-Aug-23 10:07am    
Thank you, this works great for the input fields (name and email), but it doesn't work for the textarea one (the message box).
Richard Deeming 29-Aug-23 10:09am    
<textarea name="message" ...><?php if(isset($_POST['message'])) echo $_POST['message'];?></textarea>
vlad10 29-Aug-23 10:18am    
Thank you. Yes, that's how I tried it and it doesn't want to remember the content.
Richard Deeming 29-Aug-23 11:02am    
Well, that's how you provide an initial value for a textarea. If it's not working, then you need to check the rendered HTML with your browser's "view source" option to see if the value is present. If it's not, then debug the form submission to ensure that the value is being sent to the server.
You can add an else statement to your code, if it is false do nothing -
PHP
$responseData = json_decode($verifyResponse);    
    if($responseData->success) {
       //Your current code to submit the form...
    } else {
       echo "Please use my pretty hCaptcha to continue..."
    }


[EDIT]
After additional information, your problem might be due to an issue with how you are checking the presence of the 'hCaptcha' response attribute and its value. I have changed your 'validateForm' function a little -
JavaScript
<script>
function validateForm() {
    var captcha = document.querySelector('.h-captcha');
    var response = captcha.getAttribute('data-h-captcha-response');
    var errorElement = document.getElementById('captcha-error');
    
    if (!response) {
        errorElement.textContent = "Please complete the captcha.";
        return false; //Prevent user from submitting your form...
    }

    errorElement.textContent = ''; //Clear any previous error...
    return true; //Allow form submission...
}
</script>


I also updated your form element to use the JavaScript function and perform the validation -
HTML
<form method="post" id="contactform" name="contactform" action="/contact" onsubmit="return validateForm()">
    <!--Your other form fields here -->
    <div class="h-captcha" data-sitekey="your-site-key"></div>
    <span id="captcha-error" style="color: red;"></span>
    <button type="submit">Submit</button>
</form>


This should solve your issue.
 
Share this answer
 
v2
Comments
vlad10 29-Aug-23 8:37am    
Thank you, tried that but still the same.
vlad10 29-Aug-23 10:16am    
Thank you but unfortunately this also doesn't work right. Yes , the form fields values remain, the error appears but it also appears when the hcaptcha is checked and I try to submit the form so the error appears no matter if the hcaptcha is checked or not and because of that it doesn't allow the form to be submitted.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900