javascripthtmliframedatatables

Adjust Iframe height every time the content changes


I have seen similar questions like https://stackoverflow.com/q/819416/28856530 but i think that mine is different.
I have a Table inside a Iframe and few searching fields, my search is instant onkeyup and not after i pressed on a button.

My problem is that i don't want to reload the iframe every time i search something, i only want to "filter" the content when searching for something. I use Datatables for my table if it helps

I tried this code, but it only works if i reload the iframe. I also want to keep the search instant and not add a button to search.

my js code for the height of the iframe:

document.addEventListener('DOMContentLoaded', function() {

  var iframe = document.getElementById("iframeindex");

  if (iframe) {
    iframe.onload = function() {
      iframe.style.height = iframe.contentWindow.document.documentElement.scrollHeight + 'px';
    };
  }
});

and this is the search js code:

function applyTextFilter() {
  // Volltext-Filter
  const volltext = $("#volltext-filter", parent.document);
  table.search(volltext.val()).draw();

  // Name-Filter
  const nameFilter = $("#name-filter", parent.document);
  table.columns(1).search(nameFilter.val()).draw();

  // Vorname-Filter
  const vornameFilter = $("#vorname-filter", parent.document);
  table.columns(2).search(vornameFilter.val()).draw();

  // Abteilung-Filter
  const abteilungFilter = $("#abteilung-filter", parent.document);
  table.columns(9).search(abteilungFilter.val()).draw();
}

// Keyup-Event-Listener für alle Filter anwenden
$("#volltext-filter", parent.document) .on('keyup', applyTextFilter);
$("#name-filter", parent.document)     .on('keyup', applyTextFilter);
$("#vorname-filter", parent.document)  .on('keyup', applyTextFilter);
$("#abteilung-filter", parent.document).on('keyup', applyTextFilter);

// Initiale Anwendung der Filter
applyTextFilter();

I also use datatables for my table.


