Skip to content

Add autocomplete attribute to the first name field of the form#2595

Merged
Crabcyborg merged 5 commits into
masterfrom
add-name-field-autocomplete-2
Dec 3, 2025
Merged

Add autocomplete attribute to the first name field of the form#2595
Crabcyborg merged 5 commits into
masterfrom
add-name-field-autocomplete-2

Conversation

@truongwp
Copy link
Copy Markdown
Contributor

@truongwp truongwp commented Nov 21, 2025

Except the name fields inside Repeater.

Fixes https://github.com/Strategy11/formidable-pro/issues/6099

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 21, 2025

Walkthrough

Adds a reusable method in FrmFieldCombo to build sub-field input attributes, overrides it in FrmFieldName to track per-form first-name fields and apply autocomplete to "first"/"last" sub-fields, updates the combo-field front-end view to use the new method, and registers the tracked first-name field during form field loading.

Changes

Cohort / File(s) Summary
Combo field model
classes/models/fields/FrmFieldCombo.php
Adds protected function get_sub_field_input_attrs($sub_field, $args) to centralize construction of sub-field input attributes (type, id, value, data-frmval, name) returned as an array.
Name field model (autocomplete tracking & override)
classes/models/fields/FrmFieldName.php
Adds private static $first_name_field_ids = array();, public static function track_first_name_field($fields), and overrides protected function get_sub_field_input_attrs($sub_field, $args) to apply autocomplete="given-name" / autocomplete="family-name" for the tracked first-name field while skipping repeaters and inheriting parent attributes.
Front-end combo view
classes/views/frm-fields/front-end/combo-field/combo-field.php
Replaces inline building of sub-field input attributes with a call to get_sub_field_input_attrs($sub_field, $args) and uses the returned attribute array when rendering each sub-field input.
Fields helper (tracking hookup)
classes/helpers/FrmFieldsHelper.php
Calls FrmFieldName::track_first_name_field($fields) after loading fields for a form so the first-name field can be tracked before returning paged/filtered fields.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify FrmFieldName::track_first_name_field() reliably identifies the intended first-name field across forms and does not mis-handle multiple first-name fields or nested structures.
  • Confirm FrmFieldName::get_sub_field_input_attrs() correctly detects top-level vs repeater contexts (form_id vs parent_form_id) and only adds autocomplete for the tracked field.
  • Ensure the attribute array shape from FrmFieldCombo::get_sub_field_input_attrs() matches how the view iterates/prints attributes (naming, presence of data-frmval, and escaping/encoding).
  • Review static state use ($first_name_field_ids) for cross-request assumptions and potential lifecycle issues in admin vs front-end.

Possibly related PRs

Suggested reviewers

  • lauramekaj1
  • Crabcyborg

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding autocomplete attributes to the first name field, which is the primary objective of the changeset.
Description check ✅ Passed The description is directly related to the changeset, specifying that autocomplete attributes are added to the first name field excluding those in Repeater, and references the related issue.
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-name-field-autocomplete-2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36e520f and 43e5ce9.

📒 Files selected for processing (3)
  • classes/models/fields/FrmFieldCombo.php (1 hunks)
  • classes/models/fields/FrmFieldName.php (2 hunks)
  • classes/views/frm-fields/front-end/combo-field/combo-field.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
classes/views/frm-fields/front-end/combo-field/combo-field.php (2)
classes/models/fields/FrmFieldCombo.php (1)
  • get_sub_field_input_attrs (517-533)
classes/models/fields/FrmFieldName.php (1)
  • get_sub_field_input_attrs (306-327)
classes/models/fields/FrmFieldCombo.php (1)
classes/models/fields/FrmFieldName.php (1)
  • get_sub_field_input_attrs (306-327)
classes/models/fields/FrmFieldName.php (2)
classes/models/fields/FrmFieldCombo.php (1)
  • get_sub_field_input_attrs (517-533)
classes/models/FrmField.php (2)
  • FrmField (6-1426)
  • get_option (1279-1287)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: PHP 8 tests in WP trunk
  • GitHub Check: PHP 7.4 tests in WP trunk
  • GitHub Check: Cypress
  • GitHub Check: Run ESLint
  • GitHub Check: Run PHP Syntax inspection (8.3)
  • GitHub Check: Run ESLint
  • GitHub Check: Cypress
  • GitHub Check: PHP 8 tests in WP trunk
  • GitHub Check: PHP 7.4 tests in WP trunk
🔇 Additional comments (3)
classes/models/fields/FrmFieldCombo.php (1)

517-533: Well-structured attribute construction method.

The centralized approach for building sub-field input attributes improves maintainability and enables specialized behavior in child classes (like the autocomplete additions in FrmFieldName). The logic correctly handles value population and conditional name attributes.

classes/views/frm-fields/front-end/combo-field/combo-field.php (1)

60-60: Clean refactoring to centralized attribute construction.

The change delegates sub-field input attribute construction to the field type class's get_sub_field_input_attrs() method. This enables child classes like FrmFieldName to inject specialized attributes (such as autocomplete) while keeping the view template clean and maintainable.

classes/models/fields/FrmFieldName.php (1)

316-324: HTML autocomplete attribute values are valid per the standard.

The values given-name and family-name comply with the HTML standard as specified in the WHATWG and MDN documentation.

Per-form tracking behavior is intentional and documented.

The code design explicitly implements per-form tracking using the static property $added_autocomplete_attr keyed by form ID (line 21). The documented purpose (lines 16–17) states: "Track if the autocomplete attribute is added to a name field in each form." This prevents duplicate autocomplete attributes within a single form by allowing the attributes only once per form. The implementation also excludes name fields inside repeaters (lines 309–314). This is an intentional design decision, not a limitation requiring remediation.

Comment thread classes/models/fields/FrmFieldCombo.php
Comment thread classes/models/fields/FrmFieldName.php
Comment thread classes/models/fields/FrmFieldName.php
Comment thread classes/models/fields/FrmFieldName.php Outdated
Comment thread classes/models/fields/FrmFieldName.php Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 2, 2025

Codecov Report

❌ Patch coverage is 8.33333% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 26.38%. Comparing base (7d7fe7d) to head (ef5a7ff).
⚠️ Report is 312 commits behind head on master.

Files with missing lines Patch % Lines
classes/models/fields/FrmFieldName.php 13.63% 19 Missing ⚠️
classes/models/fields/FrmFieldCombo.php 0.00% 14 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #2595      +/-   ##
============================================
- Coverage     26.95%   26.38%   -0.57%     
- Complexity     8838     8852      +14     
============================================
  Files           144      144              
  Lines         29803    29932     +129     
============================================
- Hits           8032     7899     -133     
- Misses        21771    22033     +262     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (3)
classes/models/fields/FrmFieldName.php (3)

296-312: Update the @SInCE version placeholder.

Line 299 uses @since x.x as a placeholder. Please update it to the actual release version number before merging.


314-329: Update the @SInCE version placeholder.

Line 317 uses @since x.x as a placeholder. Please update it to the actual release version number before merging.


331-335: The repeater field detection logic is fundamentally flawed.

Based on detailed past review analysis, this code will not correctly identify fields inside repeaters:

  1. Incorrect data source: parent_form_id is a form-level property stored in the frm_forms table, not a field option. FrmField::get_option() retrieves field options, not form properties.

  2. Inverted logic: The condition returns early when IDs don't match, but the correct approach is to check if the field's form has a non-zero parent_form_id property.

  3. Correct approach: Load the form record via FrmForm::getOne($form_id) and check the form object's parent_form_id property.

Apply this diff to fix the detection:

-	$parent_form_id = (int) FrmField::get_option( $args['field'], 'parent_form_id' );
-	if ( $form_id !== $parent_form_id ) {
-		// Do not add autocomplete attribute to a name field inside repeater.
-		return $attrs;
-	}
+	$form = FrmForm::getOne( $form_id );
+	if ( $form && ! empty( $form->parent_form_id ) ) {
+		// Do not add autocomplete attribute to a name field inside repeater.
+		return $attrs;
+	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 003eabb and ef5a7ff.

📒 Files selected for processing (2)
  • classes/helpers/FrmFieldsHelper.php (1 hunks)
  • classes/models/fields/FrmFieldName.php (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
classes/helpers/FrmFieldsHelper.php (1)
classes/models/fields/FrmFieldName.php (2)
  • FrmFieldName (13-349)
  • track_first_name_field (305-312)
🪛 GitHub Actions: Inspections
classes/models/fields/FrmFieldName.php

[error] 1-1: PHP CS Fixer detected issue (phpdoc_separation). File would be fixed by running the formatter. Command: './vendor/friendsofphp/php-cs-fixer/php-cs-fixer fix --dry-run --verbose'. Exit code: 8.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Cypress
  • GitHub Check: PHP 7.4 tests in WP trunk
  • GitHub Check: PHP 8 tests in WP trunk
🔇 Additional comments (2)
classes/models/fields/FrmFieldName.php (1)

337-348: Autocomplete attribute logic is correct.

The implementation correctly applies autocomplete="given-name" to the "first" sub-field and autocomplete="family-name" to the "last" sub-field for the tracked first name field. This follows HTML autocomplete standards.

However, this relies on the repeater detection logic in lines 331-335, which needs to be fixed first.

classes/helpers/FrmFieldsHelper.php (1)

493-494: No action required - name field tracking works correctly with paginated forms.

The current implementation correctly tracks name fields regardless of pagination. FrmFieldsHelper::get_form_fields() retrieves all fields for a form first, then track_first_name_field() operates on the complete field set before pagination filtering is applied. Name fields on any page (including page 2) are included in this unfiltered list and will be tracked properly.

Comment thread classes/models/fields/FrmFieldName.php
Comment thread classes/models/fields/FrmFieldName.php
@truongwp
Copy link
Copy Markdown
Contributor Author

truongwp commented Dec 2, 2025

@Crabcyborg I use another approach to make this work in paged form and with randomized fields setting. Those Pro features are done in this PR https://github.com/Strategy11/formidable-pro/pull/6122

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
classes/models/fields/FrmFieldCombo.php (1)

509-536: LGTM! Well-structured base method for sub-field attribute generation.

The method correctly builds the attributes array with proper conditional logic for the name attribute based on remove_names flag. This provides a clean extension point for subclasses like FrmFieldName to override and add custom attributes.

One minor note: the @since x.x placeholder on line 513 was already flagged in a previous review and should be updated before merging.

classes/models/fields/FrmFieldName.php (3)

15-20: Fix docblock grammar.

As previously noted, line 18 contains a grammatical error.

Apply this diff:

-	 * @var array Array with keys are form ID and values are name field IDs.
+	 * @var array Array where keys are form IDs and values are name field IDs.

335-339: Verify repeater field exclusion logic.

This was flagged in a previous review: the code retrieves parent_form_id via FrmField::get_option(), but throughout the codebase, parent_form_id is typically a form-level property, not a field option. Please confirm that this approach correctly identifies fields inside repeaters, or adjust the logic to check the form's parent_form_id property instead.


317-326: Update the @SInCE version placeholder.

The @since tag shows "x.x" as a placeholder. Please update it to the actual release version number before merging.

🧹 Nitpick comments (1)
classes/models/fields/FrmFieldName.php (1)

341-349: Minor: Inconsistent integer casting.

Line 341 uses explicit (int) cast, while line 343 uses intval() on the already-integer-keyed array value. Consider using consistent casting for clarity.

-		if ( intval( self::$first_name_field_ids[ $form_id ] ) === $field_id ) {
+		if ( (int) self::$first_name_field_ids[ $form_id ] === $field_id ) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef5a7ff and 518be0c.

📒 Files selected for processing (2)
  • classes/models/fields/FrmFieldCombo.php (3 hunks)
  • classes/models/fields/FrmFieldName.php (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
classes/models/fields/FrmFieldName.php (2)
classes/models/fields/FrmFieldCombo.php (1)
  • get_sub_field_input_attrs (520-536)
classes/models/FrmField.php (2)
  • FrmField (6-1426)
  • get_option (1279-1287)
classes/models/fields/FrmFieldCombo.php (1)
classes/models/fields/FrmFieldName.php (1)
  • get_sub_field_input_attrs (327-352)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Cypress
  • GitHub Check: PHP 8 tests in WP trunk
  • GitHub Check: PHP 7.4 tests in WP trunk
🔇 Additional comments (1)
classes/models/fields/FrmFieldName.php (1)

308-315: No changes needed. The track_first_name_field method correctly receives all form fields, including those on all pages, because FrmField::get_all_for_form() retrieves all fields for a form in a single call without page-based filtering. Multi-page structure is metadata on individual fields, not a retrieval mechanism. The method will find the first name field regardless of which page it appears on.

Copy link
Copy Markdown
Contributor

@Crabcyborg Crabcyborg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested this yet but I think these updates look great!

I'll merge shortly, after I've tried it out.

Thanks @truongwp!

🚀

@Crabcyborg Crabcyborg merged commit e7f4963 into master Dec 3, 2025
15 of 16 checks passed
@Crabcyborg Crabcyborg deleted the add-name-field-autocomplete-2 branch December 3, 2025 13:26
@Crabcyborg Crabcyborg added this to the 6.26 milestone Dec 3, 2025
stephywells pushed a commit that referenced this pull request Apr 4, 2026
Add `autocomplete` attribute to the first name field of the form
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants