1

I have a page which i validate and i show relevant validation message next to the field.

I want page to scroll to part of the page where first failed validation message is shown when user clicks the save button

Topically i want to scroll to an element with class row-validate which has visibility:visible.

<div class="row form-inputs">
    <div class="col-12">
        <label>Full Name *</label>
        <input name="txtFirstName" type="text" id="txtFirstName" class="form-control">
        <span id="rfFN" class="row-validate" style="visibility:hidden;">Mandatory field</span>
    </div>
</div>

<div class="row form-inputs">
    <div class="col-12">
        <label>Email *</label>
        <input name="txtEmail" type="text" id="txtEmail" class="form-control">
        <span id="rfvEmail" class="row-validate" style="visibility: visible;">Mandatory field</span>
        <span id="revEmail" class="row-validate" style="visibility:hidden;">Invalid email address</span>
    </div>
</div>

<div class="row form-inputs">
    <div class="col-12">
        <label>Mobile *</label>
        <input name="txtPhone" type="text" value="05" id="txtPhone" class="form-control" placeholder="0501234567">
        <span id="rfvphone" class="row-validate" style="visibility:hidden;">Mandatory field</span>
        <span id="revPhone" class="row-validate" style="visibility: visible;">! Enter correct mobile number </span>
    </div>
</div>

<div class="row form-inputs">
    <div class="col-12">
        <label>Company </label>
        <input name="txtCompany" type="text" id="txtCompany" class="form-control">
    </div>
</div>

jQuery

below code will scroll me to first element which has class row-validate but it wont check if it has visibility:visible visibility property as visible or hidden

$("#button").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $(".row-validate").offset().top
    }, 2000);
});
Learning
  • 17,618
  • 35
  • 153
  • 314
  • 2
    You can use `$(".row-validate:visible")` - https://stackoverflow.com/a/40469041/863110 – Mosh Feu Sep 25 '19 at 09:32
  • Possible duplicate of [JQuery: if div is visible](https://stackoverflow.com/questions/40468981/jquery-if-div-is-visible) / https://stackoverflow.com/questions/178325/how-do-i-check-if-an-element-is-hidden-in-jquery – freedomn-m Sep 25 '19 at 09:38
  • it still moves to top of page could it be because property is inline and not part of class `style="visibility: hidden;"` – Learning Sep 25 '19 at 09:41
  • It always moves to the top because you have the `Mandatory field` notices with the same class that are always visible. You need to give the hidden validation messages their own individual class. Then `:visible` will work, as outlined above. – Rory McCrossan Sep 25 '19 at 09:42
  • inline property is auto generated by asp.net webform page when validation fails, so not sure how i can target it? – Learning Sep 25 '19 at 09:43
  • Try `$(".form-inputs .row-validate:visible")` - of course, your validation messages are *under* the inputs, so you'll need some other tweaks, eg: `$(".row .row-validate:visible").first().closest(".row")` – freedomn-m Sep 25 '19 at 09:46
  • @freedomn-m, i tried both doesnt work it still moves to first element even if it has not failed – Learning Sep 25 '19 at 09:51
  • Ah, *first* is not the same as "top" (even if the first is at the top). – freedomn-m Sep 25 '19 at 10:14

2 Answers2

1

Try this ,

$(".row-validate:visible").offset().top

Edited:

$("#button").click(function() {
let visible = $('.row-validate').filter(function() {
    return !($(this).css('visibility') == 'hidden' || 
         $(this).css('display') == 'none');
   });

   $([document.documentElement, document.body]).animate({
        scrollTop: visible[0].offsetParent.offsetTop 
   }, 2000);
 });

OR just

$("#button").click(function() {
  $([document.documentElement, document.body]).animate({
     scrollTop: $('.row-validate:visible[style="visibility:visible;"]').parent().offset().top
  }, 200);
});

This will scroll to the parent element which is child of the body to show the label, input field and the error message . Not only the error message .

shohag sarkar
  • 169
  • 10
  • it still moves to top of page could it be because property is inline and not part of class `style="visibility: hidden;"` – Learning Sep 25 '19 at 09:42
0

How about using attribute selector?

This is not a best workaround just for your situation.

$("#button").click(function() {
  $([document.documentElement, document.body]).animate({
    scrollTop: $('.row-validate:visible[style="visibility: visible;"]').offset().top
  }, 200);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row form-inputs">
  <div class="col-12">
    <label>Full Name *</label>
    <input name="txtFirstName" type="text" id="txtFirstName" class="form-control">
    <span id="rfFN" class="row-validate" style="visibility:hidden;">Mandatory field</span>
  </div>
</div>

<div class="row form-inputs">
  <div class="col-12">
    <label>Email *</label>
    <input name="txtEmail" type="text" id="txtEmail" class="form-control">
    <span id="rfvEmail" class="row-validate" style="visibility: visible;">Mandatory field</span>
    <span id="revEmail" class="row-validate" style="visibility:hidden;">Invalid email address</span>
  </div>
</div>

<div class="row form-inputs">
  <div class="col-12">
    <label>Mobile *</label>
    <input name="txtPhone" type="text" value="05" id="txtPhone" class="form-control" placeholder="0501234567">
    <span id="rfvphone" class="row-validate" style="visibility:hidden;">Mandatory field</span>
    <span id="revPhone" class="row-validate" style="visibility: visible;">! Enter correct mobile number </span>
  </div>
</div>

<div class="row form-inputs">
  <div class="col-12">
    <label>Company </label>
    <input name="txtCompany" type="text" id="txtCompany" class="form-control">
  </div>
</div>

<button id="button" style="margin-bottom:5000px;">Button</button>
Chaska
  • 3,127
  • 1
  • 9
  • 17