L'API Google Docs ti consente di creare, inserire, aggiornare, leggere e gestire in modo programmatico i chip con elenco a discesa all'interno dei documenti Google Docs.
Che cosa sono i chip con elenco a discesa?
I chip con elenco a discesa in Documenti Google offrono agli utenti un menu di selezione interattivo e personalizzabile in linea con il testo del documento. Gli utenti possono fare clic su un chip con elenco a discesa per selezionare da un elenco predefinito di opzioni, ognuna con il proprio testo visualizzato e stile di colore. I chip con elenco a discesa vengono spesso utilizzati per il monitoraggio dei progetti, gli aggiornamenti di stato, i flussi di lavoro di revisione e le fasi di approvazione.
Tramite l'API Documenti, puoi:
- Definisci modelli di menu a discesa riutilizzabili con titoli, nomi delle opzioni e colori personalizzati.
- Inserisci i chip con elenco a discesa in una posizione valida per i caratteri.
- Aggiorna l'opzione selezionata di una singola istanza di chip con elenco a discesa.
- Modifica le definizioni dei menu a discesa condivisi in linea, aggiornando contemporaneamente tutti i chip di riferimento.
- Sostituisci o ritira in sicurezza le opzioni mantenendo l'integrità referenziale nei chip esistenti.
- Elimina i modelli di menu a discesa inutilizzati.
Architettura: definizioni e istanze
Nell'API Docs, i chip con elenco a discesa hanno definizioni e istanze. Una definizione imposta le opzioni per un'istanza del menu a discesa. Un'istanza di menu a discesa è un menu a discesa con cui le persone possono interagire e che salva le informazioni sulle selezioni.
L'API Docs separa la configurazione del modello di menu a discesa dalle istanze di chip con elenco a discesa incorporato:
- DropdownDefinition: un modello a livello di scheda che definisce il titolo del menu a discesa e la raccolta di scelte selezionabili (
DropdownOption). Non si trova in un offset di caratteri specifico nel documento, ma viene memorizzato nella mappa di definizione della scheda:document.tabs[].documentTab.dropdownDefinitions. - Menu a discesa: una singola istanza di chip incorporata in linea all'interno di un elemento paragrafo (
ParagraphElement.dropdown). Ogni istanza di menu a discesa fa riferimento a undropdownDefinitionIde memorizza il proprioselectedOptionIdattivo.
La modifica di un DropdownDefinition (ad es. l'aggiunta di un'opzione o la ridenominazione del titolo) aggiorna tutti i chip di riferimento nella scheda senza richiedere aggiornamenti a ogni singolo elemento.
Ogni istanza di Dropdown tiene traccia del proprio selectedOptionId. La modifica del valore selezionato di un singolo chip influisce solo su quella specifica istanza.
Regole di convalida e formato dell'ID
Gli ID forniti dagli utenti devono rispettare specifiche rigorose in termini di formato, prefisso e lunghezza:
| Identificatore | Prefisso obbligatorio | Espressione regolare di convalida | Limite di lunghezza | Esempio |
|---|---|---|---|---|
ID definizione menu a discesa (dropdownDefinitionId) |
kix. |
^kix\.[a-zA-Z0-9_-]{2,14}$ |
6-18 caratteri | kix.review_status |
ID opzione menu a discesa (optionId) |
dropdownItem. |
^dropdownItem\.[a-zA-Z0-9_-]{2,14}$ |
15-27 caratteri | dropdownItem.pending |
Generare ID forniti dall'utente
Per generare ID che rispettino i requisiti obbligatori relativi al prefisso e all'espressione regolare, utilizza le seguenti funzioni helper. Questi helper generano suffissi alfanumerici in base 36 minuscoli, corrispondenti al formato generato dall'interfaccia utente di Documenti Google:
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();
}
}
Creare e inserire chip con elenco a discesa
Creazione di un singolo batch (consigliata)
Il pattern più efficiente combina CreateDropdownDefinitionRequest e InsertDropdownRequest in una singola chiamata documents.batchUpdate.
Il seguente esempio di codice crea una definizione del menu a discesa "Stato revisione" con tre scelte codificate a colori utilizzando gli ID forniti dall'utente e inserisce un'istanza alla fine del documento:
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();
Regole di convalida e limiti dei menu a discesa
Quando crei o modifichi le definizioni dei menu a discesa, si applicano i seguenti vincoli:
- Conteggio opzioni: una definizione di menu a discesa deve avere un numero di opzioni compreso tra 2 e 50.
- Lunghezza titolo: la definizione
titlenon può essere vuota e non deve superare i 200 caratteri. - Lunghezza valore visualizzato: il
displayValuedi ogni opzione non può essere vuoto e non deve superare i 200 caratteri. - Stile opzione: in
DropdownOption.textStylesono supportati soloforegroundColorebackgroundColor. L'impostazione di altre proprietà di stile restituisce un errore400 Bad Request. - Selezione predefinita: in
InsertDropdownRequest, seselectedOptionIdviene omesso, il chip viene impostato per impostazione predefinita sulla prima opzione definita inDropdownDefinition.
Aggiornare la selezione di un singolo chip con elenco a discesa
Per modificare l'opzione selezionata di un'istanza di chip con elenco a discesa esistente senza alterare il modello o altri chip, utilizza UpdateDropdownPropertiesRequest:
dropdownId: (obbligatorio) l'ID dell'istanza specifica del chip con elenco a discesa da aggiornare.tabId: l'ID della scheda contenente il menu a discesa (per impostazione predefinita, la prima scheda se omesso).fields: impostato su"selectedOptionId".
Il seguente esempio di codice aggiorna la selezione attiva di un chip con elenco a discesa a "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();
Aggiornare le definizioni e le opzioni dei menu a discesa
Per modificare il modello stesso (titolo, elenco delle opzioni, etichette di visualizzazione o colori), utilizza UpdateDropdownDefinitionPropertiesRequest. L'aggiornamento di una definizione aggiorna automaticamente tutti i chip con elenco a discesa che la fanno riferimento nella scheda.
Sostituzione dell'elenco completo per le opzioni
Quando dropdownDefinitionProperties.options è incluso nella maschera fields, la richiesta esegue una sostituzione dell'elenco completo. Devi fornire l'elenco completo delle opzioni nell'ordine scelto. Il server confronta l'elenco in entrata con la definizione attuale:
- Nuova opzione: l'inclusione di un'opzione senza
optionId(o con un nuovooptionIdfornito dall'utente) la aggiunge alla definizione. - Opzione aggiornata: se fornisci un
optionIdesistente con aggiornamentidisplayValueotextStylemodificati, l'opzione viene aggiornata. - Opzioni riordinate: l'elenco delle opzioni viene salvato nella sequenza esatta fornita nella richiesta.
- Opzione eliminata: l'omissione di un
optionIdesistente elimina l'opzione dalla definizione.
Integrità referenziale e sostituzione delle opzioni
Se un'opzione da eliminare è selezionata in un chip con elenco a discesa all'interno del documento, devi fornire una mappatura in selectedOptionIdReplacements (map<string, string>). Le chiavi sono gli ID delle opzioni da eliminare e i valori sono gli ID delle opzioni di sostituzione.
Il seguente esempio di codice mostra come aggiornare una definizione di menu a discesa con sostituzioni di opzioni:
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();
Eliminare una definizione del menu a discesa
Per rimuovere un modello di menu a discesa non utilizzato, utilizza DeleteDropdownDefinitionRequest.
Il seguente esempio di codice mostra come eliminare una definizione di menu a discesa:
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();
Gestione degli errori e risoluzione dei problemi
Condizioni di errore comuni e soluzioni:
| Codice di stato | Causa | Risoluzione |
|---|---|---|
400 INVALID_ARGUMENT |
Prefisso ID o formato dell'espressione regolare non valido. | Assicurati che dropdownDefinitionId inizi con kix. (6-18 caratteri) e che optionId inizi con dropdownItem. (15-27 caratteri). |
400 INVALID_ARGUMENT |
Il conteggio delle opzioni non rientra nei limiti. | Una definizione di menu a discesa deve contenere un numero di opzioni compreso tra 2 e 50. |
400 INVALID_ARGUMENT |
Il titolo o il valore visualizzato è vuoto o supera i 200 caratteri. | Fornisci una stringa non vuota compresa tra 1 e 200 caratteri. |
400 INVALID_ARGUMENT |
Proprietà dello stile di testo non supportata nell'opzione. | Solo foregroundColor e backgroundColor sono supportati nelle opzioni del menu a discesa. Rimuovi il carattere, le dimensioni o altri attributi. |
400 INVALID_ARGUMENT |
Mapping di sostituzione dell'opzione mancante durante l'eliminazione. | Quando elimini un'opzione selezionata da un chip, fornisci una sostituzione valida in selectedOptionIdReplacements. |
400 INVALID_ARGUMENT |
Tentativo di eliminare una definizione in uso. | Elimina o riassegna il target di tutte le istanze di chip con elenco a discesa che fanno riferimento alla definizione prima di eliminarla. |
400 INVALID_ARGUMENT |
ID fornito dall'utente duplicato. | Assicurati che gli ID forniti dagli utenti siano univoci nella scheda del documento. |
Argomenti correlati
- Utilizzare le schede
- Formattare il testo
- Utilizzare commenti e suggerimenti
- Risorsa REST: documents.request
- Risorsa REST: documenti
- Risorsa REST: documents.batchUpdate