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

save only one fontFamilyName in a dropdownlist.

Explorer ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

Hi

I'm writing a script with the help of copilot.

I want to save only one fontFamilyName in a dropdownlist.

How can I do that?

 

#target indesign

// Create a new dialog
var dialog = new Window("dialog", "Choose a Font");

// Add a dropdown list for font family
var fontFamilyDropdown = dialog.add("dropdownlist", undefined, []);
fontFamilyDropdown.size = [200, 30];

// Add a dropdown list for font style
var fontStyleDropdown = dialog.add("dropdownlist", undefined, []);
fontStyleDropdown.size = [200, 30];

// Populate the font family dropdown list with all font families
var allfonts = app.fonts.everyItem().getElements();

for (var i = 0; i < allfonts.length; i++) {    

    fontFamilyDropdown.add("item", allfonts[i].fontFamily);  
 
}

// Set the first item as the default selection
fontFamilyDropdown.selection = 0;

// Function to update the font style dropdown based on the selected font family
function updateFontStyleDropdown() {
    fontStyleDropdown.removeAll();
    var selectedFontFamily = fontFamilyDropdown.selection.text;
    var fontStyles = [];
    for (var i = 0; i < allfonts.length; i++) {
        if (allfonts[i].fontFamily === selectedFontFamily) {
            fontStyles.push(allfonts[i].fontStyleName);
        }
    }
    for (var j = 0; j < fontStyles.length; j++) {
        fontStyleDropdown.add("item", fontStyles[j]);
    }
    fontStyleDropdown.selection = 0;
}

// Update the font style dropdown when a new font family is selected
fontFamilyDropdown.onChange = updateFontStyleDropdown;

// Add a button to close the dialog
dialog.add("button", undefined, "OK");

// Initial population of font style dropdown
updateFontStyleDropdown();

// Show the dialog
dialog.show();

// Get the selected font family and style
var selectedFontFamily = fontFamilyDropdown.selection.text;
var selectedFontStyle = fontStyleDropdown.selection.text;
alert("You selected: " + selectedFontFamily + " - " + selectedFontStyle);

 

 

TOPICS
Scripting

Views

425

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 1 Correct answer

Community Expert , Jan 14, 2025 Jan 14, 2025

Hi @raldrald, one possible solution could be to collect only the unique font family names. Try this way:

// Create a new dialog
var dialog = new Window("dialog", "Choose a Font");

// Add a dropdown list for font family
var fontFamilyDropdown = dialog.add("dropdownlist", undefined, []);
fontFamilyDropdown.size = [200, 30];

// Add a dropdown list for font style
var fontStyleDropdown = dialog.add("dropdownlist", undefined, []);
fontStyleDropdown.size = [200, 30];

// Populate the font family drop
...

Votes

Translate

Translate
Engaged ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

Hi @raldrald 
It sounds like you want to ensure that your dropdown list contains only a single, specific font family name, rather than a list of all available font families. This means that when the user interacts with the dropdown, they will only see and be able to select that one particular font family.

Thanks,
Prabu
Design smarter, faster, and bolder with InDesign scripting.

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
Explorer ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

A family name is repeated in the dropdownlist as many times as the number of font styles,

but I want to show only one font family name per a font. 

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
Guide ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

Fonts are complicated.

The AI is missing that the font family is not distinct within the fonts collection.

Ask it to produce a distinct set of font family names, sort that and populate the family dropdown from that.

 

If you intend to get closer to the UI: this still misses document fonts, also the edge case where InDesign under the hood uses an extended concept of font families called font groups - multiple font groups can have the same family name but differ in font type.

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
Explorer ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

At first copilot told me this, but  it took too long and didn't stop. 

 

// Populate the font family dropdown list with all font families

var fontFamilies = app.fonts.everyItem().name; 

for( var i = 0; i < fontFamilies.length; i++){

     fontFamilyDropdown.add("item", fontFamilies[i]);

}

 

 

so I've changed like this. 

 

// Populate the font family dropdown list with all font families

var allfonts = app.fonts.everyItem().getElements();

for (var i = 0; i < allfonts.length; i++) {    

    fontFamilyDropdown.add("item", allfonts[i].fontFamily);  

 }

 

I'm new to scripting so I don't know what collection means exactly ... 

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
Engaged ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

Hi @raldrald 
May i ask what purpose you have in mind for creating these scripts? it would help me better understand your needs and provide more relevent suggestions 

Thanks,
Prabu
Design smarter, faster, and bolder with InDesign scripting.

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
Explorer ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

Hi, @Anantha Prabu G  Thank you for your reply.

I have a problem with too many fonts when designing.

So I want to manage fonts by design style.

Fonts are classified by design style, and when a font is added, I want to classify the added font by design style. 

And I want to create text frames for the same content by design style to see the detailed difference.

I'm starting to study scripts, so I'm trying to make it little by little while learning the script. 

I'm learning a lot from the community. Thank you all. 

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
Engaged ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

Is this what you expect?
Screen Shot 2025-01-15 at 1.01.05 AM.pngexpand image

Thanks,
Prabu
Design smarter, faster, and bolder with InDesign scripting.

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
Explorer ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

Screenshot 2025-01-15 at 4.18.22 PM.pngexpand image

 

I hope this way.

I want the same font family names show one  time. 

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
Guide ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

Collection is the term for these plural objects "fonts", "documents" that behave similar to an array, where you also have the item(), itemByName(), everyItem() and so forth functions.

In the quoted AI code it should have used the fontFamily property instead of the name property.

 

Outcome is similar though to your change, you still have to make the result array distinct and sort, or convince the AI to do that.

 

Problem with AIs is they produce "clean" modern javascript using bells and whistles that ExtendScript does not have - a Set class, forEach() and so forth. So if you're into this to learn scripting, find matching older books and follow them. Otherwise if this is an exercise how far AI can get you, better switch to InDesign's UXPScript which is modern Javascript. In that case you have to forget about ScriptUI (all your UI code above) and work more HTML-ish.

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
Explorer ,
Jan 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

HI, @Dirk Becker 

Thank you for you explanation about collection. 

I have heard about collection, but I'm still hard to understand the exact difference and usage from array.  I hope I can figure out someday. 

As you said, AI tells me in a modern javascript way, so I get lost a lot every time, 

but it is too hard for a beginner like me to start UXP... 

So I appreciate  this commutity a lot. 

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
Guide ,
Jan 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

You can invoke UXPScript from ExtendScript.

var fontFamilies = app.doScript('require("uxp").script.setResult([...new Set(require("indesign").app.fonts.everyItem().fontFamily)])',ScriptLanguage.UXPSCRIPT)

 

require("uxp").script.setResult() is the convoluted UXP way to return a value to doScript.

require("indesign").app is the way to access the app object.

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
Explorer ,
Jan 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

Thank you @Dirk Becker , 

I'll remember it and use it later. 

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 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

That's really cool Dirk! I didn't know that sort of thing was possible with doScript. Interesting that the UXP version of fonts.everyItem().fontFamily gives unique results. I had assumed the "DOM stuff" was going to be much the same between ExtendScript and UXP. Have you observed that things are generally improved in UXP?

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
Guide ,
Jan 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

UXPScript yields the same results, its modern javascript just has a very short way to get the unique values.

Set(array) creates a Set (what you did with the object) automatically removing duplicates.

[... mySet] creates the array and initializes it using spread operator.

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 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

Oh right, I see now. I didn't read it properly. Thanks for responding.

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
Guide ,
Jan 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

That doScript still feels slow.

In a larger project I've turned to using plug-in code to query the fonts.

One trick to speed up things: when you build your unique map (actually not a set), assign an array instead of the true. Then push all found font styles into that array as they come along on the first turn.

 

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 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

LATEST

Interesting. Yes good advice about collecting the styles at the same loop!

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 14, 2025 Jan 14, 2025

Copy link to clipboard

Copied

Hi @raldrald, one possible solution could be to collect only the unique font family names. Try this way:

// Create a new dialog
var dialog = new Window("dialog", "Choose a Font");

// Add a dropdown list for font family
var fontFamilyDropdown = dialog.add("dropdownlist", undefined, []);
fontFamilyDropdown.size = [200, 30];

// Add a dropdown list for font style
var fontStyleDropdown = dialog.add("dropdownlist", undefined, []);
fontStyleDropdown.size = [200, 30];

// Populate the font family dropdown list with all font families
var allfonts = app.fonts.everyItem().getElements();

// gather only unique font family names
var allFontFamilies = [],
    unique = {};

for (var i = 0; i < allfonts.length; i++) {
    if (true !== unique[allfonts[i].fontFamily]) {
        allFontFamilies.push(allfonts[i].fontFamily);
        unique[allfonts[i].fontFamily] = true;
    }
}

for (var i = 0; i < allFontFamilies.length; i++) {
    fontFamilyDropdown.add("item", allFontFamilies[i]);
}

// Set the first item as the default selection
fontFamilyDropdown.selection = 0;

// Function to update the font style dropdown based on the selected font family
function updateFontStyleDropdown() {
    fontStyleDropdown.removeAll();
    var selectedFontFamily = fontFamilyDropdown.selection.text;
    var fontStyles = [];
    for (var i = 0; i < allfonts.length; i++) {
        if (allfonts[i].fontFamily === selectedFontFamily) {
            fontStyles.push(allfonts[i].fontStyleName);
        }
    }
    for (var j = 0; j < fontStyles.length; j++) {
        fontStyleDropdown.add("item", fontStyles[j]);
    }
    fontStyleDropdown.selection = 0;
}

// Update the font style dropdown when a new font family is selected
fontFamilyDropdown.onChange = updateFontStyleDropdown;

// Add a button to close the dialog
dialog.add("button", undefined, "OK");

// Initial population of font style dropdown
updateFontStyleDropdown();

// Show the dialog
dialog.show();

// Get the selected font family and style
var selectedFontFamily = fontFamilyDropdown.selection.text;
var selectedFontStyle = fontStyleDropdown.selection.text;
alert("You selected: " + selectedFontFamily + " - " + selectedFontStyle);

I only changed a little section where I wrote "gather only unique font family names" and the next approx  12 lines.

- Mark

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
Explorer ,
Jan 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

@m1b  

Thank you very much! 

It woks well as I wanted.

By the way, may I ask what { } is? 

I know [ ] means making array, 

but this is my first time seeing { } in a script so I'm curious about what it is. 

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 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

You're welcome!

 

{ } is an empty Object. You can read about it here and also this post might be a great one to read. You can make one like this:

var me = {
    name: 'Mark',
    username: 'm1b'
};

$.writeln('My name is ' + me.name);

// can also access like this:
$.writeln('My username is ' + me['username']); // this is how I use it in your script

// add to the object
me.lovesScripting = true;

 

I used an Object because I can check if something is unique by accessing the object's key—if the key exists already, then it isn't unique and we don't collect that font family.

- Mark

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
Explorer ,
Jan 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

Thank you @m1b ,

I'll study more. Thank you for your reference links, too!

I'm learning a lot from your script. 

 

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
Explorer ,
Jan 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer 

 

I've searched the { }, and I understand it a little. 

Thank you, m1b. 

I learned something new today. 

 

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 15, 2025 Jan 15, 2025

Copy link to clipboard

Copied

Excellent! Good on you!

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