プルダウン チップを使用する

Google Docs API を使用すると、Google ドキュメント内のドロップダウン チップの作成、挿入、更新、読み取り、管理をプログラムで行うことができます。

プルダウン チップとは

Google ドキュメントのプルダウン チップを使用すると、ドキュメントのテキスト内にインタラクティブでカスタマイズ可能な選択メニューを挿入できます。プルダウン チップをクリックすると、事前定義されたオプションのリストが表示されます。各オプションには、独自の表示テキストと色のスタイルが設定されています。プルダウン チップは、プロジェクトの追跡、ステータスの更新、レビュー ワークフロー、承認ステージでよく使用されます。

Docs API を使用すると、次のことができます。

  • カスタマイズしたタイトル、オプション名、色を使用して、再利用可能なプルダウン テンプレートを定義します。
  • 有効な文字位置にプルダウン チップを挿入します。
  • 個々のドロップダウン チップ インスタンスの選択されたオプションを更新します。
  • 共有ドロップダウンの定義をその場で変更し、参照しているすべてのチップを同時に更新します。
  • 既存のチップ全体で参照整合性を維持しながら、オプションを安全に置き換えたり、廃止したりできます。
  • 使用されていないプルダウン テンプレートを削除します。

アーキテクチャ: 定義とインスタンス

Docs API では、プルダウン チップに定義とインスタンスがあります。定義では、プルダウン インスタンスのオプションを設定します。ドロップダウン インスタンスは、ユーザーが操作できるドロップダウンで、選択に関する情報を保存します。

Docs API では、プルダウン テンプレートの構成がインライン プルダウン チップ インスタンスから分離されています。

  1. DropdownDefinition: プルダウンのタイトルと選択可能な選択肢のコレクション(DropdownOption)を定義するタブレベルのテンプレート。ドキュメント内の特定の文字オフセットには存在せず、タブの定義マップ(document.tabs[].documentTab.dropdownDefinitions)に保存されます。
  2. Dropdown: 段落要素(ParagraphElement.dropdown)内にインラインで埋め込まれた個々のチップ インスタンス。各ドロップダウン インスタンスは dropdownDefinitionId を参照し、独自のアクティブな selectedOptionId を保存します。

DropdownDefinition を変更すると(オプションの追加やタイトルの名前変更など)、タブ全体で参照されているすべてのチップが更新され、個々の要素を更新する必要はありません。

各 Dropdown インスタンスは独自の selectedOptionId を追跡します。個々のチップの選択値を変更しても、その特定のインスタンスにのみ影響します。

ID の形式と検証ルール

ユーザー提供 ID は、厳格な形式、プレフィックス、長さの仕様に準拠する必要があります。

識別子 必須の接頭辞 検証の正規表現 長さの上限 例
プルダウン定義 ID(dropdownDefinitionId) kix. ^kix\.[a-zA-Z0-9_-]{2,14}$ 6 ~ 18 文字 kix.review_status
プルダウン オプション ID(optionId) dropdownItem. ^dropdownItem\.[a-zA-Z0-9_-]{2,14}$ 15 ~ 27 文字 dropdownItem.pending

ユーザー提供の ID を生成する

必須の接頭辞と正規表現の要件に準拠した ID を生成するには、次のヘルパー関数を使用します。これらのヘルパーは、Google ドキュメント UI で生成される形式と一致する、小文字の base-36 英数字の接尾辞を生成します。

Python

import random
import string

def generate_dropdown_definition_id(suffix_len: int = 8) -> str:
    """Generates a valid user-provided DropdownDefinition ID (6-18 chars, starting with 'kix.')."""
    chars = string.ascii_lowercase + string.digits
    suffix = "".join(random.choices(chars, k=max(2, min(suffix_len, 14))))
    return f"kix.{suffix}"

def generate_dropdown_option_id(suffix_len: int = 8) -> str:
    """Generates a valid user-provided DropdownOption ID (15-27 chars, starting with 'dropdownItem.')."""
    chars = string.ascii_lowercase + string.digits
    suffix = "".join(random.choices(chars, k=max(2, min(suffix_len, 14))))
    return f"dropdownItem.{suffix}"

Java

import java.security.SecureRandom;

public final class DropdownIdGenerator {
  private static final String BASE36_CHARS =
      "abcdefghijklmnopqrstuvwxyz0123456789";
  private static final SecureRandom RANDOM = new SecureRandom();

  private DropdownIdGenerator() {}

  /** Generates a valid user-provided DropdownDefinition ID (6-18 chars, starting with "kix."). */
  public static String generateDefinitionId(int suffixLength) {
    int length = Math.max(2, Math.min(suffixLength, 14));
    StringBuilder sb = new StringBuilder("kix.");
    for (int i = 0; i < length; i++) {
      sb.append(BASE36_CHARS.charAt(RANDOM.nextInt(BASE36_CHARS.length())));
    }
    return sb.toString();
  }

  /** Generates a valid user-provided DropdownOption ID (15-27 chars, starting with "dropdownItem."). */
  public static String generateOptionId(int suffixLength) {
    int length = Math.max(2, Math.min(suffixLength, 14));
    StringBuilder sb = new StringBuilder("dropdownItem.");
    for (int i = 0; i < length; i++) {
      sb.append(BASE36_CHARS.charAt(RANDOM.nextInt(BASE36_CHARS.length())));
    }
    return sb.toString();
  }
}

プルダウン チップを作成して挿入する

単一バッチ作成(推奨)

最も効率的なパターンでは、CreateDropdownDefinitionRequest と InsertDropdownRequest を 1 回の documents.batchUpdate 呼び出しで組み合わせます。

次のコードサンプルでは、ユーザーが指定した ID を使用して 3 つの選択肢を色分けした「Review Status」プルダウン定義を作成し、ドキュメントの末尾にインスタンスを挿入します。

Python

requests = [
    {
        "createDropdownDefinition": {
            "dropdownDefinition": {
                "dropdownDefinitionId": "kix.review_status",
                "dropdownDefinitionProperties": {
                    "title": "Review Status",
                    "options": [
                        {
                            "optionId": "dropdownItem.pending",
                            "displayValue": "Pending Review",
                            "textStyle": {
                                "backgroundColor": {
                                    "color": {"rgbColor": {"red": 0.99, "green": 0.90, "blue": 0.65}}
                                },
                                "foregroundColor": {
                                    "color": {"rgbColor": {"red": 0.45, "green": 0.30, "blue": 0.0}}
                                },
                            },
                        },
                        {
                            "optionId": "dropdownItem.approved",
                            "displayValue": "Approved",
                            "textStyle": {
                                "backgroundColor": {
                                    "color": {"rgbColor": {"red": 0.85, "green": 0.95, "blue": 0.85}}
                                },
                                "foregroundColor": {
                                    "color": {"rgbColor": {"red": 0.08, "green": 0.40, "blue": 0.15}}
                                },
                            },
                        },
                        {
                            "optionId": "dropdownItem.rejected",
                            "displayValue": "Needs Changes",
                            "textStyle": {
                                "backgroundColor": {
                                    "color": {"rgbColor": {"red": 0.98, "green": 0.84, "blue": 0.84}}
                                },
                                "foregroundColor": {
                                    "color": {"rgbColor": {"red": 0.65, "green": 0.10, "blue": 0.10}}
                                },
                            },
                        },
                    ],
                },
            }
        }
    },
    {
        "insertDropdown": {
            "endOfSegmentLocation": {},
            "dropdownDefinitionId": "kix.review_status",
            "selectedOptionId": "dropdownItem.pending",
        }
    },
]

result = service.documents().batchUpdate(
    documentId=DOCUMENT_ID,
    body={"requests": requests}
).execute()

Java

List<Request> requests = new ArrayList<>();

List<DropdownOption> options = Arrays.asList(
    new DropdownOption()
        .setOptionId("dropdownItem.pending")
        .setDisplayValue("Pending Review")
        .setTextStyle(new TextStyle()
            .setBackgroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.99f).setGreen(0.90f).setBlue(0.65f))))
            .setForegroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.45f).setGreen(0.30f).setBlue(0.0f))))),
    new DropdownOption()
        .setOptionId("dropdownItem.approved")
        .setDisplayValue("Approved")
        .setTextStyle(new TextStyle()
            .setBackgroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.85f).setGreen(0.95f).setBlue(0.85f))))
            .setForegroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.08f).setGreen(0.40f).setBlue(0.15f))))),
    new DropdownOption()
        .setOptionId("dropdownItem.rejected")
        .setDisplayValue("Needs Changes")
        .setTextStyle(new TextStyle()
            .setBackgroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.98f).setGreen(0.84f).setBlue(0.84f))))
            .setForegroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.65f).setGreen(0.10f).setBlue(0.10f))))));

DropdownDefinition definition = new DropdownDefinition()
    .setDropdownDefinitionId("kix.review_status")
    .setDropdownDefinitionProperties(new DropdownDefinitionProperties()
        .setTitle("Review Status")
        .setOptions(options));

requests.add(new Request().setCreateDropdownDefinition(
    new CreateDropdownDefinitionRequest().setDropdownDefinition(definition)));

requests.add(new Request().setInsertDropdown(
    new InsertDropdownRequest()
        .setEndOfSegmentLocation(new EndOfSegmentLocation())
        .setDropdownDefinitionId("kix.review_status")
        .setSelectedOptionId("dropdownItem.pending")));

BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest().setRequests(requests);
BatchUpdateDocumentResponse response = docsService.documents()
    .batchUpdate(DOCUMENT_ID, body)
    .execute();

プルダウンの入力規則と制限

プルダウン定義を作成または変更する際には、次の制約が適用されます。

  • 選択肢の数: プルダウンの定義には、2~50 個の選択肢が必要です。
  • タイトルの長さ: 定義 title は空にできません。また、200 文字を超えてはなりません。
  • 表示値の長さ: 各オプションの displayValue は空にできず、200 文字を超えてはなりません。
  • オプションのスタイル設定: DropdownOption.textStyle では foregroundColor と backgroundColor のみがサポートされています。他のスタイル プロパティを設定すると、400 Bad Request エラーが返されます。
  • デフォルトの選択: InsertDropdownRequest で selectedOptionId が省略されている場合、チップは DropdownDefinition で定義された最初のオプションにデフォルト設定されます。

個々のプルダウン チップの選択を更新する

既存のプルダウン チップ インスタンスの選択されたオプションを、テンプレートや他のチップを変更せずに変更するには、UpdateDropdownPropertiesRequest を使用します。

  • dropdownId:(必須)更新する特定のドロップダウン チップ インスタンスの ID。
  • tabId: プルダウンを含むタブの ID(省略した場合は最初のタブがデフォルト)。
  • fields: "selectedOptionId" に設定します。

次のコードサンプルでは、ドロップダウン チップのアクティブな選択を "dropdownItem.approved" に更新します。

Python

requests = [
    {
        "updateDropdownProperties": {
            "dropdownId": "kix.chip_abc1",
            "tabId": "t.0",
            "dropdownProperties": {
                "selectedOptionId": "dropdownItem.approved",
            },
            "fields": "selectedOptionId",
        }
    }
]

result = service.documents().batchUpdate(
    documentId=DOCUMENT_ID,
    body={"requests": requests}
).execute()

Java

List<Request> requests = new ArrayList<>();
requests.add(new Request().setUpdateDropdownProperties(
    new UpdateDropdownPropertiesRequest()
        .setDropdownId("kix.chip_abc1")
        .setTabId("t.0")
        .setDropdownProperties(new DropdownProperties()
            .setSelectedOptionId("dropdownItem.approved"))
        .setFields("selectedOptionId")));

BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest().setRequests(requests);
BatchUpdateDocumentResponse response = docsService.documents()
    .batchUpdate(DOCUMENT_ID, body)
    .execute();

プルダウンの定義とオプションを更新する

テンプレート自体(タイトル、オプション リスト、表示ラベル、色)を変更するには、UpdateDropdownDefinitionPropertiesRequest を使用します。定義を更新すると、タブ全体でその定義を参照しているすべてのプルダウン チップが自動的に更新されます。

オプションのリスト全体を置き換える

dropdownDefinitionProperties.options が fields マスクに含まれている場合、リクエストはリスト全体の置換を実行します。選択した順序でオプションの完全なリストを指定する必要があります。サーバーは、受信したリストと現在の定義を比較します。

  • 新しいオプション: optionId のないオプション(またはユーザーが指定した新しい optionId を含むオプション)を追加すると、定義に追加されます。
  • 更新されたオプション: 変更された displayValue または textStyle を含む既存の optionId を指定すると、そのオプションが更新されます。
  • オプションの順序変更: オプション リストは、リクエストで指定された順序で保存されます。
  • 削除されたオプション: 既存の optionId を省略すると、そのオプションが定義から削除されます。

参照整合性とオプションの置換

削除されるオプションがドキュメント内のいずれかのプルダウン チップで選択されている場合は、selectedOptionIdReplacements(map<string, string>)でマッピングを指定する必要があります。キーは削除されるオプションの ID で、値は置換オプションの ID です。

次のコードサンプルは、オプションの置換を使用してプルダウン定義を更新する方法を示しています。

Python

requests = [
    {
        "updateDropdownDefinitionProperties": {
            "dropdownDefinitionId": "kix.review_status",
            "tabId": "t.0",
            "dropdownDefinitionProperties": {
                "title": "Editorial Review Status",
                "options": [
                    {
                        "optionId": "dropdownItem.approved",
                        "displayValue": "Approved",
                        "textStyle": {
                            "backgroundColor": {
                                "color": {"rgbColor": {"red": 0.85, "green": 0.95, "blue": 0.85}}
                            },
                            "foregroundColor": {
                                "color": {"rgbColor": {"red": 0.08, "green": 0.40, "blue": 0.15}}
                            },
                        },
                    },
                    {
                        "optionId": "dropdownItem.rejected",
                        "displayValue": "Changes Requested",
                        "textStyle": {
                            "backgroundColor": {
                                "color": {"rgbColor": {"red": 0.98, "green": 0.84, "blue": 0.84}}
                            },
                            "foregroundColor": {
                                "color": {"rgbColor": {"red": 0.65, "green": 0.10, "blue": 0.10}}
                            },
                        },
                    },
                ],
            },
            "selectedOptionIdReplacements": {
                "dropdownItem.pending": "dropdownItem.rejected"
            },
            "fields": "title,options",
        }
    }
]

result = service.documents().batchUpdate(
    documentId=DOCUMENT_ID,
    body={"requests": requests}
).execute()

Java

List<DropdownOption> updatedOptions = Arrays.asList(
    new DropdownOption()
        .setOptionId("dropdownItem.approved")
        .setDisplayValue("Approved")
        .setTextStyle(new TextStyle()
            .setBackgroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.85f).setGreen(0.95f).setBlue(0.85f))))
            .setForegroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.08f).setGreen(0.40f).setBlue(0.15f))))),
    new DropdownOption()
        .setOptionId("dropdownItem.rejected")
        .setDisplayValue("Changes Requested")
        .setTextStyle(new TextStyle()
            .setBackgroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.98f).setGreen(0.84f).setBlue(0.84f))))
            .setForegroundColor(new OptionalColor().setColor(
                new Color().setRgbColor(new RgbColor().setRed(0.65f).setGreen(0.10f).setBlue(0.10f))))));

Map<String, String> replacements = new HashMap<>();
replacements.put("dropdownItem.pending", "dropdownItem.rejected");

List<Request> requests = new ArrayList<>();
requests.add(new Request().setUpdateDropdownDefinitionProperties(
    new UpdateDropdownDefinitionPropertiesRequest()
        .setDropdownDefinitionId("kix.review_status")
        .setTabId("t.0")
        .setDropdownDefinitionProperties(new DropdownDefinitionProperties()
            .setTitle("Editorial Review Status")
            .setOptions(updatedOptions))
        .setSelectedOptionIdReplacements(replacements)
        .setFields("title,options")));

BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest().setRequests(requests);
BatchUpdateDocumentResponse response = docsService.documents()
    .batchUpdate(DOCUMENT_ID, body)
    .execute();

プルダウンの定義を削除する

使用されていないドロップダウン テンプレートを削除するには、DeleteDropdownDefinitionRequest を使用します。

次のコードサンプルは、プルダウン定義を削除する方法を示しています。

Python

requests = [
    {
        "deleteDropdownDefinition": {
            "dropdownDefinitionId": "kix.review_status",
            "tabId": "t.0",
        }
    }
]

result = service.documents().batchUpdate(
    documentId=DOCUMENT_ID,
    body={"requests": requests}
).execute()

Java

List<Request> requests = new ArrayList<>();
requests.add(new Request().setDeleteDropdownDefinition(
    new DeleteDropdownDefinitionRequest()
        .setDropdownDefinitionId("kix.review_status")
        .setTabId("t.0")));

BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest().setRequests(requests);
BatchUpdateDocumentResponse response = docsService.documents()
    .batchUpdate(DOCUMENT_ID, body)
    .execute();

エラー処理とトラブルシューティング

一般的なエラー条件と解決策は次のとおりです。

ステータス コード 原因 解決策
400 INVALID_ARGUMENT ID 接頭辞または正規表現の形式が無効です。 dropdownDefinitionId が kix.(6 ~ 18 文字)で始まり、optionId が dropdownItem.(15 ~ 27 文字)で始まることを確認します。
400 INVALID_ARGUMENT オプションの数が範囲外です。 プルダウンの定義には 2 ~ 50 個のオプションを含める必要があります。
400 INVALID_ARGUMENT タイトルまたは表示値が空であるか、200 文字を超えています。 1 ~ 200 文字の空でない文字列を指定します。
400 INVALID_ARGUMENT オプションでサポートされていないテキスト スタイル プロパティ。 プルダウン オプションでは、foregroundColor と backgroundColor のみがサポートされています。フォント、サイズ、その他の属性を削除します。
400 INVALID_ARGUMENT 削除時にオプションの置換マッピングがない。 チップで選択されているオプションを削除する場合は、selectedOptionIdReplacements で有効な代替オプションを指定します。
400 INVALID_ARGUMENT 使用中の定義を削除しようとしました。 定義を削除する前に、その定義を参照しているすべてのドロップダウン チップ インスタンスを削除するか、ターゲットを変更します。
400 INVALID_ARGUMENT ユーザー指定の ID が重複しています。 ユーザー指定の ID がドキュメント タブ内で一意であることを確認します。