Adding horizontal scroll to a table whose columns are dynamically created - html

I have a html table as below:
<div id="myDiv" class="table">
<table class="table table-striped table-bordered">
<thead>
<tr data-bind="foreach: columnNames">
<th> <span data-bind="text: $data"></span>
</th>
</tr>
</thead>
<tbody data-bind="foreach: data">
<tr data-bind="foreach: $parent.columnNames">
<td style="width:20px"><input type="text" class="form-control textbox"/> </td>
</tr>
<tr>
<td>
<input type="button" value="Remove Row" data-bind="click: $parent.removeRow" class="btn btn-danger" />
</td>
</tr>
</tbody>
</table>
</div>
The columns to these are generated dynamically via a knockout JS code. The columns can be ranging from 3 (minimum) to 20 something. So I am trying to add a horizontal scrollbar to it so that user can scroll to right. I also want to set a fixed width of column say 20%.
Below is my JS fiddle which I have.
https://jsfiddle.net/aman1981/6fjcuhcf/41/
But I have tried many changes to the css but its not adding scroll not its keeping the columns width fixed.
Please see I have used suggestions as per Add horizontal scrollbar to html table
But its not adding scroll. What else am I missing here?

I was able to add scroll and make my columns fixed width using this css:
<style>
.table {
display: block;
overflow-x: auto;
white-space: nowrap;
width:1000px;
}
.table td,th {
display:inline-block;
width: 180px !important;
}

Related

Starting hidden (based on parent element) messes up stying of child with Bootstrap 4

I want to add a class to a parent DIV that affects lots of inner elemnets. But when I do this with Bootstrap, the styling gets messed up.
This code shows the problem on 2 where you can see the bottom border is missaligned. If I just do a .toggle(".second") on the element instead, it will work.
https://www.bootply.com/KOJ4VKNbOa
.second {
display: none;
}
.show-inner .second {
display: block;
}
<div id="outer">
<table class="table">
<thead>
<tr>
<th class="first">A</th>
<th class="second">B</th>
<th class="third">C</th>
</tr>
</thead>
<tbody>
<tr>
<td width="98%" class="first">1</td>
<td width="1%" class="second">2</td>
<td width="1%" class="third">3</td>
</tr>
</tbody>
</table>
</div>
<button onclick="$('#outer').toggleClass('show-inner');">Toggle .second</button>
In my project I would like to have many dependencies of that outer DIV class, so getting it to work would save me lots of code.
use display: table-cell instead of block.
.show-inner .second {
display: table-cell;
}

HTML table div alignment across tds

I have the following code to display comparison of items
<table>
<tr> <!-- Iterating over list of Headers -->
<td>
<div class="Header"><h4>Header Value</h4></div>
<div class="HeaderList"><span>Key</span> <!-- Iterating over list of keys-->
</td>
<td> <!-- Iterating over multiple items -->
<div class="Header"></div>
<div class="HeaderList"><span>Value</span> <!-- Displaying Value next to the key by iterating over them-->
</td>
</tr>
</table>
I want to align the divs with class "Header" and "HeaderValueList" across multiple td.
The value in Header can extend to multiple lines if needed.
I want to set a maximum height for "HeaderKeyList" and "HeaderValueList" not to cross 32px but if its less than that, the height should be dynamically variable and should align across tds.
I have the following css
.HeaderList
{
width:100%;
height:auto;
max-height:32px;
overflow: hidden;
padding-top: 0.5px;
padding-bottom: 0.5px;
}
.Header
{
width:100%;
}
When any of the value spans across multiple rows, my alignment goes awry. Please help. I am open to making changes in javascript as well.
Thanks in advance.
To group rows in a table together, you use tbody. One tbody for each of the lists. So the HTML becomes
<table>
<thead>
<tr>
<th></th>
<th>Item1</th>
<th>Item2</th>
</tr>
</thead>
<tbody>
<!-- Iterating over list of Headers -->
<tr class="Header">
<th>Header Value1</th><td></td><td></td>
</tr>
<tr>
<td><div class="HeaderKey">Key1</div></td>
<td><div class="HeaderValue">Item1Value1</div></td>
<td><div class="HeaderValue">Item2Value1</div></td>
</tr>
<tr>
<td><div class="HeaderKey">Key2</div></td>
<td><div class="HeaderValue">Item1Value2</div></td>
<td><div class="HeaderValue">Item2Value2</div></td>
</tr>
<tr>
<td><div class="HeaderKey">Key3</div></td>
<td><div class="HeaderValue">Item1Value3</div></td>
<td><div class="HeaderValue">Item2Value3</div></td>
</tr>
</tbody>
<tbody>
<!-- Iterating over list of Headers -->
<tr class="Header">
<th>Header Value2</th><td></td><td></td>
etc, with this result:
See fiddle.
I made one of the values a bit wider, to demonstrate that if you make the window narrower, the div will grow to two lines, and the cells to the left and right will remain lined up (vertically centered; but you can change that) and if you make the window narrower still, the div doesn't grow to more than two lines because of the max-height.

Wrapping words in table cell, but table-layout fixed makes columns equal size

In my HTML table sometimes I have long words in my cells. So I need to break some words if they overflows its area.
This questions shows how to break table cell: Word-wrap in an HTML table
This css style is recommended : style="word-wrap: break-word; table-layout: fixed; width: 100%"
But if I use table-layout:fixed, my columns becomes equal sized. But in my case width is 100% for table and if table is fixed then columns share width equally. But this takes too much height from page.
My fiddle: http://jsfiddle.net/mavent/Y54s9/17/
What I need ?
- My table has 2 columns, I want second column to be as narrow as possible.
- 2nd column's width shouldn't exceed column's name.
- Column names shouldn't be wrapped. < th > names mustn't be wrapped.
- 1st column should be wide. I don't prefer to fixate column width like %60, %70 etc. But if it is a solution I can use fix column width, but responsiveness must be taken into account.
- Table should be responsive. I will use this table in mobile layouts.
- Word must be wrapped strictly if word exceeds the cell width. For example if cell can take max 40 characters and word is 45 characters, word can be breaked whatever 41. character is.
Output should look like this in small and big screens:
Code:
.myclass1 {
white-space: normal;
}
.myclass2 {
word-wrap: break-word;
table-layout: fixed;
}
<table class="table table-striped table-condensed dataTable myclass1" id="mytable">
<thead>
<tr>
<th class="sorting">header1</th>
<th class="sorting">header2</th>
</tr>
</thead>
<tbody>
<tr class="">
<td class="">
<span class="">Some words are generally short and easy to read
<i class="glyphicon glyphicon-share-alt"></i></span>
</td>
<td class="">
<span><button class="btn btn-primary btn-xs">123</button></span>
</td>
</tr>
</tbody>
</table>
<hr><hr>
<table class="table table-striped table-condensed dataTable myclass1" id="mytable">
<thead>
<tr>
<th class="sorting">header1</th>
<th class="sorting">header2</th>
</tr>
</thead>
<tbody>
<tr class="">
<td class="">
<span class="">Some words are generally short and easy to read, butsomewordsareĞĞÜÜveryverylongIŞÖlikeethisssssGAAAAAAAAAAAAAABBBBBBBBBBBBBbbbbbCCC
<i class="glyphicon glyphicon-share-alt"></i></span>
</td>
<td class="">
<span><button class="btn btn-primary btn-xs">123</button></span>
</td>
</tr>
<tr>
<td>
<span>Some words are generally short and easy to read, butsomewordsare veryverylonglikeethisssssGAAAAAAAAAAAAAABBBBBBBBBBBBBbbbbbCCC
<i class="glyphicon glyphicon-share-alt"></i></span>
</td>
<td class="">
<span><button class="btn btn-primary btn-xs">225</button></span>
</td>
</tr>
</tbody>
</table>
<hr><hr>
<table class="table table-striped table-condensed dataTable myclass2" id="mytable">
<thead>
<tr>
<th class="sorting">header1</th>
<th class="sorting">header2</th>
</tr>
</thead>
<tbody>
<tr class="">
<td class="">
<span class="">Some words are generally short and easy to read, butsomewordsareĞĞÜÜveryverylongIŞÖlikeethisssssGAAAAAAAAAAAAAABBBBBBBBBBBBBbbbbbCCC
<i class="glyphicon glyphicon-share-alt"></i></span>
</td>
<td class="">
<span><button class="btn btn-primary btn-xs">123</button></span>
</td>
</tr>
<tr>
<td>
<span>Some words are generally short and easy to read, butsomewordsare veryverylonglikeethisssssGAAAAAAAAAAAAAABBBBBBBBBBBBBbbbbbCCC
<i class="glyphicon glyphicon-share-alt"></i></span>
</td>
<td class="">
<span><button class="btn btn-primary btn-xs">225</button></span>
</td>
</tr>
</tbody>
</table>
It seems that with HTML and CSS, you cannot cause automatic word breaking in table cells without making table columns of fixed width and using table-layout: fixed). And you cannot specify that one column be just as narrow as it needs and the other column take all the rest (when table-layout: fixed is used).
However, there’s a rather simple JavaScript workaround, though for a large table, it might cause inefficiency (and a flash from initial layout to modified layout). You would not set fixed layout initially, or column widths, just a total width of 100%. You would thus let the browser format the table in automatic layout, so that the second column becomes just as wide as it needs to be (assuming there is enough content in the other column, as we can expect here). Then you just get the width of the second column and explicitly set it on the header cell and you set table layout to fixed.
Sample code:
<style>
#mytable {
word-wrap: break-word;
width: 100%;
}
</style>
...
<table id="mytable"
...
<script>
window.onload = function() {
var t = document.getElementById('mytable');
var th2 = t.rows[0].cells[1];
th2.style.width = th2.clientWidth + 'px';
t.style.tableLayout = 'fixed';
}
</script>
P.S. I still think this is an all wrong approach, unless the cell content is some code of very special kind, like a DNA sequence, that can really be broken at any point. For any normal and abnormal text in human languages, hyphenation or other language-specific word division should be applied. For most code expressions, permissible break points should be indicated, if needed, e.g. with the <wbr> tag or with zero-width no-break spaces.

How to set and fix html5 table column size dyamicly using knockout

I have table like this:
<table class="table table-bordered">
<tbody data-bind="foreach: { data: dataset, as: 'rowInfo' }">
<tr style="max-height: 30px"
data-bind="foreach: { data: $parent.metadata, as: 'colInfo' }">
<td style="max-height: 30px" data-bind="text: rowInfo[colInfo.DataColumn],
attr: {width: Width}"></td>
</tr>
</tbody>
</table>
I want to have a grid like experience. So I don't want the text to wrap in the cell or make the cells to resize.
I want to have fixed sized cells which their height set to 30px and the width set to the colInfo.Width which comes from knockout.
But with the above code, the cells re-size to fit their content. How should I set the attributes to have fixed height and width?
To give a max-height to cell contents you'll need to wrap it in another element (e.g. a div). In addition, I'd recommend using the style binding, like this:
<td>
<div data-bind="text: rowInfo[colInfo.DataColumn],
style: { width: Width, height: '30px' }"></div>
</td>
See this fiddle for a working demo.

Two columns table : one as small as possible, the other takes the rest

I have a to-columns table in a div :
<div>
<table>
<tbody>
<tr>
<td class="action" >
<a> ✔ </a>
</td>
<td class="content">
<p>Bigger text...(variable size).......</p>
</td>
</tr>
<tr>
<td class="action" >
<a> ✔ </a><a> ✘ </a>
</td>
<td class="content">
<p>Bigger text...(variable size).......</p>
</td>
</tr>
... same structure in all the table
</tbody>
</table>
</div>
And I would like the "action" column to fit the content, and the "content" column to take the rest of available space. The "action" column would look better with a right align.
The table should also fit 100% of the container's width.
Is there a way of doing this without fixing the columns width ?
I tried with this:
table .action
{
width:auto;
text-align:right;
}
table
{
border-collapse:collapse;
border-spacing:0;
width:100%;
}
But the left column takes half of the table...
Giving the content td a 100% width will force it to take as much space as it can, so .content{ width: 100% } should work.
Also give the .action a white-space: nowrap to make sure the x and the checkmark stay next to each other. Otherwise the content will be able to take even more space and force the icons below each other.
table .action
{
width:auto;
text-align:right;
white-space: nowrap
}
table .content {
width: 100%
}
table
{
border-collapse:collapse;
border-spacing:0;
width:100%;
border: 1px solid
}
<table>
<tbody>
<tr>
<td class="action" >
<a> ✔ </a>
</td>
<td class="content">
<p>Bigger text...(variable size).......</p>
</td>
</tr>
<tr>
<td class="action" >
<a> ✔ </a><a> ✘ </a>
</td>
<td class="content">
<p>Bigger text...(variable size).......</p>
</td>
</tr>
</tbody>
</table>
Set the column width: 1px and white-space: nowrap.
This will try to make it 1px, but the nowrap will stop it from getting smaller than the widest element in that column.
I found this answer when trying to make one column of many as small as possible.
Giving the content td a 1% width will force it to take as little space as it can, so .content{ width: 1% } worked for me.
The bootstrapian way of doing this:
<div class="row">
<div class="col-sm-1"> content... </div>
<div class="col"> content... </div>
</div>
Basically you need to try out different things keeping in mind the following:
col-sm Small column
col-sm-1 Smallest column
col-sm-2 Slightly bigger than smallest column (Numbers go from 1 to 12)
col-md Medium sized columns (same numbering rule)
col-lg Large sized columns (same numbering rule)