Reputation: 550
I've played around with a number of options, but I can't keep the table height from growing as I add lines dynamically.
This is a small section, part of a more complex page. Basically I have several div tags within the larger container div.
As more lines are added the table pushes the button below outside the boundaries of the div. Run the code snippet to observe the problem.
function onBodyLoader(obj) {
g.c.assignEventListners();
}
var g = {};
g.formClass = function() {
/*
----------------------------------
Properties for formClass
----------------------------------
*/
this.tr;
this.td;
this.elist = [];
/*
----------------------------------
Methods for formClass
----------------------------------
*/
this.assignEventListners = function() {
this.tbody = document.getElementById('emailDist');
g.sbAddELine = document.getElementById('sbAddELine');
g.sbAddELine.addEventListener("click", function(evt) {
g.c.addBlank();
}, false);
/*event listener for all links on the email list body*/
g.dataUpdate = document.querySelector("#emailDist");
g.dataUpdate.addEventListener("click", g.c.tableBodyRouter, false);
};
this.tableBodyRouter = function(e) {
/*
called from clicks on keyTable or task links
*/
if (e.target !== e.currentTarget)
if (e.target.id.indexOf('eRemove') > -1)
g.c.removeEmail(e);
e.stopPropagation();
};
this.redrawElist = function() {
/*delete current table*/
while (this.tbody.rows.length > 1)
this.tbody.deleteRow(1);
/*redraw table*/
for (var i = 0; i < this.elist.length; i++) {
this.rowLayout();
}
};
this.addBlank = function() {
/*add blank to this.elist array*/
this.elist.push({
eEmail: '',
eFirst: '',
eLast: '',
});
this.rowLayout();
}
this.removeEmail = function(e) {
var x = e.target.id.substr(7);
this.elist.splice(x, 1);
this.redrawElist();
};
this.rowLayout = function() {
var rowCnt = this.tbody.rows.length - 1;
this.tr = this.tbody.insertRow(this.tbody.rows.length);
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eFirst' + rowCnt + '" maxlength="20" size="20" value=""/>';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eLast' + rowCnt + '" maxlength="20" size="20" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eEmail' + rowCnt + '" maxlength="50" size="50" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="button" id="eRemove' + rowCnt + '" value="Remove" ">';
document.getElementById("eFirst" + rowCnt).focus();
document.getElementById("eFirst" + rowCnt).select();
}
}
g.c = new g.formClass;
table {
height: 60%;
max-height: 60%;
width: 100%;
display: inline-table;
border-style: none;
}
tbody {
font-size: 10pt;
display: block;
height: 90%;
overflow-y: scroll;
}
#container {
position: absolute;
width: 98%;
top: 40px;
height: 90%;
}
#dataEntryDiv {
border: medium groove;
position: absolute;
top: 0.5em;
height: 95%;
padding-left: 1em;
padding-right: 1em;
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Email List</title>
</head>
<body id="intactRolesBody" onLoad="onBodyLoader(this);">
<form id='intactRolesForm' method="post" action="" onSubmit="return false;">
<div id="container">
<div id="dataEntryDiv">
<input type="button" id='sbAddELine' value="Add non-company contact"><br>
<p>Email Distribution List</p>
<table>
<tbody id='emailDist'>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>email</th>
<th>remove from list</th>
</tr>
</tbody>
</table>
<input type="button" id='SaveEmailList' value="Save email List">
</div>
</div>
</form>
</body>
</html>
Upvotes: 0
Views: 67
Reputation: 9053
To get a simplified version of the situation, I would suggest writing something like this - instead of putting in the code from your actual project. This way, you can get away from trying to 'fix' something - and possibly see a better way to build the layout - or at least make the use-case more specific.
https://stackoverflow.com/help/how-to-ask
markup
<section class="table-wrapper">
<header>
I'm a table wrapper thing
</header>
<main>
<table>
<!-- populate this -->
</table>
</main>
<footer>
<button>button (add row)</button>
</footer>
</section>
styles
.table-wrapper {
height: 300px; /* arbitrary */
border: 2px solid red;
}
.table-wrapper main {
height: 260px; /* likely you'd use flexbox or percentages or JS */
border: 2px solid blue;
overflow: auto;
}
js
var $table = $('.table-wrapper').find('table');
var $moreButton = $('.table-wrapper').find('button');
var counter = 0;
function addRow() {
counter = counter + 1;
$table.prepend('<tr><td>row and data ' + counter + '</td></tr>');
}
addRow();
// populate some things to start
$moreButton.on('click', function() {
addRow();
});
https://jsfiddle.net/sheriffderek/b6z4ep46/
Upvotes: 0
Reputation: 106058
This is the basic behavior of a table. it shrinks and expand acording to its content.
What you can do to manage height is to reset the display. it can be anything but table/inline-table/table-cell/table-row/.. . nor inline.
You used inline-table, inline-block might be fine:
function onBodyLoader(obj) {
g.c.assignEventListners();
}
var g = {};
g.formClass = function() {
/*
----------------------------------
Properties for formClass
----------------------------------
*/
this.tr;
this.td;
this.elist = [];
/*
----------------------------------
Methods for formClass
----------------------------------
*/
this.assignEventListners = function() {
this.tbody = document.getElementById('emailDist');
g.sbAddELine = document.getElementById('sbAddELine');
g.sbAddELine.addEventListener("click", function(evt) {
g.c.addBlank();
}, false);
/*event listener for all links on the email list body*/
g.dataUpdate = document.querySelector("#emailDist");
g.dataUpdate.addEventListener("click", g.c.tableBodyRouter, false);
};
this.tableBodyRouter = function(e) {
/*
called from clicks on keyTable or task links
*/
if (e.target !== e.currentTarget)
if (e.target.id.indexOf('eRemove') > -1)
g.c.removeEmail(e);
e.stopPropagation();
};
this.redrawElist = function() {
/*delete current table*/
while (this.tbody.rows.length > 1)
this.tbody.deleteRow(1);
/*redraw table*/
for (var i = 0; i < this.elist.length; i++) {
this.rowLayout();
}
};
this.addBlank = function() {
/*add blank to this.elist array*/
this.elist.push({
eEmail: '',
eFirst: '',
eLast: '',
});
this.rowLayout();
}
this.removeEmail = function(e) {
var x = e.target.id.substr(7);
this.elist.splice(x, 1);
this.redrawElist();
};
this.rowLayout = function() {
var rowCnt = this.tbody.rows.length - 1;
this.tr = this.tbody.insertRow(this.tbody.rows.length);
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eFirst' + rowCnt + '" maxlength="20" size="20" value=""/>';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eLast' + rowCnt + '" maxlength="20" size="20" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eEmail' + rowCnt + '" maxlength="50" size="50" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="button" id="eRemove' + rowCnt + '" value="Remove" ">';
document.getElementById("eFirst" + rowCnt).focus();
document.getElementById("eFirst" + rowCnt).select();
}
}
g.c = new g.formClass;
table {
height: 60%;
max-height: 60%;
width: 100%;
display: inline-block;/*... or block : do not use table display if you need to constrain height */
border-style: none;
}
tbody {/* this CSS could have been set to table directly :) */
font-size: 10pt;
display: block;
height: 90%;
overflow-y: scroll;
}
#container {
position: absolute;
width: 98%;
top: 40px;
height: 90%;
}
#dataEntryDiv {
border: medium groove;
position: absolute;
top: 0.5em;
/*left: 37em; removed for demo */
height: 95%;
padding-left: 1em;
padding-right: 1em;
}
<body id="intactRolesBody" onLoad="onBodyLoader(this);">
<form id='intactRolesForm' method="post" action="" onSubmit="return false;">
<div id="container">
<div id="dataEntryDiv">
<input type="button" id='sbAddELine' value="Add non-company contact"><br>
<p>Email Distribution List</p>
<table>
<tbody id='emailDist'>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>email</th>
<th>remove from list</th>
</tr>
</tbody>
</table>
<input type="button" id='SaveEmailList' value="Save email List">
</div>
</div>
</form>
</body>
Note: You did use display:block
on tbody
, you could have apply this directly to the table
element and reset tbody
to display:table
:) (defaut is table-row-group
)
Upvotes: 1