Skip to main content
wolfeEdition
Known Participant
June 12, 2017
Answered

Adding to a textFrame from an array

  • June 12, 2017
  • 1 reply
  • 1454 views

I am populating 2 lists to form a numbered list. For example the following text items are on the artboard.

Apples

Bananas

Oranges

Apples

Bananas

Oranges

These will all be pushed to a single list called rePop and then sorted like this:

Apples

Apples

Bananas

Bananas

Oranges

Oranges

Next the code will split the text frames into 2 list like so

listOne :                     listTwo :

Apples                         Apples

Bananas                    Bananas

Oranges                    Oranges

Now I want to compare and number the 2 lists so the final text frames would look like this

(1) Apples

(2) Bananas

(3) Oranges

(1) Apples

(2) Bananas

(3) Oranges

Here is my current code....any help would be appreciated!

#target illustrator

var rePop = [];

var listOne = [];

var listTwo = [];

var oddCount = 0;

var evenCount = 1;

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

    rePop.push(allText.contents);

}

rePop.sort();

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

    listOne.push(rePop[(oddCount)]);

    listTwo.push(rePop[(evenCount)]);

    oddCount += 2;

    evenCount += 2;

}

var z = 0;

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

    var checkContents = listOne;

  alert(listOne + "  " + listTwo);

    if (listOne == listTwo) {

        var changeText = "(" + (i + 1) + ") " + checkContents;

        listOne = listOne.replace(checkContents, changeText);

        z++;

    } else {

        alert("Not a match");

    }

}

This topic has been closed for replies.
Correct answer pixxxelschubser

You are correct. the code i posted would have to be duplicated for the other array. There are two parallel arrays that contain the text frames. my code only handles one of them and, as previously stated, assumes the sorting has already been completed.

So you would run my loop twice (or better yet, change one text frame from each array within each execution of the loop, like so):

function test()

{

    var docRef = app.activeDocument;

    var listOne = []; //sorted array of text frames;

    var listTwo = []; //sorted array of text frames;

    if(listOne.length>0)

    {

        var length = listOne.length;

        for(var x=0;x<length;x++)

        {

            listOne.contents = "(" + (x+1) + ") " + thisFrame.contents;

            listTwo.contents = "(" + (x+1) + ") " + thisFrame.contents;

        }

    }

    else

    {

        alert('No text frames available!');

    }

}

test();

My previous responses addressed the fact that the sorting would need to be revisited because you cannot sort an array of text frame objects with a simple array.sort() like wolfEdition has in his/her original snippet.

The question i was attempting to answer is in the title of the post, and was clarified here in the initial response to my first answer:

My issue is I don't know how to get the formatting I want of (#) inserted back into the textFrame when it finds an array item.

So my answer became more long winded than it needed to, but all i was trying to convey is that in order to update the contents of the text frame, OP simply needs to re-assign the contents of the given text frame like so:

myTextFrame.contents = "(" + (index + 1) + ") " + myTextFrame.contents

The way i understand it, this is the question at hand. OP used the string.replace() method but never assigned the return value to the text frame at hand, it was simply updated in the array which is not associated with the text frame.


I know, this is not really the best way, but quick and dirty:

// required: only matching pairs of textFrames with same contents

// eg 111, 111, apple, apple, Banana, Banana // no other (single) textFrames allowed

// result (1) 111, (1) 111, (2) apple, (2) apple, (3) Banana, (3) Banana

var aDoc = app.activeDocument;

var allText = aDoc.textFrames;

var rePop = [];

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

    allText.name = allText.contents;

    rePop.push(allText.contents);

}

rePop.sort();

var listOne = [];

//var listTwo = []; // only need if you want to create a better error handling as in this snippet

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

    listOne.push ( rePop );

    //listTwo.push ( rePop[(i+1)] );

}

if (rePop.length % 2 == 0) {

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

        try {

            changeTextframes ( listOne );

            changeTextframes ( listOne );

        } catch (e) { alert ("missing pairs"); }

    }

} else { alert ("different lists.length") };

function changeTextframes ( x ) {

    var tf = aDoc.textFrames.getByName ( x );

    tf.contents = "(" + (i+1) + ") " + x;

    tf.name = tf.contents;

}

wolfeEdition​ and williamadowling

Have fun

1 reply

Disposition_Dev
Legend
June 12, 2017

Not sure i fully understand what the goal is, or what problem you're having. But I can say that you never actually take anything from the array and put it into a text frame. You only split contents into arrays and sort and then replace contents of the arrays.

If you can give more information about what you're trying to do, we can give better help. For now i made a brief assumption.

Assuming you want a single text frame to hold all of the resulting items of each array, preceded by a number, add this to the end of your code:

//choose one of the following:

//get an existing text frame you want to add this text to

var destTextFrame = app.activeDocument.textFrames["My Text Frame"];

//create a text frame

var destTextFrame = app.activeDocument.textFrames.add();

destTextFrame.name = "My Text Frame";

//now update the contents

//if the arrays are always the same as you showed in your example,

//you could merge these into a single loop. but i'll assume that's not the case

//and we'll use two separate loops

for(var x=0;x<listOne.length;x++)

{

     destTextFrame.contents += listOne;

}

for(var x=0;x<listTwo.length;x++)

{

     destTextFrame.contents += listTwo;

}

wolfeEdition
Known Participant
June 12, 2017

So the goal is to have a numbered list to reference items that are spaced out on a large artboard.

They are all individual textFrame items. My issue is I don't know how to get the formatting I want of (#) inserted back into the textFrame when it finds an array item. The list will ALWAYS match. The reason for splitting and sorting them is to find out how many items there are so that a number can be assigned. Here are 2 screen shots of a file before the script would be run and my goal for after the script

Hope this helps clarify some. Thank you for your reply!

Disposition_Dev
Legend
June 12, 2017

So at the beginning of your script, you're saving the contents of the text frames to variables using the 'contents' property. This property is gettable and settable.

You'll have to figure out how to get the correct text frame, but once you have it, you can just do something like this:

var currentSequenceNumber = 1;

var myTextFrame = app.activeDocument.textFrames[0]; //this just gets the first text frame. you'll have this variable set equal to the desired text frame

myTextFrame.contents = "(" + currentSequenceNumber + ") " + myTextFrame.contents;

The key is to use the assignment operator to set a new value to the contents property of the desired text frame.

For kicks.. here's a regex implementation as well, though whether it's any 'better', i don't know.

var pattern = /^/;

var replacement = " (" + currentSequenceNumber + ")

myTextFrame.contents = myTextFrame.contents.replace(pattern,replacement);