HTML's Table TD with default value - html

Is there any way to fill the empty <td></td>, if data does not exist in this?
<table><tr><td></td><td>1</td><td></td></tr></table>
Change it to:
<table><tr><td>Not Data</td><td>1</td><td>No Data</td></tr></table>

Not with HTML itself.
Usually you would do this by generating the HTML using a data in a programming language and a template, with template logic used to insert a default value if none came from the data.

A little bit hackish, because it changes only visual aspect. You can do that with CSS:
table, td {border: 1px solid black; padding: 4px; border-collapse: collapse}
td:empty::before {content: "No Data"}
<table>
<tr>
<td></td>
<td>Real data</td>
<td></td>
</tr>
</table>

Won't really work just with html.
it depends on how you build your HTML-DOM. If it is just a pure HTML-file (*.html ) you could check for value by adding some JavaScrit/JQuery.
But if you are trying to do this, make sure to give your table/tr or td to give element-ids.
<table>
<tr id="1">
<td id="1_1"></td>
<td id="1_2">1</td>
<td id="1_3"></td>
</tr>
</table>
<script type="text">
/* For the amount of rows */
for(var outeri = 1; outeri <= 1; outeri++)
{
/* For the amount of columns */
for(var ineri = 1; ineri <= 3; ineri)
{
var innertd = String(outeri + '_' + ineri);
if(document.getElementById(inntertd).innerHTML == '')
{
document.getElementById(inntertd).innerHTML = 'No Data';
}
else {continue;}
}
}
</script>
This example is not very realistic and more likely not to be done unless your table is just static.

you can add an empty space:

This can be achieved in many ways, here are 2 (c# and jquery)
Solutions:
c#:
Use razor as in the following:
<table>
<thead>
<tr>
<td>Name</td>
<td>Date</td>
</tr>
</thead>
<tbody>
<tr>
#{
if(data)
{
<td>#data.name</td>
<td>#data.date</td>
}
else
{
<td colspan="2">NO DATA</td>
}
}
</tr>
</tbody>
</table>
jQuery:
Select the table and change the html depending on if there is any data
$(document).ready(function()
{
var table = $("table-selector");
var isData = $("data-selector").length;
if(!isData){
table.html("customize HTML right here, considering 'colspan' in case
there is a headers row as well")
}
});

Related

How to find if parent row has child rows in a html table

I have the following incomplete code :
if (tr.attr('data-depth') == 0 && **tr.children()** {
}
The double star marked above is incomplete.
In the above code, what i want to achieve is check for a parent row( that i am doing by checking tr.attr('data-depth')==0) and then check if that parent row has any child rows and if no child rows are present for that parent row ,then remove a custom class which i am doing between the curly braces.
How to achieve the same?
Any code sample would be very helpful.
You can check the parent row has any row as child with find('tr') and check anything has been found with .length
This code is an example. You can modify it according to your needs.
$('tr[data-depth = 0]').each(function(){
if( $(this).find('tr').length > 0)
$(this).css('background-color','red')
})
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr data-depth = 0>
<td>
<table>
<tr>
<td>
1
</td>
</tr>
<tr>
<td>
2
</td>
</tr>
</table>
</td>
</tr>
<tr data-depth = 0 >
<td>
3
</td>
</tr>
<tr>
<td>
4
</td>
</tr>
</table>
For easier expression you must select your exact tr element
let my_row = // Your target row
if( $(my_row).data('depth') == 0 && $(my_row).find('tr').length > 0)
{
// Do something
}

Is there any way to clear/hide the first td in a two td table, without access to the first td?

Is there any way to clear or hide the contents of the first td, from the second td in a two column table, without any edit access to the actual td's?
So I'd like to hide the numbers in the table below
<table>
<tr>
<td>1.</td>
<td>Content</td>
</tr>
<tr>
<td>2.</td>
<td>More content</td>
</tr>
<tr>
<td>3.</td>
<td>Even more content</td>
</tr>
</table>
This is in a vendor-supplied application that spits out the coded page. The only access is the ability to add code in the Content section (second td in each row).
I've tried to use a div tag with some absolute positioning and just cover the first td with the second, but I could never get it to work consistently.
With CSS Selectors
If your page has only one table you could use CSS selectors. In your case you need to add a style that targets <td> tags that don't have a previous <td> sibling.
td {
/* hide the first td element */
display: none;
}
td + td {
/* display all td elements that have a previous td sibling */
display: block;
}
If you are only able to add content within the second <td> of each row then adding a whitespace stripped version of the above code within style tags to the first one will probably work, but could have messy side effects if there is more than one table on your page.
<table>
<tr>
<td>1.</td>
<td><style>td{display:none;}td+td{display:block;}</style>Content</td>
</tr>
<tr>
<td>2.</td>
<td>More content</td>
</tr>
<tr>
<td>3.</td>
<td>Even more content</td>
</tr>
</table>
With JavaScript
If you have more than one table on your page, try inserting an empty <div> with a unique ID into the first <td>'s content. Immediately after place a script that targets the closest <table> parent of that ID, from which you can extract the necessary <td>s to hide. Additionally, you need to make sure you only run the code once the page is loaded, otherwise it may not pick up any trs etc beyond where the script is implemented.
The easiest way to find the nearest parent that is <table> is by using closest but this isn't supported in Internet Explorer. This post has a good solution (parent only) that I'll use.
The complete script:
window.onload = function() {
function getClosest( el, tag ) {
tag = tag.toUpperCase();
do {
if ( el.nodeName === tag ) {
return el;
}
} while ( el = el.parentNode );
return null;
}
var table = getClosest( document.getElementById( 'unique-id' ), 'table' );
var trs = table.getElementsByTagName( 'tr' );
for ( var i = 0; i < trs.length; i++ ) {
trs[ i ].getElementsByTagName( 'td' )[ 0 ].style.display = 'none';
}
}
Including the <div> with a unique ID, stripping whitespace and adding the <script> tags, your table would look something like:
<table>
<tr>
<td>1.</td>
<td><div id="unique-id"></div><script>window.onload=function(){function getClosest(el,tag){tag=tag.toUpperCase();do{if(el.nodeName===tag){return el;}}while(el=el.parentNode);return null;}var table=getClosest(document.getElementById('unique-id'),'table'),trs = table.getElementsByTagName('tr');for(var i=0;i<trs.length;i++){trs[ i ].getElementsByTagName('td')[0].style.display='none';}}</script>Content</td>
</tr>
<tr>
<td>2.</td>
<td>More content</td>
</tr>
<tr>
<td>3.</td>
<td>Even more content</td>
</tr>
</table>

(asp.net MVC5) change background color of a tables based on what a method called profibility returns

hey i have this view in my mvc application. If you look at the "tr" where it says "lönsamhet: " and then a method is executed which counts and returns the profilbility of the project. and if the profibility method returns a number bigger than 20% i want the table background color to turn green. and if less than 20% i want it to turn red... How can i do that? and my model is a list of a object i made called project. css is not my best side so would appricieate help. thanks.
#model List<Blogg.Models.BlogPost>
#foreach (var item in Model)
{
<div>
<table style="font-family: Arial; border:1px solid black; width: 1000px; height: 20px">
<tr>
<td><b>Projekt Numer: </b>#item.ID</td>
</tr>
<tr>
<td><b>Projekt Namn: </b>#item.name</td>
</tr>
<tr>
<td><b>Kund Namn: </b></td>
</tr>
<tr>
<td><b>Lönsamhet: </b>#item.profitability()</td>
</tr>
<tr>
<td><b>#ViewBag.Basecamp</b></td>
</tr>
<tr>
<td>#Html.ActionLink("Detaljer", "Details", new { id = item.ID })</td>
</tr>
</table>
</div>
Could you not use JQuery?
<td class="profit"><b>Lönsamhet: </b>#item.profitability()</td>
if(variableName > 20){
$('.profit').css("background-color","green");
}
else{
$('.profit').css("background-color","red");
}
For multiple fields do a jquery.each loop and grab the value of each class.
$('.profit').each(function(){
var variableName = $(this).val();
if(variableName > 20){
$('.profit').css("background-color","green");
}
else{
$('.profit').css("background-color","red");
}
});

HTML Table multi column filtering

I am working on developing a multi-column multi-word filtering search and have difficulties with two problems:
I am only able to partially filter the first column; partial because typing apple it shows apple and oranges in the first column.
I am struggling with finding a way to make this a multi-word search over both columns.
I found a table filtering techniques on SO and adjusted them in this fiddle. But this code will only filter over all the columns with one word. Typing more than one word to narrow the result (find A and B) does not work.
The code below is my attempt to perform a multi-column multi-word search in a single box see my fiddle.
How can I achieve filtering over multiple columns that combines the search phrases?
Meaning show only rows where searchphrase-1 and searchphrase-2 are present.
JS
var $orig_rows1 = $('#table tbody tr td[class = "col1"]');
var $orig_rows2 = $('#table tbody tr td[class = "col2"]');
$('#search').keyup(function() {
var $rows1 = $orig_rows1;
var $rows2 = $orig_rows2;
var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
reg = RegExp(val, 'i'),
text;
$("tr:hidden").show();
$rows1.show().filter(function() {
text = $(this).text().replace(/\s+/g, ' ');
return !reg.test(text);
}).parent("tr").hide();
});
HTML
<input type="text" id="search" placeholder="Type to search title 1">
<table class="table-striped" id="table">
<thead>
<th>Title 1</th>
<th>Title 2</th>
</thead>
<tbody>
<tr>
<td class="col1">Apple</td>
<td class="col2">Green</td>
</tr>
<tr>
<td class="col1">Grapes</td>
<td class="col2">Green</td>
</tr>
</tbody>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</table>
Any advice would be great.
Mistake in your code </tbody> is placed wrong, it must be
<tbody>
<tr>
<td class="col1">Apple</td>
<td class="col2">Green</td>
</tr>
<tr>
<td class="col1">Grapes</td>
<td class="col2">Green</td>
</tr>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</tbody>
Not a perfect solution, suggestions would be greatly appreciated
Try this Demo Fiddle it has multiple words search capability made using Tag-it! plugin.
Update search for both AND and OR
Demo Fiddle with a check box to perform both operations
Edit: pieces of linked fiddle added
This is a part of the code from the linked fiddle
var search = function () {
if ($('.tagit-label').length) {
$("#table tbody tr").hide();
var toShow = [];
$('.tagit-label').each(function () {
filter = $(this).text();
$("#table tbody tr").each(function () {
if ($(this).text().search(new RegExp(filter, "i")) > 0) {
toShow.push($("#table tbody tr").index(this));
}
});
});
if ($('#chkBoth').prop("checked") && $('.tagit-label').length > 1) {
var filterShow = [];
var outputArray = [];
$(toShow).each(function (i, value) {
if (($.inArray(value, outputArray)) == -1) {
outputArray.push(value);
}
});
$(outputArray).each(function (i, value) {
var index = toShow.indexOf(value);
toShow.splice(index, 1);
});
}
$(toShow).each(function (i, value) {
$("#table tbody tr").eq(value).fadeIn();
});
} else {
$("#table tbody tr").fadeIn();
}
}
This is the result of my linked fiddle below:
Hope it helps..!!

Any way to synchronize table column widths with HTML + CSS?

I have a number of tables with the same columns and it would look a lot nicer if they shared the same column widths. Is such a thing possible? Putting them in the same table with some rows with no borders between them isn't an option.
Edit: Yeah I'm aware I can fix the widths myself but I was hoping for something that would tie in to the browser's column width algorithm but simply tied two or more tables together for the purpose of doing that layout.
I didn't think such a thing was possible but I thought I'd check just in case.
If you're not too picky about which column widths the browser comes up with, as long as they're the same across different tables, you can use the CSS table-layout property (supported by all major browsers) in combination with a table width:
table {
table-layout: fixed;
width: 100%;
}
This causes all columns (without a specified width) to have the same width, regardless of the table content.
It's only possible if you can fix-width the columns. If you can set a fixed width then some css like this should work:
td {
width: 25%;
}
You can customize each columns width like this:
<table>
<tr>
<td class="col1">...</td>
<td class="col2">...</td>
</tr>
</table>
...
<table>
<tr>
<td class="col1">...</td>
<td class="col2">...</td>
</tr>
</table>
and then specify the widths like this:
.col1 {
width: 25%;
}
.col2 {
width: 75%;
}
Here's a small JavaScript I made to resize cells to make them equal width in all tables on a page.
function resizeTables()
{
var tableArr = document.getElementsByTagName('table');
var cellWidths = new Array();
// get widest
for(i = 0; i < tableArr.length; i++)
{
for(j = 0; j < tableArr[i].rows[0].cells.length; j++)
{
var cell = tableArr[i].rows[0].cells[j];
if(!cellWidths[j] || cellWidths[j] < cell.clientWidth)
cellWidths[j] = cell.clientWidth;
}
}
// set all columns to the widest width found
for(i = 0; i < tableArr.length; i++)
{
for(j = 0; j < tableArr[i].rows[0].cells.length; j++)
{
tableArr[i].rows[0].cells[j].style.width = cellWidths[j]+'px';
}
}
}
window.onload = resizeTables;
To expand on Ken's answer, you can also specify the exact widths in pixels:
td { width: 250px }
or ems (width of the letter m):
td { width: 32em }
or ex or pt or whatever (well...actually %, pt, px, em, ex might be it). If you need your columns to be different widths, then the easy way is to give the table cells classes:
<table><tr>
<td class="col1">...</td><td class="col2">...</td>...
</tr></table>
and assign column widths to the classes:
td.col1 { width: 48em }
td.col2 { width: 200px }
...
It should be sufficient to assign column widths to the first row in each table. [edit: looks like I've been scooped on that while I was writing]
You could probably also go crazy with the CSS 2 sibling selector, and write something like
tr > td:first-child { width:48em } /* first column */
tr > td:first-child + td { width: 200px } /* second column */
tr > td:first-child + td + td { width: 5% } /* third column */
...
but if you have more than a few columns, that could get ugly. And if you're using some sort of template system or script to generate these tables, I'm sure it'll be easier/clearer to just put the class="col#" attribute on each cell in your template once.
I'm almost shocked that no one has suggested column groups! With it you can give a column a specific class, width, and other helpful properties. And since it's HTML 4.01 it's supported by all browsers that support the doctype.
Luis Siquot answer is the one I used. However instead of using clientWidth, you should use jquery width() function to normalize widths between browsers, and to not calculate padding. Using clientWidth would result in the table cells expanding on ajaxpostbacks because of the padding (if padding used in the TD's).
So, correct code using Luis Siquot's answer would be to replace
var cell = $(this)[0].rows[0].cells[j];
if(!cellWidths[j] || cellWidths[j] < cell.clientWidth) cellWidths[j] = cell.clientWidth;
with
var cell = $($(this)[0].rows[0].cells[j]);
if (!cellWidths[j] || cellWidths[j] < cell.width()) cellWidths[j] = cell.width();
The easiest way is kind of a 'dirty' way, but it works the best.
It does exactly what's required:
Just merge your two tables into one table.
In my case the only thing between the two tables was an h3
So my table
<table>
<tr></tr>
<table>
<h3>Title<h3>
<table>
<tr></tr>
<table>
became this:
<table>
<tr></tr>
<tr><td colspan="6">
<h3>Title<h3>
</td></tr>
<tr></tr>
<table>
this way your table will 'sync' it's size up.
of course this only works when there isn't too much complex stuff in between the two tables, but I'm guessing in most cases it isn't. if it was, the sync wouldn't be needed in the first place.
each pair of tables resize its columns to the same width
similar to Ole J. Helgesen but with jquery and a parameter in order to select which tables equalize.
(I cant vote but it's essentially your solution)
<table data-ss="1" border="1">
<tr><td>asdf<td>129292<td>text
</table>
<table data-ss="1" border=1>
<tr><td>a<td>1<td>each column here has the same size than the table above
</table>
<table data-ss="2" border=1>
<tr><td>asdf<td>129292<td>text
</table>
<table data-ss="2" border=1>
<tr><td>each column here has the same size than the table above<td>a<td>1
</table>
and use this sctipt
$(function(){
resizeTables('1');
resizeTables('2');
});
//please set table html attribute `data-ss="something"` to properly call this js
// ss is short for SharedSize
function resizeTables(sharedSize){
var tableArr = $('table[data-ss='+sharedSize+']');
var cellWidths = new Array();
$(tableArr).each(function() {
for(j = 0; j < $(this)[0].rows[0].cells.length; j++){
var cell = $(this)[0].rows[0].cells[j];
if(!cellWidths[j] || cellWidths[j] < cell.clientWidth) cellWidths[j] = cell.clientWidth;
}
});
$(tableArr).each(function() {
for(j = 0; j < $(this)[0].rows[0].cells.length; j++){
$(this)[0].rows[0].cells[j].style.width = cellWidths[j]+'px';
}
});
}
You can sync the column widths by combining the tables (as suggested by #Stefanvds), but using a tbody + th for each:
table {
border-collapse: collapse;
}
table thead,
table tbody {
border-bottom: solid;
}
table tbody th {
text-align: left;
}
<table>
<thead>
<tr> <th> ID <th> Measurement <th> Average <th> Maximum
<tbody>
<tr> <td> <th scope=rowgroup> Cats <td> <td>
<tr> <td> 93 <th scope=row> Legs <td> 3.5 <td> 4
<tr> <td> 10 <th scope=row> Tails <td> 1 <td> 1
<tbody>
<tr> <td> <th scope=rowgroup> English speakers <td> <td>
<tr> <td> 32 <th scope=row> Legs <td> 2.67 <td> 4
<tr> <td> 35 <th scope=row> Tails <td> 0.33 <td> 1
</table>
Source: Example in the HTML spec itself