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

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.

Related

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 apply CSS rules after a certain tag

As the title states, I have the following HTML which looks as the following:
<div id="content">
<main>
<h2 > Example Title</h2>
<p>Hello World</p>
<table class="table table-striped table-responsive-md btn-table">
<tr>
<td>Example 1 </td>
<td>Example 2</td>
</tr>
</table>
</main>
</div>
After the <h2> example title I would like to apply the CSS rule: margin-top:20px;, margin-bottom:20px, to all the other tags which are <p>, <table>.
How do I do it?
You can create a class and add it to all the elements after the h2. For example:
.example{
margin-top: 20px;
margin-botton:20px;
}
OR
you can give the margin-top: 20px and margin-botton:20px to all the elements and exclude the h2 by giving it an id. For example:
#example{
margin: 0;
}
There are (at least) two ways of going about this without changing the HTML.
The first way is to say, "Get me all of the children of main that are not the h2.
The other way, inspired by a comment by chriskirknielsen, is to use the General Sibling Combinator and get all of the siblings of the h2.
Of course, both of these assume that it is "all elements at the same level" that you want and not "all elements at the same level after a specific point in the DOM" because the latter is simply not possible.
main > *:not(h2) {
margin-top:20px;
margin-bottom:20px;
border-top: 1px solid red;
}
/* OR */
h2 ~ * {
margin-top:20px;
margin-bottom:20px;
border-bottom: 1px solid green;
}
<div id="content">
<main>
<h2 > Example Title</h2>
<p>Hello World</p>
<table class="table table-striped table-responsive-md btn-table">
<tr>
<td>Example 1 </td>
<td>Example 2</td>
</tr>
</table>
</main>
</div>
Since the question has also the Javascript tag, here it is a Javascript solution.
Let's see again your HTML. onload we call the applyStyleChanges() function:
<body onload="applyStyleChanges()">
<div id="content">
<main>
<p>Unaffected</p>
<!-- ... -->
<h2 > Example Title</h2>
<p>Hello World</p>
<table class="table table-striped table-responsive-md btn-table">
<tr>
<td>Example 1 </td>
<td>Example 2</td>
</tr>
</table>
</main>
</div>
</body>
Function applyStyleChanges() can be defined as shown below:
<script>
function applyStyleChanges()
{
var node = document.getElementsByTagName("h2")[0];
while(node = node.nextSibling)
{
if(node.nodeType == 1)
{
node.style.marginTop = "20px";
node.style.marginBottom = "20px";
}
}
};
</script>
Explanation
We get our "boundary" element. In this case it is the first h2
We loop on node.nextSibling until the end of the sibling list is reached
For every sibling we choose only those of type "1" (element nodes)
For every chosen element we apply the desired set of node.style assignments
All the siblings before our "boundary" element are unaffected
Please note how margin-top and margin-bottom properties are accessed through marginTop and marginBottom respectively. In JS properties dash are removed and a camel case notation is used
You can just
p{
margin-top: 20px;
margin-botton:20px;
}
OR
you can give class names to the tags for ex:- <p class='someClass'> and in the css select that particular tag by
.someClass{
margin-top: 20px;
margin-botton:20px;
}
Use the :not() selector
main:not(h2) {marginstuff}
it will exclude h2 but be applied to everything else in main
https://developer.mozilla.org/en-US/docs/Web/CSS/:not

Scroll to particular postion inside a table

