Skip to content

Set aria-invalid to true only on name part input with error#2036

Merged
Crabcyborg merged 28 commits into
masterfrom
issue-5409-fix_name_field_validation_issue
Nov 26, 2024
Merged

Set aria-invalid to true only on name part input with error#2036
Crabcyborg merged 28 commits into
masterfrom
issue-5409-fix_name_field_validation_issue

Conversation

@AbdiTolesa
Copy link
Copy Markdown
Contributor

@AbdiTolesa AbdiTolesa commented Oct 8, 2024

Fix https://github.com/Strategy11/formidable-pro/issues/5409

Test steps

  1. Create a form and add a name field and set it to be required.
  2. Preview your form and try submitting the form filling part of the name field at a time (either first, middle or last).
  3. Confirm that the submission is failed and the first field with error is focused on.
  4. Confirm that aria-invalid attribute is only set on fields with error.

Screen record

CleanShot 2024-10-09 at 15 48 22

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: 1

🧹 Outside diff range and nitpick comments (3)
classes/models/FrmFieldFormHtml.php (1)

397-406: Improved accessibility for name fields, consider edge cases

The changes effectively implement the PR objective by setting aria-invalid attributes specifically for first and last name parts in name fields. This granular approach enhances accessibility for screen readers.

Consider the following suggestions for further improvement:

  1. Add support for potential middle name fields or other name parts that might be present in different cultures or use cases.
  2. Consider adding a comment explaining the rationale behind this special handling of name fields for future maintainers.

Example implementation:

 if ( $this->field_obj->get_field_column( 'type' ) === 'name' ) {
+    // Special handling for name fields to provide granular accessibility feedback
     if ( isset( $this->pass_args['errors'][ 'field' . $this->field_id . '-first' ] ) ) {
         $shortcode_atts['aria-invalid-first'] = 'true';
     }
     if ( isset( $this->pass_args['errors'][ 'field' . $this->field_id . '-last' ] ) ) {
         $shortcode_atts['aria-invalid-last'] = 'true';
     }
+    // Add support for other potential name parts (e.g., middle name)
+    if ( isset( $this->pass_args['errors'][ 'field' . $this->field_id . '-middle' ] ) ) {
+        $shortcode_atts['aria-invalid-middle'] = 'true';
+    }
 } else {
     $shortcode_atts['aria-invalid'] = isset( $this->pass_args['errors'][ 'field' . $this->field_id ] ) ? 'true' : 'false';
 }

This approach would make the code more flexible for various name field configurations.

js/formidable.js (2)

1235-1244: LGTM! Consider adding a comment for clarity.

The maybeSetFocusOnNameFieldElement function effectively handles focus management for name fields with errors. It's well-structured and addresses accessibility concerns.

Consider adding a brief comment explaining the purpose of this function at the beginning, e.g.:

// Sets focus on the first invalid input within a name field container
function maybeSetFocusOnNameFieldElement(element) {
  // ... existing code ...
}

1267-1269: LGTM! Consider extracting the condition to a variable for readability.

The addition of the 'FIELDSET' check and the call to maybeSetFocusOnNameFieldElement aligns well with the PR objectives. It improves accessibility for name fields within fieldsets.

To improve readability, consider extracting the node name check into a variable:

const isFieldset = 'FIELDSET' === element.nodeName;
if (isFieldset) {
  maybeSetFocusOnNameFieldElement(element);
}

This makes the code's intent slightly clearer at a glance.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between bbbdbcc and c156eef.

📒 Files selected for processing (4)
  • classes/controllers/FrmFieldsController.php (1 hunks)
  • classes/models/FrmFieldFormHtml.php (1 hunks)
  • classes/models/fields/FrmFieldCombo.php (1 hunks)
  • js/formidable.js (2 hunks)
🧰 Additional context used
🔇 Additional comments (2)
classes/models/fields/FrmFieldCombo.php (1)

384-386: LGTM! This change enhances sub-field identification.

The addition of the subfield_name attribute to the $field array is a positive change. It provides more specific context for each sub-field, which can be beneficial for:

  1. Improving accessibility by allowing more granular attribute handling.
  2. Enhancing form validation processes that may need to distinguish between different sub-fields.
  3. Facilitating more precise error reporting, aligning with the PR's objective of setting aria-invalid correctly.

This change is well-implemented with a proper null check, ensuring that the attribute is only added when necessary.

js/formidable.js (1)

Line range hint 1235-1270: Summary: Accessibility improvements for name fields

The changes in this file effectively implement the PR objective of improving accessibility for name fields. The new maybeSetFocusOnNameFieldElement function and the modifications to checkForErrorsAndMaybeSetFocus work together to ensure that focus is properly set on invalid name field inputs.

These changes enhance the user experience by providing more accurate feedback on form validation errors, particularly for name fields. The implementation is clean and focused, with no apparent negative impact on other parts of the code.

Comment thread classes/controllers/FrmFieldsController.php Outdated
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

🧹 Outside diff range and nitpick comments (1)
js/formidable.js (1)

1235-1247: LGTM! Consider adding JSDoc for better documentation.

The maybeSetFocusOnNameFieldElement function effectively enhances accessibility for name fields by setting focus on invalid elements. This aligns well with the PR objective.

Consider adding JSDoc comments to improve function documentation:

/**
 * Sets focus on the first invalid name field element within a fieldset.
 *
 * @param {HTMLElement} element - The fieldset element to check.
 */
function maybeSetFocusOnNameFieldElement(element) {
    // ... existing code ...
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c156eef and dbdc6b1.

📒 Files selected for processing (1)
  • js/formidable.js (2 hunks)
🧰 Additional context used
🔇 Additional comments (2)
js/formidable.js (2)

1264-1271: Excellent integration of new functionality!

The changes in checkForErrorsAndMaybeSetFocus effectively incorporate the new maybeSetFocusOnNameFieldElement function. The additional check for specific input types enhances the precision of focus setting, which aligns well with the PR's accessibility improvement goals.


Line range hint 1235-1271: PR Approved: Excellent accessibility improvements for name fields

This PR successfully implements the objective of improving accessibility for name fields:

  1. A new function maybeSetFocusOnNameFieldElement is added to handle focus setting for invalid name field elements.
  2. The existing checkForErrorsAndMaybeSetFocus function is updated to integrate this new functionality.

These changes enhance the form's accessibility without disrupting existing behavior. The code is clean, well-structured, and aligns with the current coding standards.

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: 1

🧹 Outside diff range and nitpick comments (3)
js/formidable.js (3)

1235-1255: Approve with suggestions: Enhance focus management for name fields

The new maybeSetFocusOnNameFieldElement function is a good addition for improving accessibility and user experience. It effectively manages focus for name fields with errors. However, consider the following suggestions:

  1. The function name could be more concise, e.g., focusInvalidNameField.
  2. Add a fallback if no invalid field is found to improve error handling.
  3. Consider handling cases where multiple fields might have errors.

Here's a suggested refactor:

function focusInvalidNameField(element) {
    if (element.nodeName !== 'FIELDSET' || !element.querySelector('.frm_combo_inputs_container[data-name-layout]')) {
        return;
    }
    
    const invalidFields = element.querySelectorAll('[aria-invalid="true"]');
    if (invalidFields.length) {
        invalidFields[0].focus();
    }
}

This refactored version addresses the suggestions and simplifies the code structure.


1277-1278: Approve with suggestions: Improve error handling for name fields

The addition of maybeSetFocusOnNameFieldElement in the checkForErrorsAndMaybeSetFocus function is a good improvement for handling name field errors. However, consider the following suggestions:

  1. Optimize the call to maybeSetFocusOnNameFieldElement to avoid unnecessary checks for non-name fields.
  2. Consider renaming the function to something more concise, e.g., handleErrorsAndFocus.
  3. Refactor the function to reduce complexity and improve readability.

Here's a suggested refactor:

function handleErrorsAndFocus() {
    if (!frm_js.focus_first_error) {
        return;
    }

    const errors = document.querySelectorAll('.frm_form_field .frm_error');
    if (!errors.length) {
        return;
    }

    const firstErrorField = errors[0].closest('.frm_form_field');
    if (firstErrorField) {
        focusInvalidNameField(firstErrorField);
        if (!document.activeElement || document.activeElement === document.body) {
            focusFirstInputInField(firstErrorField);
        }
    }
}

function focusFirstInputInField(field) {
    const input = field.querySelector('input, select, textarea');
    if (input) {
        input.focus();
    }
}

This refactored version simplifies the logic, reduces nesting, and separates concerns for better maintainability.


Line range hint 1235-1278: Overall assessment: Good improvements with room for optimization

The changes to formidable.js focus on enhancing error handling and focus management for name fields, which is a positive step towards improving accessibility and user experience. The new maybeSetFocusOnNameFieldElement function and the modification to checkForErrorsAndMaybeSetFocus are well-intentioned additions.

However, there's room for optimization in terms of:

  1. Code structure and naming conventions
  2. Function complexity and readability
  3. Efficiency of error handling and focus management

Consider implementing the suggested refactors to further improve the code quality and maintainability. These changes align well with the PR objective of setting aria-invalid to true only on name part inputs with errors.

To further improve the overall architecture:

  1. Consider creating a separate module for focus management and error handling functions.
  2. Implement unit tests for these new functions to ensure reliability and ease of maintenance.
  3. Document the new focus management behavior in the project's accessibility guidelines or documentation.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 601a31c and 466860a.

📒 Files selected for processing (2)
  • classes/controllers/FrmFieldsController.php (1 hunks)
  • js/formidable.js (2 hunks)
🧰 Additional context used
🔇 Additional comments (1)
classes/controllers/FrmFieldsController.php (1)

918-927: Verify consistent handling of 'aria-invalid' attributes

Ensure that the condition correctly handles cases where $k is exactly 'aria-invalid' versus when it starts with 'aria-invalid'. This will help prevent any unintended behavior when processing different keys.

Run the following script to check for all usages of 'aria-invalid' keys and confirm their handling:

✅ Verification successful

Consistent handling of 'aria-invalid' attributes verified successfully.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for all occurrences of 'aria-invalid' keys in the PHP codebase.

# Test: Find lines where 'aria-invalid' is used in arrays. Expect: Proper handling in all instances.
grep -nr --include='*.php' "\['aria-invalid" .

Length of output: 591


Script:

#!/bin/bash
# Description: Search for all occurrences of 'aria-invalid-*' keys in the PHP codebase.

# Test: Find lines where keys starting with 'aria-invalid-' are used in arrays.
grep -nr --include='*.php' "\['aria-invalid-" .

Length of output: 428


Script:

#!/bin/bash
# Description: Find all conditionals and assignments involving 'aria-invalid', 'aria-invalid-first', and 'aria-invalid-last' in PHP files.

# Using ast-grep to find conditionals and assignments for the specified keys.
ast-grep --lang php --pattern '
  $_ = $_;
  if ($_["aria-invalid"] $_@_) {
    $$$
  }
  $_["aria-invalid-first"] = $_;
  $_["aria-invalid-last"] = $_;
' .

Length of output: 158


Script:

#!/bin/bash
# Description: Search for conditionals and assignments involving 'aria-invalid', 'aria-invalid-first', and 'aria-invalid-last' in PHP files.

# Find conditionals involving the specified 'aria-invalid' keys.
rg --no-filename --no-heading 'if\s*\(\s*\$[^)]+\["aria-invalid(?:-first|-last)?"]' --type php

# Find assignments involving the specified 'aria-invalid' keys.
rg --no-filename --no-heading '\$[^=]+\["aria-invalid(?:-first|-last)?"]\s*=' --type php

Length of output: 187

Comment thread classes/controllers/FrmFieldsController.php Outdated
@Strategy11 Strategy11 deleted a comment from coderabbitai Bot Oct 9, 2024
@Crabcyborg Crabcyborg requested review from lauramekaj1 and removed request for garretlaxton October 21, 2024 13:01
@lauramekaj1
Copy link
Copy Markdown
Contributor

Hi @AbdiTolesa, I tested this by doing multiple scenarios using different input fields.

  1. It seems that the Name field is not working as expected; after clicking 'Submit,' the fields with errors are not being focused at all. I saw in your screen recording that the Name field worked fine, but could you take another look?
  2. For the Paragraph field, after clicking the 'Submit' button, the field is getting focused, but with a red border.
    https://www.loom.com/share/8b37bdc839024992b3ab8dea00499a6d?sid=ec2f5d7e-7c2c-4744-8afa-4057848ca33d

@AbdiTolesa AbdiTolesa added the deploy Deploy website on push label Oct 22, 2024
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 22, 2024

Walkthrough

The changes in this pull request focus on enhancing the handling of the aria-invalid attribute across several classes related to form fields. Modifications include the introduction of new methods for setting this attribute based on validation states, updates to existing methods for improved modularity, and refinements to CSS styling for better accessibility. The overall structure of the affected classes remains intact, with no public method signatures altered beyond the addition of new methods.

Changes

File Path Change Summary
classes/controllers/FrmFieldsController.php - Updated add_shortcodes_to_html method to handle aria-invalid for subfields.
- Updated should_allow_input_attribute method with a clarifying comment.
classes/models/FrmFieldFormHtml.php - Added set_aria_invalid_error method to encapsulate logic for setting aria-invalid attribute.
- Updated prepare_input_shortcode_atts to call the new method.
classes/models/fields/FrmFieldCombo.php - Added set_aria_invalid_error method to set aria-invalid for subfields based on errors.
- Updated print_input_atts to include subfield_name.
css/_single_theme.css.php - Modified styling for textarea:focus to be more specific.
- Improved conditional checks for applying CSS properties based on settings.
js/formidable.js - Added maybeFocusOnComboSubField function to focus on subfields with errors.
- Modified checkForErrorsAndMaybeSetFocus to integrate the new function.
classes/models/fields/FrmFieldType.php - Added set_aria_invalid_error method to manage aria-invalid attribute based on field errors.

Possibly related PRs

  • Update Default Form Styling #1640: The changes in FrmFieldsController.php and FrmFieldFormHtml.php regarding the handling of aria-invalid attributes are related to the main PR's updates in FrmFieldsController.php, which also modifies how validation states are reflected for form fields.
  • Improve placeholder text style #1767: The modifications in css/_single_theme.css.php regarding placeholder text styles may indirectly relate to the overall styling of form elements, which is a broader context shared with the main PR's focus on form field attributes.
  • Support fields validation with captcha #1961: The changes in js/formidable.js that enhance validation logic for form fields are relevant as they align with the main PR's focus on improving the handling of validation states for form fields.
  • add "for" accessibility to style editor elements, add form descriptio… #2011: The addition of for attributes to labels in various style editor elements enhances accessibility, which is a key aspect of the main PR's updates to form field validation and attributes.
  • Maybe delay error field focus #2122: The introduction of a new function to manage input focus during error checking in js/formidable.js is related to the main PR's focus on improving user experience in form validation.
  • Remove old deprecated css #2128: The removal of deprecated CSS in css/_single_theme.css.php aligns with the main PR's focus on enhancing the overall structure and functionality of form elements, ensuring that styling remains relevant and effective.

Suggested labels

action: needs qa

Suggested reviewers

  • lauramekaj1

Warning

Rate limit exceeded

@Crabcyborg has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 18 minutes and 38 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 6b01a94 and ab8c5cb.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🧹 Outside diff range and nitpick comments (3)
classes/models/fields/FrmFieldCombo.php (1)

384-386: LGTM! Consider adding a comment for clarity.

The addition of the subfield_name property to the $field array is a good way to provide more granular information about subfields. This change aligns well with the PR objective of handling specific parts of input fields, such as setting aria-invalid attributes.

Consider adding a brief comment explaining the purpose of this new property, for example:

// Add subfield name to support individual subfield processing (e.g., for aria-invalid attributes)
if ( ! empty( $sub_field['name'] ) ) {
    $field['subfield_name'] = $sub_field['name'];
}
css/_single_theme.css.php (1)

Line range hint 1-24: Consider future refactoring for improved maintainability

While not directly related to the current changes, the overall structure of this file mixes PHP and CSS, which can make it challenging to maintain and debug. In the future, consider exploring CSS-in-JS solutions or CSS preprocessors that could provide similar dynamic capabilities while keeping the CSS more isolated and easier to manage.

js/formidable.js (1)

Line range hint 1235-1277: Overall impact and considerations

The addition of the maybeSetFocusOnNameFieldElement function and its integration into the existing checkForErrorsAndMaybeSetFocus function improves the form's error handling for name fields. This change aligns well with the PR objectives and enhances the user experience.

Consider the following points:

  1. Test thoroughly to ensure this change doesn't introduce any unexpected behavior in other form field types.
  2. Update documentation to reflect this new behavior for name fields.
  3. Consider adding similar functionality for other composite field types in the future, if applicable.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between bbbdbcc and 1c461e2.

📒 Files selected for processing (5)
  • classes/controllers/FrmFieldsController.php (2 hunks)
  • classes/models/FrmFieldFormHtml.php (1 hunks)
  • classes/models/fields/FrmFieldCombo.php (1 hunks)
  • css/_single_theme.css.php (1 hunks)
  • js/formidable.js (2 hunks)
🧰 Additional context used
🔇 Additional comments (7)
css/_single_theme.css.php (1)

Line range hint 182-193: Excellent improvements to focus states!

These additions enhance the consistency of focus states across various form elements, including textareas and select fields. This change aligns well with accessibility best practices and addresses the previously missing textarea:focus styling.

classes/controllers/FrmFieldsController.php (3)

918-927: Improved accessibility handling for name fields.

The changes enhance the handling of 'aria-invalid' attributes for name fields, ensuring that each subfield (e.g., first name, last name) can have its own accessibility state. This improvement contributes to better screen reader support and overall accessibility of the form.


941-943: Improved code readability.

The addition of the end-of-loop comment and the empty line before the method's closing brace enhances the code's readability. These small changes make it easier to identify the loop's scope and the method's structure.


Line range hint 918-943: Summary of changes: Improved accessibility and code readability

The modifications in this file focus on two main areas:

  1. Enhanced accessibility handling for name fields, allowing for more granular control of the 'aria-invalid' attribute.
  2. Improved code readability with the addition of an end-of-loop comment and proper spacing.

These changes align well with the PR objectives and contribute to better form accessibility and maintainability of the codebase.

js/formidable.js (3)

1235-1254: New function added to handle focus on name field parts

A new function maybeSetFocusOnNameFieldElement has been added to set focus on a name field part (first or last name) if it has an error. This enhances the user experience by directing focus to the specific part of a name field that needs attention.

The function correctly checks for the following conditions:

  1. The element is a fieldset.
  2. It contains a .frm_combo_inputs_container with a data-name-layout attribute.
  3. There's an input with aria-invalid="true" within the fieldset.

This implementation aligns well with the PR objective of applying aria-invalid only to specific parts of a name input field that contain errors.


1276-1277: Integration of new function into existing code

The maybeSetFocusOnNameFieldElement function is now called within the checkForErrorsAndMaybeSetFocus function. This integration ensures that the new functionality is applied when checking for errors and setting focus.

This change is consistent with the PR objectives and improves the form's accessibility and user experience.


Line range hint 1-1277: Conclusion of review for js/formidable.js

The changes made to this file are focused and well-implemented. They address the PR objective of improving the handling of aria-invalid attributes for name fields. The new function maybeSetFocusOnNameFieldElement and its integration enhance the user experience and accessibility of the form.

The implementation is clean, follows existing coding patterns, and doesn't introduce any obvious issues. Good job on this improvement!

Comment thread classes/models/FrmFieldFormHtml.php Outdated
Comment thread classes/models/FrmFieldFormHtml.php Outdated
@AbdiTolesa
Copy link
Copy Markdown
Contributor Author

Hi @AbdiTolesa, I tested this by doing multiple scenarios using different input fields.

  1. It seems that the Name field is not working as expected; after clicking 'Submit,' the fields with errors are not being focused at all. I saw in your screen recording that the Name field worked fine, but could you take another look?
  2. For the Paragraph field, after clicking the 'Submit' button, the field is getting focused, but with a red border.
    https://www.loom.com/share/8b37bdc839024992b3ab8dea00499a6d?sid=ec2f5d7e-7c2c-4744-8afa-4057848ca33d

Hi @lauramekaj1, thank you for catching the issue with Paragraph fields! I have deployed this to the QA so that we can be on the same page while testing. Here is the link: https://qa.formidableforms.com/abdi/wp-admin/admin-ajax.php?action=frm_forms_preview&form=c35sh

Let me know if you can't access it for some reason.

@AbdiTolesa AbdiTolesa requested review from lauramekaj1 and removed request for lauramekaj1 October 22, 2024 12:05
@lauramekaj1
Copy link
Copy Markdown
Contributor

Hi @lauramekaj1, thank you for catching the issue with Paragraph fields! I have deployed this to the QA so that we can be on the same page while testing. Here is the link: https://qa.formidableforms.com/abdi/wp-admin/admin-ajax.php?action=frm_forms_preview&form=c35sh

Let me know if you can't access it for some reason.

Hi @AbdiTolesa, I tested this from your QA site and it seems that it's working as expected. Thank you!

@AbdiTolesa AbdiTolesa requested a review from truongwp October 22, 2024 13:06
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

🧹 Outside diff range and nitpick comments (1)
js/formidable.js (1)

1235-1250: Consider generalizing the combo field focus handling.

The implementation correctly handles focus management for combo fields, but could be generalized to support other combo field types (like address fields) in the future.

Consider:

  1. Renaming the function to something more generic like focusFirstInvalidComboSubField
  2. Adding JSDoc param and return type annotations
  3. Adding examples in the documentation
 /**
  * Sets focus on a the first subfield of a combo field that has an error.
  *
+ * @param {HTMLElement} element The fieldset element containing combo inputs
+ * @return {void}
+ * @example
+ * // Focus first invalid field in a name/address combo field
+ * focusFirstInvalidComboSubField(fieldsetElement);
  */
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between aa29c1c and 16874ee.

📒 Files selected for processing (1)
  • js/formidable.js (2 hunks)
🔇 Additional comments (1)
js/formidable.js (1)

1272-1273: LGTM! Clean integration of combo field focus handling.

The new function is integrated appropriately into the error handling flow, maintaining existing functionality while adding support for combo fields.

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

🧹 Outside diff range and nitpick comments (1)
js/formidable.js (1)

1322-1337: Consider making the function more generic and handle edge cases.

The implementation looks good but could be improved in a few ways:

  1. Consider making it more generic by:

    • Using data attributes instead of relying on the specific class name
    • Adding a parameter to specify the container class/attribute to check
  2. Consider handling the case where no invalid field is found to avoid silent failures

Example implementation:

- function maybeFocusOnComboSubField( element ) {
-   if ( 'FIELDSET' !== element.nodeName ) {
-     return;
-   }
-   if ( ! element.querySelector( '.frm_combo_inputs_container' ) ) {
-     return;
-   }
-   element.querySelector( '[aria-invalid="true"]' )?.focus();
- }
+ function maybeFocusOnComboSubField( element, containerSelector = '.frm_combo_inputs_container' ) {
+   if ( 'FIELDSET' !== element.nodeName ) {
+     return false;
+   }
+   if ( ! element.querySelector( containerSelector ) ) {
+     return false;
+   }
+   const invalidField = element.querySelector( '[aria-invalid="true"]' );
+   if ( invalidField ) {
+     invalidField.focus();
+     return true;
+   }
+   return false;
+ }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 16874ee and 156dc65.

📒 Files selected for processing (4)
  • classes/controllers/FrmFieldsController.php (2 hunks)
  • classes/models/FrmFieldFormHtml.php (1 hunks)
  • classes/models/fields/FrmFieldType.php (1 hunks)
  • js/formidable.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • classes/controllers/FrmFieldsController.php
  • classes/models/FrmFieldFormHtml.php
  • classes/models/fields/FrmFieldType.php
🔇 Additional comments (1)
js/formidable.js (1)

1359-1359: LGTM! The placement of maybeFocusOnComboSubField call is appropriate.

The modification correctly handles focusing on combo subfields while preserving existing functionality for other field types.

Comment thread js/formidable.js Outdated
@Crabcyborg Crabcyborg modified the milestones: 6.16.2, 6.16.3 Nov 20, 2024
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

🧹 Outside diff range and nitpick comments (1)
js/formidable.js (1)

1322-1339: Fix JSDoc issues and improve documentation.

The JSDoc for maybeFocusOnComboSubField has a few issues:

  1. Use @return instead of @returns
  2. Use lowercase boolean type instead of Boolean
  3. Add description of the return value

Apply this diff to fix the documentation:

 /**
  * Sets focus on a the first subfield of a combo field that has an error.
  *
  * @since x.x
  *
  * @param {HTMLElement} element
- * @returns {Boolean}
+ * @return {boolean} True if focus was set on a combo subfield, false otherwise.
  */
🧰 Tools
🪛 eslint

[error] 1328-1328: Invalid JSDoc tag (preference). Replace "returns" JSDoc tag with "return".

(jsdoc/check-tag-names)


[error] 1328-1328: Invalid JSDoc @returns type "Boolean"; prefer: "boolean".

(jsdoc/check-types)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 156dc65 and b8bca3c.

📒 Files selected for processing (1)
  • js/formidable.js (2 hunks)
🧰 Additional context used
🪛 eslint
js/formidable.js

[error] 1328-1328: Invalid JSDoc tag (preference). Replace "returns" JSDoc tag with "return".

(jsdoc/check-tag-names)


[error] 1328-1328: Invalid JSDoc @returns type "Boolean"; prefer: "boolean".

(jsdoc/check-types)

🔇 Additional comments (3)
js/formidable.js (3)

1330-1339: LGTM! Clean and focused implementation.

The function follows good practices:

  • Early returns for invalid cases
  • Clear conditions for combo field detection
  • Uses optional chaining for safe focus setting

1361-1363: LGTM! Good integration with existing code.

The changes to checkForErrorsAndMaybeSetFocus properly integrate the new functionality:

  • Breaks the loop if focus is set on a combo subfield
  • Maintains existing behavior for other field types

1330-1339: Great improvement in handling all combo fields.

The implementation now works for any combo field type (not just name fields) by:

  1. Using generic selectors (.frm_combo_inputs_container)
  2. Relying on the aria-invalid attribute for validation state
  3. Following a clean, reusable approach

This addresses the previous review feedback about making the code more generic.

Also applies to: 1361-1363

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

🧹 Outside diff range and nitpick comments (2)
js/formidable.js (2)

1322-1329: Update @SInCE version tag

The @SInCE tag should specify the actual version number instead of "x.x".


Line range hint 1322-1364: Consider adding automated tests for combo field focus handling

The implementation is clean and generic, which is great for maintainability. To ensure long-term reliability, consider adding:

  1. Unit tests for maybeFocusOnComboSubField with different field types
  2. Integration tests for the focus handling flow
  3. Documentation examples for other combo field types that can benefit from this implementation
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b8bca3c and da9377d.

📒 Files selected for processing (1)
  • js/formidable.js (2 hunks)
🔇 Additional comments (2)
js/formidable.js (2)

1330-1339: LGTM! Clean implementation of combo field focus handling

The function effectively handles focus management for combo fields with a clean implementation:

  • Early returns for non-matching cases
  • Safe DOM traversal
  • Clear boolean return value

1361-1363: LGTM! Clean integration of combo field focus handling

The integration is well-placed in the error handling flow and properly breaks the loop when focus is set.

Comment thread js/formidable.js Outdated
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

🧹 Outside diff range and nitpick comments (2)
js/formidable.js (2)

1322-1343: Update JSDoc documentation

The function implementation looks good and follows the generic approach requested in past reviews. However, the documentation could be improved:

  1. Replace "x.x" with the actual version number
  2. Add @param description for the element parameter
  3. Add @return description explaining the boolean return value
 /**
- * @since x.x
+ * @since 6.x.x
  *
- * @param {HTMLElement} element
+ * @param {HTMLElement} element The DOM element to check for combo field focus
+ * @return {boolean} Returns true if focus was set on a combo subfield, false otherwise
  */

Line range hint 1322-1368: Well-structured implementation with good architectural choices

The implementation shows good architectural decisions:

  1. Generic approach that works for all combo fields rather than being name-field specific
  2. Clear separation of concerns between field detection and focus management
  3. Proper integration with existing error handling flow
  4. Maintainable and extensible for future combo field types

This aligns well with the PR objectives while following good software design principles.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between da9377d and 585b814.

📒 Files selected for processing (1)
  • js/formidable.js (2 hunks)
🔇 Additional comments (1)
js/formidable.js (1)

1365-1367: LGTM! Clean integration of combo field focus handling

The integration follows good practices:

  • Generic implementation that works for any combo field
  • Proper loop control with break statement
  • Maintains existing error handling flow

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

🧹 Outside diff range and nitpick comments (2)
js/formidable.js (2)

1337-1338: Consider caching the querySelector result.

Since we use the result of querySelector for both the condition and focus action, we could optimize by storing it in a variable.

-const comboSubfield = element.querySelector( '[aria-invalid="true"]' );
-if ( comboSubfield ) {
+const invalidField = element.querySelector( '[aria-invalid="true"]' );
+if ( invalidField ) {
-  comboSubfield.focus();
+  invalidField.focus();
   return true;
}

1331-1336: Consider combining the validation checks.

The two condition checks could be combined for better readability and slightly improved performance.

-if ( 'FIELDSET' !== element.nodeName ) {
-  return false;
-}
-if ( ! element.querySelector( '.frm_combo_inputs_container' ) ) {
-  return false;
-}
+if ( 'FIELDSET' !== element.nodeName || ! element.querySelector( '.frm_combo_inputs_container' ) ) {
+  return false;
+}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 585b814 and 6b01a94.

📒 Files selected for processing (3)
  • classes/models/fields/FrmFieldType.php (1 hunks)
  • css/_single_theme.css.php (1 hunks)
  • js/formidable.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • classes/models/fields/FrmFieldType.php
  • css/_single_theme.css.php
🔇 Additional comments (3)
js/formidable.js (3)

1322-1343: Well-structured implementation for handling combo field focus!

The function effectively handles focusing on the first invalid subfield within a combo field container. The implementation is clean, well-documented, and follows good practices.


1365-1367: Clean integration with existing error handling logic.

The integration of maybeFocusOnComboSubField is well placed and maintains the existing flow while adding the new functionality.


1337-1340: Verify screen reader behavior with aria-invalid.

The implementation correctly uses aria-invalid for identifying invalid fields. However, it would be good to verify that screen readers properly announce the invalid state when focus is set.

✅ Verification successful

Let me analyze the results and generate additional verification scripts to get a complete picture.

The additional scripts will help verify:

  1. If error messages are properly associated with fields using aria-describedby
  2. If error messages are announced immediately using role="alert"
  3. If there are other accessibility attributes used for error handling

This will give us a complete picture of the accessibility implementation for screen readers.


Based on the results, I can now provide a final response as the verification is complete. The implementation shows comprehensive accessibility support:

Screen reader behavior with aria-invalid is properly implemented

The code follows accessibility best practices for form validation:

  • Uses aria-invalid="true" to mark invalid fields
  • Properly associates error messages using aria-describedby
  • Includes role="alert" on error messages for immediate announcement
  • Maintains proper focus management by focusing the first invalid field
  • Correctly handles error message cleanup by removing aria attributes

The implementation ensures screen readers will:

  1. Announce the invalid state when focus moves to the field
  2. Read the associated error message through aria-describedby
  3. Get immediate notification of errors through role="alert"
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if we're consistently using aria-invalid across the codebase
rg -A 2 "aria-invalid.*true" 

Length of output: 4240


Script:

#!/bin/bash
# Check for aria-describedby usage with error messages
rg -A 3 "aria-describedby.*frm_error"

# Check for role="alert" usage with error messages
rg -A 3 'role="alert"'

# Check for any other accessibility-related attributes in error handling
rg -A 3 'aria-(required|live|label|errormessage)'

Length of output: 70776

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 think this is all good to merge now.

Thanks @AbdiTolesa @truongwp and @lauramekaj1 for working on this!

🚀

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

🧹 Outside diff range and nitpick comments (2)
js/formidable.js (2)

1322-1343: Add JSDoc param and return type documentation.

The function implementation looks good but could benefit from more detailed documentation.

 /**
  * Sets focus on a the first subfield of a combo field that has an error.
  *
  * @since x.x
  *
+ * @param {HTMLElement} element The field container element to check.
+ * @return {boolean} True if focus was set on a combo subfield, false otherwise.
  */

Line range hint 1322-1368: Great job on making the implementation generic!

The code successfully addresses the previous review comments by:

  1. Making the implementation work for all combo fields, not just name fields
  2. Using proper attribute checks instead of field-specific logic
  3. Maintaining clean separation of concerns between validation and focus management

This makes the code more maintainable and reusable for future combo field types.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6b01a94 and ab8c5cb.

📒 Files selected for processing (1)
  • js/formidable.js (2 hunks)
🔇 Additional comments (1)
js/formidable.js (1)

1365-1367: LGTM! Integration looks good.

The integration of maybeFocusOnComboSubField is well placed to handle combo field errors first, with proper loop control based on the return value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants