6 Replies Latest reply on Dec 9, 2017 12:27 PM by awbrown66

    Show/hide layers and fields on doc startup

    awbrown66 Level 1

      I set up my doc with layers to hide/show all active fields, etc. from anyone not using Adobe Reader DC or Acrobat. I use the script below with .hidden or .visible to control the fields and other script to hide/show text on different layers. I have the script located in a doc level script so that it runs every time the doc is opened. I also have app.runtimeHighlight = true; to highlight the fields automatically.

       

      It works, but when the document is initially opened some of the highlighted fields on the first page do not display at all on the screen while others further down the same page display with no issues. If one scrolls to the very next page and then scrolls back to the first page, all the highlighted fields are then displayed correctly. It seems like a "redraw" or "refresh" type issue, maybe?

       

      Any suggestions?

       

      for (var i = 0; i < numFields; i++) {
        var f = getField(getNthFieldName(i));
        this.getField(f.name).display = display.hidden;
       }
      
        • 1. Re: Show/hide layers and fields on doc startup
          Thom Parker Adobe Community Professional

          Things are a bit tricky when the PDF is first opened. The doc scripts run before the document is completely open.  In this case properties of visual elements may not be properly applied. There are a couple of options that may work better.

           

          1. Use a Page Open script on the first page,  This script runs after the document is fully loaded.  However, you'll need a document level variable to gate the script so it only runs once.

           

          2.  Put a time delay on running the doc script with the "app.setTimeout()" function.  This seems to work well. I've done it many times.

           

          There is another option for controlling so many fields and features. And that is to use OCG layers. Place all fields, annotations, and graphics on different layers, then just turn the layers on and off.  This is a bit of an expert activity, but it a very good solution if the form will only be used in Acrobat and Reader. 

          1 person found this helpful
          • 2. Re: Show/hide layers and fields on doc startup
            awbrown66 Level 1

            Thanks Thom, funny that you be the one to reply; I'm actually using one of your OCG functions!

             

            I tried your suggestion of using the "app.setTimeout()" function. I set up a doc level function and then called it from a page open action, and I tried calling it directly from the doc level. I set a delay of up to 6-seconds, but It behaved the same in both scenarios... some fields would not display.

             

            I noticed if the function was called twice that it seemed to "refresh" the pages and everything displayed correctly... I set it up with the script below and it works. Do you see any drawbacks to this method, or a better way to accomplish this?

             

             

            // Get Layer Names  
             function findLayers(cName) { 
              var fLayers = this.getOCGs(); 
              for (var i = 0; fLayers && i < fLayers.length; i++) { 
                if (fLayers[i].name == cName) return fLayers[i];
            
              } 
              return null;
             } 
            
             function a_check_Reader_and_OS() {
              if (app.platform == "WIN" || app.platform == "MAC") {
               if (app.viewerType == "Reader" || app.viewerType == "Exchange-Pro") { // If running Windows or Mac and using Adobe Reader / Pro, display the Application and all fields
                for (var i = 0; i < numFields; i++) {
                 var f = getField(getNthFieldName(i));
                 this.getField(f.name).display = display.visible;    
                }
                // Hide specific fields
                var fltFields = new Array("State Hidden", "SSN Hidden", "Hide CPR Exp Date", "Hide CPR Renew Radios", "Hide CPR Approx Renew Date", "Hourly Rate", "Date");  
                for (var i = 0; i < fltFields.length; i++) {
                 this.getField(fltFields[i]).display = display.hidden;
                }
                findLayers("Main-Message-Layer").state = false;
                findLayers("Text-Graphics").state = true;
                app.runtimeHighlight = true;
               } 
               else {
                findLayers("Main-Message-Layer").state = true; 
               }
              }
              else { // If not running Windows or Mac, display Not-Compatible-Layer
               findLayers("Main-Message-Layer").state = false;
               findLayers("Not-Compatible-Layer").state = true;
              }  
             }  
            run = app.setTimeOut ("a_check_Reader_and_OS()", 1000); //re-run the function to refresh highlighted fields
            a_check_Reader_and_OS();
            
            • 3. Re: Show/hide layers and fields on doc startup
              Thom Parker Adobe Community Professional

              Ideally you'd like the code to predictably do what it is supposed to do. If there is uncertainty in whether some action will actually happen, then it's possible that it won't happen even with running the code twice. Or that something you don't want to happen, will happen. But that's Acrobat JavaScript for you, and this is one of those situations. It's unfortunate that Adobe did not create an initialization event that only runs after the document is fully loaded.

               

              So, there's nothing particularly bad about running the code twice. If that's what you have to do, then you don't have a lot of choice. But does the code really need to be as dynamic as it is. For example, there are two loops setting field visibility. In the first all fields are set to visible, then the second loop sets only a few fields to hidden. First, do all the field really need to be set to visible? And second, why not combine the loops. To combine them, change the field name array to an object, like this

               

              oFlds ={"State Hidden":true, "SSN Hidden":true, "Hide CPR Exp Date":true};

               

              This type of arrangement makes it' easy to test for the fields you want to hide.

               

                  for (var i = 0; i < numFields; i++) { 

                      var f = getField(getNthFieldName(i)); 

                       this.getField(f.name).display = oFlds[f]?display.hidden:display.visible;     

                  } 

               

              OCGs are good stuff for compliant viewers. And it looks like you've tried to compensate for non-Adobe viewers and mobile. However, in such cases your code may not run at all, so the OCG layers should be setup to be fail safe, i.e set up the visibility before the user opens it.

              • 4. Re: Show/hide layers and fields on doc startup
                JR_Boulay Adobe Community Professional

                You don't need any script to achieve your goal.

                Just add a layer (prompting to open the PDF with Acrobat Reader) in front of the document and set its "Defaut state" to "Off" (in the layer's properties).

                 

                ==> Advanced softwares (as Acrobat) will never displays this layer.

                ==> Web browsers and low-end softwares (Apple Preview, Sumatra Reader…) that don't manage layers will always displays this layer.

                 

                 

                • 5. Re: Show/hide layers and fields on doc startup
                  Thom Parker Adobe Community Professional

                  I was trying to get to this point in a round about way