diff --git a/classes/controllers/FrmEntriesAJAXSubmitController.php b/classes/controllers/FrmEntriesAJAXSubmitController.php
index 00004b7c21..21286af743 100644
--- a/classes/controllers/FrmEntriesAJAXSubmitController.php
+++ b/classes/controllers/FrmEntriesAJAXSubmitController.php
@@ -73,7 +73,12 @@ public static function ajax_create() {
}
$response['errors'] = $obj;
- $invalid_msg = FrmFormsHelper::get_invalid_error_message( array( 'form' => $form ) );
+ $invalid_msg = FrmFormsHelper::get_invalid_error_message(
+ array(
+ 'form' => $form,
+ 'errors' => $errors,
+ )
+ );
$response['error_message'] = FrmFormsHelper::get_success_message(
array(
'message' => $invalid_msg,
diff --git a/classes/helpers/FrmFormsHelper.php b/classes/helpers/FrmFormsHelper.php
index 4efd31452b..65eba35d96 100644
--- a/classes/helpers/FrmFormsHelper.php
+++ b/classes/helpers/FrmFormsHelper.php
@@ -289,10 +289,77 @@ public static function get_invalid_error_message( $args ) {
}
$frm_settings = FrmAppHelper::get_settings( $settings_args );
- $invalid_msg = do_shortcode( $frm_settings->invalid_msg );
+
+ $field_error_messages = self::get_clickable_field_error_messages( $args );
+
+ $invalid_msg = '' . do_shortcode( $frm_settings->invalid_msg ) . '';
+
+ if ( $field_error_messages ) {
+ $invalid_msg .= "
";
+ }
return apply_filters( 'frm_invalid_error_message', $invalid_msg, $args );
}
+ /**
+ * Get clickable field error messages.
+ *
+ * @since x.x
+ *
+ * @param array $args
+ *
+ * @return string
+ */
+ private static function get_clickable_field_error_messages( $args ) {
+ $field_error_messages = '';
+
+ if ( empty( $args['errors'] ) ) {
+ return $field_error_messages;
+ }
+
+ $field_ids = array_map(
+ function ( $field_plus_id ) {
+ $field_id = str_replace( 'field', '', $field_plus_id );
+
+ if ( strpos( $field_id, '-' ) !== false ) {
+ $field_id = explode( '-', $field_id )[0];
+ }
+ return $field_id;
+ },
+ array_keys( $args['errors'] )
+ );
+ $field_keys = FrmDb::get_results( 'frm_fields', array( 'id' => $field_ids ), 'id,field_key,type' );
+
+ foreach ( $args['errors'] as $field_plus_id => $error ) {
+ $field_id = str_replace( 'field', '', $field_plus_id );
+ $row = '';
+
+ if ( strpos( $field_id, '-' ) !== false ) {
+ $field_id_parts = explode( '-', $field_id );
+
+ if ( count( $field_id_parts ) === 3 ) {
+ $field_id = $field_id_parts[0];
+ $row = '-' . $field_id_parts[2];
+ }
+ }
+
+ $index = array_search( $field_id, array_column( $field_keys, 'id' ), true );
+
+ if ( false === $index ) {
+ continue;
+ }
+
+ $html_id = 'field_' . $field_keys[ $index ]->field_key . $row;
+
+ if ( in_array( $field_keys[ $index ]->type, array( 'checkbox', 'radio' ), true ) ) {
+ // Needed to focus on the first option when error link is clicked.
+ $html_id .= '-0';
+ }
+
+ $field_error_messages .= '' . $error . '';
+ }//end foreach
+ return $field_error_messages;
+ }
+
/**
* @param array $atts {
* The success message details.
diff --git a/css/_single_theme.css.php b/css/_single_theme.css.php
index 8d2d8f3051..63f896fe1f 100644
--- a/css/_single_theme.css.php
+++ b/css/_single_theme.css.php
@@ -416,6 +416,23 @@
margin-bottom:var(--field-margin);
}
+. .frm_error_style span{
+ font-weight: bold;;
+}
+
+. .frm_error_style ul{
+ list-style: inside;;
+ color: ;
+}
+
+. .frm_error_style ul li a{
+ color: ;
+}
+
+. .frm_error_style ul li a:hover{
+ text-decoration: underline;;
+}
+
. #frm_loading .progress-striped .progress-bar{
background-image:linear-gradient(45deg, 25%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 50%, 50%, 75%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0));