Apply css to tr with custom data attribute in JQuery - javascript

I have a table, each tr element has a custom data attribute and I want to apply style to certain values.
In HTML:
<table id="notify" class="t_notify">
<tr data-notify="101">
<td>data</td>
<td>data</td>
</tr>
<tr data-notify="102">
<td>data</td>
<td>data</td>
</tr>
<!-- and goes -->
</table>
With CSS:
.t_notify>tbody>tr{background:#BBB;}
.t_notify>tbody>tr:hover{background:transparent;}
I tried in Jquery to make this when I click in a certain tr element, for example:
$("#notify > tbody > tr").attr("[data-notify='101']").css({"background":"#CCC"});
But this doesn't work. I would like some help.

Good Approach
Your query must be in the selector, like so :
$("#notify > tbody > tr[data-notify='101']").css({"background":"#CCC"});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="notify" class="t_notify">
<tr data-notify="101">
<td>data</td>
<td>data</td>
</tr>
<tr data-notify="102">
<td>data</td>
<td>data</td>
</tr>
<!-- and goes -->
</table>
attr()
The attr() function returns the value of the attribute or sets it. In your case, you want neither. Hope it helps.

Your issue is that attr() is intended to be used to get/set an attribute. It doesn't filter the elements in a collection. Instead you should use the attribute selector in the primary jQuery object.
Also, just to note that in the example below I changed the highlight colour as #BBB is very hard to spot against #CCC. I also amended the code to use addClass(), as you should avoid the use of css() where possible, as it ties the JS code too closely to the UI. Finally, I amended the CSS rules so that operator precedence works for all scenarios.
$("#notify > tbody > tr[data-notify='101']").addClass('foo');
.t_notify tr {
background: #BBB;
}
.t_notify > tbody > tr:hover {
background: transparent;
}
.t_notify tr.foo {
background-color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="notify" class="t_notify">
<tr data-notify="101">
<td>data</td>
<td>data</td>
</tr>
<tr data-notify="102">
<td>data</td>
<td>data</td>
</tr>
<!-- and goes on... -->
</table>

Put the data in the selector: Demon on JsFiddle
$("#notify > tbody > tr[data-notify='101']").css({"background":"#CCC"});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="notify" class="t_notify">
<tr data-notify="101">
<td>data</td>
<td>data</td>
</tr>
<tr data-notify="102">
<td>data</td>
<td>data</td>
</tr>
<!-- and goes -->
</table>
The CSS attribute selector matches elements based on the presence or value of a given attribute.
/* <a> elements with a title attribute */
a[title] {
color: purple;
}
/* <a> elements with an href matching "https://example.org" */
a[href="https://example.org"] {
color: green;
}
/* <a> elements with an href containing "example" */
a[href*="example"] {
font-size: 2em;
}
/* <a> elements with an href ending ".org" */
a[href$=".org"] {
font-style: italic;
}
source

$("#notify > tbody > tr").attr("[data-notify='101']")
should be:
$("#notify > tbody > tr[data-notify='101']")

Related

CSS - sticky positioning of more than one row

I am trying to lock certain amount of rows to be "fixed" when scrolling a table. The problems:
1) The number of rows to be locked vary (not always only the column headers) so cannot rely on fixed number.
2) The height of each row may vary depend on content, so it is not equally height and not any known value.
3) As the table and content are dynamically created and can be modified on runtime, a responsive solution will be the best.
Given the following CSS (assume all rows in thead are to be "locked"):
thead th{ position:sticky; }
And then the JavaScript approach (tbl is the table element):
var i,j,h=0,r; // Set the "top" of next "locked" rows
for(i=0 ; i<tbl.thead.rows.length ; i++) {
r=tbl.thead.rows[i];
for(j=0 ; j<r.cells.length ; j++)
r.cells[j].style.top=h+"px";
h+=r.offsetHeight;
}
The main issue: I prefer to do it ALL using CSS (if possible).
The best "solution" I have come up can only remove the inner loop, but using dynamically controlled <style> element (assuming stl is the handle to the STYLE element):
var rules="",i,h=0; // Set the "top" of next "locked" rows
for(i=0 ; i<tbl.thead.rows.length ; i++) {
rules+="thead tr:nth-child("+(i+1)+") th{ top:"+h+"px; }\n";
h+=tbl.thead.rows[i].offsetHeight;
}
/*
I know is possible to use stl.sheet.insertRule(),
but as I overwrite ALL rules whenever there is change, I have chosen this way.
*/
stl.innerHTML=rules;
However, that requires as many rules as header rows.
The question: Any solution to make ONE RULE that can create the same effect?
Is it possible to achieve it with pure CSS (responsive solution)?
Note: The table can have any position on page, but is inside a container with overflow:auto.
Thanks a lot
There is a very easy solution, make thead sticky and not the individual rows
.container {
height: 250px;
width: 200px;
overflow: auto;
}
th {
height: 60px;
}
#second {
height: 80px;
background-color: lightblue;
}
thead {
position: sticky;
top: 0px;
}
<div class="container">
<table>
<thead>
<tr>
<th>h row 1</th>
</tr>
<tr>
<th id="second">h row 2</th>
</tr>
</thead>
<tr>
<td>data</td>
</tr>
<tr>
<td>data</td>
</tr>
<tr>
<td>data</td>
</tr>
<tr>
<td>data</td>
</tr>
<tr>
<td>data</td>
</tr>
<tr>
<td>data</td>
</tr>
<tr>
<td>data</td>
</tr>
<tr>
<td>data</td>
</tr>
<tr>
<td>l data</td>
</tr>
</table>
</div>

Use 'view more' button to enhance information on each table row

I have a pretty simple html table, there are lots of information i want to add for each row but i cant display everything when the page is loaded because it is going to make everything very clumsy. So i want to add a view more button in another column for each of the row.
I have already tried writing a JavaScript code but its not working as i want. What i want is:
The row should be completely invisible until i click the view more (i tried putting the tags inside the div but it messed everything up by putting the row outside the table entirely).
I want the code to work for all the rows so i don't have to write separate codes for each row.
I want the extended information for a row to be invisible whenever i try to view more for another row.
If possible, i would like a simple animation for showing the extended animation.
Below is my HTML code:
<table>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Action</th>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>View More</td>
</tr>
<tr>
<td colspan="3">
<div id="example" class="more">
<p>John Doe is a man</p>
<p style="text-align:right;">Hide this content.</p>
</div>
</td>
</tr>
<tr>
<td>Jane</td>
<td>Doe</td>
<td>View More</td>
</tr>
<tr>
<td colspan="3">
<div id="example" class="more">
<p>Jane Doe is a woman</p>
<p style="text-align:right;">Hide this content.</p>
</div>
</td>
</tr>
</table>
Below is my CSS:
<style type="text/css">
.more {
display: none;
}
a.showLink, a.hideLink {
text-decoration: none;
color: #36f;
padding-left: 8px;
background: transparent url(down.gif) no-repeat left;
}
a.hideLink {
background: transparent url(up.gif) no-repeat left;
}
a.showLink:hover, a.hideLink:hover {
border-bottom: 1px dotted #36f;
}
</style>
Below is my Javascript:
<script language="javascript" type="text/javascript">
function showHide(shID) {
if (document.getElementById(shID)) {
if (document.getElementById(shID+'-show').style.display != 'none') {
document.getElementById(shID+'-show').style.display = 'none';
document.getElementById(shID).style.display = 'block';
}
else {
document.getElementById(shID+'-show').style.display = 'inline';
document.getElementById(shID).style.display = 'none';
}
}
}
</script>
Since you tagged jQuery, I'm assuming you're willing to use it, so here's an example of a fix with jQuery:
EDIT: The html has changed, the second row failed to work due to the ID selector
HTML
<table>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Action</th>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>View More</td>
</tr>
<tr>
<td colspan="3">
<div id="example" class="more">
<p>John Doe is a man</p>
<p style="text-align:right;">Hide this content.</p>
</div>
</td>
</tr>
<tr>
<td>Jane</td>
<td>Doe</td>
<td>View More</td><!-- Note the change in the showHide() function -->
</tr>
<tr>
<td colspan="3">
<div id="exampleFemale" class="more"><!-- Note the change in the ID -->
<p>Jane Doe is a woman</p>
<p style="text-align:right;">Hide this content.</p><!-- Note the change in the showHide() function -->
</div>
</td>
</tr>
</table>
Javascript
function showHide(shID) {
if ($('#' + shID)) {
if ($('#' + shID+'-show').css('display') != 'none') {
$('#' + shID+'-show').css({'display':'none'});
$('#' + shID).css({'display':'block'});
}
}
else {
$('#' + shID+'-show').css({'display':'inline'});
$('#' + shID).css({'display':'none'});
}
}
Note the changes inthe Javascript -> jQuery where there used to be document.getElementById(shID+'-show') is now $('#' + shID+'-show') and where there used to be .style.display = 'none'; is now .css({'display':'none'});
Don't forget to include jQuery
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
Hope this helps!

Applying less generated css to all the html table except th elements

