Horizontal Scrollbars at Top of Angular Grid

Hello,

Is there a way to place horizontal scrollbars at the top of the grid as well as at the bottom?

We are being requested to provide this functionality. I have seen similar requests in this forum for other versions of the Grid control (Web Forms, jQuery) and it looks like it may be possible but requires some knowledge of the underlying structure / css of the grid. Can you provide sample code for how to do this in the Angular version of the grid?



9 Replies 1 reply marked as answer

SM Shalini Maragathavel Syncfusion Team December 15, 2020 10:32 AM UTC

Hi Michael,  

Thanks for contacting Syncfusion support.

Based on your query we suspect that you want to render the horizontal scrollbar at  the top and bottom of the Grid. You can achieve your requirement using the custom css and onscroll event  as demonstrated in the below code snippet,

index.js 
 App.component.html      
<div class="control-section"> 
  <div id="scroll_wrapper1"> 
    <div id="scroll_div"></div> 
  </div> 
  <div id="scroll_wrapper2"> 
    <div id="grid_parent"> 
      <ejs-grid  [dataSource]="data" allowPaging="true"  height="100%" width="100%”  (load)="load($event)" 
        [pageSettings]="pageSettings" 
      > 
        <e-columns> 
         . . . 
        </e-columns> 
      </ejs-grid> 
    </div> 
  </div> 
</div> 
-----------------------------------------------------------------------------------
 App.component.ts      
export class AppComponent { 
    load(args){ 
var wrapper1 = document.getElementById("scroll_wrapper1"); 
    var wrapper2 = document.getElementById("scroll_wrapper2"); 
    wrapper1.onscroll = function() { 
      wrapper2.scrollLeft = wrapper1.scrollLeft; 
    }; 
    wrapper2.onscroll = function() { 
      wrapper1.scrollLeft = wrapper2.scrollLeft; 
    }; 
    } 
} 
 


index.html 
  <style> 
                             #scroll_wrapper1, 
                             #scroll_wrapper2 { 
                                           width: 600px; 
                                           overflow-x: scroll; 
                                           overflow-y: hidden; 
                             } 
 
                             #scroll_wrapper1 { 
                                           height: 20px; 
                                           position: -webkit-sticky !important; 
                                           position: sticky !important; 
                                           top: 0% !important;                                     
                                           z-index: 1 !important; 
                             } 
 
                             #scroll_wrapper2 { 
                                           height: 500px; 
                             } 
 
                             #scroll_div { 
                                           width: 900px; 
                                           height: 20px; 
                             } 
 
                             #grid_parent { 
                                           width: 900px; 
                                           height: 500px; 
                                           overflow: auto; 
                             } 
              </style> 
 


Please find the  below sample for more information. 

Sample : https://stackblitz.com/edit/angular-w6b3cg-pqjq3a?file=app.component.ts

Please get back to us if you need further assistance.
 

Regards, 
Shalini M. 



ME Michael Evans April 22, 2021 12:27 PM UTC

Hello,

Apologies for not replying to this thread for some time. I attempted to implement the suggested workaround but was unsuccessful. The work got deferred but it is now coming back up again.

We do still need a scroll bar at the top of the grid as well as at the bottom. I think a solution where the scroll bar is completely outside the grid, or one where the scroll bar appeared between the column headers and the data would be acceptable.

The reason your solution didn't work for us is that we also have a requirement that the grid expands to take up the full width and height of the page (outside of the header and footer of the page). As such we do not implement a fixed height and width for the grid and instead use 100%. The scroll bar that is shown at the bottom is built in to the ejs-grid and works great, however we need a way to replicate it above the grid.

I have linked to StackBlitz that shows the layout of our component:
https://stackblitz.com/edit/angular-scrollbar-top-original?file=app.component.html

The following StackBlitz shows our attempted fix using the technique shown in this thread (changing the fixed width/height to 100%)
https://stackblitz.com/edit/angular-scrollbar-top-with-attempted-fix?file=main.ts

