Copy link to clipboard
Copied
In the examples that I saw, the object selection was done like this:
var textFrame = doc.textFrames.add();
...
textFrame.selected = true;
// or like this
// textFrame.name = "obj1";
// doc.activeLayer.pageItems.getByName("obj1").selected = true;
However, this doesn't work - the object on the artboard is not selected. What kind of selection are we talking about in these examples? Or how is it done?
Copy link to clipboard
Copied
you can find such tips, but I found that they don’t always work
app.redraw();
// or
// textFrame.translate(0, 0);
strange as it may seem, but the following works, according to the sample from @m1b , if used before setting the selection
doc.selection = [];
Copy link to clipboard
Copied
Hi @fastwind you don't need to clear the selection first if you don't want to. Setting pageitem.selected = true will add it to the selection if it wasn't selected already. If you believe you have found a case where this fails, please post a demo document and script to see if we can reproduce it.
Copy link to clipboard
Copied
Hi @m1b try this
#target illustrator
if (app.documents.length > 0) {
var doc = app.activeDocument;
var textFrame = doc.textFrames.add();
textFrame.contents = "12345";
textFrame.selected = true;
app.redraw();
alert(doc.selection.length);
} else {
alert("no open docs");
}
Copy link to clipboard
Copied
Thanks @fastwind that is exactly what I wanted. I think you have found a bug. Here is my experimental script:
/**
* Experiment showing a bug found by @fastwind where
* a textFrame that has just been created, cannot
* be selected immedately. Many things can workaround
* this bug including selecting it twice!
* @author m1b
*/
(function () {
if (0 === app.documents.length)
return alert('Please open a document and try again.');
var doc = app.activeDocument,
results = ['Results:'];
// experiment 1
var tf1 = doc.textFrames.add();
tf1.contents = '1. created, selected:';
tf1.selected = true;
results.push(tf1.contents + ' ' + (tf1.selected ? 'PASS' : 'FAIL'));
// experiment 2
var tf2 = doc.textFrames.add();
tf2.contents = '2. created, selected twice:';
tf2.selected = true;
tf2.selected = true;
results.push(tf2.contents + ' ' + (tf2.selected ? 'PASS' : 'FAIL'));
// experiment 3
var tf3 = doc.textFrames.add();
tf3.contents = '3. created, redraw, selected:';
app.redraw();
tf3.selected = true;
results.push(tf3.contents + ' ' + (tf3.selected ? 'PASS' : 'FAIL'));
// experiment 4
var tf4 = doc.textFrames.add();
tf4.contents = '4. created, first select something else:';
doc.pathItems[0].selected = true;
tf4.selected = true;
results.push(tf4.contents + ' ' + (tf4.selected ? 'PASS' : 'FAIL'));
// experiment 5
var tf5 = doc.textFrames.add();
tf5.contents = '5. set selection as array:';
doc.selection = [tf5];
// tf5.selected = true;
results.push(tf5.contents + ' ' + (tf5.selected ? 'PASS' : 'FAIL'));
// experiment 6
var tf6 = doc.textFrames.add();
tf6.contents = '6. redo experiment 1:';
tf6.selected = true;
results.push(tf6.contents + ' ' + (tf6.selected ? 'PASS' : 'FAIL'));
// experiment 7
var tf7 = doc.textFrames.add();
tf7.contents = '7. transform, select:';
tf7.left++;
tf7.selected = true;
results.push(tf7.contents + ' ' + (tf7.selected ? 'PASS' : 'FAIL'));
alert(results.join('\n'));
})();
My results are:
1. created, selected: FAIL
2. created, selected twice: PASS
3. created, redraw, selected: PASS
4. created, first select something else: PASS
5. set selection as array: FAIL
6. redo experiment 1: FAIL
7. transform, select: PASS
As you can see this bug applies to immediately selecting a newly-created textFrame (I would guess it applies to pathItems, etc too?). Anything that affects the selection or moves the textFrame or causes a redraw seems to return it to normal behaviour. As I show, just selecting it twice works!!
So now your original question finally makes sense! The answer is that yes, setting a textFrame's `selected` property is the correct and normal way to select it but—until this bug is fixed—you must do so twice if you have just created it.
You only had a hard time because of this bug, that most people don't see in their particular scripts, by chance.
- Mark
Copy link to clipboard
Copied
I have created a bug report. Please vote to have it fixed.
- Mark
P.S. this bug doesn't seem to affect a newly-created PathItem, just a TextFrame.
Copy link to clipboard
Copied
Thanks @m1b, voted it.
Copy link to clipboard
Copied
Hi @fastwind, the examples you gave are fine. That is a normal way of selecting an item in Illustrator via scripting—nothing wrong with it, or missing. I think what you are concerned about is that you can't *see* the selection until after the script finishes when the UI updates. For example, see this code:
(function () {
var doc = app.activeDocument,
item = doc.pageItems[0];
// clear selection
doc.selection = [];
item.selected = true;
// app.redraw();
if (doc.selection[0] === item)
alert('Item is selected');
})();
If you run this (assuming your document has at least one page item and nothing is selected) it will select `item` and—if it confirms that the selection contains `item`—give an alert. So, when the alert appears, we can be sure that `item` is surely selected. However at this point we can't *see* it selected—it still appears that nothing is selected. This is simply because the UI doesn't get updated in the middle of a script (except for certain operations). To make the screen update, that is where a call to app.redraw()—commented out for now—is useful, but it's important to understand that it doesn't do anything except update the screen—the `item` is already selected no matter if you do app.redraw() or not, and the redraw will happen as soon as the script is finished anyway.
By the way, for some reason selecting objects in Illustrator is *sloooow*. So if you are looping through page items and setting selected = true on each it will be very slow. A quicker way is to put the items into an array and then do:
doc.selection = myItems;
- Mark
P.S. I forgot to add, every time you use app.redraw() it starts a new Undo record, so if you do a loop of 20 operations without app.redraw() they will Undo in one go, but if you app.redraw() inside the loop, you will have to Undo 20 times to go back to the starting state. Sometimes this is desirable, but not often.