PrimeNG TurboTable with custom width does not work properly - html

I am trying to use a PrimeNG turbotable with custom size (500px) and I expected the columns width to be set automatically however it does not work. I get a horizontal scrollbar and the total width seems to be fixed at 767 pixels. If I try to set the column width manually it gets ignored. If i don't set the table width and I try to put it inside a DIV that is 500px wide I still get the same result (horizontal scrollbar).
Below is the (very simple) code:
<p-table #dt [value]="statusChangesData" [paginator]="true" [alwaysShowPaginator]="false" [rows]="2" [style]="{'width':'500px'}">
<ng-template pTemplate="caption" >
<div class="tableCaption">
<span translate>Status changes</span>
</div>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td [attr.colspan]="3">
<span translate>There are no data into the table</span>
</td>
</tr>
</ng-template>
<ng-template pTemplate="header">
<tr>
<th style="width:200px" [pSortableColumn]="'date'"><span translate>Date</span><p-sortIcon [field]="'date'"></p-sortIcon></th>
<th style="width:200px" [pSortableColumn]="'status'"><span translate>Status</span><p-sortIcon [field]="'status'"></p-sortIcon></th>
<th style="width:100px" [pSortableColumn]="'userId'"><span translate>User ID</span><p-sortIcon [field]="'userId'"></p-sortIcon></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-col>
<tr>
<td>{{col.date}}</td>
<td>{{col.status}}</td>
<td>{{col.userId}}</td>
</tr>
</ng-template>
</p-table>
and this is what it looks like:
Turbo Table
As you can see both the header and the paginator respect the width I set (500px) but the body of the table does not.
I have tried every suggestion I can find in stack overflow including setting
the style like this: [style]="{'width':'200px'} or using [autoLayout]="true" but nothing seems to work. I am using primeNG 7.0.0.
PS. I don't really care to set each column width manually. I just don't want the horizontal scrollbar.

In case someone has a similar problem try setting the min-width of the table to 0:
::ng-deep .ui-table .ui-table-wrapper table {
min-width: 0px;
}

I copied your code from above and pasted it in a new Stackblitz project to test it. I even specified the 7.0.0 version of PrimeNG specifically, to make sure there are not any issues with different versions. (I have found that to be the case when I have used PrimeNG.) I also made up some data to show.
I am not seeing the issues you are talking about. Here is what my resulting grid looks like (ignore the fact that Stackblitz is not finding the primeicons.)
It is staying perfectly 500px wide and all columns are obeying the fixed widths you specified in the header row (<th> tags.) When I removed the fixed widths you provided in your <th> tags, all of the columns are auto-adjusting and fitting within the 500px table.
I have this table in its own component and it is not wrapped in a <div> or any other tags. You can check it out on the Stackblitz link I provided above.
I wonder if there is something about the rest of the page this is contained in that is causing the problem?

Related

PrimeNG table is not taking the fixed width in Angular

