typescript scrolling location

In my Angular UI code, I have a component class that includes the following structure:

app.component.html

//...
<div class="banner">
    <p-dialog [(visible)]="displayCOI" styleClass="coiDialog" [contentStyle]="{'overflow-y': 'hidden'}" [modal]="true" [style]="{width: '75vw'}" [baseZIndex]="10000" [showHeader]="false"
        [draggable]="false" [resizable]="false">  
        <coi (notify)="onCoIAccept($event)"></coi>
    </p-dialog>
</div>

...///

The structure of coi.component.html is as below:

<div>
<div class="row" style="padding: 10px 0px">
    <div class="col-sm-4">
    <p align="center"><b>Instructions</b></p>                        
    <br>...//
    </div>
    <div #scrollDiv id="scrollDiv" class="col-sm-6" style="height:350px; overflow-y: scroll;" (scroll)="onScroll($event)">
    <p-table #dt [columns]="cols" [scrollable]="true" [value]="usersLi" [(selection)]="selectedUsersLi"  dataKey="id">
    //....
    ..///
    </p-table>
    </div>
    <div class="col-sm-2">
    <div align="center">
        <button pButton type="button" label="Accept" [disabled]="disableAccept" (click)="close()" class="ui-button-rounded"></button>&nbsp;
        </a>
    </div>
</dv>
</div>

The TypeScript code for coi.component.ts is provided below:

export class coiComponent  {
  @ViewChild("scrollDiv") scrollDiv: ElementRef;
  disableAccept: boolean = false;
  
  ngOnInit():void { 
    this.keys = Object.keys(this.propertyObj); 
    this._utilService.convertKeysToHeader(this.keys,this.cols);
    this.disableAccept = true;    
    this.loadRecords();
  }
  
  
  onScroll(event: any) { 
    if (event.target.offsetHeight + event.target.scrollTop >= event.target.scrollHeight) {
        this.disableAccept = false;
        console.log("End");
    }
  }
  
   ngOnChanges(changes: SimpleChanges){
    console.log("ngOnChanges" , changes);
    for ( const propName in changes){
        let change = changes[propName];
        if ( propName == 'coi'){
            console.log(this.scrollDiv.nativeElement.offsetHeight);
            console.log(this.scrollDiv.nativeElement.scrollHeight); 
        }
    
    }
    
    }
}

The modal contains three divisions: Instructions, Table, and Accept button. The aim is to enable the "Accept" button only after all records in the table have been viewed through scrolling. However, if users see less than 5-10 records at times, the scroll feature will not be triggered. To address this issue, an id "scrollDiv" has been added with ElementRef usage, but offsetHeight and scrollHeight values return '0'. Suggestions on how to implement this effectively are welcomed. Can someone provide guidance? Thank you.

I have made updates to my query. Any suggestions would be appreciated. Thank you.

Answer №1

Let me provide you with a practical example so that you can grasp the concept and apply it to your situation. You can refer to this link for more details.

Explanation of the provided example

Within the component, there are 4 key elements to take into account:

  • isActionDisabled: a variable indicating whether the action should be disabled or not
  • @ViewChild('containerElement') containerElement
    : a reference to the scrollable container of the table
  • onScrollContainer: a method triggered when scrolling the containerElement
  • disableByScroll: a method that adjusts the value of isActionDisabled based on the scrollbar position of the containerElement. If at the bottom, isActionDisabled is set to false; otherwise, it's set to true.

The crucial method here is disableByScroll:

disableByScroll(): void {
  if (this.containerElement) {
    const element = this.containerElement.nativeElement;
    this.isActionDisabled = !(
      element.scrollTop ===
      element.scrollHeight - element.clientHeight
    );
  } else {
    this.isActionDisabled = true;
  }
}

Please refer to this article to gain a better understanding of the process. The disableByScroll function is executed each time a scroll event occurs on the containerElement

onScrollContainer(): void {
  this.disableByScroll();
}

and after the view initialization

ngAfterViewInit(): void {
  this.disableByScroll();
  this.cdr.detectChanges();
}

This approach proves beneficial when dealing with a large number of items that do not activate the scrollbar. Take a look at this guide to comprehend the lifecycle events in an Angular application. The use of detectChanges from ChangeDetectorRef will become clear once you've gone through the guide.

The template is fairly straightforward and easy to interpret.

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

Encountering TypeError with Next.js and Firebase: Unable to access properties of undefined (specifically 'apps')

My goal is to create an authentication system using NextJS and Firebase. The issue I am facing is in my firebaseClient.js file, where I am encountering the error "TypeError: Cannot read properties of undefined (reading 'apps')". Here is a snipp ...

