In order to check a checkbox, you need to ensure that the scrolling div has been scrolled to the very

I have a situation where I need to ensure that a user has scrolled to the bottom of a disclaimer before they can acknowledge it by checking a checkbox. Our legal department requires this extra step for compliance reasons. Here is an example of how the markup looks:

<div id="step2Disclaimer" style="height:50px;overflow-y:scroll">
    <p class="l-twelve l-mb1 t-base t-left">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate temporibus commodi sapiente culpa sunt iure veniam harum impedit architecto dolorem quam facilis, odio blanditiis beatae similique non voluptatibus at dolorum?</p>
    <p class="l-twelve l-mb1 t-base t-left">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate temporibus commodi sapiente culpa sunt iure veniam harum impedit architecto dolorem quam facilis, odio blanditiis beatae similique non voluptatibus at dolorum?</p>                             
</div>

<input type="checkbox" id="acknowledge" name="acknowledge" value="true">
<label class="styled" for="acknowledge">I acknowledge</label>

I am able to track when someone reaches the end of #acknowledge like this:

$('#step2Disclaimer').on('scroll', function() {
    if($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
    alert('end reached');
    }
});

However, my challenge lies in detecting whether or not someone has scrolled after checking the "acknowledge" checkbox. The condition isn't functioning as expected - specifically, I need to run a function if the checkbox is checked but the user has NOT scrolled to the bottom of "step2Disclaimer".

$(function() {
    $('input[name="acknowledge"]').change(function(){
        if ($(this).is(':checked') && ($('#step2Disclaimer').scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight)) {
            alert('checked but not scrolled');
        }
    });
});

Answer №1

Initially, the issue lies in your use of this, which is targeting the checkbox instead of the div. Additionally, you should be checking if the sum of scrollTop and innerHeight is smaller, not larger, than scrollHeight. The revised code below should resolve this:

$(function() {
    $('input[name="acknowledge"]').change(function(){
        if ($(this).is(':checked') && ($('#step2Disclaimer').scrollTop() + $('#step2Disclaimer').innerHeight() < $('#step2Disclaimer')[0].scrollHeight)) {
            alert('checked but not scrolled');
        }
    });
});

Working Fiddle

Answer №2

Unfortunately, I wasn't able to utilize jQuery.appear or appear.js because those libraries focus on the DOM viewport instead of element viewports. Therefore, here is the code that will hide the checkbox until the user manually scrolls through the agreement content (reaching the very bottom).

HTML

<div id="step2Disclaimer">
    <p class="l-twelve l-mb1 t-base t-left">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate temporibus commodi sapiente culpa sunt iure veniam harum impedit architecto dolorem quam facilis, odio blanditiis beatae similique non voluptatibus at dolorum?</p>
    <p class="l-twelve l-mb1 t-base t-left">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate temporibus commodi sapiente culpa sunt iure veniam harum impedit architecto dolorem quam facilis, odio blanditiis beatae similique non voluptatibus at dolorum?</p>
    <div class='agreement_read'>?</div>
</div>

<input class='unread' type="checkbox" id="acknowledge" name="acknowledge" value="true" disabled>
<label class="styled unread" for="acknowledge">I acknowledge</label>

CSS

#step2Disclaimer {
    width: 315px;
    border: solid 1px #ACE;
    margin-bottom: 15px;
    height: 115px;
    overflow-y: scroll;
    font-family: arial;
    font-size: 1rem;
    padding: 3px;
}

.unread {
    cursor: not-allowed;
    border: dashed 1px red;
    padding: 3px;
    color: #CCC;
}

.fully_read {
    border: solid 1px green;
    padding: 3px;
}

JavaScript

var master_agreement = document.getElementById('step2Disclaimer');

jQuery(master_agreement).scroll(function(e) {
    if (isScrolledToBottom(master_agreement) && jQuery('.unread').length) {
        jQuery('.unread').removeClass('unread').addClass('fully_read');
        jQuery('#acknowledge').prop('disabled', false);
    }
});

//Chris Martin of StackOverflow - https://stackoverflow.com/a/32283147/5076162
function isScrolledToBottom(el) {
    var $el = $(el);
    return el.scrollHeight - $el.scrollTop() - $el.outerHeight() < 1;
}

var master_agreement = document.getElementById('step2Disclaimer');

jQuery(master_agreement).scroll(function(e) {
    if (isScrolledToBottom(master_agreement) && jQuery('.unread').length) {
        jQuery('.unread').removeClass('unread').addClass('fully_read');
        jQuery('#acknowledge').prop('disabled', false);
    }
});

//Chris Martin of StackOverflow - https://stackoverflow.com/a/32283147/5076162
function isScrolledToBottom(el) {
    var $el = $(el);
    return el.scrollHeight - $el.scrollTop() - $el.outerHeight() < 1;
}
#step2Disclaimer {
    width: 315px;
    border: solid 1px #ACE;
    margin-bottom: 15px;
    height: 115px;
    overflow-y: scroll;
    font-family: arial;
    font-size: 1rem;
    padding: 3px;
}

.unread {
    cursor: not-allowed;
    border: dashed 1px red;
    padding: 3px;
    color: #CCC;
}

