Back to overview

Dropbox Picker

Scripting & Buttons Published on 04.11.2025

Integrating the Dropbox Picker

This guide explains how to implement a custom button that allows users to select a file from their Dropbox account and save a shareable link into a form field. This is a powerful feature for linking external documents without uploading them to the server.

1. Configuration in config.php

Before you can use the Dropbox Picker, you must configure your Dropbox App Key in the application's main configuration file.

  1. Get a Dropbox App Key: Go to the Dropbox App Console, create a new app (Scoped Access is recommended), and get your App Key.
  2. Set the App Key: Open config.php and set the DROPBOX_APP_KEY constant:
    define('DROPBOX_APP_KEY', 'YOUR_DROPBOX_APP_KEY');
  3. Configure Allowed Domains: In your Dropbox App settings, under the "OAuth 2" section, add your application's domain to the "Chooser/Saver domains" list. For local development, you must add localhost.

2. Implementation Steps

To use the picker, you need a target field in your table and a custom button to trigger the action.

Step 2.1: Prepare the Target Field

In your table definition (e.g., a "Documents" table), create a field to store the URL. A field of type Web (URL) is ideal. Let's assume its technical name is url_verknuepfung.

Step 2.2: Create the Custom Button

Go to Settings -> Custom Buttons and create a new button with the following properties:

  • Button Name: Select from Dropbox
  • URL / Script Path: custom_buttons/dropbox_picker_action.php?target_field=url_verknuepfung
  • Display Context: Record Form or Both (to show it in the record edit form).
  • Icon: fa-dropbox (from Font Awesome Brands)
  • Color: btn-primary

The target_field parameter in the URL tells the script which form field to populate with the selected file's URL.

3. Code Explanation: dropbox_picker_action.php

When the custom button is clicked, it fetches and executes the content of dropbox_picker_action.php. This script is designed to run entirely on the client-side.

<?php
require_once '../init.php';

// ... Access control ...

// Get the target field name from the button's URL
$target_field_name = htmlspecialchars($_GET['target_field'] ?? 'url_verknuepfung', ENT_QUOTES, 'UTF-8');
?>
<script>
// Check if the Dropbox SDK is loaded and the browser is supported.
if (typeof Dropbox === 'undefined' || !Dropbox.isBrowserSupported()) {
    // Show an error dialog if the SDK is missing (e.g., due to an invalid App Key).
    showDialog({ 
        title: 'Error: Dropbox Picker not ready', 
        text: 'Could not load the Dropbox file picker. This might be due to a missing or invalid App Key in config.php or the domain is not whitelisted in your Dropbox app settings.', 
        okText: 'OK' 
    });
} else {
    // Configure the picker
    var dbxOptions = {
        success: function(files) {
            if (files && files.length > 0) {
                var selectedFileUrl = files[0].link;
                // Find the target form field by its 'name' attribute
                var targetField = document.querySelector(`[name=""]`); 
                if (targetField) {
                    // Set the field's value and trigger a 'change' event
                    targetField.value = selectedFileUrl;<?php
require_once '../init.php';

// --- Zugriffsschutz ---
if (!isset($_SESSION['user'])) {
    header('HTTP/1.1 403 Forbidden');
    exit('FEHLER: Authentifizierung erforderlich.');
}

// --- Parameter aus dem Custom Button URL abrufen ---
$target_field_name = htmlspecialchars($_GET['target_field'] ?? 'url_verknuepfung', ENT_QUOTES, 'UTF-8');
?>
<script>
(async () => {
    // 1. Lädt das Dropbox SDK dynamisch
    function loadDropboxSdk() {
        return new Promise((resolve, reject) => {
            if (window.Dropbox) return resolve();
            const script = document.createElement("script");
            script.src = "https://www.dropbox.com/static/api/2/dropins.js";
            script.id = "dropboxjs";
            script.dataset.appKey = "";
            script.onload = () => resolve();
            script.onerror = () => reject(new Error('Dropbox SDK konnte nicht geladen werden.'));
            document.body.appendChild(script);
        });
    }

    // 2. Zeigt den Picker an, nachdem das SDK geladen wurde
    function showPicker() {
        if (!Dropbox.isBrowserSupported()) {
            showDialog({ title: 'Fehler', text: 'Ihr Browser wird vom Dropbox Picker nicht unterstützt.', okText: 'OK' });
            return;
        }

        Dropbox.choose({
            success: function(files) {
                const selectedFileUrl = files[0].link;
                const targetField = document.querySelector(`[name=""]`);
                targetField.value = selectedFileUrl;
                targetField.dispatchEvent(new Event('change', { bubbles: true }));
                showToast({ message: 'Dropbox URL erfolgreich hinzugefügt.', type: 'success' });
            }
            // ... weitere Optionen ...
        });
    }

    // 3. Hauptlogik: Laden und dann anzeigen
    try {
        await loadDropboxSdk();
        setTimeout(showPicker, 100); // Kurze Verzögerung für die Initialisierung
    } catch (error) {
        console.error(error);
        showDialog({
            title: 'Fehler: Dropbox-Picker nicht bereit',
            text: 'Der Dropbox-Dateiauswähler konnte nicht geladen werden. Prüfen Sie den App-Key und die Domain-Einstellungen.',
            okText: 'OK'
        });
    }
})();
</script>
<?php
exit();
Key Concepts:
  • Dynamic SDK Loading: The script no longer assumes the Dropbox SDK is globally available. The loadDropboxSdk function creates a <script> tag on the fly and injects it into the page. The data-app-key attribute is automatically set from your config.php.
  • Asynchronous Execution: The entire logic is wrapped in an async function. This allows us to use await loadDropboxSdk() to pause execution until the external script is fully loaded, preventing race conditions.
  • Error Handling: A try...catch block handles potential loading errors (e.g., invalid App Key, network issues) and displays a user-friendly dialog.
  • Dynamic Target Field: The $target_field_name from the button's URL is embedded into the JavaScript, making the script reusable for different fields.
  • Success Callback: When a user picks a file, the success function is called. It retrieves the file's URL and uses document.querySelector to find the correct input field in the form.
  • Event Dispatching: After setting the value, dispatchEvent(new Event('change')) is called. This is crucial for notifying other parts of the application (like dependent fields or validation logic) that the field's value has been updated programmatically.
  • targetField.dispatchEvent(new Event('change', { bubbles: true })); showToast({ message: 'Dropbox URL added successfully.', type: 'success' }); } } }, cancel: function() { /* User cancelled */ }, linkType: "preview", // Provides a shareable preview link multiselect: false, }; // Open the Dropbox Picker Dropbox.choose(dbxOptions); } </script> <?php exit();
    Key Concepts:
    • Client-Side Execution: The PHP script's only purpose is to generate a piece of JavaScript that runs in the user's browser.
    • Configuration Check: The script first verifies that the Dropbox SDK is available. If not, it displays a helpful error message pointing to common configuration issues.
    • Dynamic Target Field: The $target_field_name from the button's URL is embedded into the JavaScript, making the script reusable for different fields.
    • Success Callback: When a user picks a file, the success function is called. It retrieves the file's URL and uses document.querySelector to find the correct input field in the form.
    • Event Dispatching: After setting the value, dispatchEvent(new Event('change')) is called. This is crucial for notifying other parts of the application (like dependent fields or validation logic) that the field's value has been updated programmatically.