Show data Script
Creating a "Show Details" Button with JSON
In our last tutorial, we built a simple Google Maps button that read data directly from the form. Now, let's take it a step further. We'll create a "Show Details" button that fetches the complete data for a record from the server and displays it in a clean, formatted pop-up modal, without ever leaving the current page.
This pattern is incredibly powerful. It allows you to show rich information on demand, keeping your main table view clean and uncluttered. It's perfect for showing a quick summary, contact details, or any other information you need at a glance.
What You'll Learn
This guide will teach you how to create a button script that:
- Securely fetches a single record from the database on the server.
- Formats the data into a user-friendly HTML layout.
- Returns a structured JSON response to the browser.
- Uses our application's generic button handler to display the data in a modal dialog.
The Code: `template_showdata.php`
This script is the heart of our button. It's a pure PHP script that doesn't render a full HTML page. Instead, its sole purpose is to gather data and output a JSON object. Save this file as template_showdata.php inside your /custom_buttons/ directory.
<?php
require_once '../init.php';
require_once '../uicomponents.php'; // Required for the format_value() function
// --- Access Control ---
if (!isset($_SESSION['user'])) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Authentication required']);
exit();
}
// --- Get parameters from the URL ---
$table_id = (int)($_GET['table_id'] ?? 0);
$record_id = (int)($_GET['id'] ?? 0);
$sig_from_url = trim($_GET['sig'] ?? '');
if ($table_id === 0 || $record_id === 0) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Table ID or Record ID is missing']);
exit();
}
// --- Security Check: Validate signature ---
$data_to_sign = "{$table_id}-{$record_id}";
$expected_sig = hash_hmac('sha256', $data_to_sign, INVITE_SECRET_KEY);
if (!hash_equals($expected_sig, $sig_from_url)) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Invalid signature.']);
exit();
}
// --- Fetch Data ---
$table_definition = DBGet('custom_tables', $table_id);
$table_owner_team = $table_definition['team'];
$physical_table_name = "data_team_{$table_owner_team}_{$table_id}";
$record = DBGet($physical_table_name, $record_id);
$fields = DBGet('custom_fields', null, ['*'], 'custom_table_id = ?', [$table_id], 'sort_order ASC');
if (!$record || !$fields) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Record or field definitions not found.']);
exit();
}
// --- Build HTML for the dialog content on the server ---
$dataHtml = '<div class="row g-3">';
$pseudoFieldTypes = ['SECTION_HEADER', 'HELP_TEXT', 'CUSTOM_BUTTON'];
foreach ($fields as $field) {
// Skip layout fields and fields not present in the record
if (in_array($field['field_type'], $pseudoFieldTypes) || !array_key_exists($field['field_name'], $record)) {
continue;
}
$display_name = htmlspecialchars($field['display_name']);
// Use our helper function to format dates, numbers, etc. for display
$value = format_value($record[$field['field_name']], $field, $current_lang);
// Skip empty values to keep the dialog clean
if (trim(strip_tags($value)) === '') {
continue;
}
$dataHtml .= "<div class=\"col-md-6\"><div class=\"d-flex justify-content-between border-bottom py-1\"><strong class=\"text-muted\">{$display_name}</strong><span>{$value}</span></div></div>";
}
$dataHtml .= '</div>';
// --- Create and send the final JSON response ---
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'action' => 'showInfo', // A command for our client-side JavaScript
'title' => 'Details for: ' . htmlspecialchars($record['name'] ?? 'ID ' . $record_id),
'text' => $dataHtml,
'width' => '800px' // Make the dialog wider
]);
exit();
Breaking Down the Code
This script follows a clear, server-side logic: Secure, Fetch, Format, and Respond.
Part 1: Secure and Fetch
The first part of the script is our standard security procedure. It ensures that only a logged-in user with a valid, unaltered link can access this script. Afterwards, it fetches all necessary information from the database:
DBGet('custom_tables', $table_id): Gets the definition of the table itself to find out who owns it.DBGet($physical_table_name, $record_id): Fetches the actual data for the single record we want to display.DBGet('custom_fields', ...): Fetches all field definitions for this table. We need this to get the correct display names and formatting rules for each piece of data.
Part 2: Format the Data
This is where the script prepares the content for the pop-up. Instead of just showing raw data, we want a nicely formatted view.
$dataHtml = '<div class="row g-3">';: We start building an HTML string. We use Bootstrap's grid classes (row,col-md-6) to create a neat two-column layout.foreach ($fields as $field): The script loops through every field defined for the table.if (in_array(...)) continue;: It intelligently skips layout elements like "Section Headers" or "Help Texts" that don't contain actual data.format_value(...): This is a key step. Our application has a helper function that takes a raw database value (like "2024-12-31") and a field definition, and returns a beautifully formatted string (like "31.12.2024"). This ensures dates, currencies, and other special types are displayed correctly.- Building the HTML: For each field that has a value, it creates a small row with the field's label on the left and its formatted value on the right.
Part 3: Respond with JSON
This is the most important part and what makes this button different. The script does not output a full webpage. Instead, it constructs a PHP array and converts it into a JSON (JavaScript Object Notation) string.
echo json_encode([
'success' => true,
'action' => 'showInfo',
'title' => 'Details for: ...',
'text' => $dataHtml,
'width' => '800px'
]);
This JSON object is a set of instructions for the JavaScript in the main application. Our generic button handler is built to understand this structure:
action: 'showInfo': This tells the JavaScript, "Your job is to show a dialog."title,text,width: These are the parameters passed directly to ourshowDialog()function. Thetextparameter contains the HTML string we built in the previous step.
This approach is clean and efficient. The server does the heavy lifting of fetching and formatting data, and the client simply has to display what it receives.
Integrating the Button
The integration process is the same as for our Google Maps button, which makes our button system very consistent.
Step 1: Create the Button in Settings
- Navigate to Settings Custom Buttons.
- Click "New Button".
- Fill out the form:
- Button Display Name:
Show Details - URL / Script Path:
custom_buttons/template_showdata.php - Icon: A good choice is
fa-circle-info. - Color:
btn-info(turquoise) orbtn-secondary(gray) works well. - Display Context: Select "List View (per row)". This button is most useful for getting a quick look at a record from the main table view.
- Button Display Name:
- Save the button.
That's it! Because we are not placing this button inside a form layout, we don't need a second step. The button will now automatically appear in the "Actions" column for every row in the table view.
You've now learned a more advanced and flexible way to create custom buttons. By returning JSON from the server, you can trigger all sorts of client-side actions, from showing simple dialogs to performing complex data updates. In our next article, we'll explore how to use this to modify data with user input.