The method models.User.fromURI is unsuccessful

When I try to call models.User.fromURI as shown below: models.User.fromURI("spotify:user:" + user, function (user) { $(div).html("<b ><a style=\"color:#FFFFFF\" href=\"spotify:user:" + user.username + "\">" + us ...

Using (javascript:) within Href attributes

Recently, I've noticed some people including "javascript:" in the href attribute of an a tag. My question is: what is the purpose of this? Does it guarantee that clicking on the a tag directs the function of the click to JavaScript for handling, rathe ...

Angular Error TS2339: The property 'car' is missing from type 'Array of Vehicles'

Encountering Angular Error TS2339: Property 'vehicle' is not found on type 'Vehicle[]'. The error is occurring on data.vehicle.results. Any thoughts on what could be causing this issue? Is the problem related to the Vehicle model? I hav ...

Synchronized loops in jQuery using the .each method

I'm having trouble getting the ajaxStop function in jquery to work. Any suggestions on how to make it fire? My goal is to iterate through each anchor tag and update some content within it. After that, I want to use the ajaxstop event to trigger a scr ...

Increase the worth of current value

Whenever a user enters their name into an input box, I want it to be shown after the word 'hello'. However, currently, the word 'hello' gets replaced by the user's name instead of being displayed after it. var name = document.ge ...

JavaScript code for iframe auto resizing is not functioning properly on Firefox browser

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

Retrieve the route from a specific node in the jstree structure

Looking to retrieve the paths of selected nodes in jstree? You'll need the complete path of the nodes. I have a php file that generates the JSON, structured like this: header("Content-Type: application/json; charset=utf8"); echo json_encode(dir_to_ ...

Is there a more efficient method to tally specific elements in a sparse array?

Review the TypeScript code snippet below: const myArray: Array<string> = new Array(); myArray[5] = 'hello'; myArray[7] = 'world'; const len = myArray.length; let totalLen = 0; myArray.forEach( arr => totalLen++); console.log(& ...

Transferring image Buffer over API for uploading to IPFS network

My attempt to upload an image to IPFS involves the following steps: I start by uploading the image from my web UI, converting it to a buffer in my Angular component. The next step is to send it via a put/post request (using HttpClient) to my NodeJS Expres ...

Refresh the information being received without initiating a new process

I am fetching data from an ngrx/store I have subscribed to the data this.store.select(somedataList) .subscribe(myList => { myList.propertyA = "a different value"; }); After modifying the property values upon subscription, I must update the data ...

Easy selector for choosing jquery css backgrounds

Here is a simple background selector that I created. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <hea ...

Angular: it is impossible to access property 'x' as it is undefined

I am facing an issue where I keep getting the error message Cannot read property 'id' of undefined in my HTML component. <button (click)="getRecipeDetails()">Show</button> <div> <div [innerHTML]="recipeIn ...

Unexpected value detected in D3 for translate function, refusing to accept variable

I'm experiencing a peculiar issue with D3 where it refuses to accept my JSON data when referenced by a variable, but oddly enough, if I print the data to the console and manually paste it back into the same variable, it works perfectly fine. The foll ...

Trouble with the navbar collapse functionality in Bootstrap

3 I made some changes to the navbar, now the navbar-header is showing but the collapse navbar-collapse is not. Here is my code. Can you spot where I went wrong? <nav class="navbar navbar-default"> <div class="container-fluid" ...

What is the best method for adding a JSON array with objects to an already existing table?

After incorporating Bootstrap into my HTML file, I designed a basic table. To populate this table with data from an external JSON file upon clicking a button, I utilized XMLHttpRequest and JSON.parse successfully. However, I encountered difficulties when t ...

Accessing an element by its ID with the help of a looping

Looking to retrieve a string from my database and insert it into my paragraphs: <p id="q_1"></p> <p id="q_2"></p> The following code works correctly: $.get("bewertung/get/1", function (data) { document.getElementById("q_1") ...

monitor the location of a div within a textarea

My question revolves around a textarea that is linked to a draggable div through the following code: $('#content').children().draggable({ drag : function () { $('#textarea').text("left:" +($(this).position( ...

Unique Version: Some effective tips for utilizing a fork of type definition such as @types

Currently, I am utilizing Typescript 2.0 along with @types and the experience has been quite positive. Thanks to @types, we can easily leverage type definitions by simply installing the package via npm. Surprisingly, I have not delved into how it actually ...

ng-grid defines different cellClass based on the value of the field

I am currently using the ng-grid and I want the column to display in a different color based on different values. I have tried, but not succeeded so far... $scope.gridOptions = { ........ columnDefs: [ { field: "status", displayName: "St ...