-
-
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(); | |
}); | |
}); |
@Z1pas this is totally possible. This is done in my code in the custom_checkout_validations
function.
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_field
method.
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.
@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!
Hello, is it possible to validate the custom checkbox field in your code? I have added a privacy policy agreement to my site, but I can't get it to show an inline error if the client doesn't check the field.
Privacy policy code: https://www.businessbloomer.com/woocommerce-additional-acceptance-checkbox-checkout/.
Thanks for your help!