Task Issue 956 Cfields Rename Custom Field - sebiboga/testlink-upgraded GitHub Wiki
Task 956 β Allow renaming a custom field (name) in the modern cfields edit modals
Issue: #956
Status: IMPLEMENTED & VERIFIED (2026-09-23) β branch task/issue-956
The gap
The legacy custom field edit form lets the user change the field name even when editing an existing field:
gui/templates/dashio/cfields/cfieldsEdit.tpl:83-89βcf_nameis a plain editable text box (<input ... name="cf_name" ... value="{$gui->cfield.name|escape}">), no read-only attribute in edit mode.lib/cfields/cfieldsEdit.php:367-381(doUpdate) β before saving it re-checks uniqueness withname_is_unique($id, $name); a rename that collides with an existing name is rejected withlang_get('cf_name_exists')("Custom field name already exists. Please choose a new one"). Create has the same guarded check (cfieldsEdit.php:311-334).
The modern screens blocked renaming entirely:
gui/templates/cfields/cfieldsView.html:318β$('#editName').val(cf.name) .prop('readonly', true)forced the Name input read-only in the edit modal.gui/templates/cfields/cfieldsAssignView.html:251β the same.prop('readonly', true)in the Assign screen's edit modal (reachable from the Assigned/Available name links).
Meanwhile the modern BFF PUT /api/cfields/{id} (api/cfields/index.php:268-274)
already implemented the uniqueness guard and supported a changed name β the
front-end gate was the only thing in the way.
Measured gap (browser DOM before the fix): editing the "Deployment" field
returned {"modalVisible":true,"readonly":true,"name":"Deployment",...} β
#editName.readOnly === true.

Implementation
BFF β api/cfields/index.php (Refs #956)
- PUT /{id} (update) β the duplicate-name 400 response now carries the
machine-readable
code: 'cf_name_exists'plus the legacy localized messagelang_get('cf_name_exists', assignLocale())instead of the raw English string (:268-278). This mirrors the pre-existingwarning_no_type_changepattern so the front-ends can map the code onto the localized bundle text. - POST / (create) β the same duplicate-name 400 now also returns
code: 'cf_name_exists'+ localized message (legacydoCreatesurfaceslang_get('cf_name_exists')too,cfieldsEdit.php:311-334).
Screens β cfieldsView.html + cfieldsAssignView.html
- cfieldsView.html
editCf()β removed the.prop('readonly', true)on#editName; the Name input is now a plain editable text box in edit mode, parity with the legacycfieldsEdit.tpl:83-89. - cfieldsAssignView.html
editCf()β same removal: the Assign screen's edit modal can now rename fields too. - Both
saveCf()β the error handler mapsresp.code === 'cf_name_exists'ontoTLi18n.t('cf.msg.nameExists')(fallbackresp.message/cf.msg.errorSaveremain).

i18n
cf.msg.nameExists ("Custom field name already exists. Please choose a new
one") added to all 10 bundles (gui/templates/i18n/{en,de,es,fr,it,ja,pt,ro,ru,zh}.json).
Translations ported from the legacy $TLS_cf_name_exists in
locale/*/strings.txt. All bundles validated with python3 -m json.tool.
Verification evidence (browser + API, fixture project id=1 + fields)
- Rename via cfieldsView edit modal: "Deployment" β "DeploymentPrime"
editable, Save persisted the new name in
custom_fields(label unchanged). - Rename collision (cfieldsView): rename "Tier" β "DeploymentPrime"
rejected, modal shows "Custom field name already exists. Please choose a new
one"; switch to
?locale=roshows "Numele campului personalizat existΔ deja. AlegeΘi alt nume, vΔ rugΔm." β localization works. - Create collision (cfieldsView): Create with an existing name shows the same localized message.
- Assign screen: modal opened from the Assigned-table name link is editable
(
readonly:false); "Tier" β "TierY" persists to the DB and the table re-renders; collision rename shows the localized rejection and keeps the modal open. - Browser console clean; inline JS
node --checkclean;php -lclean; all 10 bundles valid JSON. - Event Viewer /
events: only audit entries (log_level=16), 0 new Error/Warning rows.

Suite 956 in tmp/TLU_Test_Cases.md β 5/5 PASS.
Screenshots mirrored to docs/screenshots/ in the repo:
issue-956-edit-modal-readonly-before.png, issue-956-edit-modal-editable.png,
issue-956-rename-collision-rejected.png, issue-956-rename-support-after.png.
Refs #956.