Skip to main content
Known Participant
January 15, 2025
Answered

save only one fontFamilyName in a dropdownlist.

  • January 15, 2025
  • 3 replies
  • 2088 views

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);

 

 

Correct answer m1b

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

3 replies

m1b
Community Expert
m1bCommunity ExpertCorrect answer
Community Expert
January 15, 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 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

raldraldAuthor
Known Participant
January 15, 2025

@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. 

m1b
Community Expert
Community Expert
January 15, 2025

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

Legend
January 15, 2025

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.

raldraldAuthor
Known Participant
January 15, 2025

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 ... 

Anantha Prabu G
Legend
January 15, 2025

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,PrabuDesign smarter, faster, and bolder with InDesign scripting.
Anantha Prabu G
Legend
January 15, 2025

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,PrabuDesign smarter, faster, and bolder with InDesign scripting.
raldraldAuthor
Known Participant
January 15, 2025

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.