How to use app.selection[0] for scripts in Adobe InDesign

10,912

app.selection returns an array of Objects, so each item in the array can be of a different type, and the properties and methods available to it will differ. When using the Extendscript Javascript Console you can see what a particular item in the array is on the fly by just typing

app.selection[0]

(or whatever number). The result will be something like [object TextFrame].

While looping through the selection array, you could use app.selection[0].constructor.name to determine the type of each. Or, if you're only interested in certain types,

if (app.selection[i] instanceof TextFrame){}

At that point you'll know more about which properties you can access, depending on the type.

To answer the second part of the question, there isn't an allTextFrames property, but there is an allPageItems property. This returns an array of pageItems (textFrames, groups, etc.), and you can work with it similarly to app.selection. So, if I have three text frames grouped on the first page of my document (and nothing else), I can see that the following are all true:

app.activeDocument.pages[0].textFrames.length == 0;
app.activeDocument.pages[0].allPageItems.length == 4;
app.activeDocument.pages[0].allPageItems[0] instanceof Group;
app.activeDocument.pages[0].allPageItems[1].constructor.name == "TextFrame";

So you could probably cycle through that array if it's more useful to you than the textFrames collection. Just keep in mind that you don't have access to the special collection properties of TextFrames (like everyItem()).

Share:
10,912
Admin
Author by

Admin

Updated on June 25, 2022

Comments

  • Admin
    Admin about 2 years

    I would like to run code by testing only the current selection (not the whole document) and I'm having difficulty understanding exactly how the array "app.selection" and its methods work. To start, I use a "for" loop to cycle through each item selected by using:

    for(loop = 0; loop < app.selection.length; loop++){
        var sel = loop;
    }
    

    This works okay, but when I want to get into determining what each item IS, it gets a little weird. For example,

    for(txt = 0; txt < app.selection[sel].textFrames.length; txt++){
        // do something to each text frame in the selection here.
    }
    

    does not work as expected, but

    for(img = 0; img < app.selection[sel].allGraphics.length; img++){
        // do something to each graphic in the selection here
    }
    

    seems to work fine, regardless if the selection includes more than just graphics alone, or whether it is inside or outside a group.

    At times, it seems like app.selection[0] is the only way to access the item by itself. In other words, if a text frame is selected, app.selection[0] might be the same as app.document.textFrames[0], in which case it would be redundant (and incorrect) to say

    app.document.textFrames[0].textFrames[0]
    

    And yet the same concept on different page items works like a charm. It is quite puzzling to follow. Furthermore, it seems impossible to determine what kind of object the item is. I want to say something along the lines of:

    if (app.selection[0] == [object TextFrame])
    

    but that does not seem to work for me. Is there a way to clearly test if the current item is a group, a graphic or a text frame and do different things depending on the result?

  • Admin
    Admin about 9 years
    Excellent response! I have another question regarding all text frames. To update the situation in my question where app.selection.allGraphics[0] acted okay and app.selection.textFrames[0] misbehaved, it seems that it was not a matter of misunderstanding the selection array, (although your answer cleared up the questions I had about it.) allGraphics finds every last graphic available, while textFrames fetches the outermost text frames in a group. Is there an equivalent to allTextFrames?
  • Christina
    Christina about 9 years
    There isn't an allTextFrames property, at least not in any of the versions of ID that I've worked with (5.5 through CC). There is an allPageItems property. I'll add a note about it.
  • Admin
    Admin about 9 years
    Great! Thanks! I've now got a working version thanks to allPageItems.