Show all on option click - javascript

I got this filter where everything works perflectly. When I press specific category it will list only rows with that categories. But I realized that I don't know how to show them all after click on first option. My goal is. On "Categories" click show all rows and on specific category click show only specific category.
highlightRows = () => {
let oddRows = document.querySelectorAll('tbody > tr.show')
oddRows.forEach((row, index)=> {
if (index % 2 == 0) {
row.style.background = '#f1f1f1'
} else {
row.style.background = '#fff'
}
})
}
const filterOptions = () => {
const option = document.querySelector("#filter").value;
const selection = option.replace('&', '')
const rows = document.querySelectorAll("#body1 > tr");
console.log(rows.length);
rows.forEach(row => {
let td = row.querySelector("td:last-child");
let filter = td.innerText.replace('&', '');
if (filter === selection) {
row.className = 'show'
} else {
row.className = 'hidden'
}
});
highlightRows()
};
document.getElementById("filter").addEventListener("change", filterOptions);
.table-filters {
display: flex;
align-items: center;
justify-content: center;
margin: 2em;
text-align: center;
}
.table-filters a {
color: #222;
font-size: 16px;
font-weight: 500;
margin-right: 1em;
display: inline-block;
}
.table-filters a:hover {
text-decoration: none;
}
.table-filters select {
background: #fff;
font-size: 16px;
font-weight: 500;
width: 12em;
height: 2.5em;
}
table.stats {
background: #fff;
width: 100%;
table-layout: fixed;
border-radius: 6px;
}
tbody tr.show {
display: table-row;
}
tbody tr.hidden {
display: none;
}
table.vypis {
border: 1px solid #ccc;
border-collapse: collapse;
margin: 0;
padding: 0;
width: 100%;
table-layout: fixed;
}
table.vypis > caption {
font-size: 1.5em;
margin: .5em 0 .75em;
}
table.vypis > tr.vypis-riadok {
background-color: #f8f8f8;
border: 1px solid #ddd;
padding: .35em;
}
table.vypis th,
table.vypis td {
padding: .625em;
text-align: center;
}
table.vypis th {
font-size: .85em;
letter-spacing: .1em;
text-transform: uppercase;
}
#media screen and (max-width: 800px) {
table.vypis {
border: 0;
}
table.vypis > caption {
font-size: 1.3em;
}
table.vypis > thead {
border: none;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
table.vypis tr {
border-bottom: 3px solid #ddd;
display: block;
margin-bottom: .625em;
}
table.vypis td {
border-bottom: 1px solid #ddd;
display: block;
font-size: .8em;
text-align: right;
}
table.vypis td::before {
content: attr(data-label);
float: left;
font-weight: bold;
text-transform: uppercase;
}
table.vypis td:last-child {
border-bottom: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="table-filters">
<select id="filter">
<option selected value="none">Categories</option>
<option>Hobby</option>
<option>Others</option>
</select>
</div>
<table class="vypis">
<caption>Pohyby na účte</caption>
<thead>
<tr>
<th scope="col">Refer</th>
<th scope="col">Date</th>
<th scope="col">Price</th>
<th scope="col">Category</th>
</tr>
</thead>
<tbody id="body1">
<tr class="vypis-riadok">
<td scope="row" data-label="refer">[[X04_riadok_1_popis_transakcie]] <br> [[X10_riadok_2_popis_transakcie]]</td>
<td data-label="date">[[X02_riadok_1_datum]]</td>
<td data-label="price">[[X08_riadok_1_suma]] €</td>
<td data-label="category">Others</td>
</tr>
<tr class="vypis-riadok">
<td scope="row" data-label="refer">[[X04_riadok_1_popis_transakcie]] <br> [[X10_riadok_2_popis_transakcie]]</td>
<td data-label="date">[[X02_riadok_1_datum]]</td>
<td data-label="price">[[X08_riadok_1_suma]] €</td>
<td data-label="category">Hobby</td>
</tr>
<tr class="vypis-riadok">
<td scope="row" data-label="refer">[[X04_riadok_1_popis_transakcie]] <br> [[X10_riadok_2_popis_transakcie]]</td>
<td data-label="date">[[X02_riadok_1_datum]]</td>
<td data-label="price">[[X08_riadok_1_suma]] €</td>
<td data-label="category">Others</td>
</tr>

As you are adding hidden class so need to remove this when categories option is clicked so one way is to loop through tr and check if the tr contains that class and then just change it to show .
Demo Code :
highlightRows = () => {
let oddRows = document.querySelectorAll('tbody > tr.show')
oddRows.forEach((row, index) => {
if (index % 2 == 0) {
row.style.background = '#f1f1f1'
} else {
row.style.background = '#fff'
}
})
}
const filterOptions = () => {
const option = document.querySelector("#filter").value;
const selection = option.replace('&', '')
const rows = document.querySelectorAll("#body1 > tr");
//check if value is not none
if (option != "none") {
rows.forEach(row => {
let td = row.querySelector("td:last-child");
let filter = td.innerText.replace('&', '');
if (filter === selection) {
row.className = 'show'
} else {
row.className = 'hidden'
}
});
highlightRows()
} else {
//loop though rows
rows.forEach(row => {
//check if row has class hidden
if (row.classList.contains("hidden")) {
row.className = 'show'//add showclass
}
})
highlightRows()
}
};
document.getElementById("filter").addEventListener("change", filterOptions);
.table-filters {
display: flex;
align-items: center;
justify-content: center;
margin: 2em;
text-align: center;
}
.table-filters a {
color: #222;
font-size: 16px;
font-weight: 500;
margin-right: 1em;
display: inline-block;
}
.table-filters a:hover {
text-decoration: none;
}
.table-filters select {
background: #fff;
font-size: 16px;
font-weight: 500;
width: 12em;
height: 2.5em;
}
table.stats {
background: #fff;
width: 100%;
table-layout: fixed;
border-radius: 6px;
}
tbody tr.show {
display: table-row;
}
tbody tr.hidden {
display: none;
}
table.vypis {
border: 1px solid #ccc;
border-collapse: collapse;
margin: 0;
padding: 0;
width: 100%;
table-layout: fixed;
}
table.vypis>caption {
font-size: 1.5em;
margin: .5em 0 .75em;
}
table.vypis>tr.vypis-riadok {
background-color: #f8f8f8;
border: 1px solid #ddd;
padding: .35em;
}
table.vypis th,
table.vypis td {
padding: .625em;
text-align: center;
}
table.vypis th {
font-size: .85em;
letter-spacing: .1em;
text-transform: uppercase;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="table-filters">
<select id="filter">
<option selected value="none">Categories</option>
<option>Hobby</option>
<option>Others</option>
</select>
</div>
<table class="vypis">
<caption>Pohyby na účte</caption>
<thead>
<tr>
<th scope="col">Refer</th>
<th scope="col">Date</th>
<th scope="col">Price</th>
<th scope="col">Category</th>
</tr>
</thead>
<tbody id="body1">
<tr class="vypis-riadok">
<td scope="row" data-label="refer">[[X04_riadok_1_popis_transakcie]] <br> [[X10_riadok_2_popis_transakcie]]</td>
<td data-label="date">[[X02_riadok_1_datum]]</td>
<td data-label="price">[[X08_riadok_1_suma]] €</td>
<td data-label="category">Others</td>
</tr>
<tr class="vypis-riadok">
<td scope="row" data-label="refer">[[X04_riadok_1_popis_transakcie]] <br> [[X10_riadok_2_popis_transakcie]]</td>
<td data-label="date">[[X02_riadok_1_datum]]</td>
<td data-label="price">[[X08_riadok_1_suma]] €</td>
<td data-label="category">Hobby</td>
</tr>
<tr class="vypis-riadok">
<td scope="row" data-label="refer">[[X04_riadok_1_popis_transakcie]] <br> [[X10_riadok_2_popis_transakcie]]</td>
<td data-label="date">[[X02_riadok_1_datum]]</td>
<td data-label="price">[[X08_riadok_1_suma]] €</td>
<td data-label="category">Others</td>
</tr>
</tbody>
</table>

Related

Close other div when new is clicked

So I have this table with a menu dropdown, but I'm having trouble getting the divs close when I click on one of the other menu dropdown divs. This is because the JS looks for a click inside/outside of the class, but how can I change this?
I'm trying to avoid the user from opening multiple dropdown menus at the same time, like this:
Here is the working code to see the problem.
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function wdc_jql_menu(menu_id) {
document.getElementById(menu_id).classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
.wdc_jql_table{
/* table width */
border:1;
width: 100%;
border-spacing: 0;
border-collapse: collapse;
background-color: #2F2F35;
table-layout:fixed; // Cells is fixed to the percentage the cells is assigned too
word-wrap:break-word;
color: white;
}
.wdc_jql_table thead, tr{
/* table style - bottom borders to seperate rows */
border-bottom: 1.5px solid #3A3B41;
}
.wdc_jql_table tr:last-child{
/* table style - no border at last row */
border-bottom: none;
}
.wdc_jql_table
th:nth-child(1),
th:nth-child(2),
th:nth-child(3),
th:nth-child(4){
/* table child th align (project name, owner, jql) */
text-align: left;
font-size: 24px;
padding: 5px;
}
.wdc_jql_table
td:nth-child(1),
td:nth-child(2),
td:nth-child(3){
/* table child td align (project name, owner, jql) */
text-align: left;
font-size: 16px;
padding: 5px;
}
.wdc_jql_table
td:nth-child(4){
/* table child td align (...) */
text-align: center;
font-size: 16px;
padding-top: 5px;
padding-bottom: 5px;
padding-right: 15px;
padding-left: 10px;
}
.wdc_jql_col1{
/* table col(project name) width */
width: 20%;
}
.wdc_jql_col2{
/* table col(owner) width */
width: 20%;
}
.wdc_jql_col3{
/* table col(jql) width */
width: 50%;
}
.wdc_jql_col4{
/* table col(...) width */
width: 10%;
}
/* MENU DESIGN */
.dropbtn {
background-color: #2F2F35;
color: white;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #8D90A1;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block;}
<table id="others_jql" class="wdc_jql_table padding_jql_bottom">
<col class="wdc_jql_col1">
<col class="wdc_jql_col2">
<col class="wdc_jql_col3">
<col class="wdc_jql_col4">
<thead>
<tr>
<th>Project Name</th>
<th>Owner</th>
<th>JQL</th>
<th></th>
</tr>
</thead>
<tbody id="table_body_others">
<tr id="tr1">
<td name="projectNameTable">td1</td>
<td name="employeeNo">td2</td>
<td name="jqlTable">td3</td>
<td name="edit_personal"><button onclick="wdc_jql_menu('menu_1')" class="dropbtn">⋮</button>
<div id="menu_1" class="dropdown-content">
Edit
Remove
</div>
</tr>
<tr id="tr2">
<td name="projectNameTable">td11</td>
<td name="employeeNo">td22</td>
<td name="jqlTable">td33</td>
<td name="edit_personal"><button onclick="wdc_jql_menu('menu_2')" class="dropbtn">⋮</button>
<div id="menu_2" class="dropdown-content">
Edit
Remove
</div>
</tr>
<tr id="tr3">
<td name="projectNameTable">td11</td>
<td name="employeeNo">td22</td>
<td name="jqlTable">td33</td>
<td name="edit_personal"><button onclick="wdc_jql_menu('menu_3')" class="dropbtn">⋮</button>
<div id="menu_3" class="dropdown-content">
Edit
Remove
</div>
</tr>
</tbody>
</table>
So the solution is to rewrite the JS to listen for the div ID and then close the other open/shown classes I guess, but how?
Thanks to the comment
Either find the element that currently has the class show and then remove that class, before you set it for the current one; or remember what element you added the class to the previous time, and then remove it from that. – CBroe
the solution was created here:
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function wdc_jql_menu(menu_id) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
document.getElementById(menu_id).classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
.wdc_jql_table{
/* table width */
border:1;
width: 100%;
border-spacing: 0;
border-collapse: collapse;
background-color: #2F2F35;
table-layout:fixed; // Cells is fixed to the percentage the cells is assigned too
word-wrap:break-word;
color: white;
}
.wdc_jql_table thead, tr{
/* table style - bottom borders to seperate rows */
border-bottom: 1.5px solid #3A3B41;
}
.wdc_jql_table tr:last-child{
/* table style - no border at last row */
border-bottom: none;
}
.wdc_jql_table
th:nth-child(1),
th:nth-child(2),
th:nth-child(3),
th:nth-child(4){
/* table child th align (project name, owner, jql) */
text-align: left;
font-size: 24px;
padding: 5px;
}
.wdc_jql_table
td:nth-child(1),
td:nth-child(2),
td:nth-child(3){
/* table child td align (project name, owner, jql) */
text-align: left;
font-size: 16px;
padding: 5px;
}
.wdc_jql_table
td:nth-child(4){
/* table child td align (...) */
text-align: center;
font-size: 16px;
padding-top: 5px;
padding-bottom: 5px;
padding-right: 15px;
padding-left: 10px;
}
.wdc_jql_col1{
/* table col(project name) width */
width: 20%;
}
.wdc_jql_col2{
/* table col(owner) width */
width: 20%;
}
.wdc_jql_col3{
/* table col(jql) width */
width: 50%;
}
.wdc_jql_col4{
/* table col(...) width */
width: 10%;
}
/* MENU DESIGN */
.dropbtn {
background-color: #2F2F35;
color: white;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #8D90A1;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block;}
<table id="others_jql" class="wdc_jql_table padding_jql_bottom">
<col class="wdc_jql_col1">
<col class="wdc_jql_col2">
<col class="wdc_jql_col3">
<col class="wdc_jql_col4">
<thead>
<tr>
<th>Project Name</th>
<th>Owner</th>
<th>JQL</th>
<th></th>
</tr>
</thead>
<tbody id="table_body_others">
<tr id="tr1">
<td name="projectNameTable">td1</td>
<td name="employeeNo">td2</td>
<td name="jqlTable">td3</td>
<td name="edit_personal"><button onclick="wdc_jql_menu('menu_1')" class="dropbtn">⋮</button>
<div id="menu_1" class="dropdown-content">
Edit
Remove
</div>
</tr>
<tr id="tr2">
<td name="projectNameTable">td11</td>
<td name="employeeNo">td22</td>
<td name="jqlTable">td33</td>
<td name="edit_personal"><button onclick="wdc_jql_menu('menu_2')" class="dropbtn">⋮</button>
<div id="menu_2" class="dropdown-content">
Edit
Remove
</div>
</tr>
<tr id="tr3">
<td name="projectNameTable">td11</td>
<td name="employeeNo">td22</td>
<td name="jqlTable">td33</td>
<td name="edit_personal"><button onclick="wdc_jql_menu('menu_3')" class="dropbtn">⋮</button>
<div id="menu_3" class="dropdown-content">
Edit
Remove
</div>
</tr>
</tbody>
</table>
Hello just tried below code and worked,
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function wdc_jql_menu(menu_id) {
clearDropdown();
document.getElementById(menu_id).classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
clearDropdown();
}
}
function clearDropdown() {
const boxes = document.querySelectorAll('.dropdown-content');
boxes.forEach(box => {
box.classList.remove('show');
});
}

mobile version filter is not showing properly

I made filter based on selection in input. It shows only items with same category on click. On desktop version when I click for example "Others" it will list only tr with Others in category but when I resize on mobile version and press filter, so nothing happen. All tr's are still showing. Really don't have idea what is difference between mobile and desktop version when JS is working with same code in both views.
highlightRows = () => {
let oddRows = document.querySelectorAll('tbody > tr.show')
oddRows.forEach((row, index)=> {
if (index % 2 == 0) {
row.style.background = '#f1f1f1'
} else {
row.style.background = '#fff'
}
})
}
const filterOptions = () => {
const option = document.querySelector("#filter").value;
const selection = option.replace('&', '')
const rows = document.querySelectorAll("#body1 > tr");
console.log(rows.length);
rows.forEach(row => {
let td = row.querySelector("td:last-child");
let filter = td.innerText.replace('&', '');
if (filter === selection) {
row.className = 'show'
} else {
row.className = 'hidden'
}
});
highlightRows()
};
document.getElementById("filter").addEventListener("change", filterOptions);
.table-filters {
display: flex;
align-items: center;
justify-content: center;
margin: 2em;
text-align: center;
}
.table-filters a {
color: #222;
font-size: 16px;
font-weight: 500;
margin-right: 1em;
display: inline-block;
}
.table-filters a:hover {
text-decoration: none;
}
.table-filters select {
background: #fff;
font-size: 16px;
font-weight: 500;
width: 12em;
height: 2.5em;
}
table.stats {
background: #fff;
width: 100%;
table-layout: fixed;
border-radius: 6px;
}
tbody tr.show {
display: table-row;
}
tbody tr.hidden {
display: none;
}
table.vypis {
border: 1px solid #ccc;
border-collapse: collapse;
margin: 0;
padding: 0;
width: 100%;
table-layout: fixed;
}
table.vypis > caption {
font-size: 1.5em;
margin: .5em 0 .75em;
}
table.vypis > tr.vypis-riadok {
background-color: #f8f8f8;
border: 1px solid #ddd;
padding: .35em;
}
table.vypis th,
table.vypis td {
padding: .625em;
text-align: center;
}
table.vypis th {
font-size: .85em;
letter-spacing: .1em;
text-transform: uppercase;
}
#media screen and (max-width: 800px) {
table.vypis {
border: 0;
}
table.vypis > caption {
font-size: 1.3em;
}
table.vypis > thead {
border: none;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
table.vypis tr {
border-bottom: 3px solid #ddd;
display: block;
margin-bottom: .625em;
}
table.vypis td {
border-bottom: 1px solid #ddd;
display: block;
font-size: .8em;
text-align: right;
}
table.vypis td::before {
content: attr(data-label);
float: left;
font-weight: bold;
text-transform: uppercase;
}
table.vypis td:last-child {
border-bottom: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="table-filters">
<select id="filter">
<option disabled selected value="none">Categories</option>
<option>Hobby</option>
<option>Others</option>
</select>
</div>
<table class="vypis">
<caption>Pohyby na účte</caption>
<thead>
<tr>
<th scope="col">Refer</th>
<th scope="col">Date</th>
<th scope="col">Price</th>
<th scope="col">Category</th>
</tr>
</thead>
<tbody id="body1">
<tr class="vypis-riadok">
<td scope="row" data-label="refer">[[X04_riadok_1_popis_transakcie]] <br> [[X10_riadok_2_popis_transakcie]]</td>
<td data-label="date">[[X02_riadok_1_datum]]</td>
<td data-label="price">[[X08_riadok_1_suma]] €</td>
<td data-label="category">Others</td>
</tr>
<tr class="vypis-riadok">
<td scope="row" data-label="refer">[[X04_riadok_1_popis_transakcie]] <br> [[X10_riadok_2_popis_transakcie]]</td>
<td data-label="date">[[X02_riadok_1_datum]]</td>
<td data-label="price">[[X08_riadok_1_suma]] €</td>
<td data-label="category">Hobby</td>
</tr>
<tr class="vypis-riadok">
<td scope="row" data-label="refer">[[X04_riadok_1_popis_transakcie]] <br> [[X10_riadok_2_popis_transakcie]]</td>
<td data-label="date">[[X02_riadok_1_datum]]</td>
<td data-label="price">[[X08_riadok_1_suma]] €</td>
<td data-label="category">Others</td>
</tr>
Your code works well, but the problem is with rule display: block, which is in the media query. in the table.vypis tr selector. This rule overrides another block hiding rule. You need to remove display: block out of table.vypis tr.
#media screen and (max-width: 800px) {
...
table.vypis tr {
border-bottom: 3px solid #ddd;
display: block;
margin-bottom: .625em;
}
...
}
Or a second solution:
Add! !important to rule display: none, selector tbody tr.hidden. It should look like this:
tbody tr.hidden {
display: none!important;
}
I advise you to use the second solution!

How to create td border with text

I would like to create a simply table with default border and then get the 'hover' event on td elements (probably by jquery) which will cause:
a) the top border should be black with empty space in the middle
b) in the middle of the border should be displayed the text from the p element from that td(text should be positioned between hovered and previous element)
the result should looks like (I mark the hovered element by different color):
I am not sure but probably it is impossible to do that just by using css, I tried to implement simply example but it doesnt work. The idea was to create a two divs (to imitate the top border) and p element. The problem is because the divs are always invisible (should replaces the normal td border when element is hovered), I also dont know how to position p element as needed.
How could I get the right solution?
$(document).ready(function() {
var tableBodyContent = "";
for (var i = 0; i < 10; i++) {
tableBodyContent += '<tr>' +
'<td><div class="myTopBorder"><div class="myBorder leftBorder"></div><div class="myBorder rightBorder"></div></div><p class="myText" value="' + i + ':00">ok</p>Item ' + i + '</td>' +
'<td><div class="myTopBorder"><div class="myBorder leftBorder"></div><div class="myBorder rightBorder"></div></div><p class="myText" value="' + i + ':00">ok</p>Item ' + i + '</td>' +
'<td><div class="myTopBorder"><div class="myBorder leftBorder"></div><div class="myBorder rightBorder"></div></div><p class="myText" value="' + i + ':00">ok</p>Item ' + i + '</td>' +
'<td><div class="myTopBorder"><div class="myBorder leftBorder"></div><div class="myBorder rightBorder"></div></div><p class="myText" value="' + i + ':00">ok</p>Item ' + i + '</td>' +
'<td><div class="myTopBorder"><div class="myBorder leftBorder"></div><div class="myBorder rightBorder"></div></div><p class="myText" value="' + i + ':00">ok</p>Item ' + i + '</td>' +
'</tr>'
}
$("#timeTableBody").append(tableBodyContent);
});
$("td").hover(
function() {
$(this).find(".myBorder").each(function(index) {
$(this).show();
});
},
function() {
$(this).find(".myBorder").each(function(index) {
$(this).hide();
});
}
);
table {
border: none;
border-collapse: collapse;
padding: 0;
margin: 0;
}
th,
td {
width: 45px;
height: 20px;
padding: 10px;
}
.myTopBorder {
height: 1px;
width: 100%;
}
.leftBorder,
.rightBorder {
height: 100%;
width: 30%;
display: none;
}
.leftBorder {
float: left;
}
.rightBorder {
float: right;
}
th {
border: 1px solid black;
}
td {
border-top: 1px solid lightgrey;
border-left: 1px solid lightgrey;
border-right: 1px solid lightgrey;
}
td:hover {
border: none;
}
.myText {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
</tr>
</thead>
<tbody id="timeTableBody">
</tbody>
</table>
What you require can be done using CSS alone. By placing the value to display on hover in a data attribute on the td you can easily read it out in to the content of a psuedo element using attr(). Then you can use a similar technique to create the left and right sides of the border on hover, something like this:
$(document).ready(function() {
var tableBodyContent = '';
for (var i = 0; i < 10; i++) {
var rowArr = (new Array(5)).fill('<td data-hover="' + i + ':00"><i></i><p class="item">Item ' + i + '</p></td>', 0, 5);
tableBodyContent += '<tr>' + rowArr.join('') + '</tr>'
}
$("#timeTableBody").append(tableBodyContent);
});
table {
border-collapse: collapse;
padding: 0;
margin: 0;
background-color: #EFEFEF;
}
th,
td {
width: 45px;
height: 20px;
padding: 10px;
}
th {
border: 1px solid black;
border-bottom: 0;
}
td {
border: 1px solid lightgrey;
border-bottom: 0;
position: relative;
}
td i:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 16px;
height: 1px;
background-color: #000;
display: none;
}
td i:after {
content: '';
position: absolute;
top: 0;
right: 0;
width: 16px;
height: 1px;
background-color: #000;
display: none;
}
td:before {
content: attr(data-hover);
position: absolute;
top: -7px;
left: 18px;
width: 30px;
font-size: 0.8em;
text-align: center;
display: none;
}
td:hover {
border-top-color: transparent !important;
background-color: #DEDEDE;
}
td:hover p {
display: none;
}
td:hover:before,
td:hover i:before,
td:hover i:after {
display: block;
}
tbody tr:nth-child(1) td {
border-top-color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
</tr>
</thead>
<tbody id="timeTableBody"></tbody>
</table>
You can use content: attr(data-value) like this :
Full css & shortest solution :
$(document).ready(function() {
for (let i = 0, $tr; i < 10; i++) {
$tr = $("<tr></tr>")
.appendTo("#timeTableBody");
for (var day = 0; day < 5; day++)
$("<td></td>")
.attr("data-value", i + ":00")
.text("Item " + i)
.appendTo($tr);
}
});
table {
border: none;
border-collapse: collapse;
padding: 0;
margin: 0;
}
th,
td {
width: 45px;
height: 20px;
padding: 10px;
}
th {
border: 1px solid black;
}
td {
border: 1px solid lightgrey;
position: relative;
}
td:hover::after {
content: attr(data-value);
position: absolute;
bottom: -8px;
line-height: 12px;
font-size: 12px;
background: white;
padding: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th>
</tr>
</thead>
<tbody id="timeTableBody">
</tbody>
</table>
You can use pseudo element and data attribute for the content like below:
table {
border: none;
border-collapse: collapse;
padding: 0;
margin: 0;
}
th,
td {
width: 45px;
height: 20px;
padding: 10px;
}
th {
border: 1px solid black;
}
td {
border-top: 1px solid lightgrey;
border-left: 1px solid lightgrey;
border-right: 1px solid lightgrey;
position: relative;
}
td::before {
content: attr(data-text);
position: absolute;
z-index: 2;
top: -5px;
font-size: 10px;
left: 0;
right: 0;
text-align: center;
background: linear-gradient(green, green) center left/20px 1px, linear-gradient(green, green) center right/20px 1px;
background-repeat: no-repeat;
opacity: 0;
}
td:hover {
border-top: 0;
background: orange;
}
td:hover::before {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
</tr>
</thead>
<tbody id="timeTableBody">
<tr>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
</tr>
<tr>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
</tr>
<tr>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
<td data-text="3:00">Item 0</td>
</tr>
</tbody>
</table>

Hide table header without seach input using HTML/CSS/JavaScript

I'm trying to create a table with a header, which is completely hidden without any input. I have the following code, but the header is still visible. I have tried many, many different options, but I can't seem to be able to hide the header when the search input is empty.
Detail: I can't use jQuery.
To add: I have searched and tried for 3 days now (I have zero education on this matter). I have read a lot of posts and websites.
The thing is that I have to add it to a HTML macro. The weird thing is that for instance var tr = getElementsByTagName("tr"); is not replaceable by var tr = table.rows. When I enter this in the function, it doesn't render what it normally renders. So it could be I did already find the answer, but it's purely the macro causing the issue.
The following code is working, but displays the header:
a) Javascript
document.addEventListener('DOMContentLoaded', function () {
if (document.getElementById("myInput").value.length > 1) {
document.getElementById("header").className= "hideHeader";
} else {
ContactsearchFX();
document.getElementById('myInput').addEventListener('input', ContactsearchFX);
}
});
function ContactsearchFX() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 1; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td"),
match = false;
for (j = 0; j < td.length; j++) {
if (filter && td[j].textContent.toUpperCase().indexOf(filter) > -1) {
match = true;
break;
}
}
if (!match) {
tr[i].style.display = "none";
} else {
tr[i].style.display = "";
}
}
}
b) HTML
<br>
<img src="www.example.com/somebanner.png" class="centered">
<br>
<input class="form-control" style="width:40%" type="search" id="myInput" placeholder="Enter keywords here...">
<table id="myTable">
<tr class="header">
<th style="width:20%;">One</th>
<th style="width:20%;">Two</th>
<th style="width:20%;">Three</th>
<th style="width:60%;">Four</th>
</tr>
<tr>
<td>aaaa</td>
<td>bbbb</td>
<td>cccc</td>
<td>dddd</td>
</tr>
<tr>
<td>eeee</td>
<td>ffff</td>
<td>gggg</td>
<td>hhhh</td>
</tr>
<tr>
<td>iiii</td>
<td>jjjj</td>
<td>kkkk</td>
<td>llll</td>
</tr>
</table>
c) CSS
.hideHeader {
position: fixed;
display: none;
}
.centered {
display: block;
margin-left: auto;
margin-right: auto;
width: 18%;
}
.form-control {
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: 200px;
width: 18%;
-webkit-box-shadow: 0 8px 6px -6px black;
-moz-box-shadow: 0 8px 6px -6px black;
box-shadow: 0 8px 6px -6px black;
}
#myInput{
width: 100%;
font-size: 14px;
padding: 14px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 75px;
align: center;
}
#myTable{
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 14px;
margin-top: 75px;
}
#myTable th,
#myTable td {
text-align: left;
padding: 12px;
font-size: 12px;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
margin-top: 12px;
background-color: #f1f1f1;
font-size: 14px;
}
define the class in css :
.hideHeader {
display: none;
}
add it to the header in html :
<tr class="header hideHeader">
and then use Js to remove and return the class to the header :
var table = document.getElementById("myTable");
var tableHeader = table.getElementsByClassName("header")[0];
if (input.value.length > 0) {
if (tableHeader.classList.contains("hideHeader")) {
tableHeader.classList.remove("hideHeader");
}
} else {
if (!tableHeader.classList.contains("hideHeader")) {
tableHeader.classList.add("hideHeader");
}
}
here is the whole code :
document.addEventListener('DOMContentLoaded', function() {
if (document.getElementById("myInput").value.length > 1) {
document.getElementById("header").className = "hideHeader";
} else {
ContactsearchFX();
document.getElementById('myInput').addEventListener('input', ContactsearchFX);
}
});
function ContactsearchFX() {
var input, filter, table, tr, td, i;
var input = document.getElementById("myInput");
var table = document.getElementById("myTable");
var filter = input.value.toUpperCase();
var tr = table.getElementsByTagName("tr");
var tableHeader = table.getElementsByClassName("header")[0];
if (input.value.length > 0) {
if (tableHeader.classList.contains("hideHeader")) {
tableHeader.classList.remove("hideHeader");
}
} else {
if (!tableHeader.classList.contains("hideHeader")) {
tableHeader.classList.add("hideHeader");
}
}
for (i = 1; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td"),
match = false;
for (j = 0; j < td.length; j++) {
if (filter && td[j].textContent.toUpperCase().indexOf(filter) > -1) {
match = true;
break;
}
}
if (!match) {
tr[i].style.display = "none";
} else {
tr[i].style.display = "";
}
}
}
.hideHeader {
display: none;
}
.centered {
display: block;
margin-left: auto;
margin-right: auto;
width: 18%;
}
.form-control {
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: 200px;
width: 18%;
-webkit-box-shadow: 0 8px 6px -6px black;
-moz-box-shadow: 0 8px 6px -6px black;
box-shadow: 0 8px 6px -6px black;
}
#myInput {
width: 100%;
font-size: 14px;
padding: 14px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 75px;
align: center;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 14px;
margin-top: 75px;
}
#myTable th,
#myTable td {
text-align: left;
padding: 12px;
font-size: 12px;
}
#myTable tr.header,
#myTable tr:hover {
margin-top: 12px;
background-color: #f1f1f1;
font-size: 14px;
}
<br>
<img src="http://www.atelierdecoz.fr/img/cms/thunderbird-logo-200x200.png" class="centered">
<br>
<input class="form-control" style="width:40%" type="search" id="myInput" placeholder="Enter keywords here...">
<table id="myTable">
<tr class="header hideHeader">
<th style="width:20%;">One</th>
<th style="width:20%;">Two</th>
<th style="width:20%;">Three</th>
<th style="width:60%;">Four</th>
</tr>
<tr>
<td>aaaa</td>
<td>bbbb</td>
<td>cccc</td>
<td>dddd</td>
</tr>
<tr>
<td>eeee</td>
<td>ffff</td>
<td>gggg</td>
<td>hhhh</td>
</tr>
<tr>
<td>iiii</td>
<td>jjjj</td>
<td>kkkk</td>
<td>llll</td>
</tr>
</table>

Add rows and columns to the table on click with javascript

I am completely new to JavaScript, so, sorry for asking this simple question. The point is that there have been numerous similar questions here and on other platforms. I've tried all solutions provided but neither of them worked in my case. I assume that this is because of my CSS, otherwise I do not know what is the reason. I tried different methods: insertRow, clone etc. neither of them worked.
The point is that my program needs to add row or column to the table on click on the buttons. Right button should add column to the right of the table, bottom button should add row to the bottom of the table.
// append row to the HTML table
function appendRow() {
var tbl = document.getElementById('my-table'), // table reference
row = tbl.insertRow(tbl.rows.length), // append table row
i;
// insert table cells to the new row
for (i = 0; i < tbl.rows[0].cells.length; i++) {
createCell(row.insertCell(i), i, 'row');
}
};
// create DIV element and append to the table cell
function createCell(cell) {
var div = document.createElement('div'), // create DIV element
cell.appendChild(div); // append DIV to the table cell
};
// append column to the HTML table
function appendColumn() {
var tbl = document.getElementById('my-table'), // table reference
i;
// open loop for each row and append cell
for (i = 0; i < tbl.rows.length; i++) {
createCell(tbl.rows[i].insertCell(tbl.rows[i].cells.length), i, 'col');
}
};
#canvas {
align-content: center;
height: 1000px;
}
#my-table {
margin: 0 -2px -2px 0;
border: #FFF;
border: 1px solid rgb(72, 170, 230);
display: inline-block;
}
tr {
background: rgb(72, 170, 230);
}
td {
width: 50px;
height: 50px;
}
.add {
height: 52px;
width: 52px;
background: rgb(243, 165, 0);
cursor: pointer;
color: #FFF;
text-align: center;
font-family: 'Open Sans', sans-serif;
transition-property: background;
transition-duration: 1s;
transition-timing-function: linear;
}
#addColumn {
display: inline-block;
vertical-align: top;
margin: 2px 0 0 0;
}
.add:hover {
background: rgb(246, 192, 82);
}
#addColumnChild {
line-height: 50px;
}
#addRow {
vertical-align: bottom;
margin: 0 0 0 2px;
}
#addRowChild {
line-height: 50px;
}
.del {
height: 52px;
width: 52px;
background: rgb(178, 0, 0);
cursor: pointer;
color: #FFF;
text-align: center;
font-family: 'Open Sans', sans-serif;
transition-property: background;
transition-duration: 1s;
transition-timing-function: linear;
}
#delColumn {
display: inline-block;
vertical-align: top;
margin: 2px 0 0 0;
}
.del:hover {
background: rgb(202, 76, 73);
}
#delColumnChild {
line-height: 50px;
}
#delRow {
vertical-align: left;
margin: 0 0 0 2px;
}
#delRowChild {
line-height: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<title>Test task 1</title>
<body>
<!-- <div id="delColumn" class="del" onclick="appendColumn">
<div id="addColumnChild"><b>–</b></div>
</div>
<div id="delRow" class="del" onclick="appendRow()">
<div id="delRowChild"><b>–</b></div>
</div>-->
<table id="my-table">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<div id="addColumn" class="add" onclick="appendColumn">
<div id="addColumnChild"><b>+</b></div>
</div>
<div id="addRow" class="add" onclick="appendRow()">
<div id="addRowChild"><b>+</b></div>
</div>
How to make buttons work and actually add rows and columns?
Here you go with a solution (using jQuery) https://jsfiddle.net/gmzqe5kw/11/
$('#addColumnChild').click(function(){
$('#my-table tr').each(function(){
$(this).append(`<td></td>`);
});
});
$('#addRowChild').click(function(){
$('#my-table tbody').append(`<tr>${$('#default-row').html()}</tr>`);
});
#canvas {
align-content: center;
height: 1000px;
}
#my-table {
margin: 0 -2px -2px 0;
border: #FFF;
border: 1px solid rgb(72, 170, 230);
display: inline-block;
}
tr {
background: rgb(72, 170, 230);
}
td {
width: 50px;
height: 50px;
}
.add {
height: 52px;
width: 52px;
background: rgb(243, 165, 0);
cursor: pointer;
color: #FFF;
text-align: center;
font-family: 'Open Sans', sans-serif;
transition-property: background;
transition-duration: 1s;
transition-timing-function: linear;
}
#addColumn {
display: inline-block;
vertical-align: top;
margin: 2px 0 0 0;
}
.add:hover {
background: rgb(246, 192, 82);
}
#addColumnChild {
line-height: 50px;
}
#addRow {
vertical-align: bottom;
margin: 0 0 0 2px;
}
#addRowChild {
line-height: 50px;
}
.del {
height: 52px;
width: 52px;
background: rgb(178, 0, 0);
cursor: pointer;
color: #FFF;
text-align: center;
font-family: 'Open Sans', sans-serif;
transition-property: background;
transition-duration: 1s;
transition-timing-function: linear;
}
#delColumn {
display: inline-block;
vertical-align: top;
margin: 2px 0 0 0;
}
.del:hover {
background: rgb(202, 76, 73);
}
#delColumnChild {
line-height: 50px;
}
#delRow {
vertical-align: left;
margin: 0 0 0 2px;
}
#delRowChild {
line-height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="my-table">
<tr id="default-row">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<div id="addColumn" class="add">
<div id="addColumnChild"><b>+</b></div>
</div>
<div id="addRow" class="add">
<div id="addRowChild"><b>+</b></div>
</div>
Hope this will help you.
Use jQuery events and selectors:
As an example, to add a row, use general solution is of this form:
$(".some_selector").click(function () {
$("table.your_class").append("<tr> <td>col1</td> <td>col2</td> </tr>");
});
To add columns use:
similarly to add columns:
$(".some_selector").click(function () {
// Loop over the rows of the table and append the td tag
$("table.your_class tr").append("<td>col1</td>");
});

Categories

Resources