Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

Delete last page at runtime

Avatar

Level 2

We've got an invoice adobe form in SAP where the last page should always be printed on a different kind of paper.

That requires us to use a different intput and output tray for the last page.

Out current workaround idea:

Print the document twice: First time without the last page, second time only the last page. This way we have 2 separate print jobs and can control the intput/output tray as we may. But we can't manage to always delete the last page.

The pages are filled using repeating subforms. We don't know how many times the subforms are repeated at design time, and how large they'll be.

Any ideas on how to solve this?

1 Accepted Solution

Avatar

Correct answer by
Level 10

Hi,

You could move the script to the layout:ready event.  You will need to force the relayout to get the presence update to take effect.  The problem then is to stop this script from firing again as you will probably end up with all the pages hidden eventually as the relayout will trigger the layout:ready event.

Try this code in the layout:ready event of Formular1.

if (!PagesHidden.value) {
      var pageCount = xfa.layout.pageCount();
      var lastVisible = null;
      for (var i = content._repeating_subform.count - 1; i >=0; i--) {
            if (xfa.layout.page(content.repeating_subform.all.item(i)) == pageCount) {
                 content.repeating_subform.all.item(i).presence = "hidden";
            } else {
                if (lastVisible == null) {
                      lastVisible = content.repeating_subform.all.item(i);
                }
            }
      }
      if (xfa.layout.pageSpan(lastVisible) > 1) {
          lastVisible.presence = "hidden";
      }
      PagesHidden.value = "1";
      xfa.layout.relayout();
}

PagesHidden is a form variable with an initial value of zero.  This gets set to "1" so the script only executes once.

View solution in original post

19 Replies

Avatar

Level 10

Hi,

There are some print options in Designer, if your different kinds of paper are different size then they might be all you need.

1521419_pastedImage_0.png

Regards

Bruce

Avatar

Level 2

Hi Bruce,

thanks for your explanation.

To use that option, our last page would need a different page size, correct?

How can I tell the last page to be on a different master page, or a different page size?

Best regards

Joschka

Avatar

Level 10

That is difficult to say without seeing the structure of your form. But, I would hope you could have a second master page that the last page was linked with.  Can you structure your form that way?

Avatar

Level 2

We can create a second master page, but we would need to tell the content when to switch to the second master page.

Here's the structure:

2018-07-04 16_05_30-Adobe LiveCycle Designer - [Unbenannt1].png

Repeeating_subform will eventually extend to the last page.

How do I tell repeating_subform to use my second masterpage "last_page"?

Avatar

Level 10

Hi,

I had thought the last page was different, that is an alternative to content in your sample.  So that print options approach wont work.

This script will hide all repeating_subform objects that are on the last page.

var pageCount = xfa.layout.pageCount(); 

for (var i = _repeating_subform.count - 1; i >=0; i--) {

      if (xfa.layout.page(repeating_subform.all.item(i)) == pageCount) {

           repeating_subform.all.item(i).presence = "hidden";

      }

}

Avatar

Level 2

Hm... that sounds like the right direction.

If I do that now, the last page does not contain any items, but it's still printed.

Any idea on how to avoid the blank page?

Can I access the page and set the presence to hidden? If so, how?

Avatar

Level 10

I guess your repeating_subform and my_text allows page breaks within content?  If so then we will need to get rid of one more.

So try this;

