Lewati ke konten

Drop File

Wails memungkinkan pengguna menyeret file dari sistem operasi (file manager, desktop) ke aplikasi Anda. Berbeda dengan drag-and-drop HTML5 yang hanya bekerja di dalam browser, ini memberi Anda akses ke path file aktual di disk.

Drop file dinonaktifkan secara default. Untuk mengaktifkannya, set EnableFileDrop: true di opsi window Anda:

window := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "My App",
Width: 800,
Height: 600,
EnableFileDrop: true,
})

Ketika EnableFileDrop adalah false (default), file yang diseret dari OS diblokir — tidak akan terbuka di webview atau memicu event apa pun. Ini mencegah navigasi tidak sengaja saat pengguna menyeret file di atas aplikasi Anda.

Zona drop memberi tahu Wails elemen mana yang harus menerima file. File yang di-drop di luar zona drop diabaikan.

Tambahkan atribut data-file-drop-target ke elemen mana pun:

<div id="upload" class="drop-zone" data-file-drop-target>
Drop files here
</div>

Anda dapat memiliki beberapa zona drop. id dan class CSS elemen diteruskan ke kode Go Anda, sehingga Anda dapat menangani drop secara berbeda tergantung di mana file mendarat.

Saat file diseret di atas zona drop, Wails menambahkan class file-drop-target-active. Ini memungkinkan Anda memberikan umpan balik visual agar pengguna tahu di mana mereka dapat drop:

.drop-zone {
border: 2px dashed #ccc;
padding: 40px;
text-align: center;
transition: all 0.2s ease;
}
.drop-zone.file-drop-target-active {
border-color: #007bff;
background-color: rgba(0, 123, 255, 0.1);
}

Class dihapus otomatis saat file meninggalkan zona atau di-drop.

Saat file di-drop pada zona drop yang valid, Wails memicu event WindowFilesDropped. Konteks event berisi path filesystem lengkap dari semua file yang di-drop:

import "github.com/wailsapp/wails/v3/pkg/events"
window.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
files := event.Context().DroppedFiles()
for _, file := range files {
fmt.Println("Dropped:", file)
}
})

Path bersifat absolut, seperti /home/user/documents/report.pdf atau C:\Users\Name\Documents\report.pdf.

Saat Anda memiliki beberapa zona drop, Anda dapat mengetahui zona mana yang menerima file menggunakan DropTargetDetails():

window.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
files := event.Context().DroppedFiles()
details := event.Context().DropTargetDetails()
fmt.Printf("Dropped on element: id=%s, classes=%v\n",
details.ElementID, details.ClassList)
fmt.Printf("Position: x=%d, y=%d\n", details.X, details.Y)
})

Ini memungkinkan Anda mengarahkan file ke handler yang berbeda:

switch details.ElementID {
case "images":
handleImageUpload(files)
case "documents":
handleDocumentUpload(files)
}

Go:

window := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "File Uploader",
EnableFileDrop: true,
})
window.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
files := event.Context().DroppedFiles()
details := event.Context().DropTargetDetails()
// Send to frontend
app.Event.Emit("files-dropped", map[string]any{
"files": files,
"target": details.ElementID,
})
})

HTML:

<div id="images" class="drop-zone" data-file-drop-target>
Drop images here
</div>
<div id="documents" class="drop-zone" data-file-drop-target>
Drop documents here
</div>
<style>
.drop-zone {
border: 2px dashed #ccc;
border-radius: 8px;
padding: 40px;
text-align: center;
margin: 20px;
transition: all 0.2s ease;
}
.drop-zone.file-drop-target-active {
border-color: #007bff;
background-color: rgba(0, 123, 255, 0.1);
}
</style>

Jika Anda ingin file dapat di-drop di mana saja di aplikasi, tambahkan atribut ke elemen body:

<body data-file-drop-target>
<!-- Your app content -->
</body>

Anda dapat menggunakan overlay CSS untuk menunjukkan seluruh window adalah target drop:

body.file-drop-target-active::after {
content: "Drop files anywhere";
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
color: #007bff;
background: rgba(255, 255, 255, 0.9);
pointer-events: none;
}

Anda dapat menggunakan drop file eksternal dan drag-and-drop HTML internal dalam aplikasi yang sama. Saat EnableFileDrop adalah true, Wails mencegat drag file eksternal tetapi membiarkan drag HTML5 internal melewati secara normal.

Untuk membedakannya di handler zona drop HTML Anda, periksa apakah drag berisi file:

zone.addEventListener('dragenter', (e) => {
// Skip external file drags - Wails handles these
if (e.dataTransfer?.types.includes('Files')) {
return;
}
// Handle internal HTML5 drags
zone.classList.add('drag-over');
});
zone.addEventListener('drop', (e) => {
// Skip external file drops - Wails handles these
if (e.dataTransfer?.types.includes('Files')) {
return;
}
e.preventDefault();
zone.classList.remove('drag-over');
// Handle internal drop
});

Ini memastikan handler drop HTML Anda hanya merespons drag internal (seperti memindahkan item daftar), sementara Wails menangani drop file eksternal secara terpisah melalui event WindowFilesDropped.