• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How do you write a loop for a function that runs an Action Script on one individual item completely before re-running the loop on the next item in the selection?

Community Beginner ,
May 23, 2018 May 23, 2018

Copy link to clipboard

Copied

---------------------------------------------------

Adobe Illustrator CC 2018 Javascript

---------------------------------------------------

Hi everyone,

I'm trying to write a script that involves creating an action and running it on each item within a selection, but I haven't been able to get the action script to run on each item individually in order, rather than having it all happen at the same time.

I understand how to loop through all selected items for the native built-in Illustrator functions like selected.textRange.characterAttributes.size = fontSize; but I'm unclear on how to loop custom functions to run on each individual item of the selection completely before moving onto the next selected item.

---------------------------------------------------

MAIN BLOCK OF EXAMPLE CODE HERE:

---------------------------------------------------

function runActionScript(){

     // code for Action Script goes here.

}

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

     runActionScript( selected );

     $.sleep(1000);

     app.redraw();

}

Hopefully, that's enough information to see what I did wrong and how we can fix it. I'm sure I'm making a very simple rookie mistake with how I'm writing the loop to run on each individual item of the selection.

I've seen some mentions on other posts within the forums about using $.sleep(1000) and app.redraw(); to create a pause in the script, but it didn't seem to work for me.

---------------------------------------------------

MORE DETAILS BELOW:

---------------------------------------------------

What's happening is that the part of the action script involves:

  • Outlining the selected text
  • Labeling the selected text with an attribute note: "selectToMerge"
  • Duplicating the selected item
  • Moving the duplicated item
  • Selecting all objects with the "selectToMerge" note
  • Merging all "selectToMerge" items.

So it needs to run the script on each item in the selection completely before running it on the next item. Right now it seems to run the script on all of the items either together or separately but at the exact same time—either way, it causes everything to merge into one object, instead of having separate merged shapes. Hope that makes sense:

example-800px.jpg

The actual script I'm working on is a lot more complex with many other unrelated steps involved, but if the block of code above isn't enough, I have a more extended (but still simplified) example code below that focuses just on the part that creates the action and tries to run the action script for each selected item.

WARNING: Since the loop I wrote doesn't work properly, there are some errors when it runs. It basically re-runs multiple times based on the number of items you select. So if you decide to try and run this script as is for yourself, select only two or three live text frames to test, and just click "Continue" / "Stop" until it's done. Also, it's meant to be run on live text frames:

#target Illustrator

// If a document is open, start the script:

if( app.activeDocument ){

// FIRST, DEFINE VARIABLES & FUNCTIONS //////////////////////////////////////////////////

    var doc = app.activeDocument;

    var selected = doc.selection;

    // Create Temporary Action to Load and Unload

   

    // Based on example script written by Adobe Forums User: et3d

    // Date: August 11, 2017

    // URL: https://forums.adobe.com/message/9760856

    // Which was based on:

    // "Creating a dynamic action to use with app.doScript() method." guide written by Adobe Forums User: Silly-V

    // Date: February 10, 2017

    // URL: https://forums.adobe.com/message/9323811

    // Many, many thanks to both Silly-V & et3d for sharing the immensely helpful information.

    function createAction ( actionString, set ) {

       

        var fpath = Folder ( "~/Desktop/" )

        var f = File ( fpath + set + '.aia' );

       

        f.open( 'w' );

        f.write( actionString );

        f.close();

        app.loadAction( f );

        f.remove();

    }

    function runActionScript(){

        var set = 'Example Set'; 

        var action = 'outlineDupMoveMerge';

       

        var actionString = [

       

        "/version 3",

        "/name [ 11",

        "   4578616d706c6520536574",

        "]",

        "/isOpen 1",

        "/actionCount 1",

        "/action-1 {",

        "   /name [ 19",

        "       6f75746c696e654475704d6f76654d65726765",

        "   ]",

        "   /keyIndex 0",

        "   /colorIndex 0",

        "   /isOpen 1",

        "   /eventCount 7",

        "   /event-1 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_createOutline)",

        "       /localizedName [ 15",

        "           437265617465204f75746c696e6573",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 0",

        "   }",

        "   /event-2 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_attributePalette)",

        "       /localizedName [ 17",

        "           4174747269627574652053657474696e67",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 1",

        "       /parameter-1 {",

        "           /key 1852798053",

        "           /showInPalette 4294967295",

        "           /type (ustring)",

        "           /value [ 13",

        "               73656c656374546f4d65726765",

        "           ]",

        "       }",

        "   }",

        "   /event-3 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_move)",

        "       /localizedName [ 4",

        "           4d6f7665",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 1",

        "       /showDialog 0",

        "       /parameterCount 3",

        "       /parameter-1 {",

        "           /key 1752136302",

        "           /showInPalette 4294967295",

        "           /type (unit real)",

        "           /value 0.0",

        "           /unit 592476268",

        "       }",

        "       /parameter-2 {",

        "           /key 1987339116",

        "           /showInPalette 4294967295",

        "           /type (unit real)",

        "           /value -0.0",

        "           /unit 592476268",

        "       }",

        "       /parameter-3 {",

        "           /key 1668247673",

        "           /showInPalette 4294967295",

        "           /type (boolean)",

        "           /value 1",

        "       }",

        "   }",

        "   /event-4 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_sendBackward)",

        "       /localizedName [ 13",

        "           53656e64204261636b77617264",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 0",

        "   }",

        "   /event-5 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_move)",

        "       /localizedName [ 4",

        "           4d6f7665",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 1",

        "       /showDialog 0",

        "       /parameterCount 3",

        "       /parameter-1 {",

        "           /key 1752136302",

        "           /showInPalette 4294967295",

        "           /type (unit real)",

        "           /value -21.2132034342",

        "           /unit 592476268",

        "       }",

        "       /parameter-2 {",

        "           /key 1987339116",

        "           /showInPalette 4294967295",

        "           /type (unit real)",

        "           /value -21.213203437",

        "           /unit 592476268",

        "       }",

        "       /parameter-3 {",

        "           /key 1668247673",

        "           /showInPalette 4294967295",

        "           /type (boolean)",

        "           /value 0",

        "       }",

        "   }",

        "   /event-6 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_setSelection)",

        "       /localizedName [ 13",

        "           5365742053656c656374696f6e",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 3",

        "       /parameter-1 {",

        "           /key 1952807028",

        "           /showInPalette 4294967295",

        "           /type (ustring)",

        "           /value [ 13",

        "               73656c656374546f4d65726765",

        "           ]",

        "       }",

        "       /parameter-2 {",

        "           /key 2003792484",

        "           /showInPalette 4294967295",

        "           /type (boolean)",

        "           /value 0",

        "       }",

        "       /parameter-3 {",

        "           /key 1667330917",

        "           /showInPalette 4294967295",

        "           /type (boolean)",

        "           /value 1",

        "       }",

        "   }",

        "   /event-7 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (ai_plugin_pathfinder)",

        "       /localizedName [ 10",

        "           5061746866696e646572",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 1",

        "       /parameter-1 {",

        "           /key 1851878757",

        "           /showInPalette 4294967295",

        "           /type (enumerated)",

        "           /name [ 3",

        "               416464",

        "           ]",

        "           /value 0",

        "       }",

        "   }",

        "}"

        ].join( "\n" );

        createAction( actionString, set );

        app.doScript( action, set );

        app.unloadAction( set, "" );

    }

// THEN, START SCRIPT ////////////////////////////////////////////////////////////

    // If something is selected, run the script:

    if( selected.length > 0 ){

       

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

            // If all selected items are text frames, run the action script:

            if ( selected.typename === "TextFrame" ){

                runActionScript( selected );

                $.sleep(1000);

                app.redraw();  

            }

            // If one or more of the selected selected items is not a text frame, display message:

            else{

                alert( "One or more of the selected items is not a text frame. Please select a text frame and try again." );

            }

       

        }

    }

    // If nothing selected, display message:

    else{

        alert( "Nothing is selected. Please select a text frame and try again." );

    }

}

// If no document is open, display message:

else{

    alert( "No document found. C'mon man, get it together." );

}