I have the following html code
<textarea name="mytextarea" id="mytextarea" rows="10" cols="50">
color:red;
.yellow {
color : yellow;
}
</textarea><br/>
<button id="mybutton">Parse</button><br/>
Content parsed : <br/>
<p id="parsedContent"></p>
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td>Ya</td>
<td class="yellow">Hey</td>
<td>Ho</td>
</tr>
<tr>
<th>2</th>
<td>11</td>
<td>100</td>
<td>27</td>
</tr>
<tr>
<th>3</th>
<td>sadd</td>
<td>zaa</td>
<td>ddd</td>
</tr>
</tbody>
</table>
This is used to generate some css via a user input and insert dynamically the css generated to the head of the document.
I use the folowing javascript code to generate the css with the lesscss parser:
$('#mybutton').on('click',function(){
content = 'table tbody {'+$('#mytextarea').val()+'}';
var parser = new(less.Parser);
parser.parse(content, function (err, tree) {
if (!err) {
if($('#headCss').length===0){
$('head').append('<style id="headCss"></style>');
}
css = tree.toCSS();
console.log(tree);
$('#headCss').text(css);
$('#parsedContent').text(css);
}else{
$('#parsedContent').text(err);
}
});
});
$('#mybutton').click();
I need to apply the css generated to the table but it should not be applied to the table head (column and rows).
Is there a way to do this with only pure css on the textarea (not less).
Here a jsfiddle with the code : http://jsfiddle.net/Jiwoks/Lkz0mhor/
In this exemple I don't want row headers to be red, only td elements.
Any help much appreciated
You can put this code in the js.
I just noticed that you used <th>s as the header, so the :not(:first-child) is not needed.
content = 'table tbody td {'+$('#mytextarea').val()+'}';
In the JS.
Now this code selects the tds, which prevents the .yellow class from having any effect, since it looks for an element inside the td with the .yellow class, rather than the td itself.
You can get around this by modifying the input:
color:red;
&.yellow {
color : yellow;
}
However, since you want only pure css in the textarea input, you can modify it inside the code instead. For example with this line:
content = content.replace(/^\./mg, '&.');
It replaces all dots at the start of a line with &.
http://jsfiddle.net/Lkz0mhor/3/

Injecting CSS and JavaScript in HTML code

I am new to web programming. So I have modified a code that I found online and ended up with this : jsfiddle.net/y4Mdy/673 witch works fine, all the header rows in the table are shown and the others are hidden, and then can be revealed by clicking the headers.
But When I am trying to assemble the html, CSS and JavaScript together (following the instruction found here) it does not seem to work. When I click on the headers nothing happens, the other rows are not revealed.
Here is the content of my html file :
<html>
<head>
<script type="text/javascript">
$('.header').click(function () {
$(this).find('span').text(function (_, value) {
return value == '-' ? '+' : '-'
});
$(this).nextUntil('tr.header').slideToggle(100, function () {});
});
</script>.
<style>
table, tr, td, th {
border-collapse:collapse;
}
tr {
display: none;
}
table {
margin-left:auto;
margin-right:auto;
text-align:center;
}
tr.header {
cursor:pointer;
display: table-row;
}
</style>.
</head>
<body>
<table>
<tr class="header">
<th><span>+</span> Header</th>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr class="header">
<th><span>+</span> Header</th>
</tr>
<tr>
<td>date</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
</table>
</body>
</html>
You want to load jQuery first, like other people are saying, and you may also want to put your code inside the 'ready' function, since you're running the code at the top of the page. That way, you can make sure your whole page is loaded before the code runs.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript">
$( document ).ready(function() {
// Handler for .ready() called.
$('.header').click(function () {
$(this).find('span').text(function (_, value) {
return value == '-' ? '+' : '-'
});
$(this).nextUntil('tr.header').slideToggle(100, function () {});
});
});
</script>.
<style>
table, tr, td, th {
border-collapse:collapse;
}
tr {
display: none;
}
table {
margin-left:auto;
margin-right:auto;
text-align:center;
}
tr.header {
cursor:pointer;
display: table-row;
}
</style>.
</head>
<body>
<table>
<tr class="header">
<th><span>+</span> Header</th>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr class="header">
<th><span>+</span> Header</th>
</tr>
<tr>
<td>date</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
</table>
</body>
</html>
See info here:
http://api.jquery.com/ready/
Also, keep in mind that in the above example, you're loading jQuery from the internet. You may want to download it locally and load it from within your local directory, depending on your situation. For your purposes, though, as long as you have an internet connection, you're probably fine to do it by linking from the internet.
You are using jQuery in your code, but you forgot to include the jquery files !
Add this in your html :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
Import jquery library first
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

Style on colgroup not working

I have following colgroup not working properly.
<colgroup class="" style="background-color:#FF0000;"></colgroup>
Please see this jsfiddle. My styles on colgroup not working.
Most properties that you can set on colgroup won’t have an effect, since by definitions, table cells inherit properties from tr elements (rows), not columns or column groups (to the extent that there is inheritance).
Set, in CSS, the properties directly on the cell elements. For example, to set the background color of the first two columns, assuming that only td markup is used for the cells, use
td:first-child, td:first-child + td {
background: #f00;
color: #fff;
}
Here is an example of colgroup:
<html> <body>
<table width="100%" border="1"> <colgroup style="background-color:#22FF22;"></colgroup> <colgroup style="background-color:#888888;"></colgroup> <colgroup style="background-color:#FF0000;"></colgroup>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
</tr>
<tr>
<td>D</td>
<td>E</td>
<td>F</td>
</tr>
<tr>
<td>G</td>
<td>H</td>
<td>I</td>
</tr>
</table>
</body> </html>
if your code is bit different show us the more code to repy appropriately..

Categories