I am using primeng with angular, However, it feels like my problem is with html/css.
I have found out how to present my ui the way I would like with the datatable component. However, when I leverage the datatable component inside the rowexpansion feature my column widths are not adhered to.
You will see that in the below table inside a table the column width is 100px. The parent table has it correctly set to 100px.
Here is the entry code entry
Here is where the width of the columns are set
Specifically the code that I debugged is below
for(let i = 0; i < columns.length; i++) {
columns[i].style.width = columns[i].offsetWidth + 'px';
}
The offsetWidth is different for the parent then the child even though I am setting the style the same way for both tables.
My conclusion thus far is that offsetWidth is calculated differently when my table is inside a div vs inside of a td.
I looked at the default css for each HTML element and tried to make them match. However, it must be displayed as a table-cell because it requires the colspan attribute otherwise the row won't span the table as intended.
I have looked at a number of websites to determine how offsetWidth is calculated but nothing has stood out to me. So I am going to the SO community to see if there is a bug in the browser (Chrome) or if there is a css property I can use to make it behave the same way.
The offsetWidth and offsetHeight returns the element's layout width and height.
It includs the width of the visible content, scrollbars (if any), padding, and border.
Read more here...
Table has a cellspacing property which is used by the TD tag. This cellspacing is not considered in offsetWidth or offsetHeight. Aside div tag has no cellspacing property.
Below example will clear/solve your problem.
var a = document.getElementById('div');
var b = document.getElementById('tda');
var log = document.getElementById('log');
//Border+Padding+ClientWidth
log.insertAdjacentHTML("beforeend","Div offset: "+a.offsetWidth);
log.insertAdjacentHTML("beforeend","<br />Table offset: "+b.offsetWidth);
log.insertAdjacentHTML("beforeend","<br />Table Tbody offset: "+b.children[0].offsetWidth);
log.insertAdjacentHTML("beforeend","<br />Table TR offset: "+b.children[0].children[0].offsetWidth);
//Border+Padding+ClientWidth, Except Cell spacing
log.insertAdjacentHTML("beforeend","<br />Table TD offset: "+ b.children[0].children[0].children[0].offsetWidth);
#tda {width:400px}
#div{width:100px;border: 1px solid red}
<div id="div">DIV</div>
<table id="tda" border="1" cellpadding="5" cellspacing="6">
<tr>
<td>TD</td>
<td>TD</td>
</tr>
</table>
<pre id="log"></pre>
So I still don't know why I get different results between div and td.
However, looking here I was able to find the width property that does the same thing as auto, in my case, called max-content. When I set this CSS width property value on my table, I get the same result in the child as in the parent. See screenshot below:
Again I don't know why auto gives me different results for the child and the parent table but I found a workaround.
In case someone else is still interested, the best information I found for this so far was here.
Related
I'm using an absolutely positioned element in a table header cell. To do this, the TH has to be positioned itself, to make it the child element's offsetParent (in my case, using position:relative). Unfortunately, it appears that current Firefox versions will issue a warning any time a TD or TR is given a position other than static.
With the following minimal table HTML
<table>
<tr><th>head</th></tr>
<tr><td>cell</td></tr>
</table>
and the following minimal CSS rules
th { position: relative } // either of these is enough
td { position: relative } // to trigger the warning
table { border-collapse: collapse }
this warning appears in the console for Firefox 30 and 32:
Relative positioning of table rows and row groups is now supported. This site may need to be updated because it may depend on this feature
having no effect.
(the warning does not appear when the table borders are kept separate)
The source of this message is Firefox's table layout code:
/* static */ void
nsTableFrame::RegisterPositionedTablePart(nsIFrame* aFrame)
{
// Supporting relative positioning for table parts other than table cells has
// the potential to break sites that apply 'position: relative' to those
// parts, expecting nothing to happen. We warn at the console to make tracking
// down the issue easy.
So it seems we get this warning even if we're doing nothing wrong at all, because other sites may rely on the position rule doing "nothing". Is there a way to get rid of this annoying warning? It's basically telling me: Warning, what you're doing actually works!
I was getting the same warning and resolved it by applying positioning to a div inside the th or td rather than directly to the td or th. Not sure why it cares but now I don't need to see it anymore.
td div{position:relative;}
<table>
<tr>
<td>
<div></div>
</td>
</tr>
</table>
Have you tried this?
<table>
<tr><th><span class="pos1">head</span></th></tr>
<tr><td><span class="pos2">cell</span></td></tr>
</table>
css:
.pos1{
position:absolute;
top:25px /* example*/
}
.pos2{
position:absolute;
top:10px /* example*/
}
I have a table that pulls values in an xpage in Lotus notes. I have nowrap set so it doesn't wrap. Currently the value extends the width of my columns when I set it to nowrap. However, I don't need to see the whole value that is pulls. I only need to see if a value is in there. So I need the column size to remain the same size. I have tried to use various width values in the xpage. However, the value still extends the column. So either I need to parse the value to make it smaller or figure out where to add the width value so it doesn't increase with the variable.
Thanks in advance.
<td>
<div>
<xp:text escape="false" style="white-space:nowrap" id="computedFieldStatementNotesDisplay" value="#{auditDoc.StatementNotesDisplay}">
</xp:text>
</div>
</td>
Two quick solutions I can think of:
use a css overflow statement overflow: hidden, overflow: auto or maybe overflow: scroll and apply this to the containing <td> or <div> tags; also you might consider setting the table column's width to some value
limit the amount of characters displayed in column using SSJS.
JS code could be like this:
var limit=20; //test for max allowable chars
var val=auditDoc.getItemValueString("StatementNotesDisplay");
if(val.length>limit){
val=val.left(limit);
}
return val;
CSS solution might be the preferred one
Update:
Just saw Per's comment linking to a css solution which is quite complete
I want to thank everyone for their response. I took the information given and applied it. I had to add the width to the text as well place the settings in the .css. This is what worked.
I added this to the .css
.ellipsis span {
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
display:inline-block;
}
Then inside the xpage I called ellipsis and then set the width in the text area.
<td class="ellipsis">
<xp:text escape="false" id="computedFieldStatementNotesDisplay" value="#auditDoc.StatementNotesDisplay}" style="width:100px">
</xp:text>
</td>
I've got an embedded widget from The Weather Channel and everything is working fine except that they've got a <tr> with a 1px height image that is expanding to a height equal to the other rows.
It's shifting the rest of the content down. Because it's just an embed, there is only so much of the styling I can control. But I figured it must be inheriting something from my stylesheet since it had inherited some line-height that I had to correct.
If you visit http://www.scwd.com and scroll to the bottom you'll see the weather widget. The row with the grey td below #weather.com is the issue. It should only be 1px in height. I've used multiple debuggers to see if I could find the inherit and I cannot. Any help would be great.
-- UPDATE --
Not the most elegant solution considering variable within the widget and out of my control may change in the future. But as David suggested, I solved it with the following.
<script type="text/javascript">
var x = $("img[src$='blank.gif']");
$(x).closest('tr').css('display', 'none');
</script>
Best I can find is:
Inherited from div#wx_module_6107.wow_container
.wow_container {
line-height: 14px;
}
Are you hosting this or pulling the HTML from a foreign source? I suspect you can't control the HTML that's being rendered or the CSS that it's using?
I'm no CSS expert, so thus far nothing I've tried in FireBug have made a difference without affecting the rest of the table elements in the widget.
Unless someone can give a CSS solution, maybe some JavaScript can get the job done? You should be able to, on document ready, find that img element (maybe by its src?) and from there (using something like .closest() in jQuery) find its parent td and parent tr and with those element references explicitly set their styles.
The image is in a td which has a line height of 14 according to your css:
.wow_container { line-height: 14px; }
I would give it a line-height of 1px and set the background-color to transparent. That makes things look nice for me. Is this widget coming from a wordpress plugin? If so which plugin? You may be able to edit the plugin code yourself.
I think the problem occurs because the font-size of the body. My suggestion is to add font:1px Verdana,Arial,Helvetica,sans-serif for the td that is the grey row.
On our site we have tables containing data. We like the column widths we get with a normal table, but we like the border-bottom of tds to stretch the entire width of the page like we get with CSS: table { width:100% }, as can be seen on a demo table widths page, which renders like this:
Is it possible to achieve the same column widths as with a normal (non-width-100%) table in a table where the border-bottom stretches the entire width?
And no, td { white-space: nowrap } in combination with an extra width: 100% td (see the link above) is not good, as sometimes the tds are long and so we want the tds to wrap exactly like in a normal table.
We need a solution that works in at least IE6-8 + FF.
Btw, is there a better way (tm) of showing HTML snippets than linking to an external page? I can show just source, but having HTML rendered too is very illustrative.
This was originally posted on Webmasters, but following a suggestion there, I now (re)post it here.
I finally figured it out.
My first few attempts dealt with floating <td>s and <tr>s, but apparently I was on the right track but had the wrong element.
I think what you want to do is to float the <tbody>. The <table> will still be 100% width, so it will stretch the whole width of the page, but the <tbody> inside of it will act as a container for everything else, and floating it will release it from the shackles of the size of its <table> container width.
The downside of this is that you won't be able to use <thead> or <tfoot> elements, because you will no longer have any way to align them with the <tbody> content.
Try this out:
table {
width: 100%;
border: 1px #000 solid;
}
tbody {
float: left;
}
td {
border: 1px #000 solid;
}
You can use the new CSS properties min-width and max-width to bound the columns sizes without setting them explicitly.
To get a proportional version of what would be rendered when the table's width is not specified, I think you'd have to let it render normally (remove your table width setting) and then use javascript to read the column widths and resize.
Pulled this example of using jQuery to syncronize the column widths of two tables from another question:
$("#t1").width($("#t2").width());
$("#t1 tr td").each(function (i){
$(this).width($($("#t2 tr:first td")[i]).width());
})
Should be a pretty good starting point for scaling your column widths.
This is pretty ugly and not exactly what you asked for, but it works in Firefox and appears to get the same gist...
<html>
<head>
<style type="text/css">
td{background-color:blue;}
div{border:1px solid red;position:absolute;width:100%;}
</style>
</head>
<body>
<table>
<tr>
<td>asdf<div></div></td><td>hello blah blah</td>
</tr>
<tr>
<td>lorem ipsum dolor si amet</td><td>testing</td>
</tr>
</body>
</html>
I was looking for a similar answer to this question, however I don't understand what you mean by
And no, td { white-space: nowrap } in combination with an extra width: 100% td (see the link above) is not good, as sometimes the tds are long and so we want the tds to wrap exactly like in a normal table.
But anyway, I found a solution to my problem. Not sure if it can be used here, but it solved my problem. Maybe it can be helpful to others.
I didn't add in another td. I just applied 100% to every last td with content.
So I could add a class to every last td to do that, or I could use the last-child selector to do it for me.
Something like:
table
{
width:auto;
}
table tr td:last-child
{
width:100%;
}
I've three divs. Header, central and footer. There is a table in central div (gridview) which is almost always longer than outer div. So I've made this div scrollable vertically. The question is: how can I make table header that it would be visible after div is scrolled down? I could have done this header with separate div or table and make it fixed but widths of columns in the table are not always the same - so I don't know how to maintain widths of columns in header then. Any clue?
I've just put together a jQuery plugin that does exactly what you want. Its very small in size and really easy to implement.
All that is required is a table that has a thead and tbody.
You can wrap that table in a DIV with a classname and the table will always resize to fit in that div. so for example if your div scales with the browser window so will the table. The header will be fixed when scrolling. The footer will be fixed (if you enable a footer). You also have the option to clone the header in the footer and have it fixed. Also if you make your browser window too small and all columns can't fit...it will also scroll horizontally (header too).
you just pass the DIV's classname to the plugin like so: $('.myDiv').fixedHeaderTable({footer: true, footerId: 'myFooterId'});
and the plugin will do the rest. FooterID is a element on the page that contains the mark-up for your footer. this is used if you want to have pagination as your footer.
If you have multiple tables on the page it will also work for each table you want to have a fixed header.
check it out here: http://fixedheadertable.mmalek.com/
Keep in mind its still 'beta' so I am adding new features and bug fixes daily.
Supported browsers: IE6, IE7, IE8, FireFox, Safari, and Chrome
Solution is really simple. You need 3 DIVs: a general container (in my case of class "outer"), a table container (in my case of class "inner") and a DIV in which you make a clone of an existing table using jQuery or javaScript (in my case of class "header").
Solution uses CSS and a few lines of jQuery code, which clones HTML of "inner" into "header" and sets its width and height. Supports fixed and variable columns width. Tested with IE8, Firefox 9, Safari and Google Chrome.
Here is a sample code:
$(document).ready(function() {
$('.header').html( $('.inner').html() );
$('.header').css('width', $('.inner table').outerWidth() );
$('.header').css('height', $('.inner table thead').outerHeight() );
});
table {
width:100%;
}
th {
border-top:1px solid #999;
text-align:left;
}
td, th {
border-bottom:1px solid #999;
background-color:#EEE;
}
.outer {
position:relative;
width:500px;
}
.inner {
height:150px;
overflow:auto;
}
.header {
position:absolute;
top:0;
left:0;
overflow:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="outer">
<div class="inner">
<table cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>a</th>
<th>b</th>
<th>c</th>
<th>d</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>2</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>3</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>4</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>5</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>6</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>7</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>8</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>9</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>10</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>11</td><td>b</td><td>c</td><td>d</td></tr>
<tr><td>12</td><td>b</td><td>c</td><td>d</td></tr>
</tbody>
</table>
</div>
<div class="header">
</div>
</div>
</body>
Here is a basic solution using javascript:
function position(table) {
table.rows[0].style.position="absolute";
table.rows[0].style.top="0px";
table.style.marginTop = table.rows[0].clientHeight/1.2;
var widths = Array();
for(var i = 0; i < table.rows[0].cells.length; i++) {
widths[i] = max(table.rows[0].cells[i].clientWidth, table.rows[1].cells[i].clientWidth);
}
for(var row = 0; row < table.rows.length; row++) {
for(var col = 0; col < widths.length; col ++) {
table.rows[row].cells[col].style.width = widths[col] + "px";
}
}
}
function max(num1, num2) { return (num1 > num2) ? num1 : num2; }
You would have to put the header outside the scrollable div. Everything within the div will scroll.
EDIT
Regarding the width if you go for a separate header, I can see a few solutions:
Assuming this is dynamic content, generate "fixed" widths based on the length of the string. Obviously specify in terms of EMs and leave some margin for error.
Use javascript.
Use fixed width columns.
I haven't actually tried the first, and it might be overcomplicating things a bit. It's something to try if you're desperate for the effect though.
I should also mention that there are probably javascript libraries with table widgets that do this already. Have a look at them to see how they do it.
You need to put a table with the headers about your table of data. You can maintain the column width with table-layout:fixed. JavaScript can be used to match the column widths.
Here's a nice solution (mostly CSS) which uses fixed width columns: http://www.imaputz.com/cssStuff/bulletVersion.html
And here's a bit of jQuery code to fix cell-widths when cell contents take more width than the fixed width:
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"
type="text/javascript"></script>
<script>
$(function() {
$('div.tableContainer').each(function() { // for each table
var div = $(this);
var widths = [];
var changed = false;
$('table>*>tr', div).each(function(tr_i) {
$(this).children().each(function(i) {
var w = $(this).width();
if (w > widths[i]) {
widths[i] = w;
changed = true;
}
});
}).each(function(tr_i) {
if (changed)
$(this).children().each(function(i) {
var width = widths[i];
// add some width for scrollbar
if (tr_i == 0 && changed && i == widths.length-1) width += 16;
// insert a div to ensure width
$(this).append('<div style="width:'+width+'px; height:0px"> </div>');
});
});
div.width(div.children('table').width()).css('overflow-x', 'hidden');
});
});
</script>
The output is a bit off in IE when using a non-strict DTD. Tweak the widths in the CSS if you can't use standards mode.
Note that the jQuery code increases the table width at the end, and disables the horizontal scrollbar. You may or may not want that.
You may try the jQuery plugin Stupid Fixed Header. The technique is basically the same: clone a header and put it on top of the table layer.
What you actually want to be doing is making the <tbody> of the data table scrollable, so the <thead> and <tfoot> will remain naturally fixed.
Whilst this is trivial for FF et al:
tbody
{
height: 100px; /* or whatever */
overflow: auto;
overflow-y: auto;
overflow-x: hidden;
}
IE has severe and complex issues with tbody in general. It can be solved with expressions but it's non-trivial, and specific to the design.
I haven't tested this, but perhaps you could generate the table twice, once in the header and once in the scrolling div. Then in the header, make all the rows except the heading row invisible. Perhaps with 'display: none' or set their height to zero.
This solution works using CSS in Firefox and the other Gecko browsers, and CSS expressions in IE.
http://home.tampabay.rr.com/bmerkey/examples/nonscroll-table-header.html
The header and footer do not stay fixed in Opera or Safari/Chrome, but the whole table is scrollable so it is usable. Note that the columns are given percentage widths in the author's example, but they can be removed.
If you want to experiment with Opera/Safari/Chrome support, look at giving the tbody display:block and go from there.
Take a look at YUI Data Table if you are looking for a comprehensive cross-browser implementation. I believe this is done by creating another table with matching column widths.
There appears to be tricks required to fix column widths. If I recall correctly, Firefox requires <col/> tags to be present.
In any case, there were many tricks employed in YUI DataTable (50k lines). You'd be well advised to look at it and decide how far you'd like to go on your own with this.