How to realign table columns after display property has been changed? - javascript

My goal is to get my table columns aligned. My table is currently set up this way because I wanted to have a table with a scroll bar and give each row it's own border and margin. When the mouse overs over a row that row changes color. I have these features but now I am having trouble aligning my table columns.
This is what my table looks like currently.
The tbody has a scroll bar and the each tbody tr has a margin. The tbody has a fixed height of 25vh. The table, thead, th, tbody elements are hardcoded into the html. The tbody rows are written by jquery after the page loads. I have given the td and th elements a 1px solid black border to show you there margins and padding. I plan on removing them once I have aligned them.
Below is my static html code.
<h3 id = "UpdateEmpyeeCaption">Update Employee Table</h3>
<table id = "UpdateEmployeeTable" >
<thead id ="UpdateTableHeadders" >
<tr>
<th class = "UpHeaderCell">EmployeeID </th>
<th class = "UpHeaderCell">Firstname </th>
<th class = "UpHeaderCell">Lastname </th>
<th class = "UpHeaderCell">Username </th>
<th class = "UpHeaderCell">Password </th>
<th class = "UpHeaderCell">Lifeguard </th>
<th class = "UpHeaderCell">Instructor </th>
<th class = "UpHeaderCell">Headguard </th>
<th class = "UpHeaderCell">Supervisor </th>
</tr>
</thead>
<tbody id = "UpdateEmployeeTableinner">
</tbody>
</table>
Next is the function I use to append the table rows into the tbody.
function loadTable( employeelist )
{
var MSG = "";
EmployeeList = employeelist;
for( var emp in employeelist )
{
var id = employeelist[emp]["employeeID"];
var firstname = employeelist[emp]["Firstname"];
var lastname = employeelist[emp]["Lastname"];
var username = employeelist[emp]["Username"];
var Password = employeelist[emp]["Password"];
var lifeguard = "";
if ( employeelist[emp]["Lifeguard"] == true ){ lifeguard = "Yes"; }else{ lifeguard = "no"; }
var instructor = "";
if ( employeelist[emp]["Instructor"] == true ){ instructor = "Yes"; }else{ instructor = "no"; }
var headguard = "";
if ( employeelist[emp]["Headguard"] == true ){ headguard = "Yes"; }else{ headguard = "no"; }
var supervisor = "";
if ( employeelist[emp]["Supervisor"] == true ){ supervisor = "Yes"; }else{ supervisor = "no"; }
MSG += "<tr class = \"UpdateEmployeeCell notHoverTable\">";
MSG += "<td class =\"upEmCell\"> "+id+" </td>";
MSG += "<td class =\"upEmCell\"> "+firstname+" </td>";
MSG += "<td class =\"upEmCell\"> "+lastname+" </td>";
MSG += "<td class =\"upEmCell\"> "+username+" </td>";
MSG += "<td class =\"upEmCell\"> "+Password+" </td>";
MSG += "<td class =\"upEmCell\"> "+lifeguard+" </td>";
MSG += "<td class =\"upEmCell\"> "+instructor+" </td>";
MSG += "<td class =\"upEmCell\"> "+headguard+" </td>";
MSG += "<td class =\"upEmCell\"> "+supervisor+" </td>";
MSG += "</tr>";
}//End of for each employee in employeelist
//Put the rows into tbody of the table.
$('#UpdateEmployeeTableinner').empty();
$('#UpdateEmployeeTableinner').append( MSG );
}/* End of Function loadTable */
My Css being applied to the table in the pitcure
/* Start of Update Employee Table*/
/*table*/
#UpdateEmployeeTable {
border: 3px solid black;
margin: 0;
padding: 0 0 0 0;
overflow:hidden;
display: block;
}
/*thead*/
#UpdateTableHeadders {
background: rgb(221,221, 221);
display: block;
padding: 0em 1em 0em 1em;/* top right bottom left*/
margin: 0; /*margin: <margin-top> || <margin-right> || <margin-bottom> || <margin-left>*/
border-bottom: 3px solid black;
}
/*th*/
.UpHeaderCell {
display: inline;
border: 1px solid black;
width: 11%;
}
/*tbody*/
#UpdateEmployeeTableinner {
border: 1px solid black;
background: white;
overflow: auto;
height: 25vh;
display: block;
}
/*tr inside tbody*/
.UpdateEmployeeCell {
border: 1px solid black;
margin: 0.5em 0.2em 0.5em 0.2em ; /*top right bottom left*/
display: block;
overflow: hidden;
padding: 0.1em;
}
/*td*/
.upEmCell {
display: inline-block;
border: 1px solid black;
}
/*When a table row does not have mouse hover*/
.notHoverTable {
background-color: rgb(4,211,255);
color: black;
border: 2px solid black;
}
/*When a table row does have mouse hover*/
.liOVERTable {
background-color: rgb(5, 255, 12);
border: 2px solid black;
color: black;
cursor: pointer;
cursor: hand;
}
/* End of Update Employee Table*/
So how can I change my CSS to display my table columns aligned with the correct spacing? Do I need to use Javascript to implement correct alignment? I would prefer keeping the solution as CSS.

