How to Lock Fields When Duplicating Rows in TableCrafter

Row duplication in TableCrafter lets you clone an existing Gravity Forms entry as a starting point for a new one, a massive time-saver when entries share most of their data. But sometimes you want certain fields to carry over exactly as-is while others stay editable, and other times you need the opposite: blank out sensitive values so the duplicated row starts fresh. This guide walks through how TableCrafter's column-level permission model gives you precise control over which fields are locked, pre-filled, or cleared when a row is duplicated. 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. 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, export to CSV/PDF, role-based. CSV remains the most universally supported data exchange format, used by 91% of business intelligence tools (Gartner, 2025).
What "Row Duplication" Actually Does in TableCrafter?
Row duplication is a Pro bulk action available on any table that has inline editing enabled. When a user selects one or more rows and triggers Duplicate, TableCrafter calls GFAPI::add_entry() behind the scenes to write a new Gravity Forms entry pre-populated with the source entry's field values. The handler automatically strips the source entry's id, date_created, and date_updated fields so the new entry gets a fresh ID and timestamp from Gravity Forms. The new entry is immediately visible in the table and enters edit mode so the user can adjust whatever needs to change.
The entire operation runs through wp-admin/admin-ajax.php with nonce validation and a capability check, so only users who pass the table's role-based permission gate can trigger it. No duplication happens client-side, every field value round-trips through the server, which is exactly where you apply locking logic.
How Does Understanding Column-Level Permissions Before You Lock Anything Work?
TableCrafter's permission model has two layers: table-level permissions control who can see or interact with the table at all, and column-level permissions control what individual users can do with each field inside a table. Column-level settings are where locking happens.
To reach column permissions, go to TableCrafter → Tables, open the table you want to configure, and scroll to the column list in the table builder. Each column has an expandable settings panel with a Permissions tab. The key options are:
- Editable by roles, a whitelist of WordPress roles that can edit this column's value inline. Leave blank to inherit the table default.
- Read-only override, forces the column into read-only display for everyone, regardless of the table-level edit permission. This is the primary lock mechanism.
- Hidden from roles, removes the column from view entirely for specified roles.
What Is Locking Fields During Duplication: The Two Strategies?
There are two common scenarios when duplicating rows, and each calls for a different approach.
Strategy 1, Lock a field so it copies over unchanged
If you want a field (say, a project code or a category) to carry over from the source row and stay read-only in the duplicate, enable the Read-only override on that column. When the duplicate is created and enters edit mode, that column renders as plain text, the user can see the copied value but cannot change it. The value was already written by the duplication action and is now locked in place.
Steps:
- Open TableCrafter → Tables and edit the relevant table.
- Expand the column you want to lock and open its Permissions tab.
- Toggle Read-only override on.
- Save the table.
From this point, the column displays its value in every row, including newly duplicated ones, but the inline edit input never renders for it.
Strategy 2, Lock a field so it starts blank in the duplicate
Sometimes the opposite is true: you want the duplicate to start with an empty value for a specific field (a unique invoice number, a status badge that should reset, a date that must be re-entered). For this, use a combination of a default value hook on the Gravity Forms field side and the column's role-based editable setting on the TableCrafter side.
On the Gravity Forms field, set a default value of empty or a placeholder. Then in TableCrafter, ensure the column is editable (not read-only), so after duplication the user is prompted to fill it in. The duplicate action copies whatever the GF field's stored value was, if the source entry had a non-empty value, you will need a custom filter on the GF side to intercept and clear it for new entries flagged as duplicates.
gform_after_create_entry action in a custom plugin or functions.php, check that the entry was created via the TableCrafter duplicate path using entry meta, and update the target field with GFAPI::update_entry_field().What Is Role-Based Locking: Different Rules for Different Users?
Pro Column-level permissions are role-aware, which means you can lock a field for one role and leave it editable for another. A practical example: your editor role can modify the client name when duplicating a row, but your contributor role sees it as read-only and cannot change it.
Configure this by setting the Editable by roles whitelist on the column rather than using the blanket read-only override. Roles not on the whitelist will see the column value but cannot edit it, effectively locked for them, even inside a freshly duplicated row.
To configure this for two roles concretely, open TableCrafter → Tables, edit your table, expand the column you want to lock for most users, and open its Permissions tab. In the Editable by roles field, add administrator and editor to the whitelist but leave contributor off. When an administrator or editor duplicates a row, that column is editable and they can immediately overwrite the carried-over value. When a contributor duplicates the same row, the column renders as plain read-only text. They can see the value was copied from the source row, but the inline edit input never appears. This fine-grained control is especially useful in approval workflows where one role sets a field (say, an internal cost code or a workflow status) and a downstream role is meant to view but not alter it during duplication. Save the table configuration after setting the whitelist, then test by logging in as both role types to confirm the behavior.
[tablecrafter id="12"]
The shortcode above renders the table. Permissions are enforced server-side, so even if a user inspects the DOM or crafts a custom AJAX request, the capability check on admin-ajax.php blocks unauthorized writes. Permissions are enforced server-side regardless of which page or post embeds this shortcode.
How Do I Configure a Locked-Field Duplicate Workflow?
Here is a complete walkthrough for a common use case: a load-tracking table where duplicating a row copies the truck, driver, and route fields, but locks the "Entry ID" display column and clears the "Dispatch Date" so it must be re-entered.
- Enable inline editing on the table: TableCrafter → Tables → Edit → Settings tab → Inline Editing: On.
- Enable bulk actions on the same Settings tab and ensure Duplicate is checked in the bulk action list.
- Lock the Entry ID column: expand the Entry ID column, open its Permissions tab, enable Read-only override. Save.
- Configure role access for Dispatch Date: expand the Dispatch Date column, open Permissions, set Editable by roles to the roles that should fill it in after duplication (e.g., administrator, editor). Users in those roles will see an empty editable cell on the duplicate; users outside them will see it locked.
- Test the flow: on the frontend, select a row, open the bulk action menu, choose Duplicate. The new row should appear with truck/driver/route pre-filled, Entry ID read-only, and Dispatch Date blank and ready for input.
// Hook into Gravity Forms after a new entry is created
add_action( 'gform_after_create_entry', function( $form, $entry_id ) {
// Check if this was created via TableCrafter duplicate (optional meta check)
// Clear "Dispatch Date" field (field ID 14) on the new entry
GFAPI::update_entry_field( $entry_id, 14, '' );
}, 10, 2 );
functions.php or a small site-specific plugin. Avoid editing TableCrafter's plugin files directly, as those changes will be overwritten on update.How Do Common Pitfalls and How to Avoid Them Work?
A few issues come up repeatedly when teams set up locked-field duplication for the first time.
- Read-only override blocks everyone, including admins. If you want admins to be able to edit a field that contributors cannot, use the Editable by roles whitelist instead of the blanket read-only toggle. The read-only override is absolute.
- Status badges look read-only but are not locked. TableCrafter's status badge feature renders text as a colored pill. This is a display transform only, the underlying cell is still editable unless you explicitly lock it. If your status field should not change on duplication, add the read-only override to that column.
- Data bars in numeric columns can still be edited inline. Similarly, data bars (inline bar charts for numeric fields) are a visual layer. The numeric value is editable unless the column is locked. Lock numeric columns that feed into calculated fields you do not want users changing post-duplication.
- Lookup fields resolve IDs to labels but store IDs. When a row is duplicated, the stored value is the raw ID (e.g., a user ID or a related entry ID). The label is resolved at render time. Locking a lookup column locks the ID, which is usually what you want, just confirm the relationship still resolves correctly for the duplicate.
- Auto-refresh can hide the new duplicate row briefly. If auto-refresh is enabled with a short interval, the table may refresh before the user finishes editing the duplicated row. Consider increasing the auto-refresh interval (or disabling it on tables used heavily for duplication workflows) under TableCrafter → Settings → Auto-refresh.
Frequently Asked Questions
What does "row duplication" actually do in TableCrafter?
Row duplication is a Pro bulk action available on any table that has inline editing enabled. When a user selects one or more rows and triggers Duplicate, TableCrafter calls GFAPI::add_entry() behind the scenes to write a new Gravity Forms entry pre-populated with the source entry's field values. The new entry is immediately visible in the table and enters edit mode so the user can adjust
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.
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.
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.