I have a table which may have more than 100 rows
So i have used Scroll class giving fix height..
I have a radio button inside a table
Problem is when the table is rendered suppose a row No 50 is selected by default , it must go to that position by default
Every row has a respective class given by the row code..
I just want to scroll it to particular class.
The scroll is for the particular div.which i need to go to particular class inside table
HTML
<table class="table-scroll">
<tr class="radio1"><td>1</td></tr>
<tr class="radio2"><td>2</td></tr>
<tr class="radio3"><td>3</td></tr>
</table>
CSS
.table-scroll{
max-height:500px;
overflow-x:hidden;
overflow-y:scroll;
margin-bottom:20px;
border-top:1px solid #ccc;
border-bottom:1px solid #ccc;
}
JS
<script>
How to scroll to particular class suppose radio3??
</script>
You need scrollIntoView(options) to scroll the element into the view. Refer the docs for how to pass options object and for browser compatibility.
function scrollto()
{
var selectedclass = "radio15";
var table = document.getElementById("test");
var elem = table.getElementsByClassName(selectedclass)[0];
elem.scrollIntoView();
}
.table-scroll
{
max-height:100px;
overflow-y:scroll;
border:1px solid #000;
display:block;
}
<table class="table-scroll" id="test">
<tbody>
<tr class="radio1"><td>1</td></tr>
<tr class="radio2"><td>2</td></tr>
<tr class="radio3"><td>3</td></tr>
<tr class="radio4"><td>4</td></tr>
<tr class="radio5"><td>5</td></tr>
<tr class="radio6"><td>6</td></tr>
<tr class="radio7"><td>7</td></tr>
<tr class="radio8"><td>8</td></tr>
<tr class="radio9"><td>9</td></tr>
<tr class="radio10"><td>10</td></tr>
<tr class="radio11"><td>11</td></tr>
<tr class="radio12"><td>12</td></tr>
<tr class="radio13"><td>13</td></tr>
<tr class="radio14"><td>14</td></tr>
<tr class="radio15"><td>15</td></tr>
<tr class="radio16"><td>16</td></tr>
<tr class="radio17"><td>17</td></tr>
<tr class="radio18"><td>18</td></tr>
<tr class="radio19"><td>19</td></tr>
<tr class="radio20"><td>20</td></tr>
</tbody>
</table>
<button id="scroll" onclick="scrollto()">Scroll to radio15</button>
<tr class="radio3" id="radio3"><td>3</td></tr>
<script>
$(window).load(function(){
top.location.href = '#radio3';
});
</script>
I think it is heplful to you

( css ): can i trigger two of css events simultaneously by just triggering one event or the class name that two of events are included?

