Dropbox Picker
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.
- Get a Dropbox App Key: Go to the Dropbox App Console, create a new app (Scoped Access is recommended), and get your App Key.
- Set the App Key: Open
config.phpand set theDROPBOX_APP_KEYconstant:define('DROPBOX_APP_KEY', 'YOUR_DROPBOX_APP_KEY'); - 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 FormorBoth(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="= $target_field_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 = "= defined('DROPBOX_APP_KEY') ? DROPBOX_APP_KEY : '' ?>";
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="= $target_field_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
loadDropboxSdkfunction creates a<script>tag on the fly and injects it into the page. Thedata-app-keyattribute is automatically set from yourconfig.php. - Asynchronous Execution: The entire logic is wrapped in an
asyncfunction. This allows us to useawait loadDropboxSdk()to pause execution until the external script is fully loaded, preventing race conditions. - Error Handling: A
try...catchblock handles potential loading errors (e.g., invalid App Key, network issues) and displays a user-friendly dialog. - Dynamic Target Field: The
$target_field_namefrom 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
successfunction is called. It retrieves the file's URL and usesdocument.querySelectorto 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();
- 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_namefrom 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
successfunction is called. It retrieves the file's URL and usesdocument.querySelectorto 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.