Skip to main content
Participant
December 2, 2023
Answered

API to insert a reference to merge data field into a cell

  • December 2, 2023
  • 2 replies
  • 1089 views

Hi,

I am trying to find a way to insert a data field mapped to a record reference into a cell of an array. For example, in my cell I added manually a "<<mycolumn>>" mapped field related to a CSV with a column named "mycolumn" and it is working fine. Now I want to dynamically create an array with such references (<<mycolumn2>>, <<mycolumn3>> etc...) using a script. I can set some text directly with the "cell.contents" , not a problem, but if I insert a text like "<<mycolumn2>>" it is not working because not really mapped to the record. How can I do it ? I tried to debug but did not  find. Not found also into the documentation or perhaps I do not search with the correct keyword. 

 

Regards

This topic has been closed for replies.
Correct answer m1b

Hi @Hugo290714246dr1, I was wondering how this works, and @Brito Haroldo is right on the money.

 

Here is a demonstration script, showing a function that inserts a DataMergeTextPlaceholder at an InsertionPoint of your choosing. I hope you can use the function, or adapt it to your needs.

 

I've put two example insertionPoints to try—for example 1, just put the text insertion cursor into a story somewhere, and for example 2, run it with a document containing a table.

 

You will have to set the field name you want. Because you want it dynamically, you will probably be generating the fieldNameOrIndex parameter elsewhere, for example:

myFieldName = "mycolumn" + i;

Or if it is easier in your case, you can use the numerical index instead of the field name—passing i to the function will insert data merge field i. Either of these approaches could sit in a loop.

- Mark

 

/**
 * Demonstrates a function for adding a DataMergeTextPlaceholder.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/api-to-insert-a-reference-to-merge-data-field-into-a-cell/m-p/14273192
 */
function main() {

    var doc = app.activeDocument;

    // NOTE: the field name must match a data merge field in the document.
    var myFieldName = 'mycolumn';

    // example 1: the active insertion point:
    var ip = doc.selection[0];

    // example 2: an insertion point in the 3rd cell of the first table of the document:
    // var ip = doc.stories.everyItem().tables.everyItem().getElements()[0].cells[2].insertionPoints[0];

    var placeholder = insertDataMergeTextPlaceholder(doc, ip, myFieldName);

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Add Data Merge Text Placeholder');


/**
 * Inserts a DataMergeTextPlaceholder
 * at the specified InsertionPoint.
 * @author m1b
 * @version 2023-12-03
 * @param {Document} doc - an Indesign Document.
 * @param {InsertionPoint} insertionPoint - the target InsertionPoint.
 * @param {String|Number} fieldNameOrIndex - the name, or index, of a valid DataMergeField.
 * @returns {DataMergeTextPlaceholder}
 */
function insertDataMergeTextPlaceholder(doc, insertionPoint, fieldNameOrIndex) {

    if (
        doc == undefined
        || doc.constructor.name !== 'Document'
    )
        throw Error('insertDataMergeTextField: bad `doc` supplied.');

    if (
        insertionPoint == undefined
        || insertionPoint.constructor.name !== 'InsertionPoint'
        || !insertionPoint.isValid
    )
        throw Error('insertDataMergeTextField: bad `insertionPoint` supplied.');

    // datamerge objects
    var dm = doc.dataMergeProperties,
        dmFields = dm.dataMergeFields,
        index = Number(fieldNameOrIndex);

    if (fieldNameOrIndex.constructor.name == 'String') {
        // get the index to the named field
        for (index = 0, len = dmFields.length; index < len; index++)
            if (dmFields[index].fieldName == fieldNameOrIndex)
                break;
    }

    var field = dmFields[index];

    if (!field.isValid)
        throw Error('Did not find a valid data merge field "' + fieldNameOrIndex + '".');

    // add the placeholder at the insertionPoint
    var placeholder = doc.dataMergeTextPlaceholders.add(insertionPoint.parentStory, insertionPoint, field);

    // refresh
    insertionPoint.parentStory.recompose();

    if (placeholder.isValid)
        return placeholder;

};

 

2 replies

m1b
Community Expert
m1bCommunity ExpertCorrect answer
Community Expert
December 3, 2023

Hi @Hugo290714246dr1, I was wondering how this works, and @Brito Haroldo is right on the money.

 

Here is a demonstration script, showing a function that inserts a DataMergeTextPlaceholder at an InsertionPoint of your choosing. I hope you can use the function, or adapt it to your needs.

 

I've put two example insertionPoints to try—for example 1, just put the text insertion cursor into a story somewhere, and for example 2, run it with a document containing a table.

 

You will have to set the field name you want. Because you want it dynamically, you will probably be generating the fieldNameOrIndex parameter elsewhere, for example:

myFieldName = "mycolumn" + i;

Or if it is easier in your case, you can use the numerical index instead of the field name—passing i to the function will insert data merge field i. Either of these approaches could sit in a loop.

- Mark

 

/**
 * Demonstrates a function for adding a DataMergeTextPlaceholder.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/api-to-insert-a-reference-to-merge-data-field-into-a-cell/m-p/14273192
 */
function main() {

    var doc = app.activeDocument;

    // NOTE: the field name must match a data merge field in the document.
    var myFieldName = 'mycolumn';

    // example 1: the active insertion point:
    var ip = doc.selection[0];

    // example 2: an insertion point in the 3rd cell of the first table of the document:
    // var ip = doc.stories.everyItem().tables.everyItem().getElements()[0].cells[2].insertionPoints[0];

    var placeholder = insertDataMergeTextPlaceholder(doc, ip, myFieldName);

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Add Data Merge Text Placeholder');


/**
 * Inserts a DataMergeTextPlaceholder
 * at the specified InsertionPoint.
 * @author m1b
 * @version 2023-12-03
 * @param {Document} doc - an Indesign Document.
 * @param {InsertionPoint} insertionPoint - the target InsertionPoint.
 * @param {String|Number} fieldNameOrIndex - the name, or index, of a valid DataMergeField.
 * @returns {DataMergeTextPlaceholder}
 */
function insertDataMergeTextPlaceholder(doc, insertionPoint, fieldNameOrIndex) {

    if (
        doc == undefined
        || doc.constructor.name !== 'Document'
    )
        throw Error('insertDataMergeTextField: bad `doc` supplied.');

    if (
        insertionPoint == undefined
        || insertionPoint.constructor.name !== 'InsertionPoint'
        || !insertionPoint.isValid
    )
        throw Error('insertDataMergeTextField: bad `insertionPoint` supplied.');

    // datamerge objects
    var dm = doc.dataMergeProperties,
        dmFields = dm.dataMergeFields,
        index = Number(fieldNameOrIndex);

    if (fieldNameOrIndex.constructor.name == 'String') {
        // get the index to the named field
        for (index = 0, len = dmFields.length; index < len; index++)
            if (dmFields[index].fieldName == fieldNameOrIndex)
                break;
    }

    var field = dmFields[index];

    if (!field.isValid)
        throw Error('Did not find a valid data merge field "' + fieldNameOrIndex + '".');

    // add the placeholder at the insertionPoint
    var placeholder = doc.dataMergeTextPlaceholders.add(insertionPoint.parentStory, insertionPoint, field);

    // refresh
    insertionPoint.parentStory.recompose();

    if (placeholder.isValid)
        return placeholder;

};

 

Inspiring
December 3, 2023

Or create a webscraping script, save data into  tab separated txt file and just update the data source? 

m1b
Community Expert
Community Expert
December 3, 2023

@DTPtutorialyCZ-L.Zalesky could you please elaborate on this method? I'm not sure it addresses the OPs question, but maybe I don't understand it right.

- Mark

Brito Haroldo
Inspiring
December 2, 2023

Olá @Hugo290714246dr1, pelo que entendi você quer criar um documento, editar via script e criar o mapeamento para o CSV, correto? Não sei exatamente como gerar estes códigos mas com certeza o script precisa criar o mapeamento real para que a variável funcione na posterior etapa de importação dos dados variáveis. Simplesmente "digitar" via script algo como "<<nome>>" como texto não funciona mesmo. Estes links aqui não te ajudam com nada?
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMerge.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergeField.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergeImagePlaceholder.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergeOption.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergePreference.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergeTextPlaceholder.html