Fixed header script function floatHead is adding an extra thead - javascript

I'm trying to make fixed headers for a table in my view. I searched and didn't find much so I ended up trying a plugin found here http://mkoryak.github.io/floatThead/. After implementing its adding an extra blank thead to my tblPersons table that looks like this:
So then I try and hide the thead using this jquery code (i have two total theads on the view, this selects the one I need via the id, or lack thereof):
$('thead[id!="personsHeader"]').hide();
Which does remove the thead, but then it removes the first line of my results which is:
Kirk | Alexander | 06/02/2015
Visual:
It doesn't make sense to me because the thead is separate from the tbody where the Kirk row is located...
Finally for reference, here is my View form code:
#using (Html.BeginForm("Index", "Persons"))
{
<div class="panel panel-default">
<div class="panel-heading">
<table id="tablePanelHeader" class="table table-bordered menu-options">
<tr>
<td>
Persons Pages:
#Html.DropDownList("PersonsDDL", new SelectList(listItems, "Value", "Text"))
</td>
<td>
Search filter: <input type="text" id="search" ="Type to search">
</td>
</tr>
<tr>
<td id="rowCount">
</td>
</tr>
</table>
</div>
<div class="span3">
<table id="tblPersons" class="table table-bordered">
<thead id="personsHeader">
<tr class="page-header">
<th>First Name</th>
<th>Last Name</th>
<th>Birthdate</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#item.firstname
</td>
<td>
#item.lastname
</td>
<td>
#item.birthdate.ToString("MM/dd/yyyy")
</td>
</tr>
}
</tbody>
</table>
</div>
}
I've given it my best shot and now I'm turning to the professionals... what am I doing wrong?

