Evakos
Evakos

Reputation: 312

Conditional custom checkout fields validation issue in Woocommerce

I have a checkbox which if checked opens a drop down field (requirements). If you try and send the Woocommerce order it conditionally checks if the field has content, if it doesn't it returns an error.

This all works accept when the requirements field does have information input it still treats it as not having content and returns the error.

As this is the basic way that forms should work I don't understand why I'm getting such a result. Here's the code:

/**
 * Add a message field to the WC checkout
 */
add_action( 'woocommerce_before_checkout_form', 'custom_checkout_field' );

function custom_checkout_field( $checkout ) {

    echo '<div id="message"><h3>' . __( '<i class="fas fa-envelope"></i> Message' ) . '</h3><p style="margin: 0 0 8px;">Would you like to leave a message?</p>';

        woocommerce_form_field( 'checkbox', array(
            'type'  => 'checkbox',
            'class' => array( 'msg-checkbox' ),
            'label' => __( 'Yes' ),
        ), $checkout->get_value( 'checkbox' ) );

    woocommerce_form_field( 'requirements', array(
        'type'          => 'text',
        'class'         => array('msg'),
        'label'         => __('Please input your message.'),
        'placeholder'   => __(''),
        ), $checkout->get_value( 'requirements' ));

    echo '</div>';

}

/**
 * Process checkout with additional custom field
 */
add_action('woocommerce_checkout_process', 'custom_checkout_field_process');

function custom_checkout_field_process() {

    // Check if set, if not add an error.

    if(isset($_POST['checkbox']) && ( empty($_POST['requirements'])));

        wc_add_notice( __( 'Please let us know what you would like to do' ), 'error' );
}

I hope that makes sense. basically it works to a point but the validation for the input field doesn't work when it has content.

Thanks.

Upvotes: 4

Views: 5400

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253886

Update: Code improvements and added a show/hide functionality with jQuery

The only problem comes from the hook that you are using for your custom checkout fields. It output those fields outside the checkout form, so the values are never submitted and then always empty.

Instead you will use woocommerce_checkout_before_customer_details action hook for your first hooked function that will output those fields inside the checkout form this time:

// Output custom checkout fields
add_action( 'woocommerce_checkout_before_customer_details', 'custom_checkout_field_before_billing' );
function custom_checkout_field_before_billing() {
    $domain = 'woocommerce';

    // Hide the message text field on load
    ?>
    <style>p#requirements_field{display:none;}</style>

    <div id="message">
    <h3><i class="fa fa-envelope"></i><?php _e( 'Message', 'woocommerce' ); ?></h3>
    <?php

    woocommerce_form_field( 'checkbox_msg', array(
        'type'  => 'checkbox',
        'class' => array( 'msg-checkbox' ),
        'label' => __( 'Would you like to leave a message?', 'woocommerce' ),
    ), WC()->checkout->get_value( 'cb_msg' ));

    woocommerce_form_field( 'requirements', array(
        'type'              => 'text',
        'class'             => array('msg t_msg'),
        'label'             => __('Please input your message.'),
        'placeholder'       => __(''),
    ), WC()->checkout->get_value( 'requirements' ));

    echo '</div>';

    // jQuery: show hide the text requirement field
    ?><script>
    jQuery(document).ready(function($) {
        var a = '#requirements_field';
        $('input#checkbox_msg').change( function(){
            if( $(this).is(':checked') )
                $(a).show();
            else
                $(a).hide();
        });
    });
    </script><?php
}

// Process checkout with additional custom field
add_action('woocommerce_after_checkout_validation', 'custom_checkout_field_validation_process', 20, 2 );
function custom_checkout_field_validation_process( $data, $errors ) {

    // Check if set, if not add an error.
    if( isset($_POST['checkbox_msg']) && empty($_POST['requirements']) )
        $errors->add( 'requirements', __( "Please let us know what you would like to do filling up the message field.", "woocommerce" ) );
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

enter image description here

Upvotes: 2

Related Questions