I'm trying to merge multiple Indesign documents and having problems with keeping the hyperlinks. The documents have external page hyperlinks and after merging I have to change the destination to the merged document. So I've created a little script that checks all hyperlinks and sets their documentPath to the current file. But the page from this hyperlink is lost after this. So I'm trying to save the page to a variable before changing the documentPath. But I can't set the destinationPageIndex with the variable. If I check the variable it has the right value, but setting it doesn't work, the hyperlink resets to page 1. If i just set destinationPageIndex = 20 for example it sets all links correctly. So it just ignores the page variable.
It seems like a simple problem but I seem to miss something.
var doc = app.activeDocument;
var hyperlinks = doc.hyperlinks;
for (i = 0; i < doc.hyperlinks.length; i++){
var hyperlink = hyperlinks[i];
var destination = hyperlink.destination;
if (destination instanceof HyperlinkExternalPageDestination) {
var page = destination.destinationPageIndex;
destination.documentPath = doc.fullName.absoluteURI;
destination.destinationPageIndex = page;
//destination.destinationPageIndex = 20;
}
}
As far as I can tell ExternalPageDestination destination doesn't work inside the document. You have to change the type of the destination to PageDestination if you want to make it work inside the current document.
Something like this:
var doc = app.activeDocument;
var hyperlinks = doc.hyperlinks;
var hyperlink = hyperlinks[0];
var destination = hyperlink.destination;
var page = destination.destinationPageIndex;
// create a new destination of the type 'PageDestination'
var new_destination = doc.hyperlinkPageDestinations.add();
// set the desired page
new_destination.destinationPage = doc.pages[page-1];
// assign the new destination
doc.hyperlinks[0].destination = new_destination;
// note: hyperlink.destination = new_destination; <-- won't work
Related
I have a js file which use Storage API. It just save form infos to get them if you have to fill the form again in a new session. It also re-use these infos to put them somewhere else in the page without page refreshing. It's working but I would like to make this in an object-oriented way.
Tried to learn OOP (beginner) and to make a function with the code which isn't in an object working at a window.onload event.
// STORAGE
// Used Elements
let input_textarea = document.querySelector('#firstname_area');
let input_textarea_bis = document.querySelector('#lastname_area');
let chosen_station = document.querySelector('#station')
let output_div = document.querySelector('.personal-greeting');
let output_station = document.querySelector('#custumerstation');
let save_button = document.querySelector('.send');
// Onclick start function
save_button.addEventListener('click', updateOutput);
// Saved Elements
output_div.textContent = localStorage.getItem('content');
input_textarea.value = localStorage.getItem('content');
input_textarea_bis.value = localStorage.getItem('contentbis');
chosen_station.innerHTML = sessionStorage.getItem('content');
// Function actions setting saved elements
function updateOutput() {
localStorage.setItem('content', input_textarea.value);
localStorage.setItem('contentbis', input_textarea_bis.value);
output_div.textContent = input_textarea.value;
output_station.textContent = chosen_station.innerHTML;
}
By creating a FormInformation class you could create attributes for the things you need to repeat elsewhere in your app like input text area fields, etc... This way, you could store an instance of FormInformation and set the attributes with the values of what you got while doing document.querySelector() and reuse it
I dynamically create some a tags with JavaScript when clicking on other elements. When I refresh the page, the created elements disappear. Is there a way to store the creation of the elements in a JavaScript cookie?
function showTab(ev) {
let head = document.getElementById('heading');
let node = document.createElement("a");
node.classList.add("tab");
node.appendChild(document.createTextNode(ev.target.innerHTML));
head.appendChild(node);
};
Cookies are probably not the right way to go about something like this as there are size limitations
A better approach would be to store added elements inside the browser's localStorage or indexedDB. You can see an example of the latter in this simple todo app: http://todomvc.com/examples/react/#/
If you inspect the localStorage on that todo example after adding some items, you will see that there is an array containing your entries in JSON format.
Depending on what type of information you need to save, you could either save the HTML directly, or you could save JSON containing the relevant information (tab name, link URL, etc).
I would recommend against saving the HTML directly in case you ever need to make changes to the HTML on your site. Your users would then be loading up outdated HTML.
You can store outerHTML of created element in localStorage and get it on page load
var node = document.createElement("a");
node.classList.add("tab");
node.textContent = "new tag";
var local = localStorage.getItem("html");
if (local == null){
localStorage.setItem("html", node.outerHTML);
console.log('HTML setted in localStorage');
} else
console.log(local);
Because localStorage doesn't worked in snippet you should check it in jsfiddle
Note that if your html content is large you should consider max size of local storage
Okay, I solved it like that:
// Restore
window.onload = function() {
let head = document.getElementById('heading');
archive = [];
key = allStorage();
for(var i=0; i<archive.length; i++){
if(archive[i] != null){
let node = document.createElement("a");
node.classList.add("tab");
node.innerHTML = key[i];
head.appendChild(node);
}
}
}
//Store all
function allStorage() {
keys = Object.keys(localStorage); // Gibt alle Schlüssel zurück
archive = [];
for (var i=0; i< keys.length; i++) {
archive.push(keys[i]);
}
return archive;
}
I'm looking for a way to copy pdf documents and stack them resized (I think resize works as duplicate, so once this works I will be able to complete my script).
I've been using .duplicate for now, and I can only manage to copy 1 item[0] on the same doc. Besides if I copy element by element I won't be able to replace them easily that's why I want to copy the whole document
I'm opening every script I find to understand a possible method.
Syntax is ok
var targetFile = app.documents.add(); //this is my output file - it is created
folder = Folder.myDocuments; //this paragraph works for now
sourceFolder = folder.selectDlg("source");
for ( i = 0; i < files.length; i++ ){
var sourceDoc = app.open(files[i]);
var doc = app.activeDocument;
for (l = 0; l < doc.pageItems.length; l++) { //corrected error
doc.pageItems[i].selected = true;
}
var mySel = app.activeDocument.selection; //this paragraph need rework
newItem = mySel[0].duplicate(targetFile); //mysel.duplicate(targetFile) is not a function
// MAIN ERROR
}
I use ESTK and notepad++ and have checked the variable, nothing obviously wrong during F10 debug. Using Jongware's CHM reference guide and some github tutorial but they tend to help for single operation script. My goal is to have script without GUI to reduce errors and time to proceed
Thank you for your time
EDIT: spotted an error with i used two times in a loop
Simple self solution:
var mySel = app.activeDocument.selection;
app.executeMenuCommand('copy');
targetFile.activate();
newItem = app.executeMenuCommand('paste');
Here's a js script for InDesign I wrote that exports layouts from a book file and saves them in a desktop folder. It works fine, except that I want to change the position of the automatic numbering. I have it set up now so that it adds an underscore between the filename and the automatic numbering to avoid confusion, because the end of the filenames all contain a number.
The script outputs files named like this: SampleStory_FL164.jpg. The number 4 (right after "FL16" which is part of the filename)is the automatic page number, so in this case this is page number 4 from a multipage indd document. I'd like to move the 4 from its current position to right before the underscore, so that the file would be renamed like this: SampleStory4_FL16.jpg. I can do this outside of InDesign (ignoring the exporting automation) with javascript, as seen here:
myDocument = "SampleStory_FL164.jpg"
//get position right after "FL16"
var firstIndex = myDocument.indexOf("FL16") + 4;
//get position right before ".jpeg"
var secondIndex = myDocument.indexOf(".jpg");
//find anything between firstIndex and secondIndex and assign it to a variable
var charsBetweenIndexes = myDocument.substring(firstIndex, secondIndex);
//search file name and replace anything between first and second index
var newFileName = myDocument.replace(charsBetweenIndexes, "");
//add what you deleted back right after the file name and before the underscore
newFileName = newFileName.replace("_", charsBetweenIndexes + "_");
//change myDocument to the value of newFileName before exporting
myDocument = newFileName;
But, with InDesign the tacking on of a number as the files are saved seem out of reach and not available to manipulate. I'm thinking here of the exportFile method or maybe the File object. Is there a way to do this? Here's the code I have working now:
Main();
// If you want the script to be un-doable, comment out the line above, and remove the comment from the line below
// app.doScript(Main, undefined, undefined, UndoModes.ENTIRE_SCRIPT,"Run Script");
function Main() {
// Check to see whether any InDesign documents are open.
// If no documents are open, display an error message.
if(app.documents.length > 0) {
app.jpegExportPreferences.exportingSpread = false;
app.jpegExportPreferences.jpegExportRange = ExportRangeOrAllPages.EXPORT_ALL;
if (app.books.length != 1)
alert ("This only works when you have one (1) book open");
else
for (b=0; b<app.books[0].bookContents.length; b++)
{
var myDocument = app.books[0].bookContents[b].fullName ;
c = app.open(app.books[0].bookContents[b].fullName);
myDocument = myDocument.name.replace("indd","jpg");
myDocument = myDocument.replace("FL16", "FL16_");
c.exportFile (ExportFormat.JPG, File(Folder.desktop + "/EDIT_Jpgs/" + myDocument));
}
}
else {
// No documents are open, so display an error message.
alert("No InDesign documents are open. Please open a document and try again.");
}
}
You may not be able to alter InDesign's built-in naming convention, but you could always rename them after you export them using the File object's rename method. Something like this would work (placed after your for loop):
var myFiles = Folder(Folder.desktop + "/EDIT_Jpgs/").getFiles("*.jpg");
for (var i = 0; i < myFiles.length; i++){
var myFile = myFiles[i];
//Adjust this regular expression as needed for your specific situation.
myFile.rename(myFile.name.replace(/(_FL16)(\d+)/, "$2$1"));
}
Rename returns a boolean value so you could log information on any failures if you needed to.
I am trying to construct a thumbnail slideshow with javascript. I am very new to Javascript so my way of doing it might be a little strange...
The problem I am running into is that I have a main image, and then I have 4 thumbnails. When I click on the first thumbnail it changes the main image, and the first thumbnail. But when I click on the changed thumbnail it needs to change the main image with a different photo (the one that corresponds to the new thumbnail)
I initialize my functions with a call like this:
document.getElementById('thumb1').onclick=thumbs1;
Which uses this function:
function thumbs1(){
num1 = 1;
num2 = 0;
var src1 = largeArray[num1];
var src2 = thumbArray[num2];
document.getElementById('main').src=src1;
document.getElementById('one').src=src2;
document.getElementById('one').id='change';
}
And I am trying to change the id of the new thumbnail to "change" and call another function like this:
document.getElementById('change').onclick=changed;
And this used the following function:
function changed(){
num1 = 0;
var src1 = largeArray[num1];
document.getElementById('change').src=src1;
document.getElementById('change').id='one';
}
When using Firebug I found the error, and I believe it is being caused by the fact that the call to document.getElementById('change').onclick=changed;. The browser can not find the Element Id "change" because I have not called the function which changed the ID yet.
Does anyone know how to fix this problem. (I know the code is of low quality... I am teaching my self)
Here is a live link to the page: My Page
Thanks for any help!!
var array = //id's of your images here. you could type them static or search your document for images and get their id attribute.
document.addEventListener("click", function(e){
var clicked_image = e.target || e.srcElement; //using jquery can help with this cause older versions of IE are stupid, but depends on if you want to support them.
var id = clicked_image.getAttribute(id);
var temp = document.getElementById("main").src;
for (var i = 0; i < array.length; i++){
if(array[i] == id){
document.getElementById("main").src = clicked_image.src;
clicked_image.src = temp;
}
}
})
That's pretty quick and dirty, you would be better off assigning eventlisteners to just your images. You would use the same syntax as above, but it should give you an idea of what to do.
With this you don't have to worry about what image got clicked, you just change the main, and you change the thumb to what the main was. So you eliminate the hassle of trying to keep track of what each image is.