Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Page break on condition

Avatar

Level 1

I am printing a nested table on form with headings. It prints data as shown below which is fine.

H1

   L1

   L2

   L3

H2

   L1

   L2 .....

I have setting selected to continue printing to next page in case of overflow and print Header in all pages.

My requirement is check where in the page the heading is getting printed , if it is after the 75% of the content area then trigger a page break.

Is it possible to get the location of element before it is getting printed and trigger page break if its value is greater than certain value ?

Thanks in advance ...

SK

1 Accepted Solution

Avatar

Correct answer by
Level 10

Hi SK,

There is nothing built into Designer to do this sort of thing.  But,  you could write some code to do it.  The first problem will be that you can't determine the position of the form objects until after the form has been laid out, which also means you wont be able to lay out the second page until after the first page when you know how many rows are being bumped to page 2.  The basic approach I would take would take is to add a column to your table which holds the calculated target page (this can be zero width so isn't displayed), have the code in the layout ready event and call a re-layout for each page that needs to be re-flowed.  Add a conditional break in your table on the target page column to add the page break.  Because the code is in the layout ready event (which means it will be called a lot) you will have to have a way of stopping the re-layout from being called when we know what page the rows are going to be on, in this code I am using a form variable, LayoutComplete.

if (LayoutComplete.value !== "true") {

    // this assumes only one content area, if multiple content area move copy within the loop and find content area for given row

    var contentH = parseFloat(xfa.layout.pageContent(0, 'contentArea').item(0).h); // this always returns mm (Master page is A4) but you should check for your form might uses inches

    var breakMade = false;

    var currentPage = 0;

    var targetPage = 0;

    var list = Table1.resolveNodes("Row1[*]");

    for (var i = 0; i < list.length; i++) {

        var row = list.item(i);

        row.PosY.rawValue = xfa.layout.y(row, "mm");

        row.ContentY.rawValue = contentH;

        row.Page.rawValue = xfa.layout.page(row);

        if (targetPage != row.Page.rawValue) {

            targetPage = row.Page.rawValue;

        }

        if (targetPage == row.Page.rawValue && row.PosY.rawValue > (row.ContentY.rawValue * 0.75)) {

            targetPage++;

            breakMade = true;

        }

        row.TargetPage.rawValue = targetPage;

        //console.println("index: " + row.index + ", " + targetPage + "-" + row.Page.rawValue + ", " + row.PosY.rawValue + ", " + (row.ContentY.rawValue * 0.75) + ", " + (targetPage == row.Page.rawValue && row.PosY.rawValue > (row.ContentY.rawValue * 0.75)))

    }   

    if (breakMade) {

        app.timeout = app.setTimeOut("xfa.layout.relayout();",100); // draw the next page

    } else {

        LayoutComplete.value = "true"; // Didn't find a page to break so flag layout as complete

    }

}

This code adds a couple of other columns just to show what is happening.  It also assumes there's only one content area to worry about and that the height property of the content area is returned in mm, if you get inches then you will have to make some adjustments in line 10 to get the row Y position in inches as well.

The conditional break in this sample is defined on the table row object, and triggers a page throw every time the target page column changes

1773547_pastedImage_1.png

You can see this code in this form, https://sites.google.com/site/livecycledesignercookbooks/home/ConditionBreakDependingOnLayout.pdf?at...​ and the xml for it is https://sites.google.com/site/livecycledesignercookbooks/home/ConditionBreakDependingOnLayout.xml?at...

Regards

Bruce

View solution in original post

2 Replies

Avatar

Correct answer by
Level 10

Hi SK,

There is nothing built into Designer to do this sort of thing.  But,  you could write some code to do it.  The first problem will be that you can't determine the position of the form objects until after the form has been laid out, which also means you wont be able to lay out the second page until after the first page when you know how many rows are being bumped to page 2.  The basic approach I would take would take is to add a column to your table which holds the calculated target page (this can be zero width so isn't displayed), have the code in the layout ready event and call a re-layout for each page that needs to be re-flowed.  Add a conditional break in your table on the target page column to add the page break.  Because the code is in the layout ready event (which means it will be called a lot) you will have to have a way of stopping the re-layout from being called when we know what page the rows are going to be on, in this code I am using a form variable, LayoutComplete.

if (LayoutComplete.value !== "true") {

    // this assumes only one content area, if multiple content area move copy within the loop and find content area for given row

    var contentH = parseFloat(xfa.layout.pageContent(0, 'contentArea').item(0).h); // this always returns mm (Master page is A4) but you should check for your form might uses inches

    var breakMade = false;

    var currentPage = 0;

    var targetPage = 0;

    var list = Table1.resolveNodes("Row1[*]");

    for (var i = 0; i < list.length; i++) {

        var row = list.item(i);

        row.PosY.rawValue = xfa.layout.y(row, "mm");

        row.ContentY.rawValue = contentH;

        row.Page.rawValue = xfa.layout.page(row);

        if (targetPage != row.Page.rawValue) {

            targetPage = row.Page.rawValue;

        }

        if (targetPage == row.Page.rawValue && row.PosY.rawValue > (row.ContentY.rawValue * 0.75)) {

            targetPage++;

            breakMade = true;

        }

        row.TargetPage.rawValue = targetPage;

        //console.println("index: " + row.index + ", " + targetPage + "-" + row.Page.rawValue + ", " + row.PosY.rawValue + ", " + (row.ContentY.rawValue * 0.75) + ", " + (targetPage == row.Page.rawValue && row.PosY.rawValue > (row.ContentY.rawValue * 0.75)))

    }   

    if (breakMade) {

        app.timeout = app.setTimeOut("xfa.layout.relayout();",100); // draw the next page

    } else {

        LayoutComplete.value = "true"; // Didn't find a page to break so flag layout as complete

    }

}

This code adds a couple of other columns just to show what is happening.  It also assumes there's only one content area to worry about and that the height property of the content area is returned in mm, if you get inches then you will have to make some adjustments in line 10 to get the row Y position in inches as well.

The conditional break in this sample is defined on the table row object, and triggers a page throw every time the target page column changes

1773547_pastedImage_1.png

You can see this code in this form, https://sites.google.com/site/livecycledesignercookbooks/home/ConditionBreakDependingOnLayout.pdf?at...​ and the xml for it is https://sites.google.com/site/livecycledesignercookbooks/home/ConditionBreakDependingOnLayout.xml?at...

Regards

Bruce

Avatar

Level 1

Thanks Bruce,

I will try soon and let you know if It worked or not.  I have told the business that it may not work and details will be printing till the end of content area.

I have posed another question on issue I am facing on similar type of requirement. Let me know your thoughts.

https://forums.adobe.com/message/11133891#11133891

regards,

SK