OL Learn

Limitations with a table with single row in the middle

Hi,

I am having a lot of technical issues with a document I am working on. The document is rather complex so I had to do a lot of calculations myself to make things work up to now.
The document has a header and a footer that are dynamic in height. In a post pagination script the top margin and the bottom margin are calculated after the fact.
When this is done I know exactly how much space is left for the detail section.
The detail section consists of a table that sometimes has a different cargo description (middle block in red) and sometimes the middle section is the same for all the containers.

At first I tried to solve this with a table that has a rowspan for the cargo description. Because I don’t know how big the entire table will get (depends on the amount of data in it and how PP resizes the columns). Unfortunately the system has technical difficulties handling a rowspan as I set it initially as the max number of rows. If PP determines that the rows do not all fit on one page the table is broken off to fit the rest on a second page. When I check the resulting html there is a secondary table created but the 2nd table does not have a rowspan. This in turn then shifts the rest of the columns to the left on the second page.
Working with a rowspan is the cleanest option but I do not know in the beginning how much data fits on one page because of the dynamic nature of the document. So I can only set the rowspan to the total number of records I have.
So in the screenshot example below where I have 15 records in total the rowspan is initially set to 15. Only 13 rows fit on 1 page so I would have expected PP to change the rowspan for table 1 to 13 and then add an additional rowspan of 2 for the 2nd table on page 2 as only PP knows where it will break up the page. Unfortunately this is not how the system handles this.

So as a workaround I used a div overlay (box in red) that I placed over the table. When working with this I have additional concerns I need to work out because the middle text might be too big to fit on 1 page.
Now I calculate exactly how much can be fitted on the page by removing a word from the text until it fits. The rest then needs to go to the next page.
The calculations are all done and what needs to go to the next page is also determined already.
All that needs to be done is what I expected would be a small thing but it isn’t:
Create a clone of the current page and add an additional page with the clone. I can create a clone so that works but then I need to create a new page with “addAfter” but this is not allowed in a Post Pagination script. Unfortunately I am unable to do this in a Control Script because of the dynamic nature of the document and I do not know in the beginning how many pages I will have, and how much detail size I have to work with.

The cleanest option would have been to work with a rowspan as then I would not have to calculate how much text need to go to the next page and the system all does that for me.

Note there are still other technical issues to solve (for example what to do if the number of rows is too much to fit on a page anyway and an additional page is created. Then I should not create a new page and just add the red box to the page that is already there).

Sorry for the amount of text but this is a really complex issue that I have been working on for a long time already without a solution yet. Hopefully someone is able to help me solve this.
Note that even support does not have a clean solution yet.

Sample document:

Hi @dvdmeer,

A option you might consider is to create the entire table by a Standard Script or Post Pagination Script because in that case you have more control over the table and because then you have the option to target a table element which has been placed on a specific page. For this you can make use a script like:

Post Pagination Script

Name: Example
Selector: table#dynamic-table
Code:

/* 1. Body height in pixels, whereby body height is equal to page height
 *    minus header plus footer margins.
 * 2. Index tableElement variable.
 * 3. Array (<table> elements) of arrays (<tr> elements).
 * 4. Only required when you use the following JavaScript code in a
 *    Post Pagination Script. */

var tbodyElement = null;
var maxHeight = 417; // 1.
var index = 0; // 2.
var tableElements = [[]]; // 3.

if (results.children().length > 1) {
	tbodyElement = results.children()[1];
}

if ("detail" in record.tables && tbodyElement !== null) {
	for (var i = 0; i < record.tables["detail"].length; i++) {
		var trElement = "";
		var id = ("row-" + (i + 1));
		
		var fieldOne = record.tables["detail"][i].fields["columnOne"];
		var fieldTwo = record.tables["detail"][i].fields["columnTwo"];
		var fieldThree = record.tables["detail"][i].fields["columnThree"];
		
		trElement += ("<tr id=\"" + id + "\">");
		trElement += ("<td class=\"column-1\">" + fieldOne + "</td>");
		trElement += ("<td class=\"column-2\">" + fieldTwo + "</td>");
		trElement += ("<td class=\"column-3\">" + fieldThree + "</td>");
		trElement += "</tr>";
		
		if (i == 0) {
			tbodyElement.html(trElement);
		} else {
			tbodyElement.append(trElement);
		}
		
		if (tbodyElement.height() >= maxHeight) {
			index++;
			tableElements.push([]);
			tbodyElement.html(trElement);
		}
		
		tableElements[index].push(trElement);
	}
	
	var result = "";
	
	for (var i = 0; i < tableElements.length; i++) {
		if (tableElements[i].length > 0) {
			var id = ("table-" + (i + 1));
		
			result += "<table id=\"" + id + "\" class=\"table--grid\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin-bottom: 0; width: 100%;\">";
			result += "<thead>";
			result += "<th class=\"column-1\" style=\"width: 33%;\">Column One</th>";
			result += "<th class=\"column-2\" style=\"width: 33%;\">Column Two</th>";
			result += "<th class=\"column-3\" style=\"width: 33%;\">Column Three</th>";
			result += "</thead>";
			result += "<tbody>";
		
			for (var j = 0; j < tableElements[i].length; j++) {
				result += tableElements[i][j];
			}
			
			result += "</tbody>";
			result += "</table>";
		}
	}
	
	results.replaceWith(result);
	merge.section.paginate(); // 4.
}

The above JavaScript code will add a <tr> element to a existing <table> element to calculate how many <tr> elements fit on a single page. Each time the end of the page has been reached a new array will be added to the variable tableElements and the existing table will be changed to a single <tr> element by making use of the html() method.

The id’s “table-{tableNumber}” and “row-{rowNumber}” and the class “column-{columnNumber}” are used to give you more control afterwards.

Please note that the Print Context Section needs to contain the following HTML code to use the above JavaScript code in a Standard Script or Post Pagination Script and to get it properly working:

<table id="dynamic-table" class="table--grid" cellpadding="0" cellspacing="0" style="margin-bottom: 0; width: 100%;">
    <thead>
        <tr>
            <th style="width: 33%;">
                Column 1<br>
            </th>
            <th style="width: 33%;">
                Column 2<br>
            </th>
            <th style="width: 33%;">
                Column 3<br>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr id="row-no-1">
            <td class="column-1"></td>
            <td class="column-2"></td>
            <td class="column-3"></td>
        </tr>
    </tbody>
</table>

Please keep in mind that using the above code only works when:

  1. A Page Context Section contains only a <table> element and when the Standard Script or Post Pagination Script uses this <table> element as selector.
  2. The same HTML code has been used as table in the JavaScript code as shown in the Source mode of the Connect Designer.
  3. The body height is known at the beginning of executing the above JavaScript code (in this case it does have a static value: “var maxHeight = 417;”).