3

I have some pages that have multiple input boxes that users can enter text into. Some of these are required to fill in before they click the 'next' button. I have validation errors popping up for the user to see however if the question if off the page I would like the page to scroll to it instead of them having to search for the missing/wrong field.

I have a scroll to in place, but I am having trouble ascertaining what element what element to scroll to. For example if the input in above the fold of the page I would like to scroll to the label so they can see the error and the input. But if it is below the fold I would then like to select the input so that will show above the fold. Does that make any sense?

I guess what I'm really asking is, is there a way to determine where the element is on the page. And if it is above the fold scroll to the label, but if it is below the fold then scroll to the input?

Right now I am just scrolling to error's input field.

$(".container-content").mCustomScrollbar("scrollTo",$('.container-content').find('input.error:first')); //Yes I am using a plugin for the scroll

if I just scroll to the label then it looks like this. enter image description here

zazvorniki
  • 3,181
  • 14
  • 64
  • 110
  • How big are your labels, so that simply scrolling to the label would still not make th input field below it become visible …? – CBroe Jul 02 '15 at 17:45
  • _“is there a way to determine where the element is on the page”_ – all that needs is determining the window height, its scroll position, and the position of the element on the page … and then some simply math. – CBroe Jul 02 '15 at 17:46
  • @CBroe They are normal size 1em. :) But if the input is below the fold of the page then it one scrolls to the label and does not display the input. – zazvorniki Jul 02 '15 at 17:46
  • @CBroe I'm not looking at what is currently on the screen I'm looking at what is either above the screen or below the screen. So Where I am currently scrolled to won't help... – zazvorniki Jul 02 '15 at 17:48
  • Why, are your labels and input fields not in close proximity? Scroll the page so that the label for the first invalid input field gets aligned to the top of the window, then the input should automatically become visible as well, no? – CBroe Jul 02 '15 at 17:48
  • @CBroe They are close to each other. The label is above the input. It is a normal form. And no it is not working that way at all if the input is the last on the page then it will not just scroll to the top of the page. There is a reason I am asking this particular question. I posted a screenshot above – zazvorniki Jul 02 '15 at 17:50
  • Well then maybe your custom scrollbar plugin/its `scrollTo` method just suck. Using “normal” scrolling, it is no problem to scroll something into view so that it gets aligned to the _top_ of the viewport, and with that your problem wouldn’t even exist I think. – CBroe Jul 02 '15 at 17:58
  • @CBroe I need to use this particular plugin (PM specified this one and I can't change it) and I have used regular scrolling to. It does the same exact thing if it is below the fold of the page. I really just need to be able to see if the element is below the fold and then this would not be an issue because I can then target the input instead of the label and then vice versa. Normally I would solve thins by scrolling to the parent, but each of my controls are different so I cannot do that. – zazvorniki Jul 02 '15 at 18:00
  • Can you show an actual live example? I’m afraid I still don’t see what your actual problem is. – CBroe Jul 02 '15 at 18:02
  • @CBroe I can't show a live example, I can only show bits and parts according to my PM. In the screenshot above that element was below the fold and had an error so it scrolled to the label of the field. If it is below the fold though I need it to scroll to the input. And this happens in reverse too, if it is above the fold I need it to scroll to the label of the field. – zazvorniki Jul 02 '15 at 18:06

2 Answers2

5

You can use this function: Jsfiddle

function isElementInViewport (el) {
    var rect = el[0].getBoundingClientRect();
    return (rect.top>-1 && rect.bottom <= $(window).height());
}

originally posted Here

New api which you can use in just 11 extra steps lol https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Browser_compatibility

Muhammad Umer
  • 14,722
  • 14
  • 69
  • 139
0

Create and Element in your html that you want to track. e.g

<div #elementToTrack ></div> 

In your component.ts

    @ViewChild("elementToTrack") el: ElementRef;    


    @HostListener("window:scroll", ["$event"])
      onWindowScroll() {
        if (this.el.nativeElement.getBoundingClientRect().bottom == window.innerHeight) {
//do your thing
        }
      }
Kennedy Nyaga
  • 3,127
  • 1
  • 23
  • 24