This is an image of description.
i want two of zones background to get yellow background. but it only works when mouse on "This is Actual zone", and it doesn't work on "section_tr_inbody zone"
In section_tr_inbody zone, yellow background only partially...working
what is problem with my code?
(CSS)
#Actual {
padding: 20px;
font-weight: bold;
}
.together:hover {
background-color: yellow;
}
(HTML)
(...)
<tr id="section_tr_intbody" class="together">
(...)
(...)
<div class="Slider slideup">
<div id="Actual" class="together">
(...)
each of two elements have same class name 'together' which i thought it should be fine that 1) css catch one of those elements then, 2) it applying effect to both of them at the same time
on Actual side, css catch <div id="Actual" class="together"> then apply effect both.
on the other hand,
on <tr id="section_tr_intbody" class="together"> side, css catch <tr id="section_tr_intbody" class="together"> but it apply effect not including Actual side.
thanks
I don't think this can be done with only CSS since you can't traverse up the DOM with CSS.
You can do this fairly easy with jquery though:
$('.together').hover(function() {
$('.together').addClass('yellow');
},
function(){
$('.together').removeClass('yellow');
});
#Actual, #fake, #random {
padding: 10px;
font-weight: bold;
}
td { padding: 10px; }
.yellow {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr id="section_tr_intbody" class="together">
<td>Table cell stuff</td>
</tr>
<tr id="section_tr_intbodyagain" class="nottogether">
<td>More table cell stuff</td>
</tr>
<tr id="section_tr_intbodystill" class="together">
<td>Even more table cell stuff</td>
</tr>
</table>
<div class="Slider slideup">
<div id="Actual" class="together">
Div stuff
</div>
<div id="fake" class="nottogether">
more Div Stuff
</div>
<div id="random" class="together">
Even more Div Stuff
</div>
</div>

Removing whitespace in collapse row

Bootply: http://www.bootply.com/N8lH48VBN7
I have rows where I want each row to expand to show additional rows but I'm having trouble getting rid of the whitespace even when the hidden row is not expanded. I think there might be a way to write a function in JS, but is there a faster and easier way to do this?
Also, when the collapsed rows are expanded, there is some whitespace, and I tried to change some properties of the div to no avail.
Bootstrap has a css style itself.
(so, if you want to apply your css style, you have to use '!important' keyword in your css.)
and, your code structure is not good as well.
therefore, it made a little space inside of each table row.
I think you want to do like this. :)
[RESULT] http://www.bootply.com/0QqWzFcwWo#
1. HTML Source
<div class="col-lg">
<div class="project" id="prodemo"></div>
<table class="table table-striped table-hover">
<thead align="center">
<tr>
<th width="1%"> </th>
<th width="24%">ID</th>
<th width="25%">Name</th>
<th width="25%">Phone</th>
<th width="25%">DOB</th>
</tr>
</thead>
<tbody>
<!-- [demo] -->
<tr class="prevent_drag" data-target="#demo" data-toggle="collapse">
<td> </td>
<td>MyID</td>
<td>MyName</td>
<td>MyPhone</td>
<td>MyDOB</td>
</tr>
<tr id="demo" class="collapse myOptions">
<td> </td>
<td>Details</td>
<td>Details2</td>
<td>Details3</td>
<td>Details4</td>
</tr>
<!-- [demo2] -->
<tr class="prevent_drag" data-target="#demo2" data-toggle="collapse">
<td> </td>
<td>MyID</td>
<td>MyName</td>
<td>MyPhone</td>
<td>MyDOB</td>
</tr>
<tr id="demo2" class="collapse myOptions">
<td> </td>
<td>Details</td>
<td>Details2</td>
<td>Details3</td>
<td>Details4</td>
</tr>
<!-- [demo3] -->
<tr class="prevent_drag" data-target="#demo3" data-toggle="collapse">
<td> </td>
<td>MyID</td>
<td>MyName</td>
<td>MyPhone</td>
<td>MyDOB</td>
</tr>
<tr id="demo3" class="collapse myOptions">
<td> </td>
<td>Details</td>
<td>Details2</td>
<td>Details3</td>
<td>Details4</td>
</tr>
</tbody>
</table>
</div>
2. CSS source
.myOptions {
padding: 0 !important;
margin: 0 !important;
color: red;
}
.table th {
cursor:default;
}
.prevent_drag {
cursor:pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
See this bootply
Just add this css and stay away from !important as other answers suggest.
.table>tbody>tr>td[colspan] {
padding: 0;
}
.table>tbody>tr>td[colspan] .table {
margin-bottom: 0;
}
Never use !important
Almost all answers here suggest to use !important. I think all of them need to read about CSS Specificity and stop using !important today.
...Or you could add this JS code:
$("td[colspan]").css("padding", "0");
$(".table").css("margin-bottom", "0");
Here is the Bootyply
Or can use pure CSS like this:
td[colspan]{
padding:0 !important;
}
.table{
margin-bottom:0 !important;
}
CSS Only Bootply
Use below code in css
tr td{padding: 0!important;}
Thanks With Regards
Remove padding-top and padding-bottom only from your collapsed rows. This padding is coming from bootstrap table style.
tr:not([data-toggle]) > td { padding-top: 0px; padding-bottom: 0px; }
Selecting the cells which are children of rows which do not carry an attribute called data-toggle.
There is margin in the nested table as well. You can remove that:
.table tr:not([data-toggle]) table,
.table tr:not([data-toggle]) td {
padding: 0; margin: 0px;
}
Use this CSS style
tr[data-toggle="collapse"] + tr td {
padding: 0 !important;
}

Categories