There are several ways to do this. Personally I have always been a fan of going full css instead of adding the bloat of js to this mix.
See this for an example of a fixed table header with just css - http://codepen.io/tjvantoll/pen/JEKIu
.fixed_headers {
width: #table_width;
table-layout: fixed;
border-collapse: collapse;
th { text-decoration: underline; }
th, td {
padding: 5px;
text-align: left;
}
td:nth-child(1), th:nth-child(1) { min-width: #column_one_width; }
td:nth-child(2), th:nth-child(2) { min-width: #column_two_width; }
td:nth-child(3), th:nth-child(3) { width: #column_three_width; }
thead {
background-color: #header_background_color;
color: #header_text_color;
tr {
display: block;
position: relative;
}
}
tbody {
display: block;
overflow: auto;
width: 100%;
height: #table_body_height;
tr:nth-child(even) {
background-color: #alternate_row_background_color;
}
}
}
If you are set on using a javascript library try jQuery Datatables - datatables.net/examples/basic_init/scroll_y.html

Related

Why button doesn't append row to table? [duplicate]

This question already has answers here:
How can I apply a jQuery function to all elements with the same ID?
(4 answers)
Event binding on dynamically created elements?
(23 answers)
Closed 1 year ago.
Sup! My code dynamically creates tables by clicking div, but it appends row only to first one. All tables are stored in div, containing the table itself and div with the row adding button, which is contained in the main div.
HTML
<div id="main-container">
<div id="container">
<table id="table" class="my-table">
<tr>
<th>X</th>
<th>Y</th>
</tr>
<tr>
<td class="xcell" contenteditable="true"></td>
<td class="ycell" contenteditable="true"></td>
</tr>
<tr>
<td class="xcell" contenteditable="true"></td>
<td class="ycell" contenteditable="true"></td>
</tr>
<tr>
<td class="xcell" contenteditable="true"></td>
<td class="ycell" contenteditable="true"></td>
</tr>
<tr>
<td class="xcell" contenteditable="true"></td>
<td class="ycell" contenteditable="true"></td>
</tr>
</table>
<div id="addRowChild" class="add"><b>+</b></div>
</div>
</div>
</div>
In my JS code, I've been trying to get tables from each container div with siblings() method, but it doesn't work and I have no idea why it happens.
JS
function createNewTable() {
let newTable = document.createElement("table")
let mainContainer = document.getElementById("main-container") //refers to the div, containing all tables
let containerDiv = document.createElement("div") //creates div, which contains table and row adding div
let addRowButton = document.createElement("div") //creates row adding button
mainContainer.append(containerDiv)
containerDiv.id = "container"
containerDiv.append(newTable)
newTable.className = "my-table"
newTable.id = "table"
$("#addRowChild").click(function() {
let table = $("#addRowChild").siblings(".my-table")
table.append(`<tr><td class = "xcell" contenteditable = "true"></td><td class = "ycell" contenteditable = "true"></td></tr>`);
});
The script was not working because it nested the click event handler method and the createNewTable() method. Application screenshot and test code are available below:
function createNewTable()
{
let newTable = document.createElement("table")
let mainContainer = document.getElementById("main-container") //refers to the div, containing all tables
let containerDiv = document.createElement("div") //creates div, which contains table and row adding div
let addRowButton = document.createElement("div") //creates row adding button
mainContainer.append(containerDiv);
containerDiv.id = "container";
containerDiv.append(newTable);
newTable.className = "my-table";
newTable.id = "table";
}
$("#addRowChild").click(function() {
var markup = `
<tr>
<td class = "xcell" contenteditable="true">####</td>
<td class = "ycell" contenteditable="true">####</td>
</tr>
`;
let table = $("table tbody");
table.append(markup);
});
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
.block {
display: block;
width: 100%;
border: none;
background-color: #04AA6D;
padding: 14px 28px;
font-size: 16px;
cursor: pointer;
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<title>Document</title>
</head>
<body>
<div id="main-container">
<div id="container">
<table id="table" class="my-table">
<thead>
<tr>
<th>X</th>
<th>Y</th>
</tr>
</thead>
<tbody>
<tr>
<td class="xcell" contenteditable="true">1</td>
<td class="ycell" contenteditable="true">2</td>
</tr>
</tbody>
</table>
<button style="margin-top: 25px;" class="block" id="addRowChild" class="add"><b>+</b></button>
</div>
</div>
</body>
</html>

Javascript: How to get an element by ID then add/place the element into an inline style

If possible, I would like javascript to first get an element by an ID that is placed into a table. Then add/place said element into the inline style (width="XX%") of a different div.
Note: I do not have control over the ID's output. Just know that said value will determine the width of the percentage bar.
getelementbyid:
<span *id="per-girls*">**95**</span>
place element into inline css:
<div class="bar bar1" style="width: **95**%;"></div>
$(function(){
$("#dTable").dataTable({
"columns": [
{
"title":"Languages"
},
{
"title":"Votes",
"render": function(data, type, row, meta){
return parseInt(row[1], 10) + parseInt(row[2], 10) + parseInt(row[3], 10)
}
},
{
"visible":false
},
{
"title": "Positive/Neutral/Negative",
"sortable":false,
"render": function(data, type, row, meta){
return $("<div></div>", {
"class": "bar-chart-bar"
}).append(function(){
var bars = [];
for(var i = 1; i < Object.keys(row).length; i++){
bars.push($("<div></div>",{
"class": "bar " + "bar" + i
}).css({
"width": row[i] + "%"
}))
}
return bars;
}).prop("outerHTML")
}
}
]
});
});
.bar-chart-bar {
background-color: #e8e8e8;
display: block;
position:relative;
width: 100%;
height: 40px;
}
.bar {
position: absolute;
float: left;
height: 100%;
}
.bar1 {
background-color: #007398;
z-index: 40;
}
.bar2 {
background-color: #00b0b9;
width: 100%;
z-index: 20;
}
<div class="col-sm-12">
<table id="dTable" cellspacing="0" width="100%" role="grid" aria-describedby="dTable_info">
<tbody>
<tr role="row">
<td style="width: 20%;"> % of girl gamers</td>
</td>
<td style="width: 10%;"> <span id="per-girls">95</span>% </td>
<td>
<div class="bar-chart-bar bar-girl">
<div class="bar bar1" style="width: 20%;"></div>
<div class="bar bar2"></div>
</div>
</td>
</tr>
<tr role="row">
<td> % of boy gamers</td>
</td>
<td><span id="per-boy">57</span>% </td>
<td>
<div class="bar-chart-bar bar-boy">
<div class="bar bar1" style="width: ;"></div>
<div class="bar bar2"></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
Instead of setting the width of a div (which you could also do with this same approach), it seems more elegant to me to use a background gradient to do the fill.
In the snippet below a custom css property is used to inform a linear gradient that fills the bar. By changing the property's value you can set the percentage filled:
function setBar(valueElemId) {
// find the element
const valueElem = document.getElementById(valueElemId);
// get its text as a numeric value
const value = Number(valueElem.textContent);
// find the nearest TR parent and set the css custom property
// that the linear-gradient uses to fill the bar
valueElem.closest('tr').style=`--pct: ${value}`;
}
// invoke setBar for each id
['per-girls', 'per-boy'].forEach(setBar);
:root {
--pct: 0; /* no fill by default */
}
.bar-chart-bar {
min-height: 30px;
background: #00b0b9; /* the background/base color */
background-image: linear-gradient(90deg,
#007398 0 calc(var(--pct) * 1%), /* from 0 to --pct */
transparent calc(var(--pct) * 1%) /* leave the rest transparent */
);
}
<div class="col-sm-12">
<table>
<tbody>
<tr>
<td style="width: 20%;"> % of girl gamers</td>
<td style="width: 10%;"> <span id="per-girls">95</span>% </td>
<td>
<div class="bar-chart-bar"></div>
</td>
</tr>
<tr>
<td> % of boy gamers</td>
<td><span id="per-boy">57</span>% </td>
<td>
<div class="bar-chart-bar"></div>
</td>
</tr>
</tbody>
</table>
</div>

table scroll css change from Jquery

Actually I've a table where I need to set a max-height and make it scrollable.
My Table design
<table class="table table-striped table-notactiveusers table-custom-scroll" style="border: 1px solid #e7eaec;" id="tblNonUandMeUsersList" runat="server">
<thead>
<tr>
<th style="width: 5%">#</th>
<th style="width: 33%">First Name</th>
<th style="width: 30%">Country Code</th>
<th style="width: 32%">Mobile Number</th>
</tr>
</thead>
</table>
My Table css :
.table-custom-scroll > thead, .table-custom-scroll > tbody {
display: block;
}
.table-custom-scroll > tbody {
max-height: 450px;
overflow-y: auto;
overflow-x: hidden;
}
But, if the table has less rows than the max height, there is a space for the body on the right side like shown in the image
So,I thought of changing the css to display : compact, if the table rows are less than 12.
My JS to change css
<script>
$(document).ready(function () {
var notactiverowCount = $('.table-notactiveusers tr').length;
if (notactiverowCount < 12) {
$('.table-notactiveusers > thead').css('display', 'compact');
$('.table-notactiveusers > body').css('display', 'compact');
}
if (notactiverowCount < 12) {
$('.table-notactiveusers').children('head').css('display', 'compact');
$('.table-notactiveusers').children('body').css('display', 'compact');
}
});
</script>
But the css is not changing. Can anyone tell me the mistake I was doing?
what about using only css
.table-custom-scroll{
display: block;
}
see demo HERE

jquery floating div on hover

What I have?
A html-table which has a lot of rows.
A hidden (display=none) div which contains some input controls (lets call it "div-to-display"). Only one div-to-display in whole page.
What I'm trying to do?
When the mouse hovers on the first cell in each row - show the "div-to-display" below it (like tool tip).
But, I can't create a separated div-to-display div for each table row. All cells must use the same "div-to-display" element.
While showing the div-to-display div, it should be float. What it means is that it won't change the location of the other cells in the table. It will be above them.
Do you have idea how to do this with jquery`javascript`?
DEMO: http://jsfiddle.net/sBtxq/
JQuery
// Add our div to every td
$('td').append('<div class="div-to-display">yay</div>');
CSS
.div-to-display {
display: none;
position: absolute;
top: 50%;
left: 50%;
border: 1px solid red;
background-color: #eee;
z-index: 10;
}
td {
position: relative;
}
td:hover > .div-to-display {
display: block
}
Updated (non-JS) version
CSS
td {
position: relative;
}
td:after {
display: none;
position: absolute;
top: 50%;
left: 50%;
border: 1px solid red;
background-color: #eee;
z-index: 10;
content: "yay";
}
td:hover:after {
display: block
}
DEMO: http://jsfiddle.net/sBtxq/20/
use jquery offset() method to get position of hover of those elements and apply that as a left and top for the div. (Make sure to position the div as ABSOLUTE).
If you want a simple solution try using tooltip plugins. There will be loads available out there. One such is jquery UI tooltip plugin.
Style it on your own
#div-to-display{
position:absolute;
top:50px;
left:50px;
width:300px;
height:200px;
z-index:99999;
display:none;
}
add this class="toHover" to each or table rows whom on hover you want to show div
add this function
window.onload = function(){
$('.toHover').each(function() {
$(this).mouseenter(function(){ $('#div-to-display').show(); });
$(this).mouseleave(function() { $('#div-to-display').hide();});
});
}
Html For i.e.
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
<tr>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
<tr>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
</table>
<div id="divInput" style="display:none;position:absolute;">
<input type="type" name="name" value=" " />
</div>
jQuery:
<script type="text/javascript">
var s = 'ss';
$('table tr').each(function () {
var this_tr = $(this);
this_tr.find('td:first').mouseenter(function () {
var this_td = $(this);
$('#divInput').css({ top: this_td.offset().top + this_td.height(), left: this_td.offset().left });
$('#divInput').show();
}).mouseout(function () {
var this_td = $(this);
$('#divInput').css({ top: this_td.offset().top + this_td.height(), left: this_td.offset().left });
$('#divInput').hide();
})
})
</script>

Table column re-sizing using jQuery

I am trying to write a piece of code that enables column re-sizing functionality to my data table.But its not working properly.. I explored on internet for couple of days but I could find nothing except some plug-ins. But I don't want to use any plug-in, since my data table is very complicated and if I use them the other functionalities of the table may be destroyed.Thus I tried to write my own. Can you please check and refine my code or suggest any other code that fulfills my spec....
Note: User can re-size the column towards right upto table width but towrds left, its upto td's left position only..
Eidt: Maxwell has given a great alternative..It works fine but in one case.If I try to resize towards left side, its not allowing since td width is fixed to it's content width...But I want to re-size it to left side upto it's its offset().left value by putting td's style to overflow:hidden or some other way....
Here is my piece of code....
<!DOCTYPE HTML PUBLIC>
<html>
<head>
<title> New Document </title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<style>
table{
border-collapse:collapse;
}
table td{
border:1px solid red;
}
.vUiDtColResize{
width:2px;
height:20px;
border:1px solid blue;
float:right;
display:block;
cursor:w-resize;
position:relative;
right:-3px;
float:top;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<td>S.No <div class="vUiDtColResize"></div></td>
<td>Name <div class="vUiDtColResize"></div></td>
<td>Qualif <div class="vUiDtColResize"></div></td>
</tr>
</thead>
<tbody>
<tr> <td>1</td><td>Rama Rao</td><td>M.C.A</td></tr>
<tr> <td>2</td><td>Dushyanth</td><td>B.Tech</td></tr>
<tr> <td>3</td><td>AnandKumar</td><td>M.C.A</td></tr>
<tr> <td>4</td><td>Veera Reddy</td><td>B.Tech</td></tr>
</tbody>
</table>
<div id="helper"></div>
</body>
<script>
$('.vUiDtColResize').each(function(){
var _rsTd = $(this).parent('td');
var _rsTr = _rsTd.parent('tr');
var _rsTdRight,_thisLeft,_rsTdWidth;
$(this).draggable({axis:'x',containment:_rsTd,refreshPositions:true,
create:function(event,ui){
},
start:function(event,ui){
_rsTdRight = _rsTd.offset().left + _rsTd.outerWidth();
},
drag:function(event,ui){
var _sizeDiff = $(this).offset().left - _rsTdRight;
_rsTdRight = $(this).offset().left;
_rsTdWidth = _rsTd.outerWidth() + _sizeDiff;
_rsTd.outerWidth(_rsTdWidth);
},
stop:function(event,ui){
}
});
});
</script>
</html>
I merged your code with some techniques that I found — http://jsfiddle.net/tpqn7/
IMHO, there are still some problems. First of all I suppose it's would be better (also easier) if table headers can be re-sized by pressing each TH, no only small border.
Hope this helps.
After had been exploring in internet for couple of days, I got a good code,which was modified by me to make it satisfies my requirement as well( Of course, my change is bit little.It might be useful to somebody else,so I am posting here...
style
<link rel="stylesheet" href="E:\Examples\BSP\BSPExtensions\jquery-ui-1.8.18.custom.css"/>
<style>
table {
table-layout: fixed;
border-collapse: collapse;
border: 1px solid black;
}
tr.last td {
border-bottom: 1px solid black;
}
td {
border-right: 1px solid black;
border-bottom: 1px solid black;
position: relative;
white-space:nowrap;
padding: 2px 5px;
text-align: left;
overflow:hidden;
}
td.last {
border-right: none;
}
thead td div:first-child{
text-overflow:ellipsis;
overflow:hidden;
}
tbody td div:first-child{
overflow:hidden;
}
.scrollContainer {
overflow:auto;
width:700px;
height:auto;
display:inline-block;
border:1px solid red;
}
#-moz-document url-prefix() {
.resizeHelper,.ui-resizable-e {
position: relative;
float: right;
}
}
</style>
Script
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<script>
/**
* Enables resizable data table columns.
**/
(function($) {
$.widget("ih.resizableColumns", {
_create: function() {
this._initResizable();
},
_initResizable: function() {
var colElement, colWidth, originalSize;
var table = this.element;
this.element.find("thead td").resizable({
handles: {"e": ".resizeHelper"},
minWidth: 2, // default min width in case there is no label
// set correct COL element and original size
start:function(event, ui) {
var colIndex = ui.helper.index() + 1;
colElement = table.find("thead > tr > td.ui-resizable:nth-child(" + colIndex + ")");
colWidth = parseInt(colElement.get(0).style.width, 10); // faster than width
originalSize = ui.size.width;
},
// set COL width
resize: function(event, ui) {
var resizeDelta = ui.size.width - originalSize;
var newColWidth = colWidth + resizeDelta;
colElement.width(newColWidth);
// height must be set in order to prevent IE9 to set wrong height
$(this).css("height", "auto");
}
});
}
});
// init resizable
$("#MyTable").resizableColumns();
})(jQuery);
</script>
Your html is to be like:*
<div class="scrollContainer">
<table class="resizable" id="MyTable" width="100%">
<thead>
<tr>
<td class="ui-resizable" style="width:100px;">
<div>
<span >Column 1</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable" style="width:200px;">
<div>
<span >Column 2</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable" style="width:300px;">
<div>
<span >Column 3</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable" style="width:150px;">
<div>
<span >Column 4</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable" style="width:200px;">
<div>
<span >Column 5</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
<td class="ui-resizable last" style="width:100px;">
<div>
<span >Column 6</span>
<div class="resizeHelper ui-resizable-handle ui-resizable-e"></div>
</div>
</td>
</tr>
</thead>
<tbody>
<tr><td><div>Column 1</div></td><td><div>Column 2</div></td>
<td><div>Column 3</div></td><td><div>Column 4</div></td>
<td><div>Column 5</div></td><td><div>Column 6</div></td>
</tr>
<tr class="last">
<td><div>Column 1</div></td><td><div>Column 2</div></td>
<td><div>Column 3</div></td><td><div>Column 4</div></td>
<td><div>Column 5</div></td><td><div>Column 6</div></td>
</tr>
</tbody>
</table>
</div>

Categories