Google Docs API memungkinkan Anda membuat, menyisipkan, memperbarui, membaca, dan mengelola chip dropdown dalam dokumen Google Dokumen secara terprogram.
Apa itu chip dropdown?
Chip dropdown di Google Dokumen memberi pengguna menu pilihan interaktif yang dapat disesuaikan dalam teks dokumen. Pengguna dapat mengklik chip dropdown untuk memilih dari daftar opsi standar, yang masing-masing memiliki teks tampilan dan gaya warna sendiri. Chip dropdown sering digunakan untuk pelacakan proyek, pembaruan status, alur kerja peninjauan, dan tahap persetujuan.
Melalui Docs API, Anda dapat:
- Tentukan template dropdown yang dapat digunakan kembali dengan judul, nama opsi, dan warna yang disesuaikan.
- Menyisipkan chip dropdown di lokasi karakter yang valid.
- Memperbarui opsi yang dipilih dari setiap instance chip dropdown.
- Ubah definisi dropdown bersama di tempatnya, perbarui semua chip yang mereferensikan secara bersamaan.
- Mengganti atau menghentikan penggunaan opsi dengan aman sambil mempertahankan integritas referensial di seluruh chip yang ada.
- Hapus template dropdown yang tidak digunakan.
Arsitektur: definisi dan instance
Di Docs API, chip dropdown memiliki definisi dan instance. Definisi menetapkan opsi untuk instance dropdown. Instance dropdown adalah dropdown yang dapat digunakan orang untuk berinteraksi, dan menyimpan informasi tentang pilihan.
Docs API memisahkan konfigurasi template dropdown dari instance chip dropdown inline:
- DropdownDefinition: Template tingkat tab yang menentukan judul dropdown dan kumpulan pilihan yang dapat dipilih (
DropdownOption). Template ini tidak berada pada offset karakter tertentu dalam dokumen; melainkan disimpan dalam peta definisi tab:document.tabs[].documentTab.dropdownDefinitions. - Dropdown: Instance chip individual yang disematkan sebaris dalam elemen paragraf (
ParagraphElement.dropdown). Setiap instance dropdown mereferensikandropdownDefinitionIddan menyimpanselectedOptionIdaktifnya sendiri.
Mengubah DropdownDefinition (misalnya, menambahkan opsi atau mengganti nama judul) akan memperbarui semua chip yang mereferensikan di seluruh tab tanpa memerlukan pembaruan pada setiap elemen individual.
Setiap instance Dropdown melacak selectedOptionId-nya sendiri. Mengubah nilai yang dipilih chip individual hanya memengaruhi instance tertentu tersebut.
Format ID dan aturan validasi
ID yang diberikan pengguna harus mematuhi spesifikasi format, awalan, dan panjang yang ketat:
| ID | Awalan Wajib | Ekspresi reguler validasi | Batas Panjang | Contoh |
|---|---|---|---|---|
ID definisi dropdown (dropdownDefinitionId) |
kix. |
^kix\.[a-zA-Z0-9_-]{2,14}$ |
6–18 karakter | kix.review_status |
ID opsi dropdown (optionId) |
dropdownItem. |
^dropdownItem\.[a-zA-Z0-9_-]{2,14}$ |
15–27 karakter | dropdownItem.pending |
Membuat ID yang disediakan pengguna
Untuk membuat ID yang mematuhi persyaratan awalan wajib dan ekspresi reguler, gunakan fungsi bantuan berikut. Helper ini menghasilkan sufiks alfanumerik base-36 huruf kecil, yang cocok dengan format yang dihasilkan oleh UI Google Dokumen:
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();
}
}
Membuat dan menyisipkan chip dropdown
Pembuatan batch tunggal (direkomendasikan)
Pola yang paling efisien menggabungkan CreateDropdownDefinitionRequest dan InsertDropdownRequest dalam satu panggilan documents.batchUpdate.
Contoh kode berikut membuat definisi dropdown "Status Peninjauan" dengan tiga pilihan berkode warna menggunakan ID yang disediakan pengguna, dan menyisipkan instance di akhir dokumen:
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();
Aturan dan batas validasi dropdown
Saat membuat atau mengubah definisi dropdown, batasan berikut berlaku:
- Jumlah Opsi: Definisi dropdown harus memiliki antara 2 dan 50 opsi.
- Panjang Judul: Definisi
titletidak boleh kosong dan tidak boleh melebihi 200 karakter. - Panjang Nilai Tampilan: Setiap
displayValueopsi tidak boleh kosong dan tidak boleh melebihi 200 karakter. - Gaya Opsi: Hanya
foregroundColordanbackgroundColoryang didukung diDropdownOption.textStyle. Menetapkan properti gaya lainnya akan menampilkan error400 Bad Request. - Pilihan Default: Di
InsertDropdownRequest, jikaselectedOptionIddihilangkan, chip akan ditetapkan secara default ke opsi pertama yang ditentukan dalamDropdownDefinition.
Memperbarui pilihan chip dropdown individual
Untuk mengubah opsi yang dipilih dari instance chip dropdown yang ada tanpa mengubah template atau chip lainnya, gunakan UpdateDropdownPropertiesRequest:
dropdownId: (Wajib) ID instance chip dropdown tertentu yang akan diupdate.tabId: ID tab yang berisi dropdown (secara default adalah tab pertama jika tidak ditentukan).- Tetapkan
fieldske"selectedOptionId".
Contoh kode berikut memperbarui pilihan aktif chip dropdown menjadi "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();
Memperbarui definisi dan opsi dropdown
Untuk mengubah template itu sendiri (judul, daftar opsi, label tampilan, atau warna), gunakan UpdateDropdownDefinitionPropertiesRequest. Memperbarui definisi akan otomatis memperbarui semua chip dropdown yang mereferensikannya di seluruh tab.
Penggantian daftar lengkap untuk opsi
Jika dropdownDefinitionProperties.options disertakan dalam mask fields, permintaan akan melakukan penggantian daftar lengkap. Anda harus memberikan daftar lengkap opsi dalam urutan yang dipilih. Server membandingkan daftar yang masuk dengan definisi saat ini:
- Opsi baru: Menyertakan opsi tanpa
optionId(atau denganoptionIdbaru yang disediakan pengguna) akan menambahkannya ke definisi. - Opsi yang diperbarui: Menyediakan
optionIdyang sudah ada dengan pembaruandisplayValueatautextStyleyang diubah akan memperbarui opsi tersebut. - Opsi yang diurutkan ulang: Daftar opsi disimpan dalam urutan persis seperti yang diberikan dalam permintaan.
- Opsi yang dihapus: Menghilangkan
optionIdyang ada akan menghapus opsi tersebut dari definisi.
Integritas referensial dan penggantian opsi
Jika opsi yang dihapus dipilih di chip dropdown mana pun dalam dokumen, Anda harus memberikan pemetaan di selectedOptionIdReplacements (map<string, string>). Kuncinya adalah ID opsi yang dihapus, dan nilainya adalah ID opsi pengganti.
Contoh kode berikut menunjukkan cara memperbarui definisi dropdown dengan penggantian opsi:
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();
Menghapus definisi dropdown
Untuk menghapus template dropdown yang tidak digunakan, gunakan DeleteDropdownDefinitionRequest.
Contoh kode berikut menunjukkan cara menghapus definisi dropdown:
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();
Penanganan error dan pemecahan masalah
Kondisi error umum dan penyelesaian masalah:
| Kode Status | Penyebab | Resolusi |
|---|---|---|
400 INVALID_ARGUMENT |
Awalan ID atau format ekspresi reguler tidak valid. | Pastikan dropdownDefinitionId dimulai dengan kix. (6–18 karakter) dan optionId dimulai dengan dropdownItem. (15–27 karakter). |
400 INVALID_ARGUMENT |
Jumlah opsi di luar batas. | Definisi dropdown harus berisi antara 2 dan 50 opsi. |
400 INVALID_ARGUMENT |
Judul atau nilai tampilan kosong atau melebihi 200 karakter. | Berikan string yang tidak kosong dengan panjang antara 1 hingga 200 karakter. |
400 INVALID_ARGUMENT |
Properti gaya teks tidak didukung dalam opsi. | Hanya foregroundColor dan backgroundColor yang didukung pada opsi dropdown. Hapus font, ukuran, atau atribut lainnya. |
400 INVALID_ARGUMENT |
Pemetaan penggantian opsi tidak ada saat penghapusan. | Saat menghapus opsi yang dipilih oleh chip, berikan pengganti yang valid di selectedOptionIdReplacements. |
400 INVALID_ARGUMENT |
Mencoba menghapus definisi yang sedang digunakan. | Hapus atau tetapkan ulang target semua instance chip dropdown yang mereferensikan definisi sebelum menghapusnya. |
400 INVALID_ARGUMENT |
ID yang disediakan pengguna duplikat. | Pastikan ID yang disediakan pengguna bersifat unik dalam tab dokumen. |
Topik terkait
- Bekerja dengan tab
- Memformat teks
- Menggunakan komentar dan saran
- REST Resource: documents.request
- REST Resource: documents
- REST Resource: documents.batchUpdate