Ideally we would have a scroll bar at the top that mirrors the built-in scrollbar in the grid, rather than placing the grid in a scrollable div.
Can you provide a suggestion to make this work with our sizing requirements?

EDIT: Just want to clarify, our requirement is to make it so the user does not have to scroll vertically in order to scroll horizontally. If there is a way to make the bottom scroll bar always appears in the visible viewport, that is also an acceptable solution.

Thanks,
Michael



RR Rajapandi Ravi Syncfusion Team April 28, 2021 08:48 AM UTC

Hi Michael, 

Thanks for the update 

We have analyzed your query and we could see that you like to place the top scrollbar in between header and content. Based on your query we have prepared a sample and achieved your requirement by using dataBound event of Grid.  

App.component.ts 
 
dataBound(args) { 
    var scroll = document.getElementById('wrapper1');  
    var content = document.getElementsByClassName('e-gridcontent')[0]; //get content 
    var grid = (document.getElementsByClassName('e-grid')[0] as any).ej2_instances[0]; 
    grid.element.insertBefore(scroll, content); //by using insert before function we have place the scrollbar between the content and header 
    var wrapper1 = document.getElementById("wrapper1"); 

    wrapper1.onscroll = function () {      //bind onscroll event and  
      var grid = (document.getElementsByClassName('e-grid')[0] as any).ej2_instances[0]; 
      grid.getContent().firstElementChild.scrollLeft = wrapper1.scrollLeft; // set the wrapper1 scrollLeft to the Grid scrollLeft 
    }; 
    (this.grid.getContent().firstElementChild as any).onscroll = function () { //bind onscroll in grid scroller 
      var grid = (document.getElementsByClassName('e-grid')[0] as any).ej2_instances[0]; 
      wrapper1.scrollLeft = grid.getContent().firstElementChild.scrollLeft; // set the Grid scrollLeft to the wrapper1 scrollLeft 
    }; 
    } 
   } 


App.component.html 
 
<div class="control-section"> 
  <div id="wrapper1"> 
    <div id="div1"></div> 
  </div> 
  <ejs-grid 
  #grid 
        [dataSource]="data" 
        allowPaging="true" 
        height="500px" 
        width="600px" 
        (dataBound)="dataBound($event)" 
        [pageSettings]="pageSettings" 
      > 
        <e-columns> 
          .  .  .  .  .  .  .  .  .  . 
        </e-columns> 
      </ejs-grid> 
</div> 

index.html 
 
<style> 
#wrapper1
  width: 580px; 
  overflow-x: scroll; 
  overflow-y:hidden; 

#wrapper1 {height: 20px; } 

#div1
  width:800px; 
  height: 20px; 
              </style> 



Screenshot: 

 

Regards,
Rajapandi R



ME Michael Evans April 28, 2021 03:38 PM UTC

Hi,

Thanks for showing how to place the scroll bar between the column headers and content. That is quite helpful.
However your example still uses fixed widths for wrapper1 and div1. When I tried changing those to 100%, the scroll bar no longer functions, Is there a solution that will work for a 100% width grid?

Thanks,
Michael


MS Manivel Sellamuthu Syncfusion Team April 29, 2021 09:42 AM UTC

Hi Michael, 

Thanks for your update. 

Based on your query you want to set the grid width as 100%. By default if the grid is provided width as 100% it takes width of the parent container to render the grid. So we suggest you to provide the explicit width to the parent container. If the parent container does not have any height or width, the grid renders in the whole window. Please refer the below documentation for  more information. 


Also to proceed further with your requirement please share the purpose for rendering the grid with the width as 100%. Please confirm whether you have defined a parent container for grid with explicit width. 

Regards, 
Manivel 



ME Michael Evans May 3, 2021 12:09 PM UTC

Hi,

