简体   繁体   中英

Scroll down to form after form validation failure

I have a php contact form that when submitted validates the fields but this process reloads the page and the form is not at the top of the page so I want it to automatically scroll to the bottom of the page where the form is when validation fails so the user can see the errors. It seems javascript is the only way to do this so I tried echo'ing a script along with the error message but it doesn't work. There are no errors in the browser console, just doesn't scroll.

I took the parsed HTML from the View Source after the new page loads and put it into jsFiddle here . You can see that it scrolls properly in the fiddle but the real site doesn't.

EDIT:
I also tried adding the loading of the jquery library to immediately before the scroll script and it still didn't scroll even though I confirmed the library is loading first. I'm at a loss.

This is a snippet of the php:

<?php
// define variables and set to empty values
$nameErr = $fromErr = $phoneErr = $verif_boxErr = $recaptchaErr = "";
$name    = $from = $phone = $message = $verif_box = "";
$recaptcha = NULL;
$errors  = 0;

if ($_SERVER["REQUEST_METHOD"] == "POST") { //check if form has been submitted
    if (empty($_POST["name"])) {
        $nameErr = " * Name is missing";
        $errors  = 1;
        echo '<style type="text/css"> input#name {border: 1px solid #F00; 
        box-shadow: 0px 0px 5pt .1pt #F00 inset;}</style>
        <script type="text/javascript">
function scrollSmoothToBottom(){ 
$(scrollingElement).animate({scrollTop:document.body.scrollHeight},500)
}scrollingElement=document.scrollingElement||document.body,
window.onload=scrollSmoothToBottom;</script>';
    } else {
        $name = test_input($_POST["name"]);
        // check if name only contains letters and whitespace
        if (!preg_match("/^[a-zA-Z ]*$/", $name)) {
            $nameErr = "Only letters and white space allowed";
            $errors  = 1;
            echo '<style type="text/css"> input#name {border: 1px solid #F00; box-shadow: 0px 0px 5pt .1pt #F00 inset;}</style>';
        }
    }

if ($errors == 0) { // all fields successfullty validated. 
        $message = "Message: " . "\n" . $message;
        $message = "Name: " . $name . "\n\n" . $message;
        $message = "Email: " . $from . "\n" . $message;
        mail("website@avayoupaint.com", 'Contact Form: ' . $name, $message = "Sender IP Address: " . $_SERVER['REMOTE_ADDR'] . "\n\n" . $message, "From: website-html@avayoupaint.com");            
        setcookie('tntcon', '');    // delete the cookie so it cannot sent again by refreshing this page
        header('Location: success.php');    // redirect to success page
        exit();
}


}
?>
<html>
<head></head>
<body>
<article id="contactForm">                        
    <span class="error">* All fields are required</span>
    <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post" name="form1" id="form1">
    <span class="contactTitles">Name:</span>
    <input name="name" type="text" id="name" value="<?php echo $name;?>"/><span class="error"><?php echo $nameErr;?></span>
    </form> 
</article>
</body>
</html>

Your script to get the scrollingElement variable runs immediately when the page loads, before all the HTML is ready and loaded into the page. You need to wait until all the content is loaded, otherwise the script will not find the document.body object to attach the scroll animation to. This is especially a problem because the script is positioned before the HTML document. Browsers execute script as soon as they receive it, they don't wait until the whole document is loaded.

jQuery provides the document.ready event handler for you to wrap your Javascript in, so that the main script waits for the page to be in the state where all the HTML has loaded (there's also a native JS way to do the same thing, but since you're using jQuery we'll do it this way). You actually already have an example of this in your current site, right down near the bottom.

It also makes more sense for the scrollingElement to be inside the function - it doesn't have much purpose being a global, as it's only used within that one function.

<script type="text/javascript">
  $(document).ready(function() {

  function scrollSmoothToBottom() { 
    var scrollingElement = document.scrollingElement || document.body;
    $(scrollingElement).animate({ scrollTop:document.body.scrollHeight }, 500);
  }
    scrollSmoothToBottom();
  });
</script>

Note that this version requires jQuery to be loaded before this script block runs. It would make sense to output the script block somewhere in the <head> section of the page, just below a <script block which loads jQuery.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM