Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions classes/models/fields/FrmFieldCheckbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,8 @@ public function displayed_field_type( $field ) {
* @return array
*/
protected function extra_field_opts() {
$form_id = $this->get_field_column( 'form_id' );

return array(
'align' => FrmStylesController::get_style_val( 'check_align', ( empty( $form_id ) ? 'default' : $form_id ) ),
'align' => '',
);
}

Expand Down
4 changes: 1 addition & 3 deletions classes/models/fields/FrmFieldRadio.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,8 @@ public function displayed_field_type( $field ) {
* @return array
*/
protected function extra_field_opts() {
$form_id = $this->get_field_column( 'form_id' );

return array(
'align' => FrmStylesController::get_style_val( 'radio_align', ( empty( $form_id ) ? 'default' : $form_id ) ),
'align' => '',
);
}

Expand Down
4 changes: 2 additions & 2 deletions classes/models/fields/FrmFieldType.php
Original file line number Diff line number Diff line change
Expand Up @@ -964,8 +964,8 @@ public function get_container_class() {
$align = FrmField::get_option( $this->field, 'align' );

$class = '';
if ( ! empty( $align ) && ( $is_radio || $is_checkbox ) ) {
self::prepare_align_class( $align );
if ( $is_radio || $is_checkbox ) {
$this->prepare_align_class( $align );
$class .= ' ' . $align;
}

Expand Down
31 changes: 23 additions & 8 deletions classes/views/styles/_check-box-radio-fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,25 @@ class="frm-style-item-heading"><?php esc_html_e( 'Check Box', 'formidable' ); ?>
</div>
<div class="frm7 frm_form_field">
<?php
$align_options = array(
'block' => __( 'One Column', 'formidable' ),
'inline' => __( 'Inline Options', 'formidable' ),
);

/**
* @since x.x
*
* @param array $align_options
* @param array $atts
*/
$checkbox_align_options = apply_filters( 'frm_checkbox_align_options', $align_options, $atts );

new FrmDropdownStyleComponent(
$frm_style->get_field_name( 'check_align' ),
$style->post_content['check_align'],
array(
'id' => 'frm_check_align',
'options' => array(
'block' => esc_html__( 'Multiple Rows', 'formidable' ),
'inline' => esc_html__( 'Single Row', 'formidable' ),
),
'options' => $checkbox_align_options,
)
);
?>
Expand All @@ -85,15 +95,20 @@ class="frm-style-item-heading"><?php esc_html_e( 'Radio', 'formidable' ); ?></la
</div>
<div class="frm7 frm_form_field">
<?php
/**
* @since x.x
*
* @param array $align_options
* @param array $atts
*/
$radio_align_options = apply_filters( 'frm_radio_align_options', $align_options, $atts );

new FrmDropdownStyleComponent(
$frm_style->get_field_name( 'radio_align' ),
$style->post_content['radio_align'],
array(
'id' => 'frm_radio_align',
'options' => array(
'block' => esc_html__( 'Multiple Rows', 'formidable' ),
'inline' => esc_html__( 'Single Row', 'formidable' ),
),
'options' => $radio_align_options,
)
);
?>
Expand Down
2 changes: 1 addition & 1 deletion css/admin/frm-settings-components.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion css/frm_admin.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion css/frm_testing_mode.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/addons-page.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/addons-page.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/form-templates.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/form-templates.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable-settings-components.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable-settings-components.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable_admin.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable_admin.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable_blocks.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable_blocks.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable_dashboard.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable_dashboard.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable_overlay.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion js/formidable_overlay.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable_styles.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/formidable_styles.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/frm_testing_mode.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/onboarding-wizard.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/onboarding-wizard.js.map

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions js/src/admin/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -6755,6 +6755,9 @@ window.frmAdminBuildJS = function() {
replaceWith = ' ' + setting.value,
fieldId = field.getAttribute( 'data-fid' );

if ( '' === replaceWith.trim() ) {
replaceWith = ' ' + setting.querySelector( 'option[data-align]' ).getAttribute( 'data-align' );
}
Comment on lines +6758 to +6760
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard data-align fallback and use the selected option instead of the first match

The new fallback assumes:

  • setting always has an option[data-align], and
  • the first such option is the one currently selected.

This can cause issues:

  1. Potential runtime error: If setting is a text input (e.g., .frm_classes) with an empty value, or a <select> without any option[data-align], then setting.querySelector( 'option[data-align]' ) returns null and .getAttribute( 'data-align' ) will throw.

  2. Wrong alignment when multiple options have data-align: querySelector( 'option[data-align]' ) always returns the first matching option, not the selected one, so the applied class may not match the user’s current choice.

  3. Over‑broad application: The fallback should only apply to the align dropdown (.field_options_align), not to every control wired through changeFieldClass.

Recommend tightening the logic to:

  • Only run for the align select.
  • Read data-align from the selected option.
  • Gracefully no‑op if no data-align is available.

For example:

-		if ( '' === replaceWith.trim() ) {
-			replaceWith = ' ' + setting.querySelector( 'option[data-align]' ).getAttribute( 'data-align' );
-		}
+		if ( '' === replaceWith.trim() && setting.classList.contains( 'field_options_align' ) ) {
+			const selectedOption = setting.options[ setting.selectedIndex ];
+			const dataAlign = selectedOption ? selectedOption.getAttribute( 'data-align' ) : '';
+
+			if ( dataAlign ) {
+				replaceWith = ' ' + dataAlign;
+			}
+		}

This keeps existing behavior for non‑align inputs, avoids exceptions when no data-align is present, and correctly respects the user’s selected alignment option.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ( '' === replaceWith.trim() ) {
replaceWith = ' ' + setting.querySelector( 'option[data-align]' ).getAttribute( 'data-align' );
}
if ( '' === replaceWith.trim() && setting.classList.contains( 'field_options_align' ) ) {
const selectedOption = setting.options[ setting.selectedIndex ];
const dataAlign = selectedOption ? selectedOption.getAttribute( 'data-align' ) : '';
if ( dataAlign ) {
replaceWith = ' ' + dataAlign;
}
}
🤖 Prompt for AI Agents
In js/src/admin/admin.js around lines 6734-6736, the fallback assumes
setting.querySelector('option[data-align]') exists and uses the first match;
change it so the fallback only runs when setting.matches('.field_options_align')
(the align select), then get the selected option
(setting.options[setting.selectedIndex] or
setting.querySelector('option:checked')) and read its data-align attribute; if
no selected option or no data-align is present, do nothing (no-op) to avoid
runtime errors and incorrect alignment application.

// Include classes from multiple settings.
if ( typeof fieldId !== 'undefined' ) {
if ( setting.classList.contains( 'field_options_align' ) ) {
Expand Down
2 changes: 1 addition & 1 deletion js/welcome-tour.js

Large diffs are not rendered by default.