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

Change fill color based on content

Community Beginner ,
Jan 20, 2023 Jan 20, 2023

Copy link to clipboard

Copied

Hi everybody.

I browsed hours and hours without finding a useful solution to my issue: I will have to import data within a table.

Among the imported data, there will be a string of text having RGB or CMKY value.

I'd like that such content will be processed by the script in order to fill a cell background based on value.

Is is possible?

TOPICS
How to , Scripting

Views

975

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

correct answers 3 Correct answers

Community Expert , Jan 26, 2023 Jan 26, 2023

If we assume 3 numbers equals an RGB value and 4 a CMYK value, then here’s an example that checks all the cells in the 3rd column of the document’s first table, and sets the fillColor to the content values:

 

var d = app.activeDocument
var c = d.stories.everyItem().tables[0].columns[2].cells.everyItem().getElements();


var fc, cv;
var ca= []
for (var i = 0; i < c.length; i++){
    cv = c[i].contents.split(",");
    for (var n = 0; n < cv.length; n++){
        ca.push(Number(cv[n]))
    };   
  
...

Votes

Translate

Translate
Community Expert , Jan 30, 2023 Jan 30, 2023

You could remove the contents:

 

var d = app.activeDocument
var tf = d.textFrames.everyItem().getElements();

var fc, cv, vn;
var ca= []
for (var i = 0; i < tf.length; i++){
    cv = tf[i].contents.split(",");  
    if (cv.length == 3 || cv.length == 4) {
        for (var n = 0; n < cv.length; n++){
            ca.push(Number(cv[n]))
        };   
        vn=0
        for (var x in ca) {
            vn += ca[x]
        }
        if (ca.length == 3) {
            fc = makeSwatch(d, ca.toString())
...

Votes

Translate

Translate
Community Expert , Feb 07, 2023 Feb 07, 2023

This should work:

 

var tf = d.pages.everyItem().textFrames.everyItem().getElements();

Votes

Translate

Translate
Community Expert ,
Jan 20, 2023 Jan 20, 2023

Copy link to clipboard

Copied

Yes, that's possible. Show us what you've got.

Votes

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 ,
Jan 20, 2023 Jan 20, 2023

Copy link to clipboard

Copied

Techincally speaking, I am not a developer and I'm sorry because I cannot write a working script.

I assumed it is possible to start from a basic concept like this and working on something like this one.

I sneaked peak into this link to understand a bit object, method, properties, and it seems feasible.

I was wondering if I'm the only one in need for this matter.

Votes

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 Expert ,
Jan 20, 2023 Jan 20, 2023

Copy link to clipboard

Copied

Hi @zaitexspa , the fill color’s value is an array of numbers (.colorValue), so for a script to work you would have to convert the cell’s text into an array of numbers and know what the exprected color mode is. Is the text 0/0/0/0, or 0|0|0|0, or 0,0,0,0? If it’s 4 numbers we can assume it’s a CMYK value, but if it’s 3 is it RGB, Lab, or HSB?

 

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

Votes

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 Expert ,
Jan 20, 2023 Jan 20, 2023

Copy link to clipboard

Copied

This thread may be a better help for a base script for you to work off of: 
https://community.adobe.com/t5/indesign-discussions/applying-cell-style-to-specific-cells-in-table-b...

Votes

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 Expert ,
Jan 20, 2023 Jan 20, 2023

Copy link to clipboard

Copied

Same question as Rob: can you show how those values appear in the cells? A screenshot would help.

Votes

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 Expert ,
Jan 23, 2023 Jan 23, 2023

Copy link to clipboard

Copied

@rob day said: "If it’s 4 numbers we can assume it’s a CMYK value…"

Playing devil's advocate: Or perhaps an rgba value ??!

 

Fun aside, the OP states that it will be RGB or CMYK. So that's clear, I think:

"Among the imported data, there will be a string of text having RGB or CMKY value."

 

@zaitexspa , it's important how the data is presented.

The word "Among" is showing that there is perhaps more than three or four numbers.

So you'd need an algorithm to part the color values from all other contents in a given table cell.

 

In essence: we need examples.

 

Regards,
Uwe Laubender
( Adobe Community Expert )

Votes

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 ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

Hi guys, thanks for your reply.

I can import RGB or CMYK value like 255,255,255 or 0,0,0,100 - I would rather import those values from csv, so no problem.

Attached an example.

 

Screenshot 2023-01-26 at 14.35.35.png

Votes

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 Expert ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

That doesn't make it much clearer. Whre are the colour values? How are they represented?

Votes

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 Expert ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

If we assume 3 numbers equals an RGB value and 4 a CMYK value, then here’s an example that checks all the cells in the 3rd column of the document’s first table, and sets the fillColor to the content values:

 

var d = app.activeDocument
var c = d.stories.everyItem().tables[0].columns[2].cells.everyItem().getElements();


var fc, cv;
var ca= []
for (var i = 0; i < c.length; i++){
    cv = c[i].contents.split(",");
    for (var n = 0; n < cv.length; n++){
        ca.push(Number(cv[n]))
    };   
    if (ca.length == 3) {
        fc = makeSwatch(d, ca.toString())
        fc.properties = {space:ColorSpace.RGB, model:ColorModel.PROCESS, colorValue:ca}
        c[i].fillColor = fc;
    } 
    if (ca.length == 4) {
        fc = makeSwatch(d, ca.toString())
        fc.properties = {space:ColorSpace.CMYK, model:ColorModel.PROCESS, colorValue:ca}
        c[i].fillColor = fc;
    } 
    ca = [];
};   


/**
* Makes a new named Swatch 
* @ param the document to add the color to 
* @ param color name 
* @ return the new swatch 
*/

function makeSwatch(d, n){
    if (d.colors.itemByName(n).isValid) {
        return d.colors.itemByName(n);
    } else {
        return d.colors.add({name:n});
    }
}

 

Sample result:

 

Screen Shot 11.pngScreen Shot 10.png

Votes

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 ,
Jan 30, 2023 Jan 30, 2023

Copy link to clipboard

Copied

Hi @rob day 

many many thanks for your help!

I managed to assign a fill color to the text frame.

Plus, I managed to assign the same color to the included text, which is useless to keep readable.

I just tweaked your code as follows:

var d = app.activeDocument
//var c = d.stories.everyItem().tables[0].columns[2].cells.everyItem().getElements();
var c = d.textFrames.everyItem().getElements();

var fc, cv, cn;
var ca= []
for (var i = 0; i < c.length; i++){
    cn = c[i].lines; // change color of the included text
    cv = c[i].contents.split(",");
    for (var n = 0; n < cv.length; n++){
        ca.push(Number(cv[n]))
    };

    if (ca.length == 3) {
        fc = makeSwatch(d, ca.toString())
        fc.properties = {space:ColorSpace.RGB, model:ColorModel.PROCESS, colorValue:ca}
        c[i].fillColor = fc;
    } 
    if (ca.length == 4) {
        fc = makeSwatch(d, ca.toString())
        fc.properties = {space:ColorSpace.CMYK, model:ColorModel.PROCESS, colorValue:ca}
        c[i].fillColor = fc;
    } 
    ca = [];

    for(var w = 0; w < cn.length; w++) {
        cn[w].fillColor = fc;
    }
};   


/**
* Makes a new named Swatch 
* @ param the document to add the color to 
* @ param color name 
* @ return the new swatch 
*/

function makeSwatch(d, n){
    if (d.colors.itemByName(n).isValid) {
        return d.colors.itemByName(n);
    } else {
        return d.colors.add({name:n});
    }
}

My last concern is: how can I change the background fill color (and the included text color) of a specific textframe?

If I'm not wrong, in your case, you pointed out every cell of the third column of a table; in my case, I'd like to select a specific textframe. 

So, rather than use

var c = d.textFrames.everyItem().getElements();

which might be catching all the textFrames in the document, I'd like to run the script just for a specific one.

I tried alternatively unsuccessfully to use this:

var c = d.textFrames.itemByName("test");
cn = d.contents;

but... it won't work and it makes useless the for loop. I got an error by Indesign.

 

Votes

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 Expert ,
Jan 30, 2023 Jan 30, 2023

Copy link to clipboard

Copied

Can you share a sample document?

Votes

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 ,
Jan 30, 2023 Jan 30, 2023

Copy link to clipboard

Copied

 

Votes

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 Expert ,
Jan 30, 2023 Jan 30, 2023

Copy link to clipboard

Copied

Hi @zaitexspa , itemByName probably won‘t work unless you actually give the text frame a name in the Layers panel. In the doc you posted "test" is a layer name not a text frame name, and a text frame’s name returns "" unless you give it a name.

 

You could get all of the text frames and assume if their contents gets split into an array using the "," delimiter and the length is either 3 or 4 it’s a color value string. You could also set up your color values with a less common separator something like 0|0|0, then use .contents.split("|"). Maybe some one else has a better idea?

 

Also here I’m getting the color’s total value and setting the contents color to either black or white depending on the value returned:

 

 

var d = app.activeDocument
var tf = d.textFrames.everyItem().getElements();

var fc, cv, vn;
var ca= []
for (var i = 0; i < tf.length; i++){
    cv = tf[i].contents.split(",");  
    if (cv.length == 3 || cv.length == 4) {
        for (var n = 0; n < cv.length; n++){
            ca.push(Number(cv[n]))
        };   
        vn=0
        for (var x in ca) {
            vn += ca[x]
        }
        if (ca.length == 3) {
            fc = makeSwatch(d, ca.toString())
            fc.properties = {space:ColorSpace.RGB, model:ColorModel.PROCESS, colorValue:ca}
            tf[i].fillColor = fc;
            if (vn/3 < 128) {
                tf[i].texts[0].fillColor = "Paper"
            } else {
                tf[i].texts[0].fillColor = "Black"
            }
        } 
        if (ca.length == 4) {
            fc = makeSwatch(d, ca.toString())
            fc.properties = {space:ColorSpace.CMYK, model:ColorModel.PROCESS, colorValue:ca}
            tf[i].fillColor = fc;
            if (vn/4 < 50) {
                tf[i].texts[0].fillColor = "Black"
            } else {
                tf[i].texts[0].fillColor = "Paper"
            }
        } 
    } 
    ca = [];
};   


/**
* Makes a new named Swatch 
* @ param the document to add the color to 
* @ param color name 
* @ return the new swatch 
*/

function makeSwatch(d, n){
    if (d.colors.itemByName(n).isValid) {
        return d.colors.itemByName(n);
    } else {
        return d.colors.add({name:n});
    }
}

 

 

 

Screen Shot 18.png

Votes

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 ,
Jan 30, 2023 Jan 30, 2023

Copy link to clipboard

Copied

Thanks @rob day 

my purpose is to get rid of the text which makes the textframe fill color, so I rather changed to "None" Black or White to hide it in a way.

Other solutions on that? Maybe cancel the textframe content? Otherwise it's ok for me.

This is the final code:

var d = app.activeDocument
//var c = d.stories.everyItem().tables[0].columns[2].cells.everyItem().getElements();
var c = d.textFrames.everyItem().getElements();

var fc, cv, cn;
var ca= []
for (var i = 0; i < c.length; i++){
    cn = c[i].contents; // change color of the included text
    cv = c[i].contents.split(",");
    for (var n = 0; n < cv.length; n++){
        ca.push(Number(cv[n]))
    };

    if (ca.length == 3) {
        fc = makeSwatch(d, ca.toString())
        fc.properties = {space:ColorSpace.RGB, model:ColorModel.PROCESS, colorValue:ca}
        c[i].fillColor = fc;
        c[i].texts[0].fillColor = "None"
        } 
    if (ca.length == 4) {
        fc = makeSwatch(d, ca.toString())
        fc.properties = {space:ColorSpace.CMYK, model:ColorModel.PROCESS, colorValue:ca}
        c[i].fillColor = fc;
        c[i].texts[0].fillColor = "None"
    } 
    ca = [];

};   


/**
* Makes a new named Swatch 
* @ param the document to add the color to 
* @ param color name 
* @ return the new swatch 
*/

function makeSwatch(d, n){
    if (d.colors.itemByName(n).isValid) {
        return d.colors.itemByName(n);
    } else {
        return d.colors.add({name:n});
    }
}

Votes

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 Expert ,
Jan 30, 2023 Jan 30, 2023

Copy link to clipboard

Copied

You could remove the contents:

 

var d = app.activeDocument
var tf = d.textFrames.everyItem().getElements();

var fc, cv, vn;
var ca= []
for (var i = 0; i < tf.length; i++){
    cv = tf[i].contents.split(",");  
    if (cv.length == 3 || cv.length == 4) {
        for (var n = 0; n < cv.length; n++){
            ca.push(Number(cv[n]))
        };   
        vn=0
        for (var x in ca) {
            vn += ca[x]
        }
        if (ca.length == 3) {
            fc = makeSwatch(d, ca.toString())
            fc.properties = {space:ColorSpace.RGB, model:ColorModel.PROCESS, colorValue:ca}
            tf[i].fillColor = fc;
            tf[i].contents = "";
            tf[i].contentType = ContentType.UNASSIGNED;
        } 
        if (ca.length == 4) {
            fc = makeSwatch(d, ca.toString())
            fc.properties = {space:ColorSpace.CMYK, model:ColorModel.PROCESS, colorValue:ca}
            tf[i].fillColor = fc;
            tf[i].contents = "";
            tf[i].contentType = ContentType.UNASSIGNED;
        } 
    } 
    ca = [];
};   


/**
* Makes a new named Swatch 
* @ param the document to add the color to 
* @ param color name 
* @ return the new swatch 
*/

function makeSwatch(d, n){
    if (d.colors.itemByName(n).isValid) {
        return d.colors.itemByName(n);
    } else {
        return d.colors.add({name:n});
    }
}

Votes

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 ,
Jan 30, 2023 Jan 30, 2023

Copy link to clipboard

Copied

Super solved this thread! Thank you all guys. I hope this will be useful for someone else.

Votes

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 ,
Feb 07, 2023 Feb 07, 2023

Copy link to clipboard

Copied

@rob day is there a way to only select the pages of a document, excluding the master page?

 

Votes

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 Expert ,
Feb 07, 2023 Feb 07, 2023

Copy link to clipboard

Copied

This should work:

 

var tf = d.pages.everyItem().textFrames.everyItem().getElements();

Votes

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 ,
Jun 29, 2023 Jun 29, 2023

Copy link to clipboard

Copied

Hi @rob day 

I switched to Ventura and latest Indesign.

It happens the script affects the master pages too.

How to avoid?

Votes

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 Expert ,
Jun 29, 2023 Jun 29, 2023

Copy link to clipboard

Copied

Not sure if the upgrade would change anything, but try this:

 

var d = app.activeDocument
var c = d.stories.everyItem().tables[0].columns[2].cells.everyItem().getElements();

var fc, cv;
var ca= []
for (var i = 0; i < c.length; i++){
    if (c[i].parent.parent.parent.parentPage.documentOffset > -1) {
        cv = c[i].contents.split(",");
        for (var n = 0; n < cv.length; n++){
            ca.push(Number(cv[n]))
        };   
        if (ca.length == 3) {
            fc = makeSwatch(d, ca.toString())
            fc.properties = {space:ColorSpace.RGB, model:ColorModel.PROCESS, colorValue:ca}
            c[i].fillColor = fc;
        } 
        if (ca.length == 4) {
            fc = makeSwatch(d, ca.toString())
            fc.properties = {space:ColorSpace.CMYK, model:ColorModel.PROCESS, colorValue:ca}
            c[i].fillColor = fc;
        } 
        ca = [];
    }
};   


/**
* Makes a new named Swatch 
* @ param the document to add the color to 
* @ param color name 
* @ return the new swatch 
*/

function makeSwatch(d, n){
    if (d.colors.itemByName(n).isValid) {
        return d.colors.itemByName(n);
    } else {
        return d.colors.add({name:n});
    }
}

Votes

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 ,
Jun 29, 2023 Jun 29, 2023

Copy link to clipboard

Copied

@rob day this is the error I get with your latest piece of code:

Screenshot 2023-06-30 alle 08.23.56.png

Votes

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 Expert ,
Jun 29, 2023 Jun 29, 2023

Copy link to clipboard

Copied

@zaitexspa said: "It happens the script affects the master pages too."

 

Hm. Hard to believe with a code like the one by Rob Day that text frames on parent pages are the scope.

Let's do a test document. Put one text frame on parent page A and another one on the first page of a new document. Run code 1 below and look into the alert. It should give you this result:

 

1, [object Spread]

 

The name of the page the text frame is positioned is "1" ; its spread is a normal spread and no parent one.

 

Code 1

 

var tf = app.documents[0].pages.everyItem().textFrames.everyItem().getElements();
var resultArray = [];

for( var n=0; n<tf.length; n++ )
{
	resultArray[n] = tf[n].parentPage.name +", "+ tf[n].parent.toString();
};

alert
(
	resultArray.join("\r")
);

 

 

Run code 2 on the same document.

Now the text frame on one of the pages of parent spread A is detected. Thus the alert message should look a bit different:

A, [object MasterSpread]

 

Code 2

 

var tf = app.documents[0].masterSpreads.everyItem().pages.everyItem().textFrames.everyItem().getElements();
var resultArray = [];

for( var n=0; n<tf.length; n++ )
{
	resultArray[n] = tf[n].parentPage.name +", "+ tf[n].parent.toString();
};

alert
(
	resultArray.join("\r")
);

 

 

If you see A, [object MasterSpread] also with code 1 in the alert, you have a serious problem with InDesign or your particular document.

 

FWIW: I cannot see a change in behavior with my German InDesign 2023 version 18.3.0 on Windows 10.

All results like expected. Rob's code should work:

 

 

var tf = d.pages.everyItem().textFrames.everyItem().getElements();

 

 

Regards,
Uwe Laubender
( Adobe Community Expert )

 

Votes

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 ,
Jun 29, 2023 Jun 29, 2023

Copy link to clipboard

Copied

Votes

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 ,
Jun 29, 2023 Jun 29, 2023

Copy link to clipboard

Copied

LATEST

I actually re-test the following code and it seems to work - thanks to everybody for the success! I hope it could be useful for someone else.

var d = app.activeDocument
var tf = d.pages.everyItem().textFrames.everyItem().getElements();


var fc, cv, vn;
var ca= []
for (var i = 0; i < tf.length; i++){
    cv = tf[i].contents.split(",");  
    if (cv.length == 3 || cv.length == 4) {
        for (var n = 0; n < cv.length; n++){
            ca.push(Number(cv[n]))
        };   
        vn=0
        for (var x in ca) {
            vn += ca[x]
        }
        if (ca.length == 3) {
            fc = makeSwatch(d, ca.toString())
            fc.properties = {space:ColorSpace.RGB, model:ColorModel.PROCESS, colorValue:ca}
            tf[i].fillColor = fc;
            tf[i].contents = "";
            tf[i].contentType = ContentType.UNASSIGNED;
        } 
        if (ca.length == 4) {
            fc = makeSwatch(d, ca.toString())
            fc.properties = {space:ColorSpace.CMYK, model:ColorModel.PROCESS, colorValue:ca}
            tf[i].fillColor = fc;
            tf[i].contents = "";
            tf[i].contentType = ContentType.UNASSIGNED;
        } 
    } 
    ca = [];
};   


/**
* Makes a new named Swatch 
* @ param the document to add the color to 
* @ param color name 
* @ return the new swatch 
*/

function makeSwatch(d, n){
    if (d.colors.itemByName(n).isValid) {
        return d.colors.itemByName(n);
    } else {
        return d.colors.add({name:n});
    }
}

 

 

Votes

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