Skip to main content
Community Expert
November 7, 2025
Resuelto

Place item from library - to X Y coordinates

  • November 7, 2025
  • 6 respuestas
  • 277 visualizaciones

I'm trying to script the placement of an object from the library (it does other things but only thing it doesn't do is place it where I want it).

So I have the script set to 0,0 absolute 
Then offset X= -120 and Y= 5 

But in different document sizes it doesn't go to the same place - if the page has a spread etc. 

 

For the record it's fine if it places on the page and I move manually - but hey if the script can reposition it in the why not - right?

 

I can't get it consistently to be in the position I want 

    if (placedAsset && placedAsset.length > 0) {
        var obj = placedAsset[0];

        // Save current preferences
        var oldRuler = doc.viewPreferences.rulerOrigin;
        var oldAnchor = app.activeDocument.selectionPreferences.anchorPoint;

        // Set positioning reference to page origin and top left anchor
        doc.viewPreferences.rulerOrigin = RulerOrigin.PAGE_ORIGIN;
        app.activeDocument.selectionPreferences.anchorPoint = AnchorPoint.TOP_LEFT_ANCHOR;

        // Move absolutely to 0, 0
        obj.move([0, 0]);

        // Offset in mm converted to points
        var offsetX = -120 * 2.83465; // mm to pt
        var offsetY = 5 * 2.83465;
        obj.move([offsetX, offsetY]);

        // Restore preferences
        doc.viewPreferences.rulerOrigin = oldRuler;
        app.activeDocument.selectionPreferences.anchorPoint = oldAnchor;
    }

 

Mejor respuesta de Laubender

Hi Eugene,

when placing assets from an InDesign *.indl file, script or not, the position depends on a preference for snippet files *.idms. Snippet-Import > Position: Cursor Position or Original Position

(free translation from my German InDesign).

 

This preference is a document preference:

myDoc.documentPreferences.snippetImportUsesOriginalLocation = true ; // or false

 

Note: An asset in an InDesign library file is essentially a stored snippet.

 

Kind regards,
Uwe Laubender
( Adobe Community Expert )

6 respuestas

Scott Falkner
Community Expert
Community Expert
November 8, 2025

This has nothing to do with scripting but might help. If you put only the item(s) you wnt in your library in position on a page and add a guide you can add all items as a library item (Library flyout menu: Add items on page N). When you do that the guide will be included in the library item. you won't be able to drag t he item onto a page but if you select Place Item from the flyout menu the items will be in position, along with the guide. Perhaps this can be combined with scrpting to get what you want.

Community Expert
November 8, 2025

Thanks - never thought of trying that - will give it a go.

m1b
Community Expert
Community Expert
November 8, 2025

Hey @Eugene Tyson I might be totally missing the point here, but I wrote a few functions to make this sort of thing easier—unless I've misunderstood your problem—and here's a script that uses them. Might be helpful, might not.

- Mark

/**
 * @file Position Item Relative To Nearest Page.js
 *
 * Example of moving a page item to a specific location
 * relative to the nearest page.
 *
 * @author m1b
 * @version 2025-11-08
 * @discussion https://community.adobe.com/t5/indesign-discussions/place-item-from-library-to-x-y-coordinates/m-p/15581450
 */
