JSFiddle - React, Tailwind, and code Playground

by hubfiddle

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css">
<nav class="navbar navbar-default navbar-fixed-top">
  <div class="container">
    <p class="navbar-text">A fixed navbar</p>
  </div>
</nav>

<div class="container main">
  <form id="my-form">
    <div>
      <input required class="form-control">
    </div>
    <div style="height:200px" class="padding">
      Scroll down for the textarea…
    </div>
    <div>
      <textarea required class="form-control"></textarea>
    </div>
    <div style="height:800px" class="padding">Scroll down for the submit button…</div>
    <button type="submit" class="btn btn-primary">Submit</button>
  </form>
</div>

CSS

.main {
  padding-top: 60px;
}

.padding {
  background:#dfd;
  padding: 10px;
}

JavaScript

var form = $('#my-form')
var navbar = $('.navbar-fixed-top')

// listen for `invalid` events on all form inputs
form.find(':input').on('invalid', function (event) {
    var input = $(this)

    // the first invalid element in the form
    var first = form.find(':invalid').first()

    // only handle if this is the first invalid input
    if (input[0] === first[0]) {
        // height of the nav bar plus some padding
        var navbarHeight = navbar.height() + 50

        // the position to scroll to (accounting for the navbar)
        var elementOffset = input.offset().top - navbarHeight

        // the current scroll position (accounting for the navbar)
        var pageOffset = window.pageYOffset - navbarHeight

        // don't scroll if the element is already in view
        if (elementOffset > pageOffset && elementOffset < pageOffset + window.innerHeight) {
            return true
        }

        // note: avoid using animate, as it prevents the validation message displaying correctly
        $('html,body').scrollTop(elementOffset)
    }
})