Mit Drop-down-Chips arbeiten

Mit der Google Docs API können Sie Drop-down-Chips in Google Docs-Dokumenten programmatisch erstellen, einfügen, aktualisieren, lesen und verwalten.

Was sind Drop-down-Chips?

Mit Drop-down-Chips in Google Docs können Nutzer ein interaktives, anpassbares Auswahlmenü direkt im Dokumenttext verwenden. Nutzer können auf einen Drop-down-Chip klicken, um aus einer vordefinierten Liste von Optionen auszuwählen, die jeweils einen eigenen Anzeigetext und eine eigene Farbgestaltung haben. Drop-down-Chips werden häufig für die Projektverfolgung, Statusupdates, Überprüfungs-Workflows und Genehmigungsphasen verwendet.

Mit der Docs API haben Sie folgende Möglichkeiten:

  • Sie können wiederverwendbare Drop-down-Vorlagen mit benutzerdefinierten Titeln, Optionsnamen und Farben definieren.
  • Fügen Sie Drop-down-Chips an einer gültigen Zeichenposition ein.
  • Aktualisiert die ausgewählte Option einer einzelnen Drop-down-Chip-Instanz.
  • Sie können die Definitionen von freigegebenen Drop-downs direkt bearbeiten und alle verweisenden Chips werden gleichzeitig aktualisiert.
  • Optionen sicher ersetzen oder entfernen, ohne die referenzielle Integrität der vorhandenen Chips zu beeinträchtigen.
  • Nicht verwendete Drop-down-Vorlagen löschen

Architektur: Definitionen und Instanzen

In der Docs API haben Drop-down-Chips Definitionen und Instanzen. In einer Definition werden Optionen für eine Drop-down-Instanz festgelegt. Eine Drop-down-Instanz ist ein Drop-down-Menü, mit dem Nutzer interagieren können. Informationen zu den ausgewählten Optionen werden gespeichert.

Bei der Docs API wird die Konfiguration der Drop-down-Vorlage von den Inline-Drop-down-Chip-Instanzen getrennt:

  1. DropdownDefinition: Eine Vorlage auf Tab-Ebene, die den Drop-down-Titel und die Sammlung der auswählbaren Optionen (DropdownOption) definiert. Sie befindet sich nicht an einem bestimmten Zeichen-Offset im Dokument, sondern wird in der Definitionszuordnung des Tabs gespeichert: document.tabs[].documentTab.dropdownDefinitions.
  2. Dropdown: Eine einzelne Chip-Instanz, die inline in ein Absatzelement (ParagraphElement.dropdown) eingebettet ist. Jede Dropdown-Instanz verweist auf ein dropdownDefinitionId und speichert ein eigenes aktives selectedOptionId.

Wenn Sie ein DropdownDefinition ändern, z.B. eine Option hinzufügen oder den Titel umbenennen, werden alle verweisenden Chips auf dem Tab aktualisiert, ohne dass jedes einzelne Element aktualisiert werden muss.

Jede Dropdown-Instanz erfasst ihre eigenen selectedOptionId. Wenn Sie den ausgewählten Wert eines einzelnen Chips ändern, wirkt sich das nur auf diese bestimmte Instanz aus.

ID-Format und Validierungsregeln

Von Nutzern bereitgestellte IDs müssen strengen Format-, Präfix- und Längenvorgaben entsprechen:

ID Obligatorisches Präfix Regulärer Ausdruck für Validierung Längenbeschränkung Beispiel
ID der Drop-down-Definition (dropdownDefinitionId) kix. ^kix\.[a-zA-Z0-9_-]{2,14}$ 6–18 Zeichen kix.review_status
ID der Drop-down-Option (optionId) dropdownItem. ^dropdownItem\.[a-zA-Z0-9_-]{2,14}$ 15–27 Zeichen dropdownItem.pending

Vom Nutzer bereitgestellte IDs generieren

Verwenden Sie die folgenden Hilfsfunktionen, um IDs zu generieren, die den Anforderungen für das obligatorische Präfix und den regulären Ausdruck entsprechen. Diese Helfer generieren alphanumerische Suffixe in Kleinbuchstaben im Base-36-Format, die dem Format entsprechen, das von der Google Docs-Benutzeroberfläche generiert wird:

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

Drop-down-Chips erstellen und einfügen

Erstellung in einem Batch (empfohlen)

Das effizienteste Muster kombiniert CreateDropdownDefinitionRequest und InsertDropdownRequest in einem documents.batchUpdate-Aufruf.

Im folgenden Codebeispiel wird eine Drop-down-Definition für den „Prüfstatus“ mit drei farbcodierten Optionen erstellt, wobei benutzerdefinierte IDs verwendet werden. Außerdem wird eine Instanz am Ende des Dokuments eingefügt:

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

Regeln und Limits für die Drop-down-Validierung

Beim Erstellen oder Ändern von Drop-down-Definitionen gelten die folgenden Einschränkungen:

  • Anzahl der Optionen: Eine Drop-down-Definition muss zwischen 2 und 50 Optionen enthalten.
  • Länge des Titels: Die Definition title darf nicht leer sein und darf nicht länger als 200 Zeichen sein.
  • Länge des Anzeigewerts: Die displayValue jeder Option darf nicht leer sein und darf maximal 200 Zeichen umfassen.
  • Option Styling: In DropdownOption.textStyle werden nur foregroundColor und backgroundColor unterstützt. Wenn Sie andere Stileigenschaften festlegen, wird der Fehler 400 Bad Request zurückgegeben.
  • Standardauswahl: Wenn in InsertDropdownRequest selectedOptionId weggelassen wird, wird für den Chip standardmäßig die erste in DropdownDefinition definierte Option verwendet.

Auswahl eines einzelnen Drop-down-Chips aktualisieren

Wenn Sie die ausgewählte Option einer vorhandenen Drop-down-Chip-Instanz ändern möchten, ohne die Vorlage oder andere Chips zu ändern, verwenden Sie UpdateDropdownPropertiesRequest:

  • dropdownId: (Erforderlich) Die ID der spezifischen Drop-down-Chip-Instanz, die aktualisiert werden soll.
  • tabId: Die ID des Tabs, der das Drop-down-Menü enthält. Wenn nicht angegeben, wird standardmäßig der erste Tab verwendet.
  • fields: Legen Sie "selectedOptionId" fest.

Im folgenden Codebeispiel wird die aktive Auswahl eines Drop-down-Chips auf "dropdownItem.approved" aktualisiert:

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

Drop-down-Definitionen und -Optionen aktualisieren

Wenn Sie die Vorlage selbst ändern möchten (Titel, Optionsliste, Anzeigelabels oder Farben), verwenden Sie UpdateDropdownDefinitionPropertiesRequest. Wenn Sie eine Definition aktualisieren, werden alle Drop-down-Chips, die darauf verweisen, automatisch auf dem Tab aktualisiert.

Vollständiger Ersatz der Liste für Optionen

Wenn dropdownDefinitionProperties.options in der Maske fields enthalten ist, wird in der Anfrage ein vollständiger Listenersatz durchgeführt. Sie müssen die vollständige Liste der Optionen in der gewählten Reihenfolge angeben. Der Server vergleicht die eingehende Liste mit der aktuellen Definition:

  • Neue Option: Wenn Sie eine Option ohne optionId oder mit einem neuen nutzerdefinierten optionId hinzufügen, wird sie in die Definition aufgenommen.
  • Aktualisierte Option: Wenn Sie eine vorhandene optionId mit geänderten displayValue- oder textStyle-Werten angeben, wird die Option aktualisiert.
  • Neu sortierte Optionen: Die Optionsliste wird in der genauen Reihenfolge gespeichert, die in der Anfrage angegeben wurde.
  • Gelöschte Option: Wenn Sie ein vorhandenes optionId weglassen, wird die entsprechende Option aus der Definition gelöscht.

Referenzielle Integrität und Ersetzen von Optionen

Wenn eine Option, die gelöscht wird, in einem Drop-down-Chip im Dokument ausgewählt ist, müssen Sie eine Zuordnung in selectedOptionIdReplacements (map<string, string>) angeben. Die Schlüssel sind die IDs der Optionen, die gelöscht werden, und die Werte sind die IDs der Ersatzoptionen.

Im folgenden Codebeispiel wird gezeigt, wie eine Drop-down-Definition mit Optionsersetzungen aktualisiert wird:

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

Drop-down-Definition löschen

Wenn Sie eine nicht verwendete Drop-down-Vorlage entfernen möchten, verwenden Sie DeleteDropdownDefinitionRequest.

Im folgenden Codebeispiel wird gezeigt, wie eine Drop-down-Definition gelöscht wird:

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

Fehlerbehandlung und Fehlerbehebung

Häufige Fehlerbedingungen und Lösungen:

Statuscode Ursache Auflösung
400 INVALID_ARGUMENT Ungültiges ID-Präfix oder ungültiges Format für regulären Ausdruck. dropdownDefinitionId muss mit kix. beginnen (6–18 Zeichen) und optionId mit dropdownItem. (15–27 Zeichen).
400 INVALID_ARGUMENT Die Anzahl der Optionen liegt außerhalb des zulässigen Bereichs. Eine Drop-down-Definition muss zwischen 2 und 50 Optionen enthalten.
400 INVALID_ARGUMENT Der Titel oder Anzeigewert ist leer oder enthält mehr als 200 Zeichen. Geben Sie einen nicht leeren String mit 1 bis 200 Zeichen an.
400 INVALID_ARGUMENT Nicht unterstützte Textstileigenschaft in der Option. In Drop-down-Optionen werden nur foregroundColor und backgroundColor unterstützt. Entfernen Sie Schriftart, Größe oder andere Attribute.
400 INVALID_ARGUMENT Fehlende Zuordnung für den Ersatz von Optionen beim Löschen. Wenn Sie eine Option löschen, die von einem Chip ausgewählt wird, geben Sie in selectedOptionIdReplacements einen gültigen Ersatz an.
400 INVALID_ARGUMENT Es wurde versucht, eine Definition zu löschen, die verwendet wird. Löschen Sie alle Drop-down-Chip-Instanzen, die auf die Definition verweisen, oder ändern Sie das Ziel, bevor Sie die Definition löschen.
400 INVALID_ARGUMENT Doppelte vom Nutzer bereitgestellte ID. Achten Sie darauf, dass die von Nutzern bereitgestellten IDs auf dem Dokumenttab eindeutig sind.