Skip to content

Instantly share code, notes, and snippets.

@avinash2
Forked from lucasjahn/functions.php
Created January 18, 2022 04:34
Show Gist options
  • Select an option

  • Save avinash2/95b3c5fc29b7445eba7383034208f81b to your computer and use it in GitHub Desktop.

Select an option

Save avinash2/95b3c5fc29b7445eba7383034208f81b to your computer and use it in GitHub Desktop.

Revisions

  1. Lucas Jahn revised this gist Jul 12, 2021. No changes.
  2. Lucas Jahn created this gist Jul 12, 2021.
    74 changes: 74 additions & 0 deletions functions.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,74 @@
    <?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']);
    }
    }
    73 changes: 73 additions & 0 deletions inline-validation.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    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-healy-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();
    });
    });