Related

Abp framework js code doesn't work inside modal

.net mvc efcore, no angular, abp 5.3.1
Purpose: Dynamic search within a table.
Method: I create modal according to the tutorial (https://docs.abp.io/en/abp/latest/Tutorials/Part-3?UI=MVC&DB=EF). I add table, css and js codes into it. Myinput will filter the word entered in the textbox by searching in the 3rd column of the Mytables table. (https://www.w3schools.com/howto/howto_js_filter_table.asp)
Problem: There is no problem with tables and css, but js codes are not triggered in any way.
#page
#using xxx.Localization
#using xxx.xxx.Web.Pages.xxx
#using Microsoft.Extensions.Localization
#using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
#model xxxModalModel
#inject IStringLocalizer<xxxx> L
#{
Layout = null;
}
<style>
#myInput {
width: 100%; /* Full-width */
font-size: 10px; /* Increase font-size */
padding: 5px 5px 5px 5px; /* Add some padding */
border: 1px solid #ddd; /* Add a grey border */
margin-bottom: 5px; /* Add some space below the input */
}
#myTable {
border-collapse: collapse; /* Collapse borders */
width: 100%; /* Full-width */
border: 1px solid #ddd; /* Add a grey border */
font-size: 10px; /* Increase font-size */
}
#myTable th, #myTable td {
text-align: left; /* Left-align text */
padding: 5px; /* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header, #myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #f1f1f1;
}
</style>
<form asp-page="/xxx/xxx">
<abp-modal>
<abp-modal-header title="#L["xxx"].Value"></abp-modal-header>
<abp-modal-body>
<abp-input asp-for="Id" />
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<abp-table responsive-md="true" small="true" striped-rows="true" id="myTable" border-style="Bordered">
<thead>
<tr>
<th scope="Column">#</th>
<th scope="Column">1</th>
<th >2</th>
<th >3</th>
<th >4</th>
<th >5</th>
<th >6</th>
</tr>
</thead>
<tbody>
#{
var sutun = 1;
for (var i = 0; i < Model.xxx.Count; i++)
{
if (#Model.xxx[i].IsSelected)
{
var x= Model.xxx[i];
<tr>
<th scope="Row">#sutun</th>
<td>#Model.xxx[i].1</td>
<td>#Model.xxx[i].2</td>
<td>#Model.xxx[i].3</td>
<td>#Model.xxx[i].4</td>
<td>#Model.xxx[i].5</td>
<td>#Model.xxx[i].6</td>
</tr>
sutun +=1;
}
}
}
</tbody>
</abp-table>
</abp-modal-body>
<abp-modal-footer></abp-modal-footer>
</abp-modal>
</form>
<script>
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[3];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.indexOf.toUpperCase(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>

Remove entire table when there is no input in searchbox?

I have been twisting my head around on this and I can't seem to fix it.
I have not coded much, but wanting to learn. However, I am trying to make a table in which when there is no input the entire table vanishes.
As of now I have managed to get it so that it starts as vanished, and that when information is inserted into the search box the non-relevant lines dissapear. However, when all text in the search box is removed the entire table is showing. I want the table to stay hidden when there is no text that matches.
Would love to get any feedback on what I am doing wrong here.
function performSearch() {
// Declare search string
var filter = searchBox.value.toUpperCase();
// Loop through first tbody's rows
for (var rowI = 0; rowI < trs.length; rowI++) {
// define the row's cells
var tds = trs[rowI].getElementsByTagName("td");
// hide the row
trs[rowI].style.display = "none";
// loop through row cells
for (var cellI = 0; cellI < tds.length; cellI++) {
// if there's a match
if (tds[cellI].innerHTML.toUpperCase().indexOf(filter) > -1)
{
// show the row
myTable.style.display = "table";
trs[rowI].style.display = "";
// skip to the next row
continue;
}
}
}
}
// declare elements
const searchBox = document.getElementById('searchBox');
const table = document.getElementById("myTable");
const trs = table.tBodies[0].getElementsByTagName("tr");
// add event listener to search box
searchBox.addEventListener('keyup', performSearch);
* {
box-sizing: border-box;
}
#searchBox {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 30%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
position: relative;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
#myTable {
border-collapse: collapse;
width: 80%;
border: 1px solid #ddd;
font-size: 18px;
position: relative;
left: 10%;
display: none;
}
#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;
}
#Overskrift {
width: 100%;
text-align-last: center;
font-size: 40px;
}
<input class="form-control" type="text" id="searchBox" placeholder="Search ..." onkeyup="searchTableColumns()">
<table id="myTable">
<thead>
<tr class="header">
<th onclick="sortTable(0)" style="width:35%;">Fagnavn</th>
<th onclick="sortTable(1)" style="width:21%;">LK20</th>
<th onclick="sortTable(2)" style="width:21%;">LK06</th>
<th onclick="sortTable(3)" style="width:21%;">R94</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pika</td>
<td>Chu</td>
<td>Poke</td>
<td>Mon</td>
</tr>
<tr>
<td>Temporary</td>
<td>Text</td>
<td>Fields</td>
<td>Here</td>
</tr>
</tbody>
</table>
There is a simple solution for this. Just add a check to the end your performSearch function:
if (searchBox.value === ''){
table.style.display='none';
}
else {
table.style.display='table';
}
You can also check it here:
https://codepen.io/serazoltan/pen/dyZRprb

JS Sort Table - Sort Indicators

I've built this table with a sort function and now I'm also trying to set a class for the selected th so I can put some arrows with CSS, as sort indicators.
I need a way to set dynamic .asc and .desc classes to my selected th with JS somewhere on my sortTable() ..
It also needs to be Pure JS.
var myData, asc = {'userId':true, 'id':true, 'title':true, 'completed':true};
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://jsonplaceholder.typicode.com/todos');
myRequest.onload = function () {
myData = JSON.parse(myRequest.responseText);
dataTable(myData);
};
myRequest.send();
function dataTable(data) {
if (data.length > 0) {
var temp = '';
data.forEach((u) => {
temp += '<tr>';
temp += "<td style='text-align: center'>" + u.userId + '</td>';
temp += "<td style='text-align: center'>" + u.id + '</td>';
temp += '<td>' + u.title + '</td>';
temp += "<td style='text-align: center'>" + u.completed + '</td>';
temp += "<td>" + '<input type="button" value="Delete" onclick="deleteRow(this)"> <input type="button" value="Edit" onclick="insertToForm(this)">' + '</td></tr>';
document.getElementById('data').innerHTML = temp;
});
}
}
function sortTable(col){
myData.sort(function(a, b) {
if(asc[col]){
return a[col] > b[col]? 1:-1;
}
else{
return a[col] > b[col]? -1:1;;
}
});
asc[col] = !asc[col];
document.getElementById('data').innerHTML = '';
dataTable(myData);
}
.container{
display: flex;
margin: 25px 10px;
}
.my-table {
border-collapse: collapse;
font-size: 0.9em;
font-family: sans-serif;
min-width: 400px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
margin-right: 15px;
}
.my-table td, th {
padding: 12px 15px;
}
.my-table thead {
background-color: #009879;
color: #ffffff;
text-align: left;
}
.my-table th {
background-color: #009879;
color: #ffffff;
text-align: left;
cursor: pointer;
}
.my-table tbody tr {
border-bottom: 1px solid #dddddd;
}
tbody tr input {
width: 50px;
}
.my-table tbody tr:nth-of-type(even) {
background-color: #f3f3f3;
}
.my-table tbody tr:last-of-type {
border-bottom: 2px solid #009879;
}
<table id="table" class="my-table">
<thead>
<tr>
<th id="tbl-head-userid" onclick="sortTable('userId');">UserID</th>
<th id="tbl-head-id" onclick="sortTable('id');">ID</th>
<th id="tbl-head-title" onclick="sortTable('title');">Title</th>
<th id="tbl-head-completed" onclick="sortTable('completed');">Completion</th>
<th>Action</th>
</tr>
</thead>
<tbody id="data">
</tbody>
</table>
I have edited the snipped. arrow buttons will be shown when the <th> is clicked and the icons on the other headers will be removed
var myData, asc = {'userId':true, 'id':true, 'title':true, 'completed':true};
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://jsonplaceholder.typicode.com/todos');
myRequest.onload = function () {
myData = JSON.parse(myRequest.responseText);
dataTable(myData);
};
myRequest.send();
function dataTable(data) {
if (data.length > 0) {
var temp = '';
data.forEach((u) => {
temp += '<tr>';
temp += "<td style='text-align: center'>" + u.userId + '</td>';
temp += "<td style='text-align: center'>" + u.id + '</td>';
temp += '<td>' + u.title + '</td>';
temp += "<td style='text-align: center'>" + u.completed + '</td>';
temp += "<td>" + '<input type="button" value="Delete" onclick="deleteRow(this)"> <input type="button" value="Edit" onclick="insertToForm(this)">' + '</td></tr>';
document.getElementById('data').innerHTML = temp;
});
}
}
function sortTable(col, e){
myData.sort(function(a, b) {
if(asc[col]){
return a[col] > b[col]? 1:-1;
}
else{
return a[col] > b[col]? -1:1;;
}
});
asc[col] = !asc[col];
document.getElementById('data').innerHTML = '';
dataTable(myData);
var currentTarget = e.currentTarget;
Array.from(currentTarget.parentElement.children).forEach(function(ele) {
ele.classList.remove('asc', 'des');
})
if(!asc[col]) {
currentTarget.classList.add('asc');
} else {
currentTarget.classList.add('des');
}
}
.container{
display: flex;
margin: 25px 10px;
}
.my-table {
border-collapse: collapse;
font-size: 0.9em;
font-family: sans-serif;
min-width: 400px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
margin-right: 15px;
}
.my-table td, th {
padding: 12px 15px;
}
.my-table thead {
background-color: #009879;
color: #ffffff;
text-align: left;
}
.my-table th {
background-color: #009879;
color: #ffffff;
text-align: left;
cursor: pointer;
}
.my-table tbody tr {
border-bottom: 1px solid #dddddd;
}
tbody tr input {
width: 50px;
}
.my-table tbody tr:nth-of-type(even) {
background-color: #f3f3f3;
}
.my-table tbody tr:last-of-type {
border-bottom: 2px solid #009879;
}
th {
position: relative;
}
th.asc:before,
th.des:after {
border: 4px solid transparent;
content: "";
display: block;
height: 0;
right: 5px;
top: 50%;
position: absolute;
width: 0;
}
th.asc:before {
border-bottom-color: #fff;
margin-top: -5px;
}
th.des:after {
border-top-color: #ffff;
}
<table id="table" class="my-table">
<thead>
<tr>
<th id="tbl-head-userid" onclick="sortTable('userId', event);">UserID</th>
<th id="tbl-head-id" onclick="sortTable('id', event);">ID</th>
<th id="tbl-head-title" onclick="sortTable('title', event);">Title</th>
<th id="tbl-head-completed" onclick="sortTable('completed', event);">Completion</th>
<th>Action</th>
</tr>
</thead>
<tbody id="data">
</tbody>
</table>

How to show two html tables using different table id's?

I want to display two html tables using different table id's. I am able to display one table but I am not able to display the second table and not figure it out where I am making error.
Code is given below:
var $container = $("#container");
var $row = $("#container table tbody tr");
// Loop through items in JSON data..
var $button = $("<button>" + 'xyz' + "</button>");
$container.prepend($button);
var table = $("<table1>");
table.append($("<tr><th>column1</th><th>column2</th></tr>"));
// Button click handler..
$button.on("click", function(e) {
e.preventDefault();
for( var i=0; i<2; i++) {
// Replace row HTML..
//parent row
var row=$('<tr ><td>' + 'data' + '</td>' + + '<td>' + "" + '</td></tr>');
table.append(row);
for(var j =0; j<2; j++) {
var row=$('<tr><td>' + "" + '</td></tr>');
$('<td>data</td>')
.on('click', function() {
//I want to display table2 when clicked on col2 data
var table = $("<table2>");
table.append($("<tr><th>col1</th><th>col2</th></tr >"));
var row=$('<tr><td>' + 'data' + '</td>' + + '<td>' + "" + '</td></tr>');
table.append(row);
})
.appendTo(row);
table.append(row);
$("#table2").html(table);
}
}
$("#table1").html(table);
// Show table if it's not already visible..
});
#table2 {
margin-top: 20px;
border-collapse: collapse;
border: 1px solid silver;
width: 500px;
}
#table1 {
margin-top: 20px;
border-collapse: collapse;
border: 1px solid silver;
width: 500px;
}
#table1 th {
border: 1px solid black;
text-align: left;
}
#table1 td {
border: 1px solid black;
text-align: left;
}
#table1 tr {
background-color: #f2f2f2;
}
button {
margin-left: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="table1">
</div>
</div>
<div id="table2">
</div>
I want to show second table when i click on values of column2. Kindly guide me how to fix this issue.
Here is the full code- https://jsfiddle.net/gaurav10022/styjk9vr/48/
You should first append the table column values after that apply click event on the last column.
Try below code or go through JSFiddle
var $container = $("#container");
var m = ['data','data1'];
// Loop through items in JSON data..
var $button = $("<button>" + 'xyz' + "</button>");
$container.prepend($button);
var table = $("<table>");
table.append($("<tr><th>column1</th><th>column2</th></tr>"));
// Button click handler..
$button.on("click", function(e) {
e.preventDefault();
for (var i = 0; i < 2; i++) {
// Replace row HTML..
//parent row
var row = $('<tr ><td>' + 'data' + '</td><td>' + "" + '</td></tr>');
table.append(row);
for (var j = 0; j < 2; j++) {
//child row
var row = $('<tr><td>' + "" + '</td><td>' + m[j] + '</td></tr>');
$(row).find('td:last').on('click', function() {
// second table
var tempData = $(this).text();
var table2 = $("<table>");
table2.append($("<tr><th>col1</th><th>col2</th></tr >"));
var row = $('<tr class="parent_row" ><td>' + tempData + '</td>' + +'<td>' + "" + '</td></tr>');
table2.append(row);
$("#table2").html(table2);
})
table.append(row);
}
}
$("#table1").html(table);
// Show table if it's not already visible..
});
#table2 {
margin-top: 20px;
border-collapse: collapse;
border: 1px solid silver;
width: 500px;
}
#table1 {
margin-top: 20px;
border-collapse: collapse;
border: 1px solid silver;
width: 500px;
}
#table1 th {
border: 1px solid black;
text-align: left;
}
#table1 td {
border: 1px solid black;
text-align: left;
}
#table1 tr {
background-color: #f2f2f2;
}
button {
margin-left: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="table1">
</div>
</div>
<div id="table2">
</div>
jQuery selectors are obsolete today (i.e. they can't produce live collections). $('<td>data</td>') will give you empty result, so no onclick is added. This will give you your desired collection:
table1.querySelectorAll("td:nth-child(2)")
td:nth-child(2) selects cells of second column on the called object (table1). Then you can hook the onclick event in loop to every item in the collection.

Javascript uploading file alignment

In the above image the delete button need to align properly. in my code it get align based on file name length.
<script>
var filelist = new Array();
updateList = function () {
var input = document.getElementById('fileUploader');
var output = document.getElementById('divFiles');
var HTML = "<table>";
for (var i = 0; i < input.files.length; ++i) {
filelist[i]=input.files.item(i).name;
HTML += "<tr><td>" + filelist[i] + "</td><td> <button ></button></td></tr>";
}
HTML += "</table>";
output.innerHTML += HTML;
}
</script>
Please try this.
table {
border-collapse: separate;
border-spacing: 0 3px;
width: 600px;
}
Try this
table
{
table-layout: fixed;
width: 300px;
}
td
{
border: 1px solid green;
word-wrap:break-word;
}
try jsfiddle
<style>
table {
border-collapse: separate;
border-spacing: 0 2px;
width: 600px;
table-layout: fixed;
}
tr:nth-child(1n) {
border: 2px solid;
background-color: #eceff1;
color: Black;
}
tr:nth-child(2n) {
border: 2px solid;
color: Black;
}
td {
padding-top: .5em;
padding-left: .5em;
padding-right: .5em;
padding-bottom: .5em;
}
input[type="file"] {
display: none;
}
.label1 {
padding: 3px;
background: #fff;
display: table;
color:black;
}
button {
background-image: url('../../Images/delete.ico');
background-size: cover;
padding-right:0px;
background-color: Transparent;
cursor: pointer;
border: none;
width: 30px;
height: 30px;
}
</style>
<script>
$(document).ready(function () {
$(document).on('click', "button", function (e) {
$(this).closest('tr').remove();
});
});
</script>
<script>
var filelist = new Array();
updateList = function () {
var input = document.getElementById('fileUploader');
var output = document.getElementById('divFiles');
var HTML = "<table>";
for (var i = 0; i < input.files.length; ++i) {
filelist[i]=input.files.item(i).name;
HTML += "<tr><td>" + filelist[i] + "</td><td><button ></button></td></tr>";
}
HTML += "</table>";
output.innerHTML += HTML;
}
</script>
In the above script the delete button is showing in fixed order but i want the file name to be aligned at left and delete button need to at right side corner.

Categories