Javacript: How to duplicate a table header row (in InDesign Server version)?

Community Beginner ,
May 06, 2022 May 06, 2022

Copy link to clipboard

Copied

I created this code for duplicating a header row into body row, but unfortunately, this code doesn't go well with the InDesign server version, since the .select() method is not available (but works okay in desktop version) 

// create a simple table with one header row, put the cursor on the FIRST cell and run this code
table = app.selection[0].parent;
table.rows[0].select();
app.copy();
var newRow = table.rows.add(LocationOptions.AFTER, table.rows[0], {rowType:RowTypes.BODY_ROW});
newRow.select();
app.paste();


Is there any way to copy a HEADER_ROW, create a new BODY_ROW and paste the copied HEADER_ROW into the selected BODY_ROW? Later, I would do some changes to the body_row.

 

Any idea which will work in the Server version? Please let me know your thoughts?

TOPICS
Scripting

Views

81

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
May 06, 2022 May 06, 2022

Copy link to clipboard

Copied

Hi @Shiv Allva,

You will have to think which table you want to select. In your current code you are working with selection to identify the table of interest but on the server you will have to think of another logic to identify the table.

If it's just a single table in the document then you can use something like the following

 

var table = app.documents[0].tables[0]

 

Alternatively, you can iterate all the tables in the document using the above collection and find the table that is of interest to you. The criteria to choose the table will have to be thought by you based on your workflow.

-Manan

Likes

Translate

Translate

Report

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 ,
May 06, 2022 May 06, 2022

Copy link to clipboard

Copied

@Manan Joshi That was just a sample codesnippet. But the query is how to duplicate the first header_row as body_row? Problem here is Server version doesn't have .select(). So want to know if there is an alternative way to achieve this solution in server?

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
May 06, 2022 May 06, 2022

Copy link to clipboard

Copied

Hi @Shiv Allva , why not just make the new row and set its contents to the header’s contents, or do you need to style it the same way?

 

//a document with one table
var table = app.documents[0].textFrames[0].parentStory.tables[0];
var newRow = table.rows.add(LocationOptions.AFTER, table.rows[0]);
newRow.properties = {rowType:RowTypes.BODY_ROW, contents:table.rows[0].contents}

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
May 07, 2022 May 07, 2022

Copy link to clipboard

Copied

LATEST

Hi @Shiv Allva, the problem here is that Table Rows (and Columns) don't have a duplicate method. You are using select/copy/paste to solve this problem, which doesn't work on the server version as you mention.

 

Have a look at this function I've written called duplicateRowOrColumn. It is my attempt at creating the equivalent functionality to the missing method, and I hope it will work in your case. See my example 1 in my code. (Example 2 is commented out but shows a different usage.) Script isn't well tested at all, so let me know if you have problems with it.

- Mark

example-duplicate-row-column.gif

(Screenshot above shows little sample table with example 1 AND example 2 both run at once.)

 

 

/*
    Duplicate Row Or Column
    for Adobe Indesign 2022

    Utility function to duplicate a table row or column

    by m1b
    here: https://community.adobe.com/t5/indesign-discussions/javacript-how-to-duplicate-a-table-header-row-in-indesign-server-version/m-p/12926231

    v2022-05-07
*/


