I'm working on angular 11 and ng-bootstrap 9.1 and i need to make a table with first 3 columns fixed and at the same time it should be responsive too, I've made it fixed but couldn't find a foolproof solution to make it responsive (ui breaks at some points).
I know this question is similar to some other questions, like:
I'm looking for a simple solution, like;
is there any other ways in angular or ng-bootstrap to make it happen?
or is there any way that's pretty much fool proof in a responsive way?
can't add external dependancies or anything.
Html in component to create 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 I've used to make it fixed
.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;
}
In my case, it was the CSS and inline styles that was the problem; instead of adding classes for every column I needed, I used :nth-child()
for the first two columns and added inline styles based on conditions for that, obviously, I used ng-style
to address the condition. So the code will be like this:-
/* 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>