How to make table responsive - html

I have some table and I want to make it responsive when it show in width max 760.
This is the table looks normal :
And I want to make it like this if width of the screen is max 760 :
In that table the last coloumn just appears in end of table not in each row.
Anyone can help me to do that ?

Use this html & css code for make rsponsive table
Check the Snippets is below .
Use this css with media query max-width:760px or any width
.responsive-table {
margin:0px auto;
width:500px;
border: 1px solid #efebeb;
}
.responsive-table img{height:100px; }
.responsive-table th {
display: none;
}
.responsive-table td {
display: block;
border-top: 1px solid #ddd;
}
.responsive-table td:first-child{border:none;}
.responsive-table td:first-child {
padding-top: .5em;
}
.responsive-table td:last-child {
padding-bottom: .5em;
}
.responsive-table td:before {
content: attr(data-th) ": ";
display:block;
font-weight:bold;
}
<table class="responsive-table">
<tbody>
<tr>
<th>
Room
</th>
<th>
Guest
</th>
<th>
Description
</th>
<th>
Rate
</th>
<th>
Book
</th>
</tr>
<tr>
<td data-th="Room">
<img src="http://i45.tinypic.com/t9ffkm.jpg" alt="" />
</td>
<td data-th="Guest">
2 adult
</td>
<td data-th="Description">
Room Only
</td>
<td data-th="Rate">
USD 200
</td>
<td data-th="Book">
<button type="submit"> Book</button>
</td>
</tr>
</tbody>
</table>

I wrote js function to make table responsive. You can set breakpoint and table tag or css class name as parameters.
const makeTableResponsive = (mq, t) => {
var q = window.matchMedia(mq);
if (q.matches) {
let headings = [];
let tables = document.querySelectorAll(t);
if (tables && tables.length > 0) {
tables.forEach(table => {
let thead = table.querySelector("thead");
let headingTags = thead.querySelectorAll("th");
let tbody = table.querySelector("tbody");
let tbodies = tbody.querySelectorAll("tr");
tbody.style.display = "block";
thead.style.display = "none";
headingTags.forEach((th) => {
th.style.display = "block";
headings.push(th.innerText);
});
tbodies.forEach((tr) => {
let trstyle = tr.style;
trstyle.display = "block";
trstyle.border = "1px solid #ccc";
trstyle.marginBottom = "30px";
let tds = tr.querySelectorAll("td");
tds.forEach((td, i) => {
td.style.display = "flex";
td.style.flexDirection = "row-reverse";
td.style.justifyContent = "space-between";
td.innerHTML += `<span class="font-weight-bold text-primary">${headings[i]}</span>`;
});
});
})
}
}
};
makeTableResponsive('(max-width: 992px)', 'table');

Related

Cannot remove padding in table

