Is there a method to keep the leftmost column in a Google visualization table anchored in place when scrolling horizontally?

I want to replicate the typical google visualization table header row functionality, but I would like it to be focused on the first column instead. It doesn't appear to be a default feature, so I'm curious if it could be achieved using custom CSS?

Answer №1

In my quest to understand how Google achieved the fixed top header on their table, I decided to reverse engineer it. It turns out they created a duplicate of the entire table, placed it in a div, absolutely positioned it, and set its height equal to that of the first row. This clever trick ensures that when you scroll down the main table, the header remains at the top.

Implementing side-scrolling was more complex because the header also needed to scroll horizontally. Since CSS doesn't provide a direct solution (due to the absolute positioning outside the scrollable area), Google had to utilize JavaScript for this functionality.

To replicate this behavior for a fixed column, I created a third clone of the table and then delved into some intricate CSS adjustments to fine-tune the width, height, and position. Finally, by adding an event listener to synchronize the scrolling of the header table with the main table, I was able to achieve the desired effect. The $.scrollbarWidth() function used in this process can be found in this plugin.

visualization = new google.visualization.Table(document.getElementById('table'));
visualization.draw(data);

var fullTable = $('#table > div > div:first');
var yHeader = fullTable.clone().insertAfter(fullTable);
yHeader.css('width', yHeader.children('tr td:first').outerWidth())
       .css('height', fullTable.innerHeight() - $.scrollbarWidth())
       .css('position', 'absolute')
       .css('top', '0px')
       .css('left', '0px')
       .css('overflow', 'hidden')

fullTable.scroll(function() {
  yHeader.scrollTop(fullTable.scrollTop());
});

Answer №2

After switching from using .children() to .find(), the issue was resolved and now it works perfectly. Additionally, in order to maintain functionality after sorting columns, an event listener needs to be added to run the code again. Below is a sample code snippet:

table.draw(data_summary_table, {allowHtml : true, width : '880'});    

function freezeColumn() {
var fullTable = $('#summary_table > div > div:first');
var yHeader = fullTable.clone().insertAfter(fullTable);
yHeader.css('width', yHeader.find("tr td:first-child").outerWidth())
       .css('height', fullTable.innerHeight() - $.scrollbarWidth())
       .css('position', 'absolute')
       .css('top', '0px')
       .css('left', '0px')
       .css('overflow', 'hidden')

fullTable.scroll(function() {
  yHeader.scrollTop(fullTable.scrollTop());
}); 

}

freezeColumn();

google.visualization.events.addListener(table, 'sort',
      function(event) {
freezeColumn();
      });

Answer №3

If you encounter an error in the browser saying "$.scrollbarWidth is not a function", simply update it to property. Use $.scrollbarWidth instead.

table.draw(data_summary_table, {allowHtml : true, width : '880'});    

function frozenColumn() { 

    var fullTable = $('#summary_table > div > div:first');
    var yHeader = fullTable.clone().insertAfter(fullTable);
    yHeader.css('width', yHeader.find("tr td:first-child").outerWidth())
        .css('height', fullTable.innerHeight() - $.scrollbarWidth)
        .css('position', 'absolute')
        .css('top', '0px')
        .css('left', '0px')
        .css('overflow', 'hidden')

        fullTable.scroll(function() {
        yHeader.scrollTop(fullTable.scrollTop());
        }); 


}

// Connect the event

google.visualization.events.addListener(table, 'ready', frozenColumn);
google.visualization.events.addListener(table, 'page', frozenColumn);
google.visualization.events.addListener(table, 'sort', frozenColumn);

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

Updating the default value of a MUI TextField: Step-by-step guide

I am in the final stages of completing my form, but I have encountered an issue when trying to display the current user's name in the defaultValue variable of the TextField from MUI. If the value starts as ""/null, or essentially empty, the ...

Tips for targeting the second field upon clicking the next button in React Native

I need help implementing a feature where, when a user clicks on the "Next" button, the focus shifts to the next field without using the ref method. Can someone assist me in achieving this goal without using ref? Thank you. ...

Moving through divisions that share a common class name using jquery

I am experimenting with a plugin that allows me to attach popups to images. My goal is to enable navigation between all popups using previous and next buttons upon clicking on a popup. Below is the element when it's displayed: <div class="imp-too ...

Navigate through the parent elements and show the text if the child element is not present

I'm currently exploring how to iterate through all parent classes (.grid) and if there is no child div with the class (.image-container), then to display the (.content-container) within the same (.grid) section. HTML: <style> .grid .content-co ...

Trigger a refresh of the Angular app by clicking a button

Recently, I embarked on developing a single-page application that allows users to input data in a text box and navigate to another page. While designing the second page, I aimed to incorporate a home button that would not only return me to the initial view ...

How to keep a div element fixed on the page's border vertically and horizontally adhered

Would you mind visiting the following link: and observing the layout of the page? My goal is to affix or "attach" a small div element to the right side of the page, just slightly outside of the right frame of the page. Vertically, I want this div to be ...

Tips for accessing the value of an unchecked checkbox in AngularJS

This is a snippet of HTML code: <p> <input type="checkbox" ng-model='add_product.kids' class="filled-in" id="filled-in-box1" /> <label for="filled-in-box1">Kids</label> </p> My goal is to obtain the value "fa ...

Node.js is not accurately setting the content length. How can I resolve this issue?

I could use some assistance. Even though I have set the content-length on the response object, it doesn't seem to be working. Have I done something incorrectly? res.set({ 'Content-Type': res._data.ContentType, 'Content-Length' ...

Exploring Next.js with getServerSideProps

My code has a warning from the console attached. I would appreciate it if someone could help me identify the problem... When I use the "data" hardcoded as props, I can display them in the components, but when I try to fetch from an API, I can retrieve the ...

Tips for passing XML parameters to a WCF service

How can I send an XML parameter to call a WCF method using AJAX and JSON in jQuery? I need to pass an XML value as a parameter. How should I go about passing this XML value? <value><Root>mydata</Root></value> Here is my client-sid ...

What is the process of incorporating a select form within a component?

I am currently working on creating a user registration form. Once the form is filled out and the submit button is clicked, I need the values from the form to be displayed in a specific <p id="data></p> component. Can anyone assist me with this ...

How to retrieve the data variable in Vue JS script

I recently started using vue.js and I'm working with version 2.5.13. In my component file script, I am trying to access a data variable but it keeps returning as undefined. The id attribute in the component is displaying the correct value, however w ...

AXIOS: Is it possible to send multiple data items in a single POST request to an API?

My form collects data, which is then sent to an API using the new FormData(). However, one of the items in the model contains multiple attributes in the MongoDB model. Since the form requires a 1-to-1 key-pair relationship, it can't be sent as an obje ...

accessing a member of a PHP class from within a jQuery function

I am relatively new to using jQuery, so I may have overlooked something basic. However, despite my efforts, I can't seem to find a solution to my issue. I have a PHP class where one of its attributes (retrieved from the database) is the font color for ...

Displaying a List of Files Uploaded with Jquery File Upload in an ASP.NET MVC Application

I have successfully installed the NuGet Jquery File Upload Plugin. The uploader functions flawlessly, allowing me to easily drag and drop files for upload to my server. However, there are two issues that are hindering the completion of this project: Aft ...

Conceal the div element if the value exceeds 0

I'm looking for a way to display a div when the number of remaining days is less than 0. I got it working on jsfiddle, but for some reason, it doesn't work anywhere else. if ($('.daysrem&a ...

Passport.js is throwing an error due to an unrecognized authentication

I need to implement two separate instances of Passport.js in my application - one for users and one for admins, both using JWT authentication. According to the official documentation, the way to differentiate between them is by giving them unique names. W ...

What is the best way to retrieve the height of a div that includes an image that has been

I have a script that inserts images into different columns. I want the script to insert images into the column with the smallest height. However, every time I try to check the height of the columns, it always returns 30px (likely because the images are not ...

Issues with the functionality of the jQuery UI datepicker arise following a body replacement

Currently, I am working on a project that involves updating the page content via ajax by replacing the entire body. However, I have encountered an issue with using the jQuery datepicker in this scenario. The datepicker functionality works fine until the co ...

Other options besides re-flowing and repainting

After doing some research on various platforms like Stack Overflow, I've come across information stating that re-paints and re-flows can be quite taxing on a browser's resources. I am interested in learning about alternative CSS/JS techniques to ...