TOPICS
Scripting

Views

2.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Beginner , May 24, 2018 May 24, 2018

Thank you so much, Ten A !

It almost worked, but I had to make a few tweaks to the code to get it to work for me. See below:

-------------------------------------------------------------------

WORKING SOLUTION CODE

-------------------------------------------------------------------

var slct = doc.selection;

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

    if ( slct.selected ){

        slct.name = "selectTag";

    }

}

app.executeMenuCommand( "deselectall" );

var tg = app.activeDocument.textFrames;

for ( var i =

...

Votes

Translate

Translate
Adobe
Community Expert ,
May 23, 2018 May 23, 2018

Copy link to clipboard

Copied

Your action process all selected textFrames one time. So, You need to deselect all items before in loop.

Here is a sample solution, Mark selected textFrames, deselect all items and run action with marked textFrames. However, It's not tested.

var slct = app.selection;

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

  if (slct.selected) slct.name = "selected";

app.executeMenuCommand("deselectall");

var tg = app.activeDocument.textFrames;

for (i=0,i<tg.length;i++){

  if (tg.name=="selected") {

  tg.selected = true;

  runActionScript();

  }

  }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 24, 2018 May 24, 2018

Copy link to clipboard

Copied

LATEST

Thank you so much, Ten A !

It almost worked, but I had to make a few tweaks to the code to get it to work for me. See below:

-------------------------------------------------------------------

WORKING SOLUTION CODE

-------------------------------------------------------------------

var slct = doc.selection;

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

    if ( slct.selected ){

        slct.name = "selectTag";

    }

}

app.executeMenuCommand( "deselectall" );

var tg = app.activeDocument.textFrames;

for ( var i = tg.length - 1; i >= 0; i-- ){

    if ( tg.name === "selectTag" ) {

        tg.selected = true;

        runActionScript();

        app.executeMenuCommand( "deselectall" );

        app.redraw();

    }

}

-------------------------------------------------------------------

Main Issues w/ Ten A's Original Sample Solution Code

-------------------------------------------------------------------

The main thing was, for some odd reason:

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

caused a weird issue where:

  • I select 3 text frames to run the script on
  • It applies does the runActionScript(); function on the last item first, then on the first item in the selection, and skips the middle item.
  • Then, without deleting or undoing anything, if I select two completely new and different text frames, it does the runActionScript(); on that middle item that was skipped last time—even though I didn't have it selected at all this time—along with one of the new text frames. The reason is because that previous middle item still had the "selectTag" name, but I still don't understand why it continually skips one of the newly selected items.
  • This was a consistent, repeatable issue on every selection that was larger than one item  and in any document I tried.

Also, it was still merging multiple lines together.

-------------------------------------------------------------------

The Fixes

-------------------------------------------------------------------

Since there seemed to be something weird with the counter, I first tried to change the variable on the second counter in case there was some conflict from the first, but that didn't fix anything.

I also tried changing it to i <= tg.length (less than or equal to the number of total text frames in the document), but that didn't work either.

Eventually, I figured out the solution was to change the counter to:

for ( var i = tg.length - 1; i >= 0; i-- )

And it worked beautifully! It properly worked on all selected items and did them in order.

Although, if you or someone else understand why exactly the original counter didn't work, but this one works, please let me know. I don't actually really understand why it fixed the issue. To me, they both are basically the same, but the second one counts backwards instead. Why does that fix the problem or am I actually not understanding it correctly?

**EDIT (May 25, 2018):**

From what I understand now, since part of this specific action script outlines the text—making it no longer an actual live text frame—the tg.length (count of all text frames in the document) is constantly changing and shifting as it's looping through. So starting the index counter from 0 is problematic.

Imagine if there's 6 total text frames in the document, and #3, #4, #5 are the frames with the "selectTag". The script would loop through #0, #1, #2, #3, stop there and run the action script, which turns the text frame into an outlined text (pathItem), so now the total text frames in the document drops from 6 total to 5 total. What was originally text frame index #3, is taken out of the count, so text frame index #4 becomes the new #3, #5 becomes the new #4, and #6 becomes the new #5.

