How to insert a page break within a <table> element in a React application

Essentially, my table consists of several sub-headers and I need to insert a page break after a certain number of these subsections while avoiding automatic breaks within the sections. It should appear like this rough layout. The gray areas represent the sub-headers where a page break would occur before the 4th, 8th, 12th, etc. subsection.

https://i.sstatic.net/6JGFq.png

I am encountering two main challenges which may or may not be specific to React. Bootstrap is also being used in this scenario.

1) The <div> as a child of <table>, <tbody>, <thead> issue:

Initially, I attempted to add

<div className='pagebreak'>
after every 4th <th>. However, this generated an error stating that a <div> cannot be nested inside
<table>/<tbody>/<thead>
.

The following approach, therefore, is not allowed:

let i = 1;

return _.map(section, s => {
    i++;
    return (
        <table>
            <tbody>
                <tr>
                    <th colSpan='6'>{s.subSectionTitle}</th>
                </tr>
                <tr>
                    <td>{s.data1}</td>
                    <td>{s.data2}</td>
                    <td>{s.data3}</td>
                    <td>{s.data4}</td>
                    <td>{s.data5}</td>
                    <td>{s.data6}</td>
                </tr>
                { i = 4 ? <div className='pagebreak'></div> : null }
            </tbody>
        </table>
    )
})

Several alternative approaches were considered but proved ineffective, such as:

{ i = 4 ? <tr className='pagebreak'></tr> : null }

Or:

{ i = 4 ? <th><td className='pagebreak'></th></tr> : null }

Or:

{ i = 4 ? <tr><th><div className='pagebreak'></div></th></tr> : null }

While these circumvent the error, they do not accomplish the desired pagebreak functionality.

Hence, it appears impossible to introduce a page break within a <table> tag.

2) Creating a new <table> for each subsection.

This method yields poor results due to varying column widths across tables unless static widths are enforced, contrary to my preference. Dynamic resizing of columns is maintained by ensuring uniform width throughout determined by the widest data point within any given column.

However, the following approach does succeed in inserting a break:

    return (
        <table>
            <tbody>
                <tr>
                    <th colSpan='6'>{s.subSectionTitle}</th>
                </tr>
                <tr>
                    <td>{s.data1}</td>
                    <td>{s.data2}</td>
                    <td>{s.data3}</td>
                    <td>{s.data4}</td>
                    <td>{s.data5}</td>
                    <td>{s.data6}</td>
                </tr>
            </tbody>
        </table>
        <div className='pagebreak'></div>
        <table>
            <tbody>
                <tr>
                    <th colSpan='6'>{s.subSectionTitle}</th>
                </tr>
                <tr>
                    <td>{s.data1}</td>
                    <td>{s.data2}</td>
                    <td>{s.data3}</td>
                    <td>{s.data4}</td>
                    <td>{s.data5}</td>
                    <td>{s.data6}</td>
                </tr>
            </tbody>
        </table>   
    )

If you have any suggestions on how to address these issues, please let me know!

Answer №1

Expanding on Rounin's explanation with a React demonstration:

@media print {

    tr {
        display: block;
    }

    .pagebreak {
        break-after: always !important;
        page-break-after: always !important;
        page-break-inside: avoid !important;
    }
}

// component.jsx
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

import styles from '../assets/scss/app.scss';

class TestPrint extends Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test'
            ]
        }
    }

    renderContent() {
        let i = 0;
        return this.state.data.map((d) => {
            i++
            if (i % 10 === 0) {
                return (
                    <tr key={i} className='pagebreak'>
                        <td key={i}>{i} - {d}</td>
                    </tr>                    
                )
            } else {
                return (
                    <tr key={i}>
                        <td key={i}>{i} - {d}</td>
                    </tr>
                )
            }
        });
    }

    render() {
        return (
            <table>
                <tbody>
                    { this.renderContent() }
                </tbody>
            </table>
        )
    }
}

ReactDOM.render(<TestPrint />, document.getElementById('app'));

Answer №2

This statement is true:

It's not valid to have a <div> as a child of <table>, <tbody>, or <thead>

However, you can structure and style your table in such a way that occasionally a row, styled like a block-level element, serves as a page break. This can be achieved in CSS by using:

page-break-before: always;

You can also prevent page breaks within standard table rows by applying:

page-break-before: avoid 

See the Example Below:

table {
border-collapse: collapse;
}

td {
height: 12px;
padding: 6px 24px;
border: 1px solid rgb(0, 0, 0);
}

tr {
page-break-before: avoid;
}

tr.page-break {
display: block;
page-break-before: always;
}

tr.page-break td {
border: 1px solid rgba(0, 0, 0, 0);
}
<table>
<tr class="page-break">
<td colspan="7">
</tr>

<tr>
<td>A1</td>
<td>A2</td>
<td>A3</td>
<td>A4</td>
<td>A5</td>
<td>A6</td>
<td>A7</td>
</tr>

... additional table rows ...

<tr class="page-break">
<td colspan="7">
</tr>

<tr>
<td>G1</td>
<td>G2</td>
<td>G3</td>
<td>G4</td>
<td>G5</td>
<td>G6</td>
<td>G7</td>
</tr>
</table>

Explore more about the page-break-* properties:

https://css-tricks.com/almanac/properties/p/page-break/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error encountered while generating PDF using xhtml2pdf Pisa.CreatePDF() due to CSS parsing issue

Currently, I am referencing the xhtml2pdf instructions. I opted to utilize one of the provided sample html files and saved it as test.html: <html> <head> <style> @page { size: a4 portrait; @frame header_frame { ...

Ways to extract full text from HTML documents

Currently, I am utilizing a sybex platform to access flashcards. This website displays one flashcard at a time out of a total of 100 cards. My goal is to gather the text from all the flashcards in order to compile them into a single document, rather tha ...

Display a div when collapsing in Bootstrap for screen widths of 991px or smaller

I am currently working on optimizing the mobile version of my website using Bootstrap. There is a div element that is taking up too much space on the page, and I would like to hide it on page load for screen widths of 991px or less. I want users to have th ...

Error Alert: Node.js Detected an Unhandled Promise Rejection on the Login Form

I have created a user registration form in Node.js where I check for duplicate usernames and emails. However, I am facing an error. Can someone please help me out or provide an example? Thank you if (req.body.email_reg && req.body.name_reg & ...

Avoiding interference with adjacent elements caused by long content in a div

Hey there, I could really use some help with my CSS layout, I'm pretty new to CSS and Flexbox and I'm trying to create a simple layout. The issue I'm running into is how to stop long content inside a pre tag from pushing other divs. Here& ...

Tips for showcasing model data dynamically on a webpage using HTML

My model is constantly updating within a function, and I need a way to dynamically display this updated data without the need to refresh the page. How can I achieve this? models.py class MyLongProcess(models.Model): active_uuid = models.UUIDField(&apo ...

Vertical tabs in Bootstrap display content when hovered over

I have implemented some tabs using Bootstrap and I want to show these tabs when hovering over them. Here is the link to view the tabs: https://jsfiddle.net/uzfxmrs3/ Below is the HTML code for the tabs: <div class="d-flex align-items-start respon ...

Webpack is notorious for creating multiple copies of images

Having an issue with Webpack where it's generating duplicate images, one of which is broken. I have an original image image, and after running Webpack, two duplicates are created. One works fine: image, but the other one is broken: image. I'm us ...

The Node.js application is unable to locate the source file path

Currently, I am in the process of creating a simple quiz application. While working on this project, I encountered an issue with linking a JS file in an HTML template. Even though I have confirmed that the path is correct, every time I run my node app, the ...

Are the form fields and database table fields sharing identical names?

Do you think it is a poor practice to use the same name for HTML form fields as for table field names? I'm creating dynamic SQL insert queries and currently, I am using regular expressions to change the names to match the corresponding database fields ...

Looking to make the Bootstrap navigation bar fixed when scrolling down

Can someone help me fix this bootstrap code to stay fixed at the top of the webpage while scrolling down? Below is the bootstrap code that I currently have. I need assistance in making it change from a static position to a fixed one as users scroll down t ...

How to customize the font size in three.js CSS3DRenderer

I am trying to use threejs's CSS3DRenderer to display text in my 3D view. However, I am facing issues with controlling the font size. Despite setting font-size: 1px in CSS, the text remains large. I also attempted to adjust the scale of the css3dobjec ...

Creating a horizontal scrolling section for mobile devices using CSS

Looking to create a horizontal scroll area specifically for mobile devices, similar to the design seen here: https://i.sstatic.net/oSNqL.png Additionally, I want to hide the scrollbar altogether. However, when attempting to implement this, there seem to ...

What is the best method for effectively showcasing the data obtained from the fetch request?

As I embark on my journey of learning Reactjs, I have successfully retrieved data from the specified API , which showcases the profile of a Lichess User (in this case, nihalsarin2004). However, to make use of every detail, I have written code for each spec ...

Keep table header stationary while accommodating varying column widths

I have come across various solutions for freezing a table header row, such as creating a separate table containing only the header and hiding the header of the main table. However, these solutions are limited to cases where column widths are predetermine ...

Exploring the possibilities offered by utilizing semantic-ui-react within a React

I am looking to utilize the same component library for both web and mobile applications with React. I have had success with using semantic-ui-react for web projects, but when I tried to implement it in a react-native project, I encountered some difficult ...

Issues concerning date and time manipulation - Library Moment.js

As a beginner in JavaScript, I've been working on an activity that generates a table of train times based on user input. However, I'm facing issues with formatting the arrival time correctly. Whenever I input the arrival time in military format ( ...

Incorporate a unique identifier for dynamic elements

Is there a way to give generated divs the same name so I can markup them easily? $.getJSON("data/reviews.json", function(data){ for(var i=0; i<data.length; i++) { var review = sym.createChildSymbol("Template", "content"); review.$("title").html ...

Is there a speed advantage in Angular 2+ when using [disabled] instead of "disabled" in a template?

Let's analyze the differences between these two HTML snippets: <input formControlName="address" [disabled]=isDisabled/> <input formControlName="address" disabled={{isDisabled}}/> While it seems that the first option is more readable, I ...

Guide on using axios to send form values dynamically as they change in a select dropdown?

I have successfully populated a select form from MaterialUI with choices received through an axios GET request. But now, in order to proceed, I need to make an axios POST request when the user selects an option in my handleChange(event) function. The data ...