0

With a table already rendered, if I hide some row the width of the columns is dynamically recalculated per the contents:

function switchRow(ixRow){

let table = document.getElementById('theTable');

let row = table.rows[ixRow];
let currentVisibility = row.style.display;

row.style.display= currentVisibility== 'none' ? 'table-row' : 'none';

}
table{
  border: 2px solid black;
  padding: .5em;
}
<table id='theTable'>
<tr><td>Hellen</td><td>Smith</td></tr>
<tr><td>Montgomery</td><td>Wolfeschlegelsteinhausenbergerdorff</td></tr>
</table>
<br>
<button onclick="switchRow(1)">Switch row 1</button>

Is there a simple way to "freeze" the width of all the columns after the first rendering so hidding/displaying keeps the witdh of all the table / columns?

Edit to differentiate from the other question supposedly duplicated What I am looking for is to keep the widths that have been calculated when the table has been rendered -whatever the rules explicit or implicit-. Once displayed the widths must be constant. I do not want to add any width prior rules, I want the default rendering of the table but once rendered I look for no dynamic changes in widths.

tru7
  • 6,348
  • 5
  • 35
  • 59
  • Is there any issue to append width in CSS? e.g. `table{ width:200px } ` – Jitendra G2 Jan 08 '19 at 12:16
  • I will edit to make it clearer, I want to keep the dynamic widths calculated after the table has been rendered -whatever the rules explicit or implicit. Once calculated the widths must be constant – tru7 Jan 08 '19 at 12:27
  • @Pete is it really a duplicate? – tru7 Jan 08 '19 at 12:40
  • 1
    I am answering with a working snippet on the Fixed Table Cell Width answer because here I can't. @Pete to me it seem that this answer isn't a duplication of the other referenced, tru7 seems interested to handle columsn with unknown initial width, not simply fixed. – 0xc14m1z Jan 08 '19 at 12:48
  • @tru7 here is your answer: https://stackoverflow.com/a/54092200/3359473. I knew I would get a downvote but you know what? I don't care. Hope this helps a bit. Because it's clearly not a duplicate. – 0xc14m1z Jan 08 '19 at 13:06
  • 1
    @0xc14m1z Well, you got my upvote on the other thread. I am not sure of understanding why a question can be blocked by someone that says that there's an only way. At least your solution answers my question, shame that I cannot be further discussed here. – tru7 Jan 08 '19 at 17:19
  • @0xc14m1z by the way, why did you foresee a downvote?, perhaps the answer might be refined but it works.... – tru7 Jan 08 '19 at 17:20
  • 1
    I knew I would get the downvote (and I got it few minutes later) because the answer is related to your question, which I still think is different from the one references by @Pete. So, for your answer is right, but for the other no, at least not properly. I tried to answer here, but nada. Glad it helped you :) – 0xc14m1z Jan 08 '19 at 17:22
  • @0xc14m1z The question is now open so feel free to move your answer here and I will edit the edits – tru7 Jan 09 '19 at 12:52
  • Thank you, I'm going to do it now! Thanks @Pete, hope you agree with us :) – 0xc14m1z Jan 09 '19 at 13:54
  • @0xc14m1z You're still going to have the changing width problems if you then add a column that is wider than the original - but if you're just toggling, your solution will work. But if you don't want to do this the proper way then fill your boots. I won't waste my time trying to teach people who don't want to learn – Pete Jan 09 '19 at 13:59

1 Answers1

1

I would first compute the maximum cell widths after the page load and assign it to the cells, in order to be kept for later:

window.onload = function () {
   const table = document.getElementById('theTable');
   const widths = computeColumnWidths(table)
   setColumnWidths(table, widths)
}

function computeColumnWidths(table) {
  const widths = Array.from({ length: table.rows[0].cells.length })
                      .fill(0);
  
  for (let i = 0; i < table.rows.length; i++ ) {
    const row = table.rows[i]
    
    for (let j = 0; j < row.cells.length; j++) {
      const cell = row.cells[j]
      widths[j] = Math.max(widths[j], cell.offsetWidth);
    }
  }
  
  return widths;
}

function setColumnWidths(table, widths) {
  for (let i = 0; i < table.rows.length; i++ ) {
    const row = table.rows[i]
    
    for (let j = 0; j < row.cells.length; j++) {
      const cell = row.cells[j]
      cell.style.width = widths[j] + 'px';
    }
  }
}

function switchRow(ixRow){

  let table = document.getElementById('theTable');

  let row = table.rows[ixRow];
  let currentVisibility = row.style.display;

  row.style.display = currentVisibility == 'none' ? 'table-row' : 'none';

}
table{
  border: 2px solid black;
  padding: .5em;
}
<table id='theTable'>
<tr><td>Hellen</td><td>Smith</td></tr>
<tr><td>Montgomery</td><td>Wolfeschlegelsteinhausenbergerdorff</td></tr>
</table>
<br>
<button onclick="switchRow(1)">Switch row 1</button>
0xc14m1z
  • 3,675
  • 1
  • 14
  • 23