Copy link to clipboard
Copied
Hi Guys,
First time Poster here. I have been scratching my head over this for a few days now.
Im trying to create a script to add hyperlinks (from a text box) to a grouped object (Square with text on).
I can read thurl from the Text Box but cannot work out how to add this copied URL to the Group Box, I receive 'Object does not support this method...'
Any Help would be much appreciated.
Below is a snippet of what I have so far:
var document = app.activeDocument;
var selection = document.selection;
var myDocument = app.activeDocument;
var myFrames = document.allPageItems;
var myUrlLabel = 0;
var thisUrl;
//Cycle through ALL items and Pick out those with the URL and the BUTTON
for (var i=1; i< myFrames.length; i++) {
if (myFrames[i].label == 'url'){
myUrlLabel ++;
thisUrl = myFrames[i].contents;
thisItem = myFrames[i];
// alert (myFrames[i].constructor.name);
//alert( thisItem +" - "+ thisUrl);
//gotoURLBehaviors.add({ url: t.contents })
} // END IF LABEL URL
// FIND BUTTON to Add the url from the variable thisUrl ( from text box)
if (myFrames[i].label == 'BTN'){
var group = myFrames[i];
var mySelectedFrame = myFrames[i];
alert( myFrames +" BTN - "+thisUrl);
addHyperlink(thisUrl, mySelectedFrame)
}
}
function addHyperlink(thisUrl, mySelectedFrame){
mySelectedFrame.hyperlinks.add( thisUrl , thisUrl);
}
I'm a bit rusty with hyperlinks, but they can be tricky. Hyperlinks are added through the document object, and you need specific objects for them to point to. So, you should pass myDocument to your addHyperlink function then try something like this:
var hypeSource = myDocument.hyperlinkPageItemSources.add(mySelectedFrame);
var hypeUrl = myDocument.hyperlinkURLDesitnations.add(thisUrl);
myDocument.hyperlinks.add(hypeSource, hypeUrl);
(Side note: I'd avoid naming variables "this"anything, as "this"
...Copy link to clipboard
Copied
I'm a bit rusty with hyperlinks, but they can be tricky. Hyperlinks are added through the document object, and you need specific objects for them to point to. So, you should pass myDocument to your addHyperlink function then try something like this:
var hypeSource = myDocument.hyperlinkPageItemSources.add(mySelectedFrame);
var hypeUrl = myDocument.hyperlinkURLDesitnations.add(thisUrl);
myDocument.hyperlinks.add(hypeSource, hypeUrl);
(Side note: I'd avoid naming variables "this"anything, as "this" is a reserved JS word for objects.)
Hope this helps.
For DOM reference, see:
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#Hyperlinks.html#d1e113322__d1e113371
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#HyperlinkURLDestinations.html#d1e119260
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#HyperlinkPageItemSource.html#d1e114735
Copy link to clipboard
Copied
Hey thanks for the quick reply.
Yeah my code is always a little sloppy...
I will give it a try tomorrow and let you know how I go 🙂
Copy link to clipboard
Copied
Hi Adriano,
several things you should know if you want to add a hyperlink to a page item with an URL as destination:
A document contains a:
hyperlinks collection
hyperlinkURLDestinations array
hyperlinkPageItemSources array
If you want to add a new hyperlink you add it to the document.
If you want to add a new URL destination you add it to the hyperlinkURLDestinations array of the document.
If you want to add a hyperlinkPageItemSource, your page item in that group, add it to the hyperlinkPageItemSources array of the document.
If the source is already listed in the array hyperlinkPageItemSources you cannot add that hyperlink.
You could loop that array and compare value of sourcePageItem with your selected object.
No problem to add a new URL destination with a URL that is already stored in a different URL destination.
Also: If you give the hyperlink a name, first check the hyperlinks collection if the name is already there.
Sample code:
// "Adds" a hyperlink to a selected page item with some properties:
var doc = app.documents[0];
var selectedItem= app.selection[0];
var urlDestString = "https://web.de";
app.documents[0].hyperlinks.add
(
{
source : doc.hyperlinkPageItemSources.add
(
{
sourcePageItem : selectedItem
}
) ,
destination : doc.hyperlinkURLDestinations.add
(
urlDestString
) ,
borderStyle : HyperlinkAppearanceStyle.SOLID ,
hidden : false ,
highlight : HyperlinkAppearanceHighlight.INVERT
}
);
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
Thanks for pointing me in the right Direction.
this has gotten me closer to what I was to achieve however I constantly get the error:
79111
"Error String: The object you have chosen is already in use by another hyperlink"
Even though no Hyperlinks have been added?
Any ideas?
Copy link to clipboard
Copied
Maybe throw you hyperlinks.add function in a try/catch statement and log the ones that get skipped in the catch part?
Copy link to clipboard
Copied
Hi Brian,
I have placed the function in a try as suggested
The function then cycles through the 3 Buttons and throws the same
"The object you have chosen is already in use by another hyperlink" error.
If I make no selection then I get "Invalid value for parameter 'source' of method 'add'. Expected PageItem, but received nothing." -- which is probably expected.
This leads me to believe I might be calling the PageItem Incorrectly in the add function?
Copy link to clipboard
Copied
Looking back at the original code before you are calling your homespun addHyperlink function, I think you need to do a better job of reading the group. The following would read through all grouped objects, pluck out the URL, then turn the whole group into a hyperlink with that URL:
var groups = app.activeDocument.groups;
for (var i = 0; i < groups.length; i++) {
for (var j = 0; j < groups[i].pageItems.length; j++) {
if (groups[i].pageItems[j].label == "URL") {
var thisUrl = groups[i].pageItems[j].contents;
break;
}
}
addHyperlink (thisUrl, groups[i]);
}
Copy link to clipboard
Copied
Thanks Brian,
yes thats what I thought and tried your solution of cycling through groups.
This oddly enough doesnt find any Group?
If I search by the label it finds the group and recognises it as a Group.
Will try a couple more things
Copy link to clipboard
Copied
Hi Brian,
sorry my bad I was able to get the count on the Groups.
I think the issue is still more with the assigning the hyperlink than actually spotting the pageitems
here is a break down of what I did with your suggestion with forced URLs
There is some redundant code in there but its part of my thought process lol
var groups = app.activeDocument.groups;
for (var i = 0; i < groups.length; i++) {
$.writeln("---- GROUPS ---------------------" + groups[i]);
for (var j = 0; j < groups[i].pageItems.length; j++) {
if (groups[i].label == "btn") {
$.writeln("---- FOUND BUTTON GROUP ---------------------");
var thisUrl = "http://ch2.net.au";
}
}
addHyperlink (thisUrl, groups[i], i);
}
function addHyperlink(thisUrl, mySelectedFrame, i){
$.writeln("---- INSIDE FUNCTION ---------------------");
$.writeln("Hyperlinks Length: " + document.hyperlinks.length );
$.writeln("Url: " + thisUrl );
// $.writeln("Selected : " + mySelectedFrame[i].name );
$.writeln("i : " + i );
$.writeln("Selected length : " + app.selection.length);
var selectedItem= document.selection[0];
$.writeln("SELECTED DONE" + groups[i]);
thisUrl = "http://ch2.net.au";
urlDestString = "http://ch2.net.au";
var selectedItem= app.selection[0];
var selectedItem= mySelectedFrame;
var hypeSource = document.hyperlinkPageItemSources.add(selectedItem);
var hypeUrl = document.hyperlinkURLDesitnations.add(urlDestString);
document.hyperlinks.add(hypeSource, hypeUrl);
/*
doc.hyperlinks.add(document.hyperlinkPageItemSources.add(selectedItem), urlDestString, {name: urlDestString.name});
myFrames[i].label = "btnURL Added" + i;
selectedItem[i].label = "btnURL Added" + i;
selectedItem.label = "SELECTED DONE" + i;
/*
doc.hyperlinks.add
( { source : doc.hyperlinkPageItemSources.add ( { sourcePageItem : selectedItem } ) ,
destination : doc.hyperlinkURLDestinations.add
(
urlDestString
) ,
borderStyle : HyperlinkAppearanceStyle.SOLID ,
hidden : false ,
highlight : HyperlinkAppearanceHighlight.INVERT
}
);
*/
//document.hyperlinks.add ( { source : document.hyperlinkPageItemSources.add ( { sourcePageItem : selectedItem } ) , destination : document.hyperlinkURLDestinations.add ( urlDestString ) , borderStyle : HyperlinkAppearanceStyle.SOLID , hidden : false , highlight : HyperlinkAppearanceHighlight.INVERT } );
}
Copy link to clipboard
Copied
I don't understand why you are using app.selection. I didn't realize the URL was going to be the same for all buttons. Also, you should be passing the document reference instead of i as your third arg in addHyperlinks, since you're not using i at all. AddHyperlinks needs to know the document it's adding to. Here's full code I would try. And does the whole group have a label, or just one pageItem in the group? If the whole group has the label, you don't need the inner for loop.
var groups = app.activeDocument.groups;
for (var i = 0; i < groups.length; i++) {
if (groups[i].label == "btn") {
var thisUrl = "http://ch2.net.au";
addHyperlink (thisUrl, groups[i], app.activeDocument);
}
}
function addHyperlink(thisUrl, mySelectedFrame, document){
try {
var hypeSource = document.hyperlinkPageItemSources.add(mySelectedFrame);
} catch(e) {
return;
}
var hypeUrl = document.hyperlinkURLDesitnations.add(urlDestString);
document.hyperlinks.add(hypeSource, hypeUrl);
}
Copy link to clipboard
Copied
Hi Brian,
thanks for that
Im not actually using app.selection. As I mentioned there is code in there that is left over from experimentation.
I am using [i] in my full script (this loops through the different urls). What I posted was a fragment of the whole, i did this to narrow down where I am going wrong.
The same applies for the URL. These will not be the same but for simplicity I have hard coded the URLs.
Yes the Full Group (which consists of a Rectangle and Text FRame) has the label of 'btn' so correct that the inner loop is not necesary.
Below is the Error I get in the console which is what is driving me insane from day 1 - No hyperlinks in sight.
Could it simply be a bug?
catchError: The object you have chosen is already in use by another hyperlink.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
I have been deleting from the hyperlink panels, believe me there are no hyperlinks ANYWHERE lol>
I have started with blank documents and still the scripts errors the same.
Here is the full code for the section with the reading of the URLs and your latest suggestion which is the closest I have gotten to getting this to work.
Just a recap: On the Indesign page I have one or more text boxes with urls in them as plain text (not links) then I have the Grouped objects which will work as buttons. Remember the idea is to 'read' the url strings from the text boxes and add these url strings to the buttons as hyperlinks.
Thanks heaps
var document = app.activeDocument;
var document = app.activeDocument;
var myFrames = document.allPageItems;
var groups = app.activeDocument.groups;
//FIND URL IN TEXT FRAME AND COPY READY TO PASS ON TO GROUPED OBJECT
for (var i=0; i< myFrames.length; i++) {
$.writeln("Url : " );
if ( myFrames[i].label == "url" && myFrames[i].constructor.name == "TextFrame" ) {
$.writeln(" URL FOUND - TRY COPYING TO bnt" );
urlDestString = myFrames[i].contents;
myItem = myFrames[i];
myFrames[i].label = "url Copied";
checkBTN (urlDestString, i, myItem, myFrames); // FIND THE CLOSEST GROUP TO ADD HYPERLINK URL
}
}
function checkBTN (urlDestString, i, myItem, myFrames){
for (var i = 0; i < groups.length; i++) {
if (groups[i].label == "btn") {
var thisUrl = "http://ch2.net.au";
$.writeln("FOUND btn Group - TRY ADDING HYPERLINK TO BTN");
addHyperlink (thisUrl, groups[i], app.activeDocument);
}
}
}
function addHyperlink(thisUrl, mySelectedFrame, document){
try {
var hypeSource = document.hyperlinkPageItemSources.add(mySelectedFrame);
} catch(e) {
$.writeln( e);
return;
}
var hypeUrl = document.hyperlinkURLDesitnations.add(urlDestString);
document.hyperlinks.add(hypeSource, hypeUrl);
/*
myHyperlinkURL = document.HyperlinkURLDestinations.Add(mySelectedFrame)
myHyperlinkSource = document.HyperlinkPageItemSources.Add(mySelectedFrame)
myHyperlink = document.Hyperlinks.Add(myHyperlinkSource, myHyperlinkURL)
myHyperlink.Visible = False
*/
//urlDestString = 'http://www.mysite.com';
}
Copy link to clipboard
Copied
Try this. Reply with any error message received. It will add the ch2.au.net url to every button group. There is no way to find the "nearest" button group to the text frame. Is the text frame a part of the group? If so, we could use the nested j loop we had previously to match the URL to the right button group.
var document = app.activeDocument;
var myFrames = document.textFrames;
var groups = document.groups;
//FIND URL IN TEXT FRAME AND COPY READY TO PASS ON TO GROUPED OBJECT
for (var i=0; i< myFrames.length; i++) {
if ( myFrames[i].label == "url" ) {
urlDestString = myFrames[i].contents;
myItem = myFrames[i];
myFrames[i].label = "url Copied";
checkBTN (urlDestString, myItem, myFrames); // FIND THE CLOSEST GROUP TO ADD HYPERLINK URL
}
};
function checkBTN (urlDestString, myItem, myFrames) {
for (var i = 0; i < groups.length; i++) {
if (groups[i].label == "btn") {
var thisUrl = "http://ch2.net.au";
$.writeln("FOUND btn Group - TRY ADDING HYPERLINK TO BTN");
addHyperlink (thisUrl, groups[i], document);
}
}
};
function addHyperlink(thisUrl, mySelectedFrame, document){
try {
var hypeSource = document.hyperlinkPageItemSources.add(mySelectedFrame);
} catch(e) {
$.writeln( e);
return;
}
var hypeUrl = document.hyperlinkURLDesitnations.add(thisUrl);
document.hyperlinks.add(hypeSource, hypeUrl);
};
Copy link to clipboard
Copied
The catch prints out
Error: The object you have chosen is already in use by another hyperlink.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Actually, you need to pull checkBTN function out of the for loop. Here's a full code to try on a clean page with no hyperlinks.
var document = app.activeDocument;
var myFrames = document.textFrames;
var groups = document.groups;
//FIND URL IN TEXT FRAME AND COPY READY TO PASS ON TO GROUPED OBJECT
for (var i=0; i< myFrames.length; i++) {
if ( myFrames[i].label == "url" ) {
urlDestString = myFrames[i].contents;
myItem = myFrames[i];
myFrames[i].label = "url Copied";
}
}
checkBTN (); // FIND THE CLOSEST GROUP TO ADD HYPERLINK URL
function checkBTN () {
for (var i = 0; i < groups.length; i++) {
if (groups[i].label == "btn") {
var thisUrl = "http://ch2.net.au";
$.writeln("FOUND btn Group - TRY ADDING HYPERLINK TO BTN");
addHyperlink (thisUrl, groups[i], document);
}
}
}
function addHyperlink(thisUrl, mySelectedFrame, document){
try {
var hypeSource = document.hyperlinkPageItemSources.add(mySelectedFrame);
} catch(e) {
$.writeln( e);
return;
}
var hypeUrl = document.hyperlinkURLDesitnations.add(thisUrl);
document.hyperlinks.add(hypeSource, hypeUrl);
};
Copy link to clipboard
Copied
Im wondering if this is because because of the checkBtn out of the loop. what I am trying to do in the loop is if the item has the label URL then exit the Loop and try add it to the button but I guess its the same.
One thing I noticed was the first time I run this I got the error in the image but when I tried running again I got the same 'hyperlink used' error in the console
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Also, hyperlinkDestinations is misspelled in your error code. That's why you're getting that error.
Copy link to clipboard
Copied
Yes I did take it out. thats the error I got
Error String: Object does not support the property or methos'hyperlinkUrlDestinations' on line 39
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Oh FFS!!!!
That did it. you are a legend!!
I cant believe I didnt even check for misspelt functions. I feel so dumb right now
Your original post would have done the trick, thats where the error carried over through DAMN!
Thanks for keeping with me on this one. totally thank you for your help.
I'll complete what i was doing and post the final script.
Thanks again
Copy link to clipboard
Copied
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more