I am trying to remove the padding from the cells inside my table. I have set it to not have padding in the relevant CSS selectors but not a success.
As you can see, there is padding on all of these cells.
I would like there to not be. I have tried various different padding settings and changing the vertical alignment makes no difference other than to move the text, the padding just goes from all at the bottom to spread between bottom and top.
Below is the code:
'use strict'
let table = document.getElementById("mainTable")
let rows = table.querySelectorAll("tbody tr")
let columns = table.querySelectorAll("#weeks th")
for (let row of rows) {
for (let o = 0; o<columns.length-1; o++) {
let cell = document.createElement("td")
cell.innerHTML='&nbsp'
cell.addEventListener("click", function() {
if (cell.getElementsByTagName("input")[0]) { return } //If cell currently has an input box
//
let oldValue = ""
if (cell.innerHTML !== " ") { //if cell has a saved value
oldValue = cell.innerHTML
}
cell.innerHTML = '<input type="text" class="cellInputs">'
//update input box with old value and focus it
cell.getElementsByTagName("input")[0].focus()
cell.getElementsByTagName("input")[0].value = oldValue
cell.getElementsByTagName("input")[0].addEventListener("keypress", function(e) {
if (e.keyCode === 13) {
cell.innerHTML=cell.getElementsByTagName("input")[0].value
e.preventDefault()
return true
}
})
cell.getElementsByTagName("input")[0].addEventListener("input", function(e) {
console.log(e)
let cellValue = cell.getElementsByTagName("input")[0].value
if (e.data === "." && (cellValue.split('.').length-1 > 1 || cellValue === ".")) {
console.log("stop")
cell.getElementsByTagName("input")[0].value = (cellValue).substring(0, cellValue.length - e.data.length)
}
if (isNaN(e.data) && e.data !==".") {
console.log("Stop")
cell.getElementsByTagName("input")[0].value = (cellValue).substring(0, cellValue.length - e.data.length)
}
//store value inputted into the actual cell
})
cell.getElementsByTagName("input")[0].addEventListener("paste", function(e) {
// clipboardData = e.clipboardData || window.clipboardData;
// pastedData = clipboardData.getData('Text');
let cellValue = cell.getElementsByTagName("input")[0].value
if (cellValue !== "") {
e.preventDefault()
return false
}
if (e.clipboardData.getData('text') === "." && (cellValue.split('.').length-1 > 1 || cellValue === ".")) {
e.preventDefault()
return false
}
if (isNaN(e.clipboardData.getData('text')) && e.clipboardData.getData('text') !==".") {
e.preventDefault()
return false
}
//store value inputted into the actual cell
})
cell.getElementsByTagName("input")[0].addEventListener("focusout", function() {
console.log(document.activeElement)
cell.innerHTML=cell.getElementsByTagName("input")[0].value
})
})
row.appendChild(cell)
}
}
*{
padding: 0;
margin: 0;
font-family: "Trebuchet MS", Times, serif;
box-sizing:border-box;
}
html{
background-color: #35454E;
overflow: hidden;
}
html *{
font-family: "Work Sans", Arial, sans-serif !important;
color: white !important;
}
table{
border-collapse: collapse;
border-spacing: 0px;
color:#35454E;
height:100%;
width:100%;
}
table, th{
border: 2px solid white;
padding:0;
}
th{
vertical-align:top;
font-size: 2.5vw;
}
td{
vertical-align:top;
box-sizing:border-box;
position: relative;
border: 2px solid white;
padding:0;
text-align: center;
font-size: 2.5vw;
padding:0;
}
.cellInputs{
position: absolute;
width:100%;
height:100%;
display: block;
top:0;
left:0;
border:none;
text-align: center;
background-color: #35454E;
word-wrap: break-word;
font-size: 2.5vw;
}
<html>
<head>
<link rel="stylesheet" type="text/css" href="MMS.css">
<title>Money Management</title>
</head>
<body>
<table id="mainTable">
<thead>
<tr>
<th>2019</th>
<th colspan="5">January</th>
</tr>
<tr id="weeks">
<th>&nbsp</th>
<th>31/12/2018</th>
<th>07/01/2019</th>
<th>14/01/2019</th>
<th>21/01/2019</th>
<th>28/01/2019</th>
</tr>
</thead>
<tbody>
<tr>
<th>Balance</th>
</tr>
<tr>
<th>Pay</th>
</tr>
<tr>
<th>&nbsp</th>
</tr>
<tr>
<th>Rent</th>
</tr>
<tr>
<th>Food</th>
</tr>
<tr>
<th>&nbsp</th>
</tr>
<tr>
<th>Total</th>
</tr>
</tbody>
</table>
</body>
<script src="MMS.js"></script>
</html>
Remove height:100% from table .

Why table cells width are depends on dynamic content of another inner table in Chrome 69?

