change table column width - javascript

I'm using react library that constructs table in the following template:
<div class="table-container" style="width:100%">
<table style="width:100%">
<thead>
<tr>
<th>BLA_Column</th>
</tr>
</thead>
</table>
<table style="width:100%">
<tbody>
<tr>
<td>BLA_Body</td>
</tr>
</tbody>
</table>
</div>
I'm able to set the width of the th and the td to auto, but, the result is that I get two different sizes (one for the th and one for the td).
When I try to use the following selector (for example), nothing happens:
table > thead > th {
width: 100px;
}
Also when I try to change directly the width using the chrome dev-tools, there is no change at all.
Thanks ahead!

CSS character > select only direct childs. Change your CSS with :
table > thead th {
width: 100px;
}
or
table > thead > tr > th {
width: 100px;
}

Related

Puppeteer - thead overlapping on page break ONLY when thead is cut off by footer on previous page

What I am trying to do?
I am using Puppeteer to convert raw HTML to PDF. I have saved the HTML code in a file, and I'm reading from that file and converting it to PDF.
What is the problem
The thead is NOT overlapping on every page, NO.
It is ONLY overlapping when a thread has multiple rows and half of it gets cut off because of the page break. On the next page, the remainder of the thead is printed ALONG with the overlapped entire thead.
Here is the Output of the converted PDF Overlapping thead
<table id='TblCustomerRating' class='display unbreakable' border='1' cellspacing='0' cellpadding='0'
style=' width: 100%;border-collapse:collapse;'>
<thead>
<tr>
<th class='Greyheader' align="center" style="padding-top: 5px; padding-bottom: 5px;" colspan="4">Askari
Cement Limited</th>
</tr>
<tr>
<th class='Greyheader' align="center" style="padding-top: 5px; padding-bottom: 5px;" colspan="4">External
Rating</th>
</tr>
<tr class='Greyheader'>
<th width="12%" align="center" class='Greyheader'><b> ECAI</b> </th>
<th width="12%" align="center" class='Greyheader'><b>Long Term</b></th>
<th width="12%" align="center" class='Greyheader'><b>Short Term</b></th>
<th style='display:none' width="12%" align="center" class='Greyheader'><b>Rating Date</b></th>
</tr>
</thead>
<tbody>
<tr id="4" type="data" LT="" ST="" MT="" class=" GreyBorder">
<td width="10%" agencyCode='4' class='GreyBorder'
style='background-color:lightgray;text-align: center;padding-top: 5px;padding-bottom: 5px;font-weight: bold;width:10%;'>
JCR-VIS</td>
<td width="10%" RsCode='35' class='GreyBorder' align="center">A</td>
<td width="10%" RsCode='' class='GreyBorder' align="center"></td>
<td align="center" style='display:none' class='GreyBorder'></td>
</tr>
</tbody>
</table><br />
What I have tried?
I have tried adding the following CSS: (it didn't work)
table { overflow: visible !important; }
thead { display: table-header-group !important; }
tr { page-break-inside: avoid !important; }
NOTE:
I repeat, the overlapping is not occurring when the table rows are cut off from page-break. It is ONLY overlapping when thead is cut off because of the page break. as shown in the image above.
Puppeteer version
1.19.0
Node.js version
v16.13.0
npm version
8.1.0
What operating system are you seeing the problem on?
Windows
I think I had the same issue. It is when you have a repeating table header (thead { display: table-header-group }) and the table breaks for printing between tr tags within thead. I couldn't find a way to do it with only the break-after, break-before or break-inside properties. This is a bit of a hack, but here is how I fixed it:
:root {
--header-height: 60px;
}
th {
break-inside: avoid;
}
thead th::after {
content: '';
display: block;
height: var(--header-height);
margin-bottom: -var(--header-height);
break-inside: avoid;
}
The height and negative margin-bottom are equal to the height of the tr elements below the first tr. In my code I just have 60px and -60px hard coded in, but I wanted to be clear that depending on the height of your table header that you will have to change those values. The height creates the size of element that can't be broken inside by a page break and the negative margin-bottom brings back up the table content so that it is not impacted by the existence of the pseudo-element. It essentially forces the header to be on the next page.
face the same problem.
You may put the content of <td> into <div> tag.

Show last table column on line hovering

In a centered table is the last column hidden.
On hovering over a specific line I want the table to show the last column of this single line.
This should be offering the ability to edit and delete (AJAX) the content/object of the line.
Here's a example:
https://jsfiddle.net/5x2wv160/1/
The problem is the changed size of the table so it is moving a little bit to the left.
My idea fixing this is to change the last column to
tr > td:last-child {
position: relative;
}
But what base element do I have to set the display-style too?
Does anyone have any better ideas?
Check this way of showing the last column on hover to <tr>
.action {
display: none;
}
tr:hover .action{
display: block;
}
<table>
<thead>
<tr>
<th>One</th>
<th>Two</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Content1</td>
<td>Content2</td>
<td class="action">Edit</td>
</tr>
<tr>
<td>Content3</td>
<td>Content4</td>
<td class="action">Edit</td>
</tr>
<tr>
<td>Content5</td>
<td>Content6</td>
<td class="action">Edit</td>
</tr>
</tbody>
</table>
You can use visibility instead of dispay:none like this:
table {
margin: 0 auto;
}
tr > td:last-child {
visibility: hidden;
}
tr:hover > td:last-child {
visibility: visible;
}
You are on the right way. But how about only showing contents thus the hyperlink on hover. tr td a { display:none; } VS tr:hover td a{ display:block} so the content would not be moving left and right. Also setting standard widths for each table column would prevent that the columns are moving

convert rows of html table into bootstrap cards

I have html table with rows like below:
<table id="tb" class="table table-bordered table-hover table-condensed">
<thead>
<tr>
<th>title</th>
<th>price</th>
<th>discount</th>
<th>image</th>
</tr>
</thead>
<tbody>
<tr>
<td>PRODUCT 1</td>
<td align="right">24.43</td>
<td align="right">53</td>
<td>https://images-na.ssl-images-amazon.com/images/I/81xV%2BD1OkGL._AC_SL1500_.jpg</td>
</tr>
<tr>
<td>PRODUCT 2</td>
<td align="right">50.27</td>
<td align="right">70</td>
<td>https://images-na.ssl-images-amazon.com/images/I/61d-BO4sARL._AC_SL1500_.jpg</td>
</tr>
<!-- ... many other rows -->
<!-- I added this script to put the image link inside src -->
<script>
$('#tb td:nth-child(4n)').each((i, el) => {
$(el).wrapInner(`<img src="${el.innerText}" class="img-fluid"/>`);
});
</script>
I want to convert each row to a bootstrap card
I tried to give each the bootstrap class class="card" using jquery:
$('#tb tr').addClass("card")
it didn't worked, returns each row on top of each other
I want results like this:
It's pretty hard to take HTML code and use javascript to convert that into some other complicated format. If you want to do everything manually, you can make the cards by hand with HTML. However, I suggest using a database and PHP to programmatically create those cards or tables with the data in the database.
Here is some information about how to create those Bootstrap cards: https://getbootstrap.com/docs/4.0/components/card/
Here is some information about how to use databases and PHP to create those cards automatically: https://www.phpzag.com/create-bootstrap-cards-with-php-and-mysql/
The thing which you are trying to achieve makes no sense. I myself came across this dilemma of converting a table into a card but after some quick search I got to know, this makes no sense.
Think of it like transformers. Table and card are two different transformers and they cannot be converted into each other until and unless we you brute force.
You can convert the table into cards. I have done this in the WordPress admin tables. Though I have not done it into bootstrap.
Here is a way to do with straight CSS.
First remove the table header and footer (if you have one).
thead, tfoot {
display: none;
}
Then remove the background of the table
table {
background: none !important;
border: none !important;
}
Change your rows so that they display as a card:
make them inline-block so they will appear on the same row but as a full container
add a background, border, padding and shadow to style it
tr {
display: inline-block;
padding: 1rem 0.5rem 1rem 0.5rem;
margin: 1.5rem;
border: 1px solid grey;
border-radius 10px;
box-shadow: 0 0 10px;
}
Make the cells appear on their own rows
td {
display: block;
}
If you want to add labels to the cell data you can use ::before and use a specific CSS attribute selector. For example, in my WordPress admin tables the column names are added to each cell with the attribute "data-colname".
td[data-colname="Guardian"]::before {
content: "Guardian :";
}
Here is an example of my WordPress table as cards:
(And as you can imagine, you can't easily alter a WordPress admin table -- you work with what you get).
Don't need to write single line of CSS code for hide thead or tfoot. first you need to know about replaceWith() method in jQuery & replace() method in JavaScript. So just pull the table contents as a string and run a simple string replace. And add Bootstrap classes as you want for card design.
Helpful Links
https://stackoverflow.com/a/9230045/7052927
https://api.jquery.com/replacewith/
https://www.w3schools.com/jsref/jsref_replace.asp
$(document).ready(function () {
$("#tb thead, #tb tfoot").remove(); //Remove element
$("#tb").find('td').removeAttr("align"); // Remove attribute
$('#tb').replaceWith($('#tb').html()
.replace(/<tbody/gi, "<div id='tb' class='row row-cols-2 row-cols-md-3 row-cols-lg-4 g-3' ")
.replace(/<tr/gi, "<div class='col'> <div class='card'> <div class='card-body text-center' ")
.replace(/<\/tr>/gi, "</div></div></div>")
.replace(/<td/gi, "<div")
.replace(/<\/td>/gi, "</div>")
.replace(/<\/tbody/gi, "<\/div")
);
// each loop for card layout
$("#tb .card").each(function() {
$(this).find('.card-body div:first-child').addClass('h6 fw-bold text-primary'); // Change product style
var imgPath = $(this).find('.card-body div:last-child');
$(this).find('.card-body').before(`
<div class="ratio ratio-4x3">
<img src="`+ imgPath.text()+`" class="card-img-top1 p-2 w-auto mx-auto start-0 end-0" alt="...">
</div>
`);
imgPath.remove() // After pick text then remove
});
});
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container py-3">
<table id="tb" class="table table-bordered table-hover table-condensed">
<thead>
<tr>
<th>title</th>
<th>price</th>
<th>discount</th>
<th>image</th>
</tr>
</thead>
<tbody>
<tr>
<td>PRODUCT 1</td>
<td align="right">24.43</td>
<td align="right">53</td>
<td>https://images-na.ssl-images-amazon.com/images/I/81xV%2BD1OkGL._AC_SL1500_.jpg</td>
</tr>
<tr>
<td>PRODUCT 2</td>
<td align="right">50.27</td>
<td align="right">70</td>
<td>https://images-na.ssl-images-amazon.com/images/I/61d-BO4sARL._AC_SL1500_.jpg</td>
</tr>
</tbody>
</table>
</div>

How to dynamically modify CSS class using Javascript / jQuery with wrapper?

I have an existing html code of table.
eg.
<div class="content-entry">
<table class="old-style" border="3">
<tr align="middle">
<td style="font-weight:bold"></td>
</tr>
</table>
</div>
I would like to conditionally remove all attributes/classes of the current table with the injection of a wrapper <div> and apply css class style to override the existing table behavior using Javascript / jQuery.
conten-entry might have multiple table blocks, and I would like to apply the same style change to all of them.
to:
<div class="content-entry">
<div class="responsive-table">
<table class="table table-bordered table-condensed">
<tr>
<td></td>
</tr>
</table>
</div>
</div>
How can I do this without changing the original html code?
Use .wrap, wraps an HTML structure around each element in the set of matched elements
$('.old-style').wrap('<div class="responsive-table"></div>').removeClass().addClass('table table-bordered table-condensed');
.responsive-table {
color: red;
}
.table {
font-weight: bold;
}
.table-bordered {
border: 2px solid black;
}
.table-condensed>tbody>tr>td,
.table-condensed>tbody>tr>th,
.table-condensed>tfoot>tr>td,
.table-condensed>tfoot>tr>th,
.table-condensed>thead>tr>td,
.table-condensed>thead>tr>th {
padding: 5px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="content-entry">
<table class="old-style">
<tr>
<td>Hello</td>
</tr>
</table>
</div>
Note: Calling .removeClass with no arguments will remove all of the item's classes.

Produce horizontal scroll for table 'tbody'

I have a traditional table with thead, tbody,etc. This is necessary for tablesorter.js.
What I have:
<div id="tableWrapper">
<div id="tableContainer" class="tableContainer">
<table id="scrollTable">
<thead class="fixedHeader">
<tr class="tableHeader even">
<th class="header">
<span>Name</span>
</th>
<th class="header">
<span>Address</span>
</th>
</tr>
</thead>
<tbody class="scrollContent">
<tr class="tableRow">
<td class="td_0">
<span>
Doe, John
</span>
</td>
<td class="td_0">
<span>
Memory Lane
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
CSS:
#tableWrapper tbody{
color:#00467f;
font-weight:500;
position:absolute;
overflow-y: auto;
overflow-x: scroll;
height:300px;
width:300px;
}
#tableWrapper #tableContainer{
width: 1100px;
overflow: hidden;
}
#tableWrapper tbody>tr{
width: 1200px;
}
I am keeping the table header section vertically fixed, so tbody position is absolute to keep the table header outside the tbody vertical scroll event. I tried setting the width of the tbody>tr to something higher than the tbody but no luck.
The tbody>tr width automatically shrinks to the size of the tbody.
Problem: I can't get the tbody horizontal scrollbar to scroll without horizontally scrolling the entire table, (thus the vertical scrollbar would disappear into the overflow:hidden). I want to just scroll the tbody horizontally and then I have some jquery to bind that event to the header. So no issue there. Just trying to get the horizontal scrollbar to scroll for tbody only.
I am able to get the tbody overflow-y:auto to work, but not overflow-x:auto. Is there a way to make the tr wider to get the tbody to scroll left and right? If so, how?
Ah I figured it out.
I added float:left; and display:block to the tbody>tr.
CSS:
#tableWrapper tbody>tr{
display:block;
float:left;
width: 1200px; /*desired width*/
}

Categories