function main() {

    // important! because this only affects scripts, it doesn't alter the users rulers etc.
    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    // good way to handle magic numbers
    const mm = 2.83465;

    // this part is just so I have something similar to your script
    var doc = app.activeDocument;
    var placedAsset = [doc.allPageItems[0]];

    // same as what your script but neater
    if (!placedAsset || placedAsset.length === 0)
        return;

    // same as your script
    var obj = placedAsset[0];

    // convenient function to do the moving
    positionItemRelativeToNearestPage(obj, -120 * mm, 5 * mm);

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Move Item');

/**
 * Moves `item` to the top left of the nearest page, offset by [dx, dy].
 * @author m1b
 * @version 2025-11-08
 * @param {PageItem} item - an Indesign PageItem.
 * @param {Number} dx - the X offset.
 * @param {Number} dy - the Y offset.
 */
function positionItemRelativeToNearestPage(item, dx, dy) {

    if ('function' !== typeof item.move)
        throw new Error('positionItemRelativeToNearestPage: cannot move item.');

    // a function I had already written
    var page = getNearestPage(item);

    if (!page)
        // I don't think this should ever happen...
        throw new Error('Could not get nearest page.');

    // get the top left of the page
    var pos = [page.bounds[0], page.bounds[1]];

    // move the item
    item.move([pos[1] + dx, pos[0] + dy]);

};

/**
 * Returns the nearest page to `item`.
 * @author m1b
 * @version 2025-08-02
 * @param {PageItem} item - the target item.
 * @returns {Page} - the nearest page to `item`.
 */
function getNearestPage(item) {

    var page = item.parentPage;
    var spread;

    while (!page) {

        spread = item.parent;

        if ('Page' === spread.constructor.name)
            page = spread;


        if ('Spread' === spread.constructor.name) {

            var index = findClosestBounds(
                item.visibleBounds,
                spread.pages.everyItem().bounds
            );

            page = spread.pages.item(index);

        }

    }

    return page;

};

/**
 * Returns the index of the bounds in `boundsArray` that is
 * closest to the target bounds. All bounds are in [T, L, B, R] format.
 * @author m1b
 * @version 2025-08-02
 * @param {Array} targetBounds - The target bounds [T, L, B, R].
 * @param {Array<bounds>} boundsArray - An array of bounds arrays.
 * @returns {Number} Index of the closest bounds in the array.
 */
function findClosestBounds(targetBounds, boundsArray) {

    var targetCenter = centerOfBounds(targetBounds);
    var minDist = Infinity;
    var closestIndex = -1;

    for (var i = 0, center, dx, dy, distSq; i < boundsArray.length; i++) {

        center = centerOfBounds(boundsArray[i]);
        dx = targetCenter[0] - center[0];
        dy = targetCenter[1] - center[1];
        distSq = dx * dx + dy * dy;

        if (distSq < minDist) {
            minDist = distSq;
            closestIndex = i;
        }

    }

    return closestIndex;

};

/**
 * Returns the center of `bounds`;
 * @param {Array} bounds - The bounds [T, L, B, R].
 * @returns {Array<Number>} - [cx, cy].
 */
function centerOfBounds(bounds) {
    return [(bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2];
};
Community Expert
November 8, 2025

Amazing - thank you all! Gonna give a whirl first thing Monday - have a great weekend!

rob day
Community Expert
Community Expert
November 7, 2025

Not sure if this helps, but the move() method can be used in different ways depending on the parameters (the API docs are a bit confusing on the usage). The move can be relative to the page or spread, or it can be relative to the current position—like this:

 

//sets the units this script will use
app.scriptPreferences.measurementUnit = MeasurementUnits.MILLIMETERS;

var d = app.activeDocument
//save the zero point
var zp = d.zeroPoint;

//current selection
var s = app.activeDocument.selection[0]

d.zeroPoint = [0, 0];
d.viewPreferences.rulerOrigin = RulerOrigin.PAGE_ORIGIN;

//move to a new x,y position relative to the ruler origin
//s.move([-120 , 0 ])

//move to a new postion relative to the current position, 0,0 in this case
s.move([ 0 , 0 ] , [ -120 , 0 ])

//reset
d.zeroPoint = zp;
app.scriptPreferences.measurementUnit = AutoEnum.AUTO_VALUE;

 

 

Community Expert
November 7, 2025

Thanks a lot @Laubender @rob day I'll go again and see if I can get it to behave using these methods. 

Amazing the simplest things end up being the most complex. 

 

 

rob day
Community Expert
Community Expert
November 7, 2025

Hi @Eugene Tyson , I’m not using the latest version, but what is

 

app.activeDocument.selectionPreferences.anchorPoint = AnchorPoint.TOP_LEFT_ANCHOR;?
 
It throws an error and I don’t see a document selectionPreferences property in the latest API

 

Community Expert
November 7, 2025

It was originally there to force the top-left anchor as the reference point when moving objects, so the movement would be calculated from the object's top-left corner instead of the centre. But because we’re now using absolute page coordinates to place the object, the anchor reference doesn’t matter anymore. Also the property name wasn’t correct in this version of InDesign so it threw the error. Removing it makes the script work and doesn’t change the behaviour.

 

Actually think I just muted the alert for testing purposes. 

 

I am pulling the script out of my posterior to be honest. Getting there for most things. But you know, I'm not a scripter, more of a cobble things together and get it to work. 

I'm sure there's a better way.

rob day
Community Expert
Community Expert
November 7, 2025

Check the InDesign 2026 API, I’m not seeing a selectionPreferences document property:

 

https://www.indesignjs.de/extendscriptAPI/indesign-latest/#Document.html

 

VSCode throws this error:

 

 

If you are trying to do more than simply move (you need to rotate, scale, skew, etc.), a pageItem does have the transform method.

 

https://www.indesignjs.de/extendscriptAPI/indesign-latest/#PageItem.html#d1e208939__d1e212537

 

LaubenderCommunity ExpertRespuesta
Community Expert
November 7, 2025

Hi Eugene,

when placing assets from an InDesign *.indl file, script or not, the position depends on a preference for snippet files *.idms. Snippet-Import > Position: Cursor Position or Original Position

(free translation from my German InDesign).

 

This preference is a document preference:

myDoc.documentPreferences.snippetImportUsesOriginalLocation = true ; // or false

 

Note: An asset in an InDesign library file is essentially a stored snippet.

 

Kind regards,
Uwe Laubender
( Adobe Community Expert )

Community Expert
November 17, 2025

Thank you all - this fixed the issue placing from Library was hitting the original location 

I have fixed it 

// Script Name: DeleteAllXMLStructureAndPlaceLibraryAsset.jsx
// Description: Deletes XML structure and allows selecting an asset from an open library, then moves it to -120,0
// Version: 2.2
// Date: 2025-11-17

#target indesign

// ---- STEP 1: Check for open document ----
if (app.documents.length === 0) {
    alert("Please open a document before running this script.");
    exit();
}

var doc = app.activeDocument;

// ---- STEP 2: Remove XML structure if present ----
if (doc.xmlElements.length > 0) {
    try {
        doc.xmlElements.item(0).remove();
    } catch (e) {
        $.writeln("Error deleting XML structure: " + e);
    }
}

// ---- STEP 3: Find open library ----
var libFileName = "Info-Table_V03 2023.indl";
var myLibrary = null;

for (var i = 0; i < app.libraries.length; i++) {
    if (app.libraries[i].name === libFileName) {
        myLibrary = app.libraries[i];
        break;
    }
}

if (myLibrary === null) {
    alert("The library '" + libFileName + "' is not open.\nPlease open the .indl file before running this script.");
    exit();
}

// ---- STEP 4: Disable "use original location" BEFORE placing asset ----
doc.documentPreferences.snippetImportUsesOriginalLocation = false;

// ---- STEP 5: List and select asset ----
var assets = myLibrary.assets;

if (assets.length === 0) {
    alert("Library is empty or assets could not be read.");
    exit();
}

// Build asset list
var assetList = "";
for (var i = 0; i < assets.length; i++) {
    assetList += i + ": " + assets[i].name + "\n";
}

var assetIndex = prompt("Choose an asset by index:\n\n" + assetList, "0");
if (assetIndex === null || assetIndex === "") {
    alert("No asset selected.");
    exit();
}

assetIndex = parseInt(assetIndex);
if (isNaN(assetIndex) || assetIndex < 0 || assetIndex >= assets.length) {
    alert("Invalid asset index.");
    exit();
}

// ---- STEP 6: Place selected asset ----
var assetToPlace = assets[assetIndex];
var placedAsset = assetToPlace.placeAsset(doc);

if (placedAsset && placedAsset.length > 0) {
    var obj = placedAsset[0];
    var page = obj.parentPage || doc.pages[0];

    // ---- STEP 7: Move object relative to page ----
    var oldRuler = doc.viewPreferences.rulerOrigin;
    doc.viewPreferences.rulerOrigin = RulerOrigin.PAGE_ORIGIN;

    // Move object to -120,0 relative to page top-left
    obj.move([-120, 0]);

    // Restore ruler origin
    doc.viewPreferences.rulerOrigin = oldRuler;

    alert("Asset '" + assets[assetIndex].name + "' placed at -120,0 on page " + (page.name || page.documentOffset + 1));
}
Community Expert
November 7, 2025

In this document it's landing up here for some reason