.fully_read {
    border: solid 1px green;
    padding: 3px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="step2Disclaimer">
    <p class="l-twelve l-mb1 t-base t-left">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate temporibus commodi sapiente culpa sunt iure veniam harum impedit architecto dolorem quam facilis, odio blanditiis beatae similique non voluptatibus at dolorum?</p>
    <p class="l-twelve l-mb1 t-base t-left">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate temporibus commodi sapiente culpa sunt iure veniam harum impedit architecto dolorem quam facilis, odio blanditiis beatae similique non voluptatibus at dolorum?</p>
</div>

<input class='unread' type="checkbox" id="acknowledge" name="acknowledge" value="true" disabled>
<label class="styled unread" for="acknowledge">I acknowledge</label>

Answer №3

To enhance user experience, consider implementing a feature that hides the checkbox until the visitor reaches the bottom of the page. Utilize tools such as Jquery's hover or mouse over to trigger the box's appearance when the user nears the end.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for segmenting text into pages according to the dimensions of the viewport and the font style

Here's a puzzle for you. I have a horizontal slider that loads pages via Ajax, with pre-loading features to maintain smooth performance. Similar to Facebook Billboarding but with a slight twist. By determining the viewport size, I calculate boxSizeX a ...

Ways to determine if an element is the initial child

I am currently facing issues while attempting to make my bootstrap carousel dynamic and inject data properly. My aim is to locate the first child of the injected data and apply the "active" class to it. I am utilizing Laravel Blade for rendering my data. B ...

"Server request with ajax did not yield a response in JSON format

http://jsfiddle.net/0cp2v9od/ Can anyone help me figure out what's wrong with my code? I'm unable to see my data in console.log, even though the network tab in Chrome shows that my data has been successfully retrieved. Here is my code snippet: ...

When resizing the window, the click events are getting stuck and not releasing the click

I'm attempting to implement a dropdown menu using jQuery on a click event. Here is the code snippet: $(".sidebar-nav li > a").click(function(e) { $(this).parent().siblings().find('ul').slideUp(500); $(this).next('ul& ...

Incorporate the list seamlessly into the remaining content of the page

I am currently developing a Vue component that utilizes an API call to search for a list of cities based on user input. My challenge is ensuring that the displayed list does not overlap with the header component, specifically overlapping the image of the s ...

Is it possible to utilize AngularJS ngAnimate to perform cross-fading transitions on list items?

I am currently exploring the ins and outs of angularJS with my simple message ticker example. This ticker displays messages by toggling the CSS display property of one of the li elements. <div id="ngtickerMessage" class="ngtickerMessage"> ...

What is the approach for incorporating JavaScript variables in Jade templates for writing inline CSS styles?

Struggling to inject CSS code dynamically? You're not alone. style(type='text/css') #header a#logo { background:url(constants.logo) no-repeat; } @media only screen and (-webkit-min-device-pixel-ratio: 1.5) { #header a#logo { ...

Keeping track of the toggle state using a cookie

While searching for a way to retain the toggle state, I stumbled upon js-cookie on GitHub. The documentation provides instructions on creating, reading, and deleting a cookie. However, an example would have been really helpful in enhancing my understanding ...

Is it more effective to specify the class within the selector when using jQuery to remove a class?

Does including the class in the selector when removing a class using jQuery have any impact on performance or best practices? I'm curious if there will be any noticeable difference. For example, do you include it like this: $('#myList li.classT ...

The HTML element <a> can have both a href attribute and a onclick attribute

I'm currently facing a challenge with my project - I am trying to create a submenu that includes all sub-pages within a single HTML file. However, whenever I attempt to use both href and onclick, the functionality fails to work as intended. The only ...

Switch the design and save it in the browser's cache

Exploring the possibility of having two themes, "dark" and "light," that toggle when a checkbox is clicked. To implement the theme change, I used the following JavaScript code: document.documentElement.setAttribute('data-theme', 'dark&apos ...

Click to position custom text on image

Is there a way to adjust the position of text on an image after it has been clicked? I have included an image below to demonstrate how I would like it to appear: https://i.stack.imgur.com/unmoD.png function revealContent(obj) { var hiddenText = obj. ...

Refreshing button labels in Rails utilizing ajax and jQuery

Despite researching numerous other SO inquiries, I am unable to make this function work as desired. Upon clicking "complete," I wish for the button to switch to "un-complete" (for example only). The AJAX action executes successfully, but I struggle with re ...

Adjusting the color of a child element only when hovering over a certain parent element (each parent belonging to the same class)

Within my navigation items, each ".nav_item" contains multiple paragraphs. My goal is to dynamically change the color of the first paragraph by adding or removing a CSS class when hovering over the respective ".nav_item" container. $('.nav_item' ...

What is preventing me from setting the height of a span to 0 pixels?

It seems that when the height is set to 0px, the element doesn't visually shrink... <div id="bg"> <div id="animate"><span>WINNER ALERT! Click here to get a million dollars!!!</span></div> </div> #bg { back ...

The resizing of iframes in Javascript is malfunctioning when it comes to cross-domain functionality

I have implemented a script to dynamically resize iframe height and width based on its content. <script language="JavaScript"> function autoResize(id){ var newheight; var newwidth; if(document.getElementById){ newheight=docume ...

Is it possible for the `position: fixed` property to interfere with mix-blend-mode, and if so, are there

Struggling to make box-shadows cooperate with different backgrounds? The traditional method involves using mix-blend-mode and adding a pseudo element behind the main one for the effect. You can see an example of this technique here (click the + icon in th ...

Is there a way to undo the transition when hovering out?

Is it possible to achieve a reverse transition animation on hover out using CSS? I want the "Menu" text to slide to the right blue line when I hover out, and after a delay of 400ms, slide back from the left grey line. Can this be done? .menu { displ ...

Inability to submit page after clicking on lower half of button while eliminating validations

In my current Struts2 application, I am encountering a issue related to validations on textfields. The validations include checks for missing values and incorrect values. Below these fields, there is a button that should submit the form once all validation ...

JavaScript strangeness

I am currently working on a dynamic page loaded with ajax. Here is the code that the ' $.get' jQuery function calls (located in an external HTML page): <script type="text/javascript"> $(function() { $('button').sb_animateBut ...