var pageCount = xfa.layout.pageCount();   
var lastVisible = null;
for (var i = _repeating_subform.count - 1; i >=0; i--) { 
      if (xfa.layout.page(repeating_subform.all.item(i)) == pageCount) { 
           repeating_subform.all.item(i).presence = "hidden"; 
      } else {
           if (lastVisible == null) {
                lastVisible = repeating_subform.all.item(i);
           }
      }

if (xfa.layout.pageSpan(lastVisible) > 1) {
     lastVisible.presence = "hidden"; 
}

Avatar

Level 2

Thanks again for your input.

Same problem. I've tried to hide all items from the second-last page (... == pageCount - 1).

With 4 pages of subforms, pages 3 and 4 are now empty, but are still printed.

Is the event ready:layout maybe too late?

The page count is only available at this event though, right? At least the script doesn't work in ready:form.

Avatar

Level 10

Hi, 

There's lots I'm not sure about with what you are trying o do.  I tried that code in the click event of a button.  But maybe the DocReady would work?

Brue

Avatar

Level 2

Hi Brue,

what I'm trying to do is to split the document into last page and everything but last page.

Since I can't use external tools for this (like PDF Toolkit / PDF Toolbox), I have to find a script to do just that.

I hope it's clearer now.

A button will not work for us, since the form is not interactive.

So I really just need a command to delete the last page from the resulting PDF, or every page before that.

Avatar

Level 10

So what software is producing the PDF, one of the server products like LiveCycle Output?  How will the script know to delete the last page or all but the last page?

Avatar

Level 2

It's called Adobe Document Services (ADS), a cross-product of Adobe and SAP. I don't know how the script can delete the last page or all but, and that's exactly what I'm trying to find out. Any ideas on that?

Avatar

Correct answer by
Level 10

Hi,

You could move the script to the layout:ready event.  You will need to force the relayout to get the presence update to take effect.  The problem then is to stop this script from firing again as you will probably end up with all the pages hidden eventually as the relayout will trigger the layout:ready event.

Try this code in the layout:ready event of Formular1.

if (!PagesHidden.value) {
      var pageCount = xfa.layout.pageCount();
      var lastVisible = null;
      for (var i = content._repeating_subform.count - 1; i >=0; i--) {
            if (xfa.layout.page(content.repeating_subform.all.item(i)) == pageCount) {
                 content.repeating_subform.all.item(i).presence = "hidden";
            } else {
                if (lastVisible == null) {
                      lastVisible = content.repeating_subform.all.item(i);
                }
            }
      }
      if (xfa.layout.pageSpan(lastVisible) > 1) {
          lastVisible.presence = "hidden";
      }
      PagesHidden.value = "1";
      xfa.layout.relayout();
}

PagesHidden is a form variable with an initial value of zero.  This gets set to "1" so the script only executes once.

Avatar

Level 2

Hi Brue,

thanks again for the extensive answer and explanation.

Unfortunately the script does only help when deleting the last page.

We have masterpages FIRST, NEXT and LAST.

If we remove every element except the ones on the last page, the content would be printed on masterpage FIRST instead of LAST.

Is there maybe a way to switch masterpages at runtime?

It would be way easier if the deletePages(n-1, 1) command would still be available .

Is there a similar command available? Can we maybe use the pageSet to remove pages?

Avatar

Level 10

Hi,

I new the script was only going to help deleting the last page, that is why I asked how it was going to know to delete the last or all but the last two responses ago.

The only way I know of switching master pages at runtime is to duplicate the form, one for each master page and then only add the interactive pages for the master page you want.

Even if the deletePages() method was available how are you going to tell it to delete the last or all but the last.

Avatar

Level 2

Hi Brue,

ok, I understand now what you meant.

Well, if deletePages() would work, the script could be as follows:

this.deletePages(xfa.layout.pageCount(), 1);

xfa.layout.relayout();

(Pseudocode)

Having each page duplicated sounds costy, but I guess it's a costy requirement anyways.

Do you mean duplicating the whole XDP file, or the Form WITHIN the file?

Avatar

Level 10

Hi,

There's an example in this blog of choosing different page sizes at run time (which means choosing different master pages).  It uses a technique to define the form once and placing it under the reference element in the form structure.

Maybe they will help

Avatar

Level 2

Hi Brue,

I have bin looking for the blog post you are talking about, but I can't find it at all.

Where can I find this technique?

Best regards

Joschka

Avatar

Level 2

Ok, I was able to combine your solutions to a working prototype.

I am using a dummy-subform in "repeating_subform", which has the target "last_page". This subform is hidden by default.

With your script from above I now determine which subform-instances are on the last page, and set the dummy-subform to "visible" for all corresponding instances. Then I use relayout() to apply the changes.

This way I have the last page on a different master page and can now use a different paper tray.

Thanks again for all your help.