function main() {

    var doc = app.documents[0],
        table = doc.textFrames[0].parentStory.tables[0];

    /*
        example 1:
        duplicate first row after itself
    */
    var newRow = duplicateRowOrColumn(table.rows[0], LocationOptions.AFTER);
    // then convert to body row
    if (newRow != undefined && newRow.isValid)
        newRow.rowType = RowTypes.BODY_ROW;


    /*
        example 2:
        duplicate 3rd column before first column
    */
    // var newColumn = duplicateRowOrColumn(table.columns[2], LocationOptions.BEFORE, table.columns[0]);


    /**
     * Duplicates a table Row or Column
     * @param {Row|Column} rowOrColumn - the row or column to duplicate
     * @param {LocationOptions} [locationOption] - LocationOptions.AFTER or LocationOptions.BEFORE
     * @param {Row|Column} [referenceRowOrColumn] - after or before this row or column
     * @returns {Row|Column} - the duplicate row or column
     */
    function duplicateRowOrColumn(rowOrColumn, locationOption, referenceRowOrColumn) {
        // defaults:
        locationOption = locationOption || LocationOptions.AFTER;
        referenceRowOrColumn = referenceRowOrColumn || rowOrColumn;

        if (!rowOrColumn.isValid) {
            alert('Duplicate Row or Column: rowOrColumn is invalid.');
            return;
        }

        var type = rowOrColumn.constructor.name,
            cells = rowOrColumn.cells.everyItem().getElements(),

            // make the new row or column
            newRowOrColumn = (
                type == 'Row'
                    ? table.rows
                    : table.columns
            ).add(locationOption, referenceRowOrColumn),

            newCells = newRowOrColumn.cells.everyItem().getElements(),

            // list of all the properties
            // we want to duplicate
            propNames = CellPropertyNames();

        // loop over each cell
        cellsLoop:
        for (var i = 0; i < newCells.length; i++) {
            newCells[i].contents = '';

            // and 'copy' properties to new cell
            propertiesLoop:
            for (var p = 0; p < propNames.length; p++)
                newCells[i][propNames[p]] = cells[i][propNames[p]];

            // then copy contents
            if (cells[i].cellType == CellTypeEnum.TEXT_TYPE_CELL) {
                // duplicate text
                cells[i].texts[0].duplicate(LocationOptions.AFTER, newCells[i].texts[0]);
            }

            else if (cells[i].cellType == CellTypeEnum.GRAPHIC_TYPE_CELL) {
                // duplicate graphic cell
                newCells[i].convertCellType(CellTypeEnum.GRAPHIC_TYPE_CELL);
                var rect = cells[i].allPageItems[0],
                    newRect = newCells[i].allPageItems[0];
                // duplicate content
                newRect.contentPlace(rect);

                // position content
                if (rect.pageItems[0].isValid) {
                    var delta = getRelativePosition(rect.pageItems[0], rect),
                        newDelta = getRelativePosition(newRect.pageItems[0], newRect),
                        deltaMove = getRelativePosition([delta[1], delta[0]], [newDelta[1], newDelta[0]]);
                    newRect.pageItems[0].move(undefined, deltaMove);
                }
            }
        }

        return newRowOrColumn;

        /**
         * Calculates relative position between two items or bounds
         * @param {PageItem|Array} item1 - can be PageItem or bounds [T,L,B,R]
         * @param {PageItem|Array} item2 - can be PageItem or bounds [T,L,B,R]
         * @returns {Array} - [x,y]
         */
        function getRelativePosition(item1, item2) {
            // accepts PageItems or Arrays
            // returns [dx,dy]
            var b1 = item1.hasOwnProperty('geometricBounds')
                ? item1.geometricBounds
                : item1;
            var b2 = item2.hasOwnProperty('geometricBounds')
                ? item2.geometricBounds
                : item2;
            if (
                b1.constructor.name == 'Array'
                && b2.constructor.name == 'Array'
            )
                return [b2[1] - b1[1], b2[0] - b1[0]];
        }

        function CellPropertyNames() {
            return [
                'autoGrow',
                'appliedCellStyle',
                'bottomEdgeStrokeColor',
                'bottomEdgeStrokeGapColor',
                'bottomEdgeStrokeGapOverprint',
                'bottomEdgeStrokeGapTint',
                'bottomEdgeStrokeOverprint',
                'bottomEdgeStrokeTint',
                'bottomEdgeStrokeType',
                'bottomEdgeStrokeWeight',
                'bottomInset',
                'clipContentToCell',
                'clipContentToGraphicCell',
                'clipContentToTextCell',
                'diagonalLineInFront',
                'diagonalLineStrokeColor',
                'diagonalLineStrokeGapColor',
                'diagonalLineStrokeGapOverprint',
                'diagonalLineStrokeGapTint',
                'diagonalLineStrokeOverprint',
                'diagonalLineStrokeTint',
                'diagonalLineStrokeType',
                'diagonalLineStrokeWeight',
                'fillColor',
                'fillTint',
                'firstBaselineOffset',
                'gradientFillAngle',
                'gradientFillLength',
                'gradientFillStart',
                'graphicBottomInset',
                'graphicLeftInset',
                'graphicRightInset',
                'graphicTopInset',
                'leftEdgeStrokeColor',
                'leftEdgeStrokeGapColor',
                'leftEdgeStrokeGapOverprint',
                'leftEdgeStrokeGapTint',
                'leftEdgeStrokeOverprint',
                'leftEdgeStrokeTint',
                'leftEdgeStrokeType',
                'leftEdgeStrokeWeight',
                'leftInset',
                'maximumHeight',
                'minimumFirstBaselineOffset',
                'minimumHeight',
                'overprintFill',
                'paragraphSpacingLimit',
                'rightEdgeStrokeColor',
                'rightEdgeStrokeGapColor',
                'rightEdgeStrokeGapOverprint',
                'rightEdgeStrokeGapTint',
                'rightEdgeStrokeOverprint',
                'rightEdgeStrokeTint',
                'rightEdgeStrokeType',
                'rightEdgeStrokeWeight',
                'rightInset',
                'rotationAngle',
                'textBottomInset',
                'textLeftInset',
                'textRightInset',
                'textTopInset',
                'topEdgeStrokeColor',
                'topEdgeStrokeGapColor',
                'topEdgeStrokeGapOverprint',
                'topEdgeStrokeGapTint',
                'topEdgeStrokeOverprint',
                'topEdgeStrokeTint',
                'topEdgeStrokeType',
                'topEdgeStrokeWeight',
                'topInset',
                'topLeftDiagonalLine',
                'topRightDiagonalLine',
                'verticalJustification',
                'writingDirection',
            ];
        }

    } // end duplicateRowOrColumn

}

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Duplicate Row Or Column");

 

 

Likes

Translate

Translate

Report

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