Claus
Claus

Reputation: 550

Cannot get table height to contstrain with in div

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

Answers (3)

sheriffderek
sheriffderek

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

G-Cyrillus
G-Cyrillus

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

Axion
Axion

Reputation: 722

Add

#dataEntryDiv {
    overflow: auto;
}

Upvotes: 0

Related Questions