And since the script counter was just on #3, the new #3 (what was originally text frame #4) is skipped, and it moves on to the new #4 (originally text frame #5). And the whole problem repeats itself again.

But starting the index counter from the end and going backwards will work because the shift in total count doesn't affect it.

Again, if there are 6 total text frames, and #3, #4, #5 are the frames with the "selectTag", the script would loop start with #6, then stop at #5 to run the action script, turning it into an outlined text, dropping the total text frames count to 5 total. What was originally text frame #6, will now become text frame #5, but that doesn't matter because the script will move on to #4, whose index number hasn't changed at all.

Hope that makes sense.

Anyway, just thought I'd share that in case it's helpful for anyone else in the future to recognize the same problem within their script, understand it, know how to fix it, and why it works.

**END EDIT**

Anyway, to fix the merging of multiple lines together, I just needed to add the extra app.executeMenuCommand("deselectall");

-------------------------------------------------------------------

Note on the addition of "app.redraw();"

-------------------------------------------------------------------

The example code I posted actually works with the new code without app.redraw();

However, when I tested the code within my actual complete script, I was still running into some sort of issue with the action script merging multiple lines together—which shouldn't happen anymore because the extra app.executeMenuCommand("deselectall"); fixed the problem in the isolated example code I posted.

It seemed like maybe the script was running faster than it was unselecting or some other reason, so I tried adding app.redraw(); at the end, and violà! Everything works perfectly.

-------------------------------------------------------------------

THANKS!

-------------------------------------------------------------------

Thanks again for the help, Ten A ! It was simple but I was trying to figure it out for days and couldn't find any relevant example code on the forums or elsewhere that looped through a selection and run a function on each item one by one. I was so close to finishing this long script that will save a ton of time for everyone involved on a current project and this was the last main thing I needed to solve, but if I couldn't get it to work properly on each item of a selection one at a time, then the entire script would've been completely useless and wasted time and effort.

Hope this is helpful to someone else out there in the future.

-------------------------------------------------------------------

FULL WORKING EXAMPLE CODE FOR REFERENCE

-------------------------------------------------------------------

#target Illustrator

// If a document is open, start the script:

if( app.activeDocument ){

// FIRST, DEFINE VARIABLES & FUNCTIONS //////////////////////////////////////////////////

    var doc = app.activeDocument;

    var slct = doc.selection;

    // Create Temporary Action to Load and Unload

   

    // Based on example script written by Adobe Forums User: et3d

    // Date: August 11, 2017

    // URL: https://forums.adobe.com/message/9760856

    // Which was based on:

    // "Creating a dynamic action to use with app.doScript() method." guide written by Adobe Forums User: Silly-V

    // Date: February 10, 2017

    // URL: https://forums.adobe.com/message/9323811

    // Many, many thanks to both Silly-V & et3d for sharing the immensely helpful information.

    function createAction ( actionString, set ) {

       

        var fpath = Folder ( "~/Desktop/" )

        var f = File ( fpath + set + '.aia' );

       

        f.open( 'w' );

        f.write( actionString );

        f.close();

        app.loadAction( f );

        f.remove();

    }

    function runActionScript(){

        var set = 'Example Set'; 

        var action = 'outlineDupMoveMerge';

       

        var actionString = [

       

        "/version 3",

        "/name [ 11",

        "   4578616d706c6520536574",

        "]",

        "/isOpen 1",

        "/actionCount 1",

        "/action-1 {",

        "   /name [ 19",

        "       6f75746c696e654475704d6f76654d65726765",

        "   ]",

        "   /keyIndex 0",

        "   /colorIndex 0",

        "   /isOpen 1",

        "   /eventCount 7",

        "   /event-1 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_createOutline)",

        "       /localizedName [ 15",

        "           437265617465204f75746c696e6573",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 0",

        "   }",

        "   /event-2 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_attributePalette)",

        "       /localizedName [ 17",

        "           4174747269627574652053657474696e67",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 1",

        "       /parameter-1 {",

        "           /key 1852798053",

        "           /showInPalette 4294967295",

        "           /type (ustring)",

        "           /value [ 13",

        "               73656c656374546f4d65726765",

        "           ]",

        "       }",

        "   }",

        "   /event-3 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_move)",

        "       /localizedName [ 4",

        "           4d6f7665",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 1",

        "       /showDialog 0",

        "       /parameterCount 3",

        "       /parameter-1 {",

        "           /key 1752136302",

        "           /showInPalette 4294967295",

        "           /type (unit real)",

        "           /value 0.0",

        "           /unit 592476268",

        "       }",

        "       /parameter-2 {",

        "           /key 1987339116",

        "           /showInPalette 4294967295",

        "           /type (unit real)",

        "           /value -0.0",

        "           /unit 592476268",

        "       }",

        "       /parameter-3 {",

        "           /key 1668247673",

        "           /showInPalette 4294967295",

        "           /type (boolean)",

        "           /value 1",

        "       }",

        "   }",

        "   /event-4 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_sendBackward)",

        "       /localizedName [ 13",

        "           53656e64204261636b77617264",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 0",

        "   }",

        "   /event-5 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_move)",

        "       /localizedName [ 4",

        "           4d6f7665",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 1",

        "       /showDialog 0",

        "       /parameterCount 3",

        "       /parameter-1 {",

        "           /key 1752136302",

        "           /showInPalette 4294967295",

        "           /type (unit real)",

        "           /value -21.2132034342",

        "           /unit 592476268",

        "       }",

        "       /parameter-2 {",

        "           /key 1987339116",

        "           /showInPalette 4294967295",

        "           /type (unit real)",

        "           /value -21.213203437",

        "           /unit 592476268",

        "       }",

        "       /parameter-3 {",

        "           /key 1668247673",

        "           /showInPalette 4294967295",

        "           /type (boolean)",

        "           /value 0",

        "       }",

        "   }",

        "   /event-6 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (adobe_setSelection)",

        "       /localizedName [ 13",

        "           5365742053656c656374696f6e",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 3",

        "       /parameter-1 {",

        "           /key 1952807028",

        "           /showInPalette 4294967295",

        "           /type (ustring)",

        "           /value [ 13",

        "               73656c656374546f4d65726765",

        "           ]",

        "       }",

        "       /parameter-2 {",

        "           /key 2003792484",

        "           /showInPalette 4294967295",

        "           /type (boolean)",

        "           /value 0",

        "       }",

        "       /parameter-3 {",

        "           /key 1667330917",

        "           /showInPalette 4294967295",

        "           /type (boolean)",

        "           /value 1",

        "       }",

        "   }",

        "   /event-7 {",

        "       /useRulersIn1stQuadrant 0",

        "       /internalName (ai_plugin_pathfinder)",

        "       /localizedName [ 10",

        "           5061746866696e646572",

        "       ]",

        "       /isOpen 0",

        "       /isOn 1",

        "       /hasDialog 0",

        "       /parameterCount 1",

        "       /parameter-1 {",

        "           /key 1851878757",

        "           /showInPalette 4294967295",

        "           /type (enumerated)",

        "           /name [ 3",

        "               416464",

        "           ]",

        "           /value 0",

        "       }",

        "   }",

        "}"

        ].join( "\n" );

        createAction( actionString, set );

        app.doScript( action, set );

        app.unloadAction( set, "" );

    }

// THEN, START SCRIPT ////////////////////////////////////////////////////////////

        // Based on answer from Adobe Forums User: Ten A

        // Date: May 23, 2018

        // URL: https://forums.adobe.com/thread/2494445

        var slct = doc.selection;

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

            if ( slct.selected ){

                slct.name = "selectTag";

            }

        }

        app.executeMenuCommand( "deselectall" );

        var tg = app.activeDocument.textFrames;

        for ( var i = tg.length - 1; i >= 0; i-- ){

            if ( tg.name === "selectTag" ) {

                tg.selected = true;

                runActionScript();

                app.executeMenuCommand( "deselectall" );

                app.redraw();

            }

        }

}

// If no document is open, display message:

else{

    alert( "No document found. C'mon man, get it together." );

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines