What is the best way to make a responsive HTML table with a fixed left column and a scrollable body using Angular 11?

Currently, I am working on angular 11 and ng-bootstrap 9.1 with the requirement to create a table where the first three columns are fixed and responsive at the same time. While I have managed to make them fixed, achieving responsiveness has been challenging as the UI breaks at certain points.

I understand that this question is similar to others like:

  • HTML table with fixed headers and a fixed column?

  • How can I lock the first row and first column of a table when scrolling, possibly using JavaScript and CSS?

  • How do I create an HTML table with a fixed/frozen left column and a scrollable body?

I am seeking a simple solution such as;

  • Are there any other methods in angular or ng-bootstrap to achieve this?

  • Or is there a foolproof way to ensure responsiveness?

No external dependencies are allowed.

Here is the HTML code snippet used in the component to generate the table:

<div class="row mb-2 view" *ngIf="value1.length">
    <div class="col-md-12 mb-2 wrapper" style="max-height: 65vh; overflow-y: auto;">
        <table class="bg-white roundedCorner table-sm table table-bordered">
            <tr class="font-weight-bolder text-monospace" style="background-color: aliceblue; font-size: 1em;">
                <th class="text-center align-middle sticky-col check-box" rowspan="2" *ngIf="####" >                                 <input type="checkbox" [(ngModel)]="checkAll" (click)="fnCall($event)">                             </th>
                <th rowspan="2" class="text-center align-middle sticky-col first-col" [ngStyle]="{'left': lockMode?'80px':'0px'}" style="background-color: aliceblue;">                                 Chest Number                               </th>
                <th  rowspan="2" class="text-center align-middle sticky-col  second-col"  [ngStyle]="{'left': lockMode?'180px':'100px'}" style="background-color: aliceblue;">                                 Project Name                             </th>
                <th  [attr.colspan]="rubrics.length" class="text-center align-middle">                                 Rubrics                             </th>
                <th class="text-center align-middle"rowspan="2" style="max-width: 80px;">                                 Total Mark                             </th>
                <th class="text-center align-middle" rowspan="2">                                 Remarks                             </th>
            </tr>
            <tr class="text-monospace text-center align-middle font-italic font-bold" style="background-color: azure;" >
                <th *ngFor="let rubric of rubrics">                                     {{ rubric.rubricName }} ({{rubric.maxMark}})                                </th>
            </tr>
        </table>
    </div>
</div>

CSS code snippet used to achieve fixed positioning:


.view {
    margin: auto;
    width: auto;
    border-collapse: separate;
    border-spacing: 0;
}
.wrapper {
    position: relative;
    overflow: auto;
    white-space: nowrap;
}

.sticky-col {
    position: -webkit-sticky;
    position: sticky;
}

.first-col {
    width: 100px;
    min-width: 100px;
    max-width: 100px;
}

.second-col {
    width: 20vw;
    min-width: 20vw;
    max-width: 20vw;
}

.check-box {
    width: 25px;
    min-width: 25px;
    max-width: 25px;
    left: 0px;
}

Answer №1

My issue was with the CSS and inline styles in my particular scenario. Instead of assigning classes to each column needed, I utilized the :nth-child() selector for the first two columns and incorporated inline styles based on specific conditions. To handle these conditions, I made use of ng-style directive. The code snippet demonstrating this approach is as follows:

/* CSS */  
  th:first-child, td:first-child{
    position: sticky;
    left: -1px;
    width: 40px;
  }

  td:nth-child(2), th:nth-child(2){
    position: sticky;
  }
<!--HTML-->
<tr class="font-weight-bolder text-monospace " style="background-color: aliceblue; font-size: 1em;">
   <th class="text-center align-middle " style="background-color: aliceblue; z-index: 33" rowspan="2" *ngIf="lockMode">
  <input type="checkbox" [(ngModel)]="checkAll" (click)="selectAllProjectsCheckChange($event)">
   </th>
   <th rowspan="2" class="text-center align-middle " [ngStyle]="{'left': lockMode? '20px' :'0px'}" style="background-color: aliceblue; z-index: 33;">
  Chest Number
   </th>
   <th  rowspan="2" class="text-center align-middle" [ngStyle]="{'left': lockMode?'76px':'55px'}"  style="background-color: aliceblue; position: sticky; z-index: 33">
  Project Name
   </th>
</tr>
<tr class="text-center align-middle sticky-col" *ngFor="let project of projectMappings">
   <!-- *ngIf="project.pending" -->
   <ng-container *ngIf="isShowPendingEnabled? !project.isValid : true">
  <td class="text-center align-middle" *ngIf="lockMode" style="z-index: 33 ; background-color: white;">
     <input type="checkbox" [disabled]="project.judgeDetails.status? project.judgeDetails.status === 'locked': false" [checked]="(project.judgeDetails.status? project.judgeDetails.status === 'locked': false) || checkLockValid(project._id)" (click)="projectLockCheckboxChange(project)">
  </td>
  <td class="text-center align-middle" style="z-index: 33 ; background-color: white;" [ngStyle]="{'left': lockMode?'20px':'0px'}">
     {{ project.chestNumber? project.chestNumber : 'N/A'}}
  </td>
  <td class="text-center align-middle" style="z-index: 33 ; background-color: white; position: sticky;" [ngStyle]="{'left': lockMode?'76px':'55px'}" >
     {{ project.projectName }}
  </td>
   </ng-container>
</tr>

   

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

CSS can be used to overlay a portion of an image when resizing

Looking to add some animation to a sprite image on hover - specifically, sliding up or down to reveal another hidden part (colored sprite). The CSS code below works well for pixels, but I also need it to be responsive so that it resizes when the browser wi ...

CSS positioning of a close button is vital for a seamless

My modal has a close button at the bottom, but its position seems to be shifting up and down based on the length of the comment section directly above it. I'm looking for a way to keep the close button fixed at the bottom regardless of the comment sec ...

Tips for hiding a class while scrolling up with jQuery

I have been experimenting with making classes appear and disappear based on scrolling behavior in a browser. I successfully made a class appear when reaching a certain height using the following code: jQuery(".tetapElement").css("opacity", 1); jQuery ...

Creating an HTML tag from Angular using TypeScript

Looking at the Angular TypeScript code below, I am trying to reference the divisions mentioned in the HTML code posted below using document.getElementById. However, the log statement results in null. Could you please advise on the correct way to reference ...

Is there a way to compel Blazor to display a lone, non-breaking space?

Blazor has a default behavior of trimming "insignificant" whitespace during compile time, as mentioned in this Microsoft document. Moreover, Blazor also trims significant whitespace. For instance: <span>some text</span> @if (true) { <sp ...

Manage the jQuery resize handles by controlling their behavior when clicked inside and outside of the corresponding DIV

I am dynamically creating DIV elements and using jQuery resizeable handles on them. Is there a way to show the handles on click or hover, and then hide them when clicking outside the relevant div? Check out this jsFiddle $('.resizable').on(&ap ...

Stop the page from scrolling

I'm trying to find a way to disable page scrolling, so I used this style for the body: overflow: hidden; Surprisingly, it worked perfectly on desktop but had no effect on mobile devices. After checking out this resource, it seems that creating a ch ...

Unable to retrieve the value of a selected table cell from dynamically generated HTML tables

I've gone through a plethora of Google and Stack Overflow examples To showcase my problem, I have set up a fiddle. Issue: "Upon clicking on a person's name, I want to retrieve their name from the first column." While I managed to create a click ...

Creating a navigation bar with a logo: A step-by-step guide

I'm trying to create a subnav below my navbar with the text aligned to the right and the logo positioned on the left. However, I'm facing issues with moving the text to the right and adjusting the position of the logo. How can I move the logo dow ...

What could be causing the Bootstrap Navbar toggle icon button to not display navigation items when clicked?

Bootstrap has been a reliable tool for my projects until I encountered an issue in an Angular project. The navbar toggler icon button is visible, but clicking on it does not display the navigation items. <div> <nav class="navbar navbar-ex ...

When the user clicks, the event is triggered twice but only within the tabs

I am having an issue with my webpage where I have a container named task1 that includes a slideshow, back button, and next button. The final page will feature task1 as one of the tabs in a series of containers called tasks. When I use the onClick event wit ...

What are the best practices for creating responsive Iframes in videos?

I have been attempting to create a responsive video iframe, but unfortunately, I am facing some difficulties in achieving this. So far, the iframe works fine without any background frame. .embed-container { position: relative; padding-bottom: 56.25% ...

Embedding Custom CSS Within a Parent CSS Element

After implementing a Wordpress Theme, I encountered the need to customize the styles of one of its elements. (This particular element displays our tours automatically) Currently, the style is as follows: .tourmaster-tour-grid .tourmaster-tour-content-wrap ...

Why are the height and width values I specified not matching the values returned?

I am currently learning HTML and JavaScript, specifically diving into the width() and height() methods in JavaScript. Setting the dimensions of div1 to 100px for height and 300px for width, I encountered a discrepancy when running the code. Upon execution ...

Angular validation to ensure future dates are not selected

I am interested in exploring Angular's datepicker functionality and implementing date validation to restrict the selection of future or past dates. For example, if today's date is 17/12/2020, users should only be able to select the current date ( ...

Component rendering based on conditions is not working properly when using Next.js, especially on the initial load

While utilizing Ant Design and a Custom Stylesheet, I have encountered an issue where the style appears broken upon first load. However, if I navigate to another page and return to the original broken page, it displays correctly. This problem only occurs d ...

Creating two rows within the `<nav>` element using Bootstrap

I currently have a navigation bar that looks like this: <nav class="navbar navbar-expand-lg navbar-dark fixed-top scrolling-navbar" id="navbar"> <div class="container"> <b-navbar-toggle target="navbarContent"> &l ...

What steps should I take to create a JavaScript-based downloader application?

I am looking for a way to sell some files from my Web Server to clients. I have created my own HTTP server and I have experience programming in HTML, CSS, and a little bit of JavaScript. While I have seen tutorials on creating download links with HTML 5, I ...

Is there a way to verify if the overflow of an element with a width of 100% has occurred?

Here is the structure I am working with: <div class="card"> <div class="container"> <slot /> </div> </div> The Card element has a fixed width of 33rem. The container within it spans 100% of ...

Determining the file size of an HTML and JavaScript webpage using JavaScript

Is there a way to determine the amount of bytes downloaded by the browser on an HTML+JS+CSS page with a set size during page load? I am looking for this information in order to display a meaningful progress bar to the user, where the progress advances bas ...