With plain JavaScript, how can I get all the elements who do not have a CSS style? I need to get the rows of a table which are not hidden, and they don't have an explicit 'display' attached.
<table>
<tr class='form-row-links'>
Stuff...
</tr>
</table>
document.querySelectorAll('.form-row-links[style="display:is_not_none;"]') //pseudocode, of course :)
The css style display=none is applied after the initialisation of the page, to the <tr> element.
Thanks to #Ry- for pointing me towards the getComputedStyle
I actually thought that I could just declare an initial style of the row, which might then be overwritten by my JavaScript with 'none' or not:
<table>
<tr class='form-row-links' style='display:table-row;'>
Stuff...
</tr>
</table>
document.querySelectorAll('.form-row-links[style="display:table-row;"]')
Related
Could someone please explain to me why
$(".transaction_history_tab").hide();
will not hide both
// Container
<tbody class="transaction_history_tab">
</tbody>
// In example this is inside the transaction_history_tab container
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
After hiding transaction_history_tab the "NO DATA TO SHOW" still appears.
$(".transaction_history_tab").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
// Without table tags around
<tbody class="transaction_history_tab">
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
</tbody>
Working with the answer from Rory
$(".transaction_history_tab").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
// With table tags around
<table>
<thead>
<tr>
<td></td>
</tr>
</thead>
<tbody class="transaction_history_tab">
<tr>
<td>
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
</td>
</tr>
</tbody>
</table>
The issue is solely caused by invalid HTML. The tbody element must be contained within a table. As yours is not, it isn't rendered. You can see this if you check the DOM in the inspector. The tbody can only contain tr elements too. The child div is therefore also a problem, it should be wrapped in a tr and then a td.
As the tbody element is not rendered, and the .transaction_history_tab doesn't exist, hence there's nothing to hide.
To fix the issue correct your HTML. Either add a table around the tbody, including a tr and td around the div, or remove the tbody completely.
$(".transaction_history_tab").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>This will be shown...</td>
</tr>
</thead>
<tbody class="transaction_history_tab">
<tr>
<td>
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
</td>
</tr>
</tbody>
</table>
Maybe because structure tbody>div without a table/rows/cells is not a valid HTML structure.
Try either using a table>tbody>tr>td>div structure as in this JSFiddle https://jsfiddle.net/u58460ot
or use just the div without tbody as parent
<table>
<tbody class="transaction_history_tab">
<tr>
<td>
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
</td>
</tr>
</tbody>
</table>
try like above it will work...
You haven't included your css here, but it is possible that your css includes something like this:
.data-info-box {
visibility: visible;
}
which would need changing to:
.data-info-box {
visibility: inherit;
}
This is because a child element set to 'visible' will still show up, even if their parent is 'hidden'. Setting the visibility to 'inherit' means that the child will take on whatever visibility attribute the parent has.
'Inherit' is the default setting for visibility, so if this is the problem you would have had to manually set it to 'visible' in your css (or dynamically in your js).
I have a standard table with option to hide columns and I want to use a plugin for re-sizing the width of the columns.
I tried with colResizable and resizableColumns but the things get messy when I hide a column and then try re-sizing.
Edit: My table:
<table id="mytable">
<thead>
<tr><th class="column1"></th>text 1 <th class="column2">text 2</th></tr>
</thead>
<tbody>
<tr><td class="column1"> cell00 </td> <td class="column2"> cell01 </td></tr>
<tr><td class="column1"> cell10 </td> <td class="column2"> cell11 </td></tr>
<tr><td class="column1"> cell20 </td> <td class="column2"> cell21 </td></tr>
</tbody>
</table>
Activating colResizable:
$("#mytable").colResizable({
liveDrag:false,
gripInnerHtml:"<div class='grip'></div>",
draggingClass:"dragging",
minWidth:50
});
Function for hidding / displaying columns:
function toggleColumn(index){
if(something){
$('.column'+index).hide();
}else{
$('.column'+index).show();
}
$("#"+tableID).colResizable({
disable:true
});
$("#"+tableID).colResizable({
disable:false,
liveDrag:false,
gripInnerHtml:"<div class='grip'></div>",
draggingClass:"dragging",
minWidth:50
});
}
After each toggle i restart colResizable, so it can get the new values.
The problem comes when I re-size any columns beyond the hidden ones.
I also need the option to set default widths to each column. All suggestions are welcomed.
colResizable 1.5 is compatible with hidden columns. You can download it on http://www.bacubacu.com/colresizable
if you want to change column visibility after colResizable is already activated, those are the steps you have to follow:
call colResizable (as usual)
before you perform any DOM modifications (such as hiding a column), destroy colresizable using disable:true
change columns visibility
call colResizable again
It looks like Datatables has everything you may want.
Check out this fiddle. You get everything: Show, hide columns, resized columns, and many more cool options. And using it is very easy
$(document).ready( function () {
$('#example').dataTable( {
"option": value;
} );
} );
option 1:
Use a class name on the TD. Give the class name in a style element that is added dynamically to the document. To resize, delete the style element from the document then add again with new specifics.
option 2:
Cycle through the rows collection of the table setting style.width on .cells[0], .cells[1], ....
To hide, set style.display to none, then to unhide, inline.
I just try a table with <ol> as list elements with which it is possible to insert new table row.
<table>
<thead>
<tr>
<th>head</th>
<th>head</th>
<th>head</th>
<th>head</th>
</tr>
</thead>
<tbody>
<ol id="list">
<li><tr><td>row</td><td>row</td><td>row</td></tr></li>
</ol>
</tbody>
However, I have the problem that the element appear outside of my tables. When I add dynamically content via .append(), the formatting is not taken some elements gets removed.
Jsfiddle example
I want to use this solution for counting currently positions in an "container list".
I got a similar function like the example below for counting my lists, that's working great but the insert into the table does not work properly.
countinglists example: Nested ordered lists
Maybe its possible to achieve that counting syntax in a table without the <ol>? or is there any <ol> equivalent?
You need to do some reading on basic HTML: http://www.w3schools.com/html/html_tables.asp
Here is how it should look...
<table>
<thead>
<tr>
<th>head</th>
<th>head</th>
<th>head</th>
<th>head</th>
</tr>
</thead>
<tbody id="list">
<tr>
<td>row</td><td>row</td><td>row</td><td>row</td>
</tr>
<tr>
<td>row</td><td>row</td><td>row</td><td>row</td>
</tr>
<tr>
<td>row</td><td>row</td><td>row</td><td>row</td>
</tr>
</tbody>
In theory, you should be able to use CSS counters.
table {
counter-reset: myTableCounter;
}
thead th:first-child:before {
display: table-cell;
content: "";
}
tbody td:first-child:before {
display: table-cell;
counter-increment: myTableCounter;
content: counter(myTableCounter);
}
However, when I attempted to do that I found there were issues with display: table-cell generated content.
You may have to look at adding additional elements to the table to generate the content inside the first cell of each row.
My question is: what are you trying to achieve? Is this an exercise just to see how much can you stretch the HTML?
For your jsfiddle, the action associated to the click removes some of the HTML tags (at least on my browser) resulting in a <li>rowrowrow</li>, so you end up having a rather odd formatted-table. My renderer takes all <li> tags added by clicking as the content of a row; if you have only <li> tags, the dom parser will likely wrap them into a <ul> (it does on mine).
IMHO you don't need to use the ol to be able to count stuff. You can do it in jquery afaik. If you insist to use lists, then you probably need to style them and use e.g. divs inside (styled too). Emulating a table via a list and divs is madness imho :)
Update - for the hierarchical table
My idea would be to have something similar to this jsfiddle. I basically styled in the .sub and the .main classes. However, things get a bit more complex is you need to add some extra columns. In this case, you'd need something like a treetable.
I am trying to hide subsequent tr's with role="metadata" and the same data-group-id as the first occurring tr.
I cannot use JavaScript here and I am trying to achieve this using pure CSS.
<table>
<tbody>
<!-- BEGIN this tr should be visible -->
<tr data-group-id="1" role="metadata">
<td>
First rows group title
</td>
</tr>
<!-- END this tr should be visible -->
<tr data-group-id="1" role="data">
<td>
Row belonging to group 1
</td>
</tr>
<!-- BEGIN this tr should be hidden -->
<tr data-group-id="1" role="metadata">
<td>
Rows group title
</td>
</tr>
<!-- END this tr should be hidden -->
<tr data-group-id="1" role="data">
<td>
Another row belonging to group 1
</td>
</tr>
<!-- BEGIN this tr should be visible -->
<tr data-group-id="2" role="metadata">
<td>
Second rows group title
</td>
</tr>
<!-- END this tr should be visible -->
<tr data-group-id="2" role="data">
<td>
Row belonging to group 2
</td>
</tr>
</tbody>
</table>
Selectors like this...
[data-group-id="1"][role~="metadata"] ~ [data-group-id="1"][role~="metadata"]
display: none
... work very well, except that data-group-id may change dynamically.
Something like this would be perfect (I know that this is invalid CSS code, its just my fantasy with regular expressions to help illustrating the problem):
[data-group-id="(.*?)"][role~="metadata"] ~ [data-group-id="\\1"][role~="metadata"]
Is there any way I can achieve this using only CSS?
Thanks in advance.
Seems to me that using the data-group-id in CSS is impractical, especially since it's dynamically mutable and conditions of wether an element is hidden or not change. You end up with a huge chunk of CSS thats impossible to maintain.
In the initial rendering, it might be better to add a className so you determine serverside wether the initial state should be shown or not.
<tr data-group-id="1" role="data" class="hidden">
<td>Another row belonging to group 1</td>
</tr>
I am assuming JavaScript is used to dynamically change data-group-id, so why not use JavaScript to add/remove the className "hidden" when/where it makes sense. At least in JavaScript you CAN use regular expressions ;)
When you get to the point where you have to write impossible, long winded, error prone and unmaintainable CSS expressions, you're doing something wrong.
You're going to have to write some code to achieve this anyways, might as well do it the clean way instead of trying to shoehorn it into a styling language that isn't fit for the job.
Having an HTML page with a simple table and js code to do show / hide on it:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>title</title>
<script type="text/javascript">
function showErrorSteps()
{
var el = document.getElementById("t1");
if(el.style.display=="none")
{
el.style.display="block";
}
else
{
el.style.display="none";
}
}
</script>
</head>
<body>
<br />
<span onclick="showErrorSteps()">[click]</span>
<br />
<br />
<table id="t1" border="1" width="100%" style="table-layout: fixed">
<tr>
<td>s</td>
<td>d</td>
<td>a</td>
</tr>
</table>
</body>
</html>
What happens is that on Mozilla the table gets resized after you click twice(even with the table-layout: fixed css). IE works fine.
Tables shouldn't be set to display: block. Table rows and cells shouldn't either. They have different display values. My advice? Don't do it this way. Use a class:
.hidden {
display: none;
}
and dynamically add it and remove it from the table to avoid problems of setting the right display type on an element that you show.
Edit: To clarify the comment as to why do it this way and what's going on. Try this:
<table>
<tr>
<td>Cell 1</td>
<td style="display: block;">Cell 2</td>
</tr>
</table
It will (or should) screw up your table layout. Why because a <td> element, by default, has display: table-cell not block. Tables are the same. They have display: table.
Unsetting CSS attributes is... problematic.
Thus you are best off using classes to set and unset attributes. It's easier to change (the class resides in a CSS file and isn't code), avoids problems like setting the value back to the correct original value and generally provides a cleaner solution, especially when used with a library like jQuery. In jQuery, you can do:
$("table").toggleClass("hidden");
Done.
Or you can use addClass() and removeClass() if that's more appropriate. For example:
<input type="button" id="hide" value="Hide Table">
...
<table id="mytable">
...
and
$(function() {
$("#hide").click(function() {
if ($("#mytable").is(".hidden")) {
$("#hide").val("Hide Table");
$("#mytable").removeClass("hidden");
} else {
$("#hide").val("Show Table");
$("#mytable").addClass("hidden");
}
});
});
And there you have a robust, succinct and easy-to-understand solution (once you get your head around the jQuery syntax, which doesn't take that long).
Messing about with Javascript directly is so 2002. :-)
This is not a direct answer to your question, but a serious recommendation. I have recently discovered the joys of JQuery. All this kind of stuff can be done effortlessly and there is extensive online examples and references available.
If you haven’t got time to get into it now then I’m sure someone will offer a solution here, but I would recommend anyone who does anything beyond the most cursory JavaScript DOM manipulation to consider JQuery (or a similar framework).
JQuery offers browser independent Hide(), Show() and Toggle() methods. Here’s one of my favourite references.
This might be because you set the style.display to "block". Try to set it to "". You should also set the table width using CSS. (width: 100%;)