Solution

  • you should use a message mechanism between your page and its iframe.

    more info on Window: postMessage() method

    sample usage:
    parent.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>test iframe msg</title>
      <style>
        iframe {
          --sizeH : 20px;
          width   : 531px; 
          height  : var(--sizeH);
          background : darkblue;
          border     : 0;
          padding    : 0;
        }
      </style>
    </head>
    <body>
      
      <iframe id="my-iFrame" src="Iframe.html" ></iframe>
    
    <script>
      const my_iFrame = document.querySelector('#my-iFrame');
    
      // get message events
      window.addEventListener('message', e =>
        {
        let msg = JSON.parse(e.data);  // get messge data
    
        // resize iframe height
        my_iFrame.style.setProperty('--sizeH',  `${msg.h +17}px`);
        })
    </script>
    </body>
    </html>
    

    Iframe.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
    <style>
    html {font-family: Arial, Helvetica, sans-serif;font-size: 16px;}
    table {border-collapse: separate;border-spacing: 1px;background-color: coral;margin: 0;color: black;}
    table td {background-color: whitesmoke;padding: .2em .6em;min-width: 4.2em;text-align: center;}
    table thead td {padding: .3em .6em;background-color: #3acec2;font-weight: bold;}
    table thead td:nth-of-type(1) {width: 10em;}
    table caption {font-size: 1.2em;padding: .3em 0;background:coral;}
    </style>
    </head>
    <body>
    <script>
    const 
      mTcars = 
        [ { model: 'Mazda RX4',           mpg: 21,   cyl: 6, hp: 110, carb: 4 } 
        , { model: 'Mazda RX4 Wag',       mpg: 21,   cyl: 6, hp: 110, carb: 4 } 
        , { model: 'Datsun 710',          mpg: 22.8, cyl: 4, hp: 93,  carb: 1 } 
        , { model: 'Hornet 4 Drive',      mpg: 21.4, cyl: 6, hp: 110, carb: 1 } 
        , { model: 'Hornet Sportabout',   mpg: 18.7, cyl: 8, hp: 175, carb: 2 } 
        , { model: 'Valiant',             mpg: 18.1, cyl: 6, hp: 105, carb: 1 } 
        , { model: 'Duster 360',          mpg: 14.3, cyl: 8, hp: 245, carb: 4 } 
        , { model: 'Merc 240D',           mpg: 24.4, cyl: 4, hp: 62,  carb: 2 } 
        , { model: 'Merc 230',            mpg: 22.8, cyl: 4, hp: 95,  carb: 2 } 
        , { model: 'Merc 280',            mpg: 19.2, cyl: 6, hp: 123, carb: 4 } 
        , { model: 'Merc 280C',           mpg: 17.8, cyl: 6, hp: 123, carb: 4 } 
        , { model: 'Merc 450SE',          mpg: 16.4, cyl: 8, hp: 180, carb: 3 } 
        , { model: 'Merc 450SL',          mpg: 17.3, cyl: 8, hp: 180, carb: 3 } 
        , { model: 'Merc 450SLC',         mpg: 15.2, cyl: 8, hp: 180, carb: 3 } 
        , { model: 'Cadillac Fleetwood',  mpg: 10.4, cyl: 8, hp: 205, carb: 4 } 
        , { model: 'Lincoln Continental', mpg: 10.4, cyl: 8, hp: 215, carb: 4 } 
        , { model: 'Chrysler Imperial',   mpg: 14.7, cyl: 8, hp: 230, carb: 4 } 
        , { model: 'Fiat 128',            mpg: 32.4, cyl: 4, hp: 66,  carb: 1 } 
        , { model: 'Honda Civic',         mpg: 30.4, cyl: 4, hp: 52,  carb: 2 } 
        , { model: 'Toyota Corolla',      mpg: 33.9, cyl: 4, hp: 65,  carb: 1 } 
        , { model: 'Toyota Corona',       mpg: 21.5, cyl: 4, hp: 97,  carb: 1 } 
        , { model: 'Dodge Challenger',    mpg: 15.5, cyl: 8, hp: 150, carb: 2 } 
        , { model: 'AMC Javelin',         mpg: 15.2, cyl: 8, hp: 150, carb: 2 } 
        , { model: 'Camaro Z28',          mpg: 13.3, cyl: 8, hp: 245, carb: 4 } 
        , { model: 'Pontiac Firebird',    mpg: 19.2, cyl: 8, hp: 175, carb: 2 } 
        , { model: 'Fiat X1-9',           mpg: 27.3, cyl: 4, hp: 66,  carb: 1 } 
        , { model: 'Porsche 914-2',       mpg: 26,   cyl: 4, hp: 91,  carb: 2 } 
        , { model: 'Lotus Europa',        mpg: 30.4, cyl: 4, hp: 113, carb: 2 } 
        , { model: 'Ford Pantera L',      mpg: 15.8, cyl: 8, hp: 264, carb: 4 } 
        , { model: 'Ferrari Dino',        mpg: 19.7, cyl: 6, hp: 175, carb: 6 } 
        , { model: 'Maserati Bora',       mpg: 15,   cyl: 8, hp: 335, carb: 8 } 
        , { model: 'Volvo 142E',          mpg: 21.4, cyl: 4, hp: 109, carb: 2 } 
        ] 
    , colNames = Object.keys(mTcars[0])
    , table    = document.body.appendChild(document.createElement('table'));
      ;
    table.createCaption().textContent = 'Motor Trend Cars'
      ;
    let
      tHead = table.createTHead() 
    , tBody = table.createTBody() 
    , rowX  = tHead.insertRow()
      ;
    colNames.forEach(cn => rowX.insertCell().textContent = cn)
      ;
    rowX.cells[2].innerHTML += '&nbsp;<select id="s_cyl"><option>4</option><option>6</option><option>8</option></select>'
      ;
    showCars();
    s_cyl.onchange = showCars;
    
    function showCars()  // Table update
      {
      let sCyl = Number(s_cyl.value);
    
      while (tBody.lastElementChild)  // clear 
          tBody.removeChild(tBody.lastElementChild);
    
      mTcars.filter(({cyl})=>cyl===sCyl).forEach( row =>
        {
        rowX  = tBody.insertRow();
        colNames.forEach( cn => rowX.insertCell().textContent = row[cn] );
        });
    
      let msg = JSON.stringify({ h: table.clientHeight });
      
      // send heigh information to parent document...
      window.parent.postMessage(msg,'*'); 
      }  
    </script>
    </body>
    </html>