We do want the grid to take up the full width of the screen, and provide a scrollbar for the user to scroll left and right if the width of the columns exceeds the width of the screen. When we set width=100% on the grid, this is the behavior that we get. The challenge is that we would also like a horizontal scroll bar at the top of the grid that mirrors the one that is generated at the bottom. I am open to a solution that calculates the width of the grid component in pixels so long as the existing behavior is maintained; that is, when the screen is resized the grid continues to take up the full width of the viewport and the horizontal scrollbar allows the user to see the remaining columns of the grid. I have tried a number of solutions to duplicate the scroll bar and haven't been able to make it work. Even adapting your solution to have the wrapper and inner dev have a fixed width, only allows me to partially scroll the grid; scrolling all the way to the right only partially scrolls the grid. I am sure this is due to the ratio of the widths being unequal to the real width of the grid and its content, but I am unable to find a way to calculate these widths correctly.

Thanks,
Michael


MS Manivel Sellamuthu Syncfusion Team May 4, 2021 10:03 AM UTC

Hi Michael, 

Thanks for your update. 

We have prepared the sample based on your requirement. We have provided the width for the horizontal scrollbar(at the top of content) value in percentage.  
So it automatically adjust based  on the grid width. Please refer the below code example and sample for more information. 

<div class="control-section"> 
  <div id="wrapper1"> 
    <div id="div1"></div> 
  </div> 
  <ejs-grid 
  #grid 
        [dataSource]="data" 
        allowPaging="true" 
        height="500px" 
        width="100%" 
        (dataBound)="dataBound($event)" 
        [pageSettings]="pageSettings" 
      > 
        <e-columns> 
. . . 
        </e-columns> 
      </ejs-grid> 
</div> 

export class AppComponent { 
    public data: Object[]; 
    public pageSettings: Object; 
     @ViewChild('grid') 
    public grid: GridComponent; 
     
    ngOnInit(): void { 
        this.data = data; 
        this.pageSettings = { pageCount: 5 }; 
    } 
  dataBound(args) { 
    var scroll = document.getElementById('wrapper1') 
    var content = document.getElementsByClassName('e-gridcontent')[0]; 
    var grid = (document.getElementsByClassName('e-grid')[0as any).ej2_instances[0]; 
    grid.element.insertBefore(scroll, content); 
    var wrapper1 = document.getElementById("wrapper1"); 
 
    wrapper1.onscroll = function () { 
      var grid = (document.getElementsByClassName('e-grid')[0as any).ej2_instances[0]; 
      grid.getContent().firstElementChild.scrollLeft = wrapper1.scrollLeft; 
    }; 
    (this.grid.getContent().firstElementChild as any).onscroll = function () { 
      var grid = (document.getElementsByClassName('e-grid')[0as any).ej2_instances[0]; 
      wrapper1.scrollLeft = grid.getContent().firstElementChild.scrollLeft; 
    } 
   } 
} 
    #wrapper1 { 
      width: 98.8%; 
      overflow-x: scroll; 
      overflow-y: hidden; 
    } 
   
    #wrapper1 { 
      height: 20px; 
    } 
   
    #div1 { 
      width: 2800px; 
      height: 20px; 
    } 


Please let us know if you need further assistance. 

Regards, 
Manivel 


Marked as answer

ME Michael Evans May 4, 2021 12:24 PM UTC

Hi Manivel,

Thanks for your assistance. I was able to take your suggestions and incorporate them into a solution that works as desired.
The only major change I had to make was to dynamically set the width of the div1 component. I was able to set a property called "scrollDivWidth" like this:

    this.scrollDivWidth = this.grid.getContent().firstElementChild.scrollWidth;

And then use [ngStyle] on the div itself:

      <div id="div1" [ngStyle]="{'width': scrollDivWidth + 'px'}"></div>

This made the width of the div the same as the width of the grid, so the scrollbars would be the same size and sync between the top and bottom ones. In your example, the div was fixed at 2800px which made the scrollbars either too large or too small depending on the width of the grid.

I'm pleased I was able to get this working and appreciate your assistance.

Thanks,
Michael


MS Manivel Sellamuthu Syncfusion Team May 5, 2021 06:58 AM UTC

Hi Michael, 
 
Thanks for your update. 
 
We are glad that you have resolved your requirement by incorporating with our given solution. 
 
Please let us know  if you need further assistance. 
 
Regards, 
Manivel 


Loader.
Up arrow icon