5 Replies Latest reply on Apr 9, 2012 8:22 AM by cfranklin8

    adding a placed item to a button state

    cfranklin8

      Hello everyone--

       

      First off, I'm using InDesign CS5 on a MacBook Pro.

       

      I'm having trouble with targeting a placed item that I would like to add to a button.  It was my understanding that, when you place a file, it could be referenced as master.pageItems[0]. This is the snippet I tried.

       

       

      var doc = app.activeDocument;
      var master = doc.masterSpreads.itemByName("A-Body_Page");
      var lay = doc.layers.item("navigation");
      var imgFile = File( "~/desktop/eGuide/NavBtnNormal.png");
      master.place(imgFile,["131.25px", "637px"], lay);
      var img = master.pageItems[0];
      
      var btnHide = master.buttons.add();
      btnHide.geometricBounds = ["637px","131.25px", "670px","164.25px"];
      btnHide.states[0].addItemsToState(img);
      

       

      On some documents, this will work. On others, it seems to randomly add a different page item to the Button State. Since I added a button to the page, I thought the issue was that master.pageItems[0], changed. Consequently, I tried to approach it differently, before adding the button I tried targeting the id of img or adding a name to the img variable. I tried to access the graphic that way. I also tried to store the "master.place" statement within the img variable itself. As I said, sometimes it works; sometimes it doesn't.

       

      I guess I really just want to know—when you place an item, how do you target that item later in the script? I'm pretty new to JavaScript but I really enjoy learning it. As such, the more descriptive you could be, the better. 

       

      Thank you in advance for all your help.  

        • 1. Re: adding a placed item to a button state
          [Jongware] Most Valuable Participant

          The problem is that "pageItems[0]" does point to your just-placed item, but only if it's the single one item on that page! Otherwise, it does what it usually (actually, always) does, that is, it points to the very first item on your page. Note that this does not contradict my first line :-)

           

          If you place an item with a script and immediately want to do something with it, you need to save the return value of the "place" command. That is an array of "pageItem", and usually you only place one item, so it would be

           

          placedContentArray = master.place(imgFile,["131.25px", "637px"], lay);

          var img = placedContentArray[0];

           

          or, simply (safe because you always place one image at a time)

           

          var img = master.place(imgFile,["131.25px", "637px"], lay)[0];

           

          (Note the [0] at the very end.)

           

          >It was my understanding that, when you place a file, it could be referenced as master.pageItems[0].

           

          I guess you picked up your initial example from a sample script that didn't expect any other items to be on that page.

          • 2. Re: adding a placed item to a button state
            cfranklin8 Level 1

            Thank you for the response! 

             

            I incorporated that into my script, and I received an error about this object cannot be added to a button type. To make sure that I was using these statements correctly, I just added img.move([100, 200]) to see what, if anything, might move.  Sure enough, the image itself moved to the new coordinates but the frame in which the was placed stayed at the place point. So I learned you answer my question correctly, but that I didn't ask the right question. 

             

            Since the image is put into a graphic frame upon placement, how do you recommend targeting that frame? Would you create a rectangle, store it in a variable and then place the image inside the rectangle? 

             

            Also: as for master.pageItems[0], you are right...I did see that in other scripts. It made sense to me since, when you add any item within InDesign, it gets added to the top of the layer stack (which I assumed corresponded within the DOM as "most recently added object = lay.pageItems[0]". When I first was writing my script, I tried to target that page item within the specific layer. It was hit and miss, so when I looked at other sample scripts and saw master.pageItems[0], I thought that this was something I needed to be targeting on the page level, not at the layer level. 

            • 3. Re: adding a placed item to a button state
              cfranklin8 Level 1

              Figured it out. I just created a frame and placed the image within the frame.

               

              var doc = app.activeDocument;
              var master = doc.masterSpreads.itemByName("A-Body_Page");
              var lay = doc.layers.item("navigation");
              var rec = doc.rectangles.add();
              rec.geometricBounds = ["637px","131.25px", "670px","164.25px"];
              rec.itemLayer = lay;
              rec.strokeWeight = 0;
              var imgFile = File( "~/desktop/eGuide/NavBtnNormal.png");
              rec.place(imgFile);
              
              var btnHide = master.buttons.add();
              btnHide.geometricBounds = rec.geometricBounds;
              btnHide.states[0].addItemsToState(rec);
              
              

               

               

               

              Thanks Jongware for pointing me in the right direction.

              • 4. Re: adding a placed item to a button state
                [Jongware] Most Valuable Participant

                ... I missed something in my instructions! Congrats on finding that out, and on finding a solution to it as well. This touches upon one of the many subtleties of scripting InDesign, so you deserve a pat on the back for that.

                Allow me to clarify what goes on under the hood; you can decide if your code does what it needs to, or you may change it according to this little expansion.

                 

                Yes, the command "img = master.place(..)[0]" *does* return the image, but you are correct -- this returns the *image* component of the required "image is always inside a frame" that gets placed.

                Your solution works, but alternatively you could use this:

                 

                img = master.place(..)[0];

                imgFrame = img.parent;

                // now imgFrame will point to its frame instead!

                 

                The reason this (finally) works is because you cannot place an image without it *automatically* having a frame as its parent as well. Your solution works because you are placing inside an existing frame, which is also a good solution -- except you (probably) don't know what size the placed image is. Placing the image itself and then using its own default frame will ensure the size matches.

                • 5. Re: adding a placed item to a button state
                  cfranklin8 Level 1

                  I actually prefer your approach .  Not only fewer steps, but by creating a frame first using the rectangle method, I needed to set additional properties like strokeWeight  or check if object styles were applied to remove certain default settings. By using your approach, InDesign will place within a basic graphic frame rather than converting a rectangle to a graphic frame.

                   

                  It's interesting because essentially...

                  if I use img = master.place(...)[0]; it is like I want to select an image with the direct selection tool or the content grabber

                  if I use imgFrame =img.parent; it is like I want to select the image with the selection tool. 

                   

                   

                  Thank you very much...I really appreciate the under the hood explanations. It helps me better understand what the heck I'm putting together and what may be a more robust approach to any script.