I have noticed strange behavior of table cells width in Chrome.
For example, we have a table with 2 columns and 2 rows, but 1 cell will have colspan="2" and contain inner table with some content.
So, inner table content will affect on top-table cells widths.
JSFiddle: http://jsfiddle.net/Lzro9p6b/2/
let maxChars = 20;
let str = 'z';
setDynamicContent(str);
setInterval(function() {
if (str.length >= maxChars)
str = '';
str += 'zz';
setDynamicContent(str);
}, 1000);
function setDynamicContent(value) {
Array.from(document.getElementsByClassName('dynamic')).forEach(function(el){
el.innerHTML = value;
});
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
text-align: left;
}
td[colspan="2"] {
width: 100%;
}
.left-interesting-cell {
background: #faa;
}
.right-interesting-cell {
width: 100%;
background: #aaf;
}
.inner-table td {
width: 50%;
}
<h1>Why <code>left</code> and <code>right</code> cells are depends on dynamic content in Chrome 69?</h1>
<table>
<tbody>
<tr>
<td colspan="2">
<table class="inner-table">
<tbody>
<tr>
<td>Some dynamic content:</td>
<td class="dynamic"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="left-interesting-cell">left</td>
<td class="right-interesting-cell">right</td>
</tr>
</tbody>
</table>

Can't page break to work without messing up the table formatting

I have been having issues with page breaks in tables. Thought I had a solution as it was working fine in this SO question:
Inserting a page break into of <table> in React app
This worked fine for a table with one column, but nowt that I am working with multiple columns, it is a mess.
Basically I have to include display: block to get the page break to work properly, but that makes it go from a well formatted table to this:
I have gone down the list in MDN just trying anything that might work.
https://developer.mozilla.org/en-US/docs/Web/CSS/display
Furthermore, page breaks are only working when on their own separate <tr> which is undesirable since it generates a blank page. Got this sorted out by moving the pagebreak to the <tr> instead of the <td>.
I haven't been able to resolve these issues; any suggestions on how to approach this problem?
Not sure how useful a JSFiddle will be given the printing issue, but here is the compiled HTML. I can never get JSFiddle working with React:
https://jsfiddle.net/5gz62d91/
Best would probably be the Github repo:
https://github.com/ishraqiyun77/page-breaks
Here is the code separately:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import styles from '../assets/scss/app.scss';
class PageBreakIssues extends Component {
// Render the data points
renderDataPoint() {
let dataPoint = [];
for (let i = 1; i <= 3; i++) {
let num = (Math.random() * 100).toFixed(2);
dataPoint.push(
<td className='data-point' key={ i }>
{ num < 25 ? null : num }
</td>
)
}
return dataPoint;
}
// Start generating the row data
renderDataRow() {
let dataRow = [];
for (let i = 1; i <= 5; i++) {
dataRow.push(
<tr key={ i }>
<td className='data-name' colSpan='3' key={i}>Test - { i }</td>
{ this.renderDataPoint() }
</tr>
)
}
return dataRow;
}
// Start generating table sections with the section name
// COMMENT THIS OUT TO TRY WITOUT ADDING A BLANK ROW
renderSections() {
let sections = [];
for (let i = 1; i <= 10; i++) {
sections.push(
<tbody key={ i }>
<tr key={ i }>
<td colSpan='7' className='section-name' key={i} >
Section - { i }
</td>
</tr>
{ this.renderDataRow() }
{
i % 2 === 0
?
<tr className='pagebreak'>
<td colSpan='7'></td>
</tr>
:
null
}
</tbody>
)
}
return sections;
}
// Start generating table sections with the section name
// UNCOMMENT THIS SECTION TO TRY WITHOUT INSERT BLANK TR
// renderSections() {
// let sections = [];
// for (let i = 1; i <= 10; i++) {
// sections.push(
// <tbody key={i}>
// <tr key={i}>
// <td colSpan='7' className={ i % 2 === 0? 'section-name pagebreak' : 'section-name'} key={i} >
// Section - {i}
// </td>
// </tr>
// {this.renderDataRow()}
// </tbody>
// )
// }
// return sections;
// }
// Render the table with <th>
render() {
return (
<table>
<thead>
<tr>
<th colSpan='3'>Results</th>
<th>1</th>
<th>2</th>
<th>3</th>
</tr>
</thead>
{ this.renderSections() }
</table>
)
}
}
ReactDOM.render(<PageBreakIssues />, document.getElementById('app'));
#mixin borders {
border: 1px solid black;
}
%borders {
#include borders;
}
table {
border-spacing: 0;
th {
text-align: center;
}
tr {
th{
#extend %borders;
}
td {
#extend %borders;
&.data-name {
padding: 3px 100px 3px 3px;
}
&.data-point {
text-align: center;
padding: 3px 10px;
}
&.section-name {
background-color: #999;
}
}
}
}
#media print {
tr {
display: block;
}
.pagebreak {
break-before: always !important;
page-break-before: always !important;
page-break-inside: avoid !important;
}
}
I figure out an even more hard-coding method (so call perfectly solve your problem). I must said it is not elegant.
My method's main idea is changing tbody to display:block (as usual), but adding the .pagebreak to target tbody as well.
However, this method unattach tbody from the table and thus no longer align with thead. That's why I add a tr for printing thead, and remove the origin thead when print.
Added printing th, don't show in normal view
//Thead part, add a printing thead only shown in Print
//As originaly thead will has alloction problem
{ i % 2 === 1 ?
<tr className='printing-thead'>
<td colspan="3">Results</td>
<td>1</td>
<td>2</td>
<td>3</td>
</tr> : null
}
....
...
//Corrected Page break
</tbody>
<tbody class="pagebreak">
<tr>
<td colspan="7"></td>
</tr>
</tbody>
<tbody>
...
Corresponding CSS
table {
border-spacing: 0;
table-layout: fixed;
th {
text-align: center;
}
tr {
th {
#extend %borders;
}
td {
#extend %borders;
&.data-name {
padding: 3px 100px 3px 3px;
}
&.data-point {
text-align: center;
padding: 3px 10px;
}
&.section-name {
background-color: #999;
}
}
}
tr.printing-thead {
display: none;
}
}
#media print {
thead {
display: none;
}
tbody {
display: block;
tr.printing-thead {
display: contents;
font-weight: bold;
text-align: center;
}
}
.pagebreak {
height: 0px;
break-before: always !important;
page-break-before: always !important;
page-break-inside: avoid !important;
td {
display: none;
}
}
}
The JSfiddle.
And the react version
JSfiddle React Version

How to fix the positioning of scroll bar using css

I have a table:- HTML Code
<div class="table-scroll">
<table class="my-table" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>firstName</th>
<th>lastName</th>
<th>age</th>
<th>email</th>
<th>balance</th>
<th>Mode</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rowCollection" ng-class-even="'striped'">
<td>{{row.Row1}}-{{row.Row2}}</td>
<td>{{row.Row3 != null ? row.Row3 : " "}}</td>
<td><div class="width">{{row.Row4 != null ? row.Row4 : " "}}</div></td>
<td>{{row.Row5 != null ? (row.Row2 >= "50"? row.Row5 : (row.Row5 | date:'dd-MMM-yyyy')) : " "}}</td>
<td>{{row.Row2}}</td>
<td>{{row.Row5}}</td>
</tr>
</tbody>
</table>
</div>
CSS Code:-
.table-scroll {
overflow-x: scroll;
overflow-y:hidden;
height:60vh;}
.width{
width:50%;
}
.my-table {
width: 100%; }
.my-table tbody tr {
outline: none; }
.my-table tbody, thead {
display: block; }
.my-table tbody{
overflow-y:scroll;
max-height:50vh;
}
.my-table td {
min-width: 90px;
font-size: .7em;
padding: 6px;
text-align: center;
border-bottom: 1px solid #ddd; }
.my-table th {
min-width: 90px;
background-color: #58595b;
font-size: .7em;
color: #ddd;
padding: 6px;
border-bottom: 1px solid #777;
font-weight: bold;
border-right: 1px solid #333;
border-left: 1px solid #777;
text-align: center; }
.striped {
background-color: #eeeff1; }
JS Code:-
angular.module('myApp', ['smart-table','lrDragNDrop'])
.controller('mainCtrl', ['$scope', '$timeout',
function ($scope, $timeout) {
var nameList = ['Pierre', 'Pol', 'Jacques', 'Robert', 'Elisa'];
var familyName = ['Dupont', 'Germain', 'Delcourt', 'bjip', 'Menez'];
$scope.isLoading = false;
$scope.rowCollection = [];
function createRandomItem() {
var
firstName = nameList[Math.floor(Math.random() * 4)],
lastName = familyName[Math.floor(Math.random() * 4)],
age = Math.floor(Math.random() * 100),
email = firstName + lastName + '#whatever.com',
balance = Math.random() * 3000;
return {
Row1: firstName,
Row2: lastName,
Row3: age,
Row4: email,
Row5: balance
};
}
$scope.columns=['Row1','Row2','Row3','Row4','Row5'];
for(var i=0;i<50;i++){
$scope.rowCollection.push(createRandomItem());
}
}
]);
https://plnkr.co/edit/YCXMSjAQ4VVSyvVFNLoI?p=preview
Here I am trying to fix the column headers and applying the vertical scroll to my tbody.
But the scroll appears at the very end when user scrolls through the horizontal scroll. I am trying to fix the position of vertical scroll but it changes my table look. Also, to achieve above I used display:block to tbody and thead but that ruins the alignment of columns. Can anybody please help me fixing the above issue.
.my-table tbody, thead {display: inline-block; }
.my-table th {min-width:92px;}

Filter table with multiple columns

Just trying to filter a table but also have it filter the number with and without dashes (working) but also search the name and id as well. Its only searching the one column since the index is [0].
How would I have it search all 3 columns? So if I search number or id or name it would filter. Here is the working code I have so far to search number.
<!DOCTYPE html>
<html>
<head>
<style>
* {
box-sizing: border-box;
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 18px;
}
#myTable th, #myTable td {
text-align: left;
padding: 12px;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#myTable tr.header, #myTable tr:hover {
background-color: #f1f1f1;
}
</style>
</head>
<body>
<h2>Number search</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Number</th>
<th style="width:60%;">Name</th>
<th style="width:60%;">ID</th>
</tr>
<tr>
<td>905-373-3333</td>
<td>Mike</td>
<td>4563</td>
</tr>
<tr>
<td>905-333-3333</td>
<td>adam</td>
<td>8963</td>
</tr>
<tr>
<td>416-373-3432</td>
<td>Jim</td>
<td>9363</td>
</tr>
</table>
<script>
function myFunction() {
var input, filter, table, tr, td, i, cleanedFilter;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
cleanedFilter = filter.replace("-","");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
cellContent = td.innerHTML.toUpperCase().replace(/-/g,"");
if (cellContent.indexOf(cleanedFilter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>
</body>
</html>
If you want to use a filter for every td available in your rows, you can use the following:
(function(document) {
'use strict';
var LightTableFilter = (function(Arr) {
var _input;
function _onInputEvent(e) {
_input = e.target;
var tables = document.getElementsByClassName(_input.getAttribute('data-table'));
Arr.forEach.call(tables, function(table) {
Arr.forEach.call(table.tBodies, function(tbody) {
Arr.forEach.call(tbody.rows, _filter);
});
});
}
function _filter(row) {
var text = row.textContent.toLowerCase(), val = _input.value.toLowerCase();
row.style.display = text.indexOf(val) === -1 ? 'none' : 'table-row';
}
return {
init: function() {
var inputs = document.getElementsByClassName('light-table-filter');
Arr.forEach.call(inputs, function(input) {
input.oninput = _onInputEvent;
});
}
};
})(Array.prototype);
document.addEventListener('readystatechange', function() {
if (document.readyState === 'complete') {
LightTableFilter.init();
}
});
})(document);
<section class="container">
<input type="search" class="light-table-filter" data-table="order-table" placeholder="Filter">
<table class="order-table table">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Number 2</th>
<th>Number 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Column One</td>
<td>Two</td>
<td>352353</td>
<td>1</td>
</tr>
<tr>
<td>Column Two</td>
<td>Two</td>
<td>4646</td>
<td>2</td>
</tr>
</tbody>
</table>
</section>