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

Add Hyperlink to Grouped objects

Community Beginner ,
Nov 26, 2019 Nov 26, 2019

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);

 

}

TOPICS
How to , Scripting
4.9K
Translate
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 Expert , Nov 26, 2019 Nov 26, 2019

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"

...
Translate
Community Expert ,
Nov 26, 2019 Nov 26, 2019

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

Translate
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 ,
Nov 26, 2019 Nov 26, 2019

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 🙂

 

 

Translate
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 Expert ,
Nov 27, 2019 Nov 27, 2019

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 )

Translate
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 ,
Nov 28, 2019 Nov 28, 2019

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?

Translate
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 Expert ,
Nov 29, 2019 Nov 29, 2019

Maybe throw you hyperlinks.add function in a try/catch statement and log the ones that get skipped in the catch part?

Translate
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 ,
Dec 01, 2019 Dec 01, 2019

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?


 

 

 

Translate
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 Expert ,
Dec 01, 2019 Dec 01, 2019

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]);

}

Translate
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 ,
Dec 04, 2019 Dec 04, 2019

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

Translate
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 ,
Dec 04, 2019 Dec 04, 2019

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 } );
 


  }
Translate
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 Expert ,
Dec 04, 2019 Dec 04, 2019

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);
}

 

 

 

 

Translate
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 ,
Dec 04, 2019 Dec 04, 2019

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.

 

Translate
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 Expert ,
Dec 04, 2019 Dec 04, 2019
Please post the full code, or link to it on pastebin. You need a try/catch around hyperlinkSourceItem.add to skip any buttons that may have been added already. You can also open the hyperlinks panel and delete all the existing hyperlinks so you are starting from scratch.
Translate
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 ,
Dec 04, 2019 Dec 04, 2019

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';

}

 

 

 

Translate
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 Expert ,
Dec 04, 2019 Dec 04, 2019

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);
};

 

Translate
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 ,
Dec 04, 2019 Dec 04, 2019

The catch prints out

Error: The object you have chosen is already in use by another hyperlink.
Translate
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 Expert ,
Dec 04, 2019 Dec 04, 2019
With your grouped objects, are there groups within groups? That's the only thing I can think of.
Translate
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 Expert ,
Dec 04, 2019 Dec 04, 2019

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);
};
Translate
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 ,
Dec 04, 2019 Dec 04, 2019

error.JPG

 

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

Translate
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 Expert ,
Dec 04, 2019 Dec 04, 2019
Yes, take checkBtn out of the loop. Check the code I just posted. It should work on a clean page. The previous code would have turned all the buttons into the hyperlink too, but just failed when they were repeated in the loop.
Translate
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 Expert ,
Dec 04, 2019 Dec 04, 2019

Also, hyperlinkDestinations is misspelled in your error code. That's why you're getting that error. 

Translate
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 ,
Dec 04, 2019 Dec 04, 2019

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

Translate
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 Expert ,
Dec 04, 2019 Dec 04, 2019
check the spelling of destinations in the code
Translate
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 ,
Dec 04, 2019 Dec 04, 2019

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

Translate
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 Expert ,
Dec 04, 2019 Dec 04, 2019
No problem. Glad I could help. The trick now will be getting the right URL to match the right button. I'm not sure of a good way to do that, unless you grouped the textFrame with the URL to the button group, then did the inner loop like we had earlier. But at that point, it might just be easier to paste the hyperlinks manually.
Translate
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