How to Show a Change Indicator When a Table Cell Is Edited

When five people are editing the same table during the day, it becomes impossible to tell at a glance which cells have been changed in the current session versus which values have been there since the entry was created. TableCrafter's diff badge feature solves this with a small visual indicator that appears on any cell that has been edited since the page loaded. It's a lightweight audit trail built directly into the table without requiring a separate change log page. WordPress powers 43% of all websites globally (W3Techs, July 2026), and TableCrafter bridges the gap between the data you collect and the tables your users need to see, no custom PHP, no dashboard access required for viewers, and no per-row limits on the free tier. The free version on WordPress.org supports CSV, JSON, Google Sheets, and Excel. Pro adds Gravity Forms, Airtable, Notion, WooCommerce, REST APIs, inline cell editing,. Over 60,000 plugins are available on the WordPress.org plugin directory (WordPress.org, 2026).
What the Diff Badge Is?
The diff badge is a short text label that appears inline inside the cell immediately after a successful save. It displays ← was: {oldValue}, showing a left-arrow, the word "was:", and the value the cell held before the edit. If the user saves without actually changing the value, no badge appears at all - the badge only renders when the new value differs from the old value. This keeps visual noise minimal: cells saved to the same value look unchanged.
The badge uses the CSS class gt-diff-badge and ships with these default inline styles: font-size: 11px, color: #6b7280, background: rgba(0,0,0,0.06), border-radius: 4px, and padding: 1px 6px. It is purely cosmetic, client-side feedback; it is not written to the database. The badge begins fading at the 2.4-second mark and is fully removed from the DOM at 3 seconds. Refreshing the page clears all badges immediately because no badge state is preserved between page loads. This is a Free feature, available without a Pro license (issue #1749).
How Do I Enable the Diff Badge?
The diff badge is enabled per table in the table builder. Open your table under TableCrafter → Tables → [your table]. In the Display Options panel, find the Show Edit Indicator toggle and turn it on. Save the table.
No shortcode parameter is needed, the badge setting is stored in the table configuration, not the shortcode. The same shortcode that embeds the table will now show badges when cells are edited:
[tablecrafter id="3" edit="true"]
The badge feature works independently of other display options. You can have search, filters, and export active alongside it.
TableCrafter re-fetches this data on each page load by default. If your data source updates infrequently and your site has significant traffic, enable the built-in caching option in the table's Performance tab. This stores the fetched data for a configurable number of minutes and serves it from WordPress transients, reducing API calls to the source and improving page load time for visitors.
How Do What Admins See and How It Helps Work?
Consider a table showing 50 load entries. A dispatcher works through it during their shift, updating statuses and adding notes. An operations manager reviews the table afterward. Without the diff badge, every cell looks the same, there's no way to tell which cells were touched. With the diff badge enabled, the manager sees orange dots on exactly the cells that changed. They can review just those cells rather than reading every value in the table.
Common admin workflows enabled by the diff badge:
- End-of-shift review: Manager opens the table and scans for badges to verify that a dispatcher's work is complete
- Catching accidental edits: A user accidentally edited the wrong cell. The badge makes the accidental change visible immediately rather than surfacing only in a database audit
- Training new users: A supervisor can watch a trainee work on a table and see exactly which cells they edited by looking at badge positions
- Multi-user awareness: When two users have the same table open, badge positions show the current user which cells their colleague has already updated (session-local, not real-time cross-user sync)
How Does CSS Customization Work?
The diff badge renders as an inline <span> element injected into the cell after a successful save. TableCrafter assigns it the CSS class gt-diff-badge, which is the stable public selector for all style overrides. The default visual is intentionally low-contrast: small gray text on a near-transparent background pill, designed to annotate a change without distracting the viewer from the cell's new value. If your site uses dark table backgrounds, strong brand colors, or a design system with strict typography standards, the default styling may clash or become invisible. You can override any property through your theme's stylesheet, a child theme CSS file, or the WordPress Additional CSS panel under Appearance → Customize. All overrides target .gt-diff-badge directly. Changes take effect immediately for the next edit cycle; no cache flush is required. The examples below cover the most common customization needs.
Change the Badge Color
The default badge text color is #6b7280, a medium gray that reads as a secondary annotation on white or light-gray table backgrounds. The default background is rgba(0,0,0,0.06), a near-transparent overlay that produces a faint pill shape without strong contrast. To make the badge more prominent as a change alert, raise the background opacity and use a high-contrast text color. To make it even less prominent as a passive log, push both values lighter. The color property controls the text including the arrow character and the "was:" label. The background property (or background-color) controls the pill fill. Set them independently depending on your layout. For tables on dark row backgrounds, use a light-colored text and a semi-transparent light background. The snippet below switches the badge to a blue pill with white text:
.gt-diff-badge {
background: rgba(37,99,235,0.12);
color: #1d4ed8; /* blue text */
}
Change the Badge Size
The default font size is 11px, chosen to keep the badge visually subordinate to the cell's main content. On tables with small cells or dense column layouts, the "was: {oldValue}" text can feel cramped if the old value is long. Increasing to 13px or 14px improves readability in tables where users need to scan old values carefully, such as audit dashboards or dispatcher review screens. Reducing below 10px is not recommended because the arrow character and the old value text become too small to read comfortably. The font-size property scales all badge text uniformly. Adjust padding alongside font-size to maintain proportional spacing. If you need different badge sizes on different tables, scope the selector to a specific table container wrapper rather than applying a global override.
.gt-diff-badge {
font-size: 13px;
padding: 2px 8px;
}
Use a Badge Tag Instead of a Dot
The default badge shows the actual old value, which is useful when reviewers need to know exactly what changed. Sometimes you want a simpler signal: just the word "edited" or a short status keyword, without the previous value text. This is appropriate when old values are long strings that would overflow a cell, when the workflow only requires knowing that a change happened rather than what it was, or when you want a high-visibility colored pill that scans more clearly across rows than small gray text. You can restyle the badge to suppress the old value display and show a fixed label instead by combining CSS overrides on .gt-diff-badge with stronger background and font-weight. The snippet below produces an orange high-contrast pill. Adjust background-color and color to match your design system:
.gt-diff-badge {
font-size: 10px;
font-weight: 600;
color: #ffffff;
background-color: #f97316;
border-radius: 3px;
padding: 2px 6px;
}
Position the Badge at the Bottom of the Cell
By default the badge renders inline after the cell value text, flowing on the same line as the main content. In most single-line cells this is unobtrusive. In cells with multiline content, numeric values that must align left for scanning, or date fields where the badge text would push the date off its natural right-alignment, you may want the badge on a separate visual line below the main value. Setting display: block on the badge moves it to its own line. A small margin-top creates visual separation between the cell value and the badge text. Combine this with a reduced opacity if you want the badge to recede further into the background in the final line of a cell. The snippet below places the badge on a new line beneath the value with a 3-pixel gap:
.gt-diff-badge {
display: block;
margin-top: 3px;
}
Highlight the Entire Edited Cell
The inline badge text draws attention to a change within a single cell. In operational dashboards where a manager needs to scan dozens of rows and spot all changed cells at a glance, a cell-level background highlight is more effective than reading small badge text. Since the gt-diff-badge span exists inside the cell after a successful save, you can use the CSS :has() selector to target the entire table cell that contains a badge and apply a background wash to it. A light amber or green tint makes edits visually scannable across a full table without requiring the user to focus on individual cells. Use a subtle wash rather than a strong color to avoid interference with row striping or hover states in your theme. The inline badge continues to display the previous value alongside the highlighted background:
/* Highlight any table cell that contains a diff badge */
td:has(.gt-diff-badge) {
background-color: #fef3c7; /* light amber wash */
}
What the Diff Badge Does Not Do?
The diff badge is session-local and display-only. It does not:
- Persist across page reloads or browser sessions
- Show who made the edit (it only shows that an edit occurred in the current session)
- Persist the previous value for recovery or undo: the old value is shown inline as
← was: {oldValue}for the current session only, it is not written to the database and cannot be restored after the badge fades or the page is reloaded - Sync across users in real-time (another user loading the same table sees no badges until they make their own edits)
For persistent change logging with user attribution and timestamps, you would need Gravity Forms' entry update history feature or a separate audit log plugin. The diff badge is a lightweight session indicator, not a full audit system.
The configuration you set here applies to every visitor who loads a page containing this table, regardless of whether they are logged in. Role-specific overrides for columns and rows are a separate layer and do not replace these global display settings. Apply global settings first, then add role restrictions as needed for tables that serve multiple user types.
What Are the Next Steps?
The diff badge works best as part of a broader data quality strategy. Combine it with role restrictions (so you know that badges only appear from authorized editors) and validation rules (so badged cells are guaranteed to contain valid data). For a full picture of how these features compose into a data integrity workflow, see the guide on preventing bad data with inline editing in WordPress tables.
Filters applied to the table URL as query parameters persist if the user copies and shares the URL. This makes filtered views bookmarkable and shareable, which is particularly useful for team dashboards where different users need to see different default views of the same underlying table.
This step completes the connection between your data source and the TableCrafter table engine. Once saved, the plugin caches the connection credentials in the WordPress options table and uses them on every subsequent page load. If you update the source configuration later - for example, rotating an API key or changing a sheet URL - return to this step, enter the new value, and save again. The table updates immediately on next load without any shortcode changes.
Frequently Asked Questions
What is the diff badge?
The diff badge is a short text label that appears inside a table cell after a successful inline edit, showing ← was: {oldValue}. It uses the CSS class gt-diff-badge and carries default styles of font-size: 11px, color: #6b7280, and background: rgba(0,0,0,0.06). The badge fades out after 2.4 seconds and is fully removed from the DOM at 3 seconds. It only renders when the new value differs from the old value, so editing a cell to the same value leaves no badge. It is a Free feature, purely cosmetic, and not stored in the database. Refreshing the page clears all badges immediately.
What Is TableCrafter?
TableCrafter is a WordPress plugin that turns data from Gravity Forms, Google Sheets, Airtable, Notion, REST APIs, CSV files, and WooCommerce into interactive, sortable, filterable frontend tables. Embed any table on any WordPress page with the [tablecrafter] shortcode or the native Gutenberg block. No PHP or custom development required. The free version supports CSV, JSON, Google Sheets, and Excel. Pro adds Gravity Forms, Airtable, Notion, WooCommerce, REST APIs, inline cell editing, export to CSV and PDF, role-based column visibility, and auto-refresh.
Does this require PHP or developer skills?
No. TableCrafter is configured entirely through the WordPress admin interface. You choose your data source, map fields to columns, and set display preferences using point-and-click controls. Embedding uses the [tablecrafter] shortcode or the native Gutenberg block.
Is the free version sufficient or do I need Pro?
The free plugin on WordPress.org supports CSV, JSON, Google Sheets, and Excel sources with unlimited tables, rows, and columns. Pro adds Gravity Forms, Airtable, Notion, WooCommerce, REST API sources, inline cell editing, bulk row actions, export to CSV and PDF, role-based column visibility, and auto-refresh every N seconds.
Ready to try it?
TableCrafter is free on WordPress.org. Pro unlocks inline editing, role-based permissions, and advanced data sources.
Column order is preserved across sessions. Once you set a column order in the table builder, that order persists in the shortcode output for all visitors. Users with the column reorder permission can adjust their own view without affecting the default seen by others.
If this step produces unexpected output, check the source data directly in the connected system. TableCrafter passes data through without modification - if a cell displays an unexpected value, the source record contains that value. Use the TableCrafter debug log (Settings > Advanced > Debug Mode) to trace the exact query sent to the source and the raw response received, which narrows the diagnosis to either a source-side or rendering-side issue.