-
-
Save lucasjahn/2da5405d3bd7d3e12555e902c25ed784 to your computer and use it in GitHub Desktop.
| <?php | |
| /** | |
| * adds custom js file to handle inline error messages | |
| */ | |
| add_action( 'woocommerce_after_checkout_form', 'add_custom_validation_script', 20 ); | |
| function add_custom_validation_script() { | |
| wp_enqueue_script( | |
| 'inline_validation_script', | |
| get_stylesheet_directory_uri() . '/js/inline-validation.js', | |
| ['jquery'] | |
| ); | |
| } | |
| /** | |
| * adds error message field element to get inline error messages working | |
| * | |
| * @param array $fields | |
| * @param object $errors | |
| */ | |
| add_filter( 'woocommerce_form_field', 'add_inline_error_messages_element', 10, 4 ); | |
| function add_inline_error_messages_element( $field, $key, $args, $value ) { | |
| if ( strpos( $field, '</span>' ) !== false ) { | |
| $error = '<span class="js-custom-error-message" style="display:none"></span>'; | |
| $field = substr_replace( $field, $error, strpos( $field, '</span>' ), 0); | |
| } | |
| return $field; | |
| } | |
| /** | |
| * process custom checkout validations | |
| * | |
| * @param array $fields | |
| * @param object $errors | |
| */ | |
| add_action('woocommerce_after_checkout_validation', 'custom_checkout_validations', 10, 2); | |
| function custom_checkout_validations($data, $errors) | |
| { | |
| $your_custom_checkout_field = filter_input(INPUT_POST, 'your_custom_input_field'); | |
| // your custom validations goes here | |
| // this is an example to check for the length of the string | |
| if ( !empty($your_custom_checkout_field) && strlen($your_custom_checkout_field) > 50 ) { | |
| $errors->add('your_custom_input_field', __('This field needs to be max 50 chars', 'YourThemeName')); | |
| } | |
| // this loop adds a data array to all error messages which will be applied as a "data-error-for" HTML attribute | |
| // to read out the corresponding field ids with javascript and display the error messages inline | |
| foreach( $errors->errors as $original_key => $error ) { | |
| $field_key = $original_key; | |
| // filter and rewrite the field id for native woocommerce error messages with a key containing _required | |
| if(strpos($original_key, '_required') !== false) { | |
| $field_key = str_replace('_required','', $original_key); | |
| $error[0] = __('This is a required field', 'YourThemeName'); | |
| } | |
| // switch out the old error messages with the ones including a spiced up data array | |
| // to display with javascript | |
| $errors->remove($original_key); | |
| $errors->add($original_key, trim($error[0]), ['error-for' => $field_key . '_field']); | |
| } | |
| } |
| jQuery(function ($) { | |
| 'use strict'; | |
| addInlineMessages(); | |
| // Implementation | |
| // Listen to js event | |
| $(document.body).on('updated_checkout', function() { | |
| addInlineMessages(); | |
| }); | |
| function addInlineMessages() { | |
| var woocommerceErrorsEl = $('.woocommerce-error'); | |
| var woocommerceInlineErrorsEl = $('li[data-error-for]', woocommerceErrorsEl); | |
| var inlineErrorMessagesEl = $('.js-custom-error-message'); | |
| // as we use ajax submitting hide old validation messages | |
| if(inlineErrorMessagesEl.length) { | |
| inlineErrorMessagesEl.hide(); | |
| } | |
| if(woocommerceInlineErrorsEl.length) { | |
| woocommerceInlineErrorsEl.each(function () { | |
| var errorEl = $(this); | |
| var errorText = $.trim(errorEl.text()); | |
| var targetFieldId = errorEl.data('error-for'); | |
| if(errorText && targetFieldId) { | |
| var targetFieldEl = $('#' + targetFieldId); | |
| var errorMessageField = $('.js-custom-error-message', targetFieldEl); | |
| if(targetFieldEl.length && errorMessageField.length) { | |
| targetFieldEl.removeClass('woocommerce-validated'); | |
| targetFieldEl.addClass('woocommerce-invalid'); | |
| errorMessageField.text(errorText); | |
| errorMessageField.show(); | |
| errorEl.hide(); | |
| } | |
| } | |
| }); | |
| if(woocommerceInlineErrorsEl.filter(':visible').length === 0) { | |
| woocommerceErrorsEl.hide(); | |
| if(inlineErrorMessagesEl.filter(':visible').length > 0) { | |
| scrollToElement(inlineErrorMessagesEl.filter(':visible').first()); | |
| } | |
| } else { | |
| $('li:not([data-error-for])', woocommerceErrorsEl).hide(); | |
| scrollToElement(woocommerceErrorsEl); | |
| } | |
| } | |
| } | |
| function scrollToElement(el) { | |
| if(el.length) { | |
| $([document.documentElement, document.body]).animate({ | |
| scrollTop: el.offset().top - 100 | |
| }, 2000); | |
| } | |
| } | |
| // event listeners | |
| $(document.body).on('checkout_error', function (event) { | |
| jQuery('html, body').stop(); | |
| addInlineMessages(); | |
| }); | |
| }); |
@lucasjahn thank you so much for your help and quick response. I finally validated my checkbox field! The code works perfectly!
All the best to you!
Hey there, I just wanted to ask i want to show radio button error which is required but its not visible even though i wrote code and in backend it is working its just not visible on frontend please if you can help me solve this issue.
add_filter( 'woocommerce_form_field', 'wtwh_checkout_fields_in_label_error', 10, 4 );
function wtwh_checkout_fields_in_label_error( $field, $key, $args, $value ) {
if ( strpos( $field, '</label>' ) !== false && $args['required'] ) {
$error = '<span class="error" style="display:none">';
$error .= sprintf( __( '%s is a required.', 'woocommerce' ), $args['label'], $args['radio'] );
$error .= '</span>';
// Append the error message inside the field
$field = substr_replace( $field, $error, strpos( $field, '</label>' ) + strlen('</label>'), 0);
}
if ($args['type'] === 'radio' && $args['required']) {
// Add the error message inside the radio button container
$error = '<span class="error" style="display:none">';
$error .= sprintf(__(' %s is a required field.', 'woocommerce'), $args['label']);
$error .= '</span>';
// Append the error message inside the field
$field = str_replace('<input', $error . '<input', $field);
}
return $field;
}
Thanks, everyone, for your questions here. Actually, I did not receive notifications here anymore, so I overlooked your messages. Sorry for that. I’ve put it on my plate to prepare a more tested and documented script for you to try out, and maybe write a little post about it to have it more detailed.
I’ll keep you posted!
@Z1pas this is totally possible. This is done in my code in the
custom_checkout_validationsfunction.Basically you can add any validation you want and it will add it to the corresponding fields if it is created with the
woocommerce_form_fieldmethod.Anyway, I think I have to have a little overhaul of the code above as some people have some problems with it (probably due to other themes/plugins) enabled etc. but the basic I idea stays.
Cheers.