I am trying to fix the width of the first column in the primeNG table but somehow it is overriding my CSS even though it is showing while inspecting the element.
Basically, I am looking for CSS in which by changing the tab the first column of the table will have a fixed width no matter what is the size of all columns.
I have tried following way by defining fixed width for the first child but it is taking based width:100%.
In the above image, you can see the size is coming as 368 even though it is 100px defined.
Same when I change the tab, the width is coming as 920 even 100px is fixed.
Is there any way I can define fixed-width 100px with having table width:100% as I don't want to break responsiveness?
Below is reproducible example for reference:
https://stackblitz.com/edit/primeng-tablescroll-demo-wtpbny
In primeng 12 they removed colgroup template so if you are using colgroup over the application need to remove because custom width is not working for column if you are using scrollable check migration guide.
link:https://github.com/primefaces/primeng/wiki/Migration-Guide
solution:
you need to add same width for both tags <th [style]="'width':'100px'"> and <td [style]="'width':'100px'">
if you are using dynamic columns then add one more property width like below
[{ header: "Name", field: "name", width: '100px' }] // column object array object
<p-table [value]="data" [columns]="ColumnObjectArray">
<ng-template pTemplate="header" let-columns>
<tr>
<th *ngFor="let col of columns; let idx=index;" class=""
[style]="'width':col.width">{{col.header}}</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-data let-columns="columns">
<tr>
<td *ngFor="let col of columns" [style]="'width':col.width">
{{data[col.field]}}
</td>
</tr>
</ng-template>
</p-table>
try this one you will definitely get the responsive width to table and also you will get the custom column and header width
I've the solution required in one of my projects.
You should perform these steps:
Set a width for your desired columns
Set the horizontal scroll as per primeng documentation, in Horizontal Scroll section:
Horizontal Scroll:
In horizontal scrolling, it is required to give fixed widths to columns. In general when customizing the column widths of scrollable tables, use colgroup as below to avoid misalignment issues as it will apply both the header, body and footer sections which are different separate elements internally.
Here is a live example including a fixed size only for first column and a responsive table.
This is the only solution (setting a fixed size for your table) because if you set the width to 100% in a mobile device, probably not all columns will be displayed or will be overlapped, breaking responsiveness.
I think the problem is just that your selector for the th element is slightly incorrect. You have:
::ng-deep .p-datatable .p-datatable-tbody > tr > th:nth-child(1) {
but you just need to use .p-datatable-thead instead of .p-datatable-tbody:
::ng-deep .p-datatable .p-datatable-thead > tr > th:nth-child(1) {
This should fix. Removing fixed with for all th elements.
Add this to your style.css
.p-datatable .p-datatable-thead > tr > th {
width: inherit !important;
}

Is there a case when table cell will ignore min-width?

I have a table with table-layout set to fixed. In the first row I have a td with text inside. It's something like:
<table>
<tbody>
<tr>
<td colspan="2" style=" min-width: 250px; width: 100%;">
<b>Vendor/Firm Information</b>
</td>
</tr>
<tr>
some content
</tr>
... and so on
</tbody>
</table>
So, the width of the first row is actually less than 250px. It's even less than content. So, I need to know: is there any reason for that? Is there something that don't allow the table cell to take appropriate width?
I use old version of Chrome (22.0.1229.0) and I think that it's rather a bug than incorrect styles.
In latest Chrome everything is alright.
I think that colspan="2" there is the reason.
There is no reasonable way to split that min-width between two spanned columns. So min-width constraint just get ignored on spanned cells.
Please see the response here:
Chrome, Safari ignoring max-width in table
The gist is that "max-width" only applies to block elements. So setting the table to "display: block;" should resolve the issue.

table columns does not show up in resize

I have three tables......
The first table is not given margin left.....
where as the next two tables i have given margin-left to move it slightly on the left side....
but when i resize the window i am not able to see the last column in other two tables....
how to fix it....
the first table looks fine even even after resize......
http://jsfiddle.net/x7HD9/
providing my code below
<table class="table" style="margin-left: 160px; width: 1759px;">
<thead>
<tr class="subBomListHeading subBomHeading" style="">
<th>BOM Type</th>
<th>Product P/N</th>
<th>Version</th>
<th>Brand Name</th>
<th>BOM Description</th>
<th>Generation</th>
<th>Version</th>
<th>Notes</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr style="background-color: #e5dcd1;" class=" subBom">
<td>sub BOM</td>
<td>99-00302-00</td>
<td>v.02</td>
<td>Creative</td>
<td>Hardware v1.0 System</td>
<td>G1</td>
<td>1</td>
<td>new</td>
<td><input type="radio" name="sex" value="male"></td>
</tr>
</tbody>
</table>
Try :
<table class="table" style="margin-left: 160px; width: 100%;">
Also, keep in mind that <tables> are not 'responsives' (has in 're-layout'), but still 'extensibles'.
Your table is displayed at it's minimum width, it's normal you don't see the last column, it overflows the viewport.
Im going to assume you have width: 100% set on your tables, thats your problem, they are set as the width of the window and then moved right so you cant see the last column, You should change the width to a lower value.
You have a couple problems here.
First, you've defined a fixed width to the tables. Depending on how the overflow property is set on ancestor elements, it can cause the clipping you describe because the element is too wide for that space. It's unclear as to how wide you want these elements to be, but something like this would do the trick:
table.brown {
min-width: 80%; /* or just plain `width: 80%` */
}
Ultimately, there will come a point where you won't be able to resize because the contents of the table simply won't allow it. Once your cells are down to 1 word wide, there's not much you can do to help longer words like "Description" without adding word-break: break-all.
Second, you want to use a different setting for your margins if you want to push it in a particular direction. Using auto as the value for margin-left would cause the element to shift all the way to the right.
table.brown {
margin-left: auto;
}
http://jsfiddle.net/x7HD9/3/
There's way too much CSS for me to even try and comprehend. I think starting from scratch with just a table and then gradually add CSS would be a good idea.

CSS table 100% width, td width

Edit 2:
Problem seemed to reside on "bigTable" elements th rules. Apparently th's were inheriting wrong min-width's when used on layout-template. I'm still investigating this.
Still, I'm going to give one more try for divs. One big problem was using fixed nav and dynamic content, but I already found Holy Grail -solution for this (http://alistapart.com/article/holygrail).
Thanks for suggestions & all the lovely trolololo.
Edit:
I replicated this problem to http://jsbin.com/eyitij/4/edit
I have a strange problem with table + td width. I have code similar to this:
<table class="mainLayout" style="width: 100%;">
<tr>
<td style="width: 250px;">
<div id="leftNavigationPanel"> * content * </div>
</td>
<td id="panelCell">
<div class="panel">
<table id="bigTable" width="100%"> * LOTS OF CONTENT, includes big table * </table>
</div>
</td>
<tr>
</table>
When I run this code on browsers, mainLayout is getting overflowed, so it becomes 3600px, and this happens because of big table inside Panel.
Big table I'm referring to can be contained within screen. When done so, it gets horizontal scrollbar (which is what I want). This works if big-table is loaded in separate html-file with rule "width: 100%".
After adding mainLayout a rule "display: block;", mainLayout table is rendered ~1800px and is contained within screen, but problem is that "panelCell"-TD is still ~3400px wide, so I'm still having whole page scrolling... TD isn't contained within table, but always expands to 250px + bigTable.width() !?
Basically browser doesn't know how to calculate "panelCell" to fill only : window.width - leftNavigationPanel.
Any ideas how to make right rules without using javascript + precalculated max-width rule for "panelCell"?
panelCell must be contained within window
bigTable must be contained within panelCell, with scrollbar
Setting table-layout:fixed fixes a lot of weird problems with tables :
<table style="table-layout:fixed;">
<col style="width:250px"/>
<col/>
<tr>
...

How do I specify that a html cell should have the minimum width it needs to display all of its content

In the following example,
<table style="width: 100%;"><tr>
<td>First Cell</td>
<td>Second Cell</td>
</tr></table>
How do I set the widths so that the first cell/column is exactly as wide as it needs to be to show the content of the first cell and let the second cell fill the rest of the width of the table?
I'm using a GWT HorizontalPanel to do this, so if there's either a html, css or gwt trick. Please let me know.
Thank you
Assuming that “as wide as it needs to be to show the content of the first cell” refers to width needs to show the content without line breaks, you can use something like this:
<table width=681 border><tr>
<td nowrap>First Cell</td>
<td width="100%">Second Cell</td>
</tr></table>
There is no guarantee that this will keep working, since requiring a cell to be 100% wide, yet include another cell with nonzero width, is an impossible requirement. But browsers currently do what seems to be closest to the requirement.
You could achieve the layout you’re aiming for without tables, as explained in this question:
xHTML/CSS: How to make inner div get 100% width minus another div width
HTML
<div class="two-columns">
<div class="fit-to-contents">First Cell</div>
<div class="fill-remaining-space">Second Cell</div>
</div>
CSS
.two-columns {
overflow: hidden;/* Contains descendant floats */
}
.two-columns .fit-to-contents {
float: left;
background: #ffd;
}
.two-columns .fill-remaining-space {
overflow: hidden;
background: #fdf;
}
I’m not sure if that would actually be appropriate for your use-case though, I’d need to see the context.
Tables take care of themselves in HTML. There is no need to force any cell to be any particular size.
What is it you're really trying to do?
What version of HTML are you using? (Hint: Upgrade to HTML5 and CSS!)
Just don't specify any widths at all (neither on the table nor on the cells) and use white-space: nowrap on your table cells.
Put a style of width:1px on the first cell. The table will then make the first cell as narrow as possible, without causing overflow.
Since "as narrow as possible" is the width of the word "First" in this case, you may want to throw in a white-space:nowrap too, otherwise it will display "First" and "Cell" on two lines.
Jsfiddle