Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Ligonsker's avatar

Entire non-paginated table hidden in the DOM

Hello,

I want to let the users print the entire table using JavaScript's window.print(). My table is paginated so if I try to print the table it will only show the rows that are currently displayed. To bypass that what I did was to add the entire data object, non-paginated from the Controller, and echo it as a hidden table in the DOM:

From the Controller:

$data = Model::paginate(100);
$data_not_paginated = Model::get();
return view('myview', compact('data', 'data_not_paginated'));

From the Blade file:

// displaying the paginated table
<table>
@foreach($data as $row)
  <tr>
    <td>{{$row->col1}}></td>
    <td>{{$row->col2}}></td>
    // ... more columns ... 
  </tr>
@endforeach
</table>

// echoing a hidden full table
<table hidden id="table_to_print">
@foreach($data_not_paginated as $row)
  <tr>
    <td>{{$row->col1}}></td>
    <td>{{$row->col2}}></td>
    // ... more columns ... 
  </tr>
@endforeach
</table>

And now I can add the print media query:

@media print {
  body * {
    visibility: hidden;
  }
  #table_to_print {
    visibility: visible;
  }
  #table_to_print{
    position: absolute;
    left: 0;
    top: 0;
  }
}

And it's working. But sometimes the table can be really big, thousands of rows. How bad is it to have a hidden table with thousands of rows? And is there a better solution? Is there a problem with my solution?

Thanks

0 likes
5 replies
LaryAI's avatar
Level 58

Having a hidden table with thousands of rows can cause performance issues, especially on slower devices. A better solution would be to use JavaScript to fetch the non-paginated data when the print button is clicked, and then generate a printable version of the table on the fly. This way, you only load the data when it's needed, and you don't have to worry about performance issues caused by a large hidden table.

Here's an example of how you could implement this:

  1. Add a button to your page that triggers the print function:
<button id="print-button">Print</button>
  1. Add a script that fetches the non-paginated data and generates a printable table:
<script>
  document.getElementById('print-button').addEventListener('click', function() {
    // Fetch the non-paginated data
    fetch('/path/to/non-paginated-data')
      .then(response => response.json())
      .then(data => {
        // Generate the printable table
        let table = '<table>';
        data.forEach(row => {
          table += '<tr>';
          table += '<td>' + row.col1 + '</td>';
          table += '<td>' + row.col2 + '</td>';
          // ... more columns ...
          table += '</tr>';
        });
        table += '</table>';

        // Open the print dialog with the printable table
        let printWindow = window.open('', 'Print', 'height=600,width=800');
        printWindow.document.write(table);
        printWindow.document.close();
        printWindow.focus();
        printWindow.print();
        printWindow.close();
      });
  });
</script>
  1. Add a route to your Laravel application that returns the non-paginated data:
Route::get('/path/to/non-paginated-data', function() {
  return Model::get();
});

With this solution, you only load the non-paginated data when the print button is clicked, and you generate a printable version of the table on the fly. This way, you don't have to worry about performance issues caused by a large hidden table.

tykus's avatar

This seems very inefficient; how often does a user really want to print the table?

1 like
Ligonsker's avatar

@tykus I'm not sure as I was just told it's necessary. I don't think a user would print it that much.

In that case should I implement the bot's answer - calling the print data only on click?

Please or to participate in this conversation.