Required custom WooCommerce checkout fields don't validate entered value

北城以北 提交于 2019-12-20 04:26:13

问题


I'm adding WooCommerce custom checkout fields in a Storefront child theme functions.php file.
They have a "required" attribute.
The aim is to have these fields appear at the top of the page, before the billing fields.

when clicking the submit button to proceed to payment, I'm getting the required custom field validation error ('please fill in your name') and can't continue with payment, even though filling the field with valid data.

Any clue how to fix this or where to start debugging ?

here is the code in functions.php:

add_action( 'woocommerce_before_checkout_form', 'my_custom_checkout_fields' );

function my_custom_checkout_fields( $checkout ) {

    echo '<div id="my_custom_checkout_field" class="col4-set"><h2>' . __('name') . '</h2>';

    woocommerce_form_field( 'developer_name', array(
        'type'          => 'text',
        'class'         => array('developer_name-class form-row form-row-first'),
        'label'         => __('name'),
        'placeholder'   => __('fill in your name'), 
        'required'      => true,
        ), $checkout->get_value( 'developer_name' ));                               

    echo '</div>';

}

/**
 * Process the checkout
 */
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');

function my_custom_checkout_field_process() {
    // Check if set, if its not set add an error.
if ( ! $_POST['developer_name'] )
        wc_add_notice( __( 'please fill in your name' ), 'error' );  
}

I tried the following but none of them helped:

1. changing:

if ( ! $_POST['developer_name'] ) 

to

if ( empty( $_POST['developer_name']) )

2. changing the trigger from:

 add_action( 'woocommerce_before_checkout_form', 'my_custom_checkout_fields' ); 

to

add_action( 'woocommerce_after_checkout_form', 'my_custom_checkout_fields' );

3. updating to latest Woocomerce 3.0.5 version

I'm running Wordpress 4.7.4
additional related active plugins:
Uni CPO - WooCommerce Options and Price Calculation Formulas


回答1:


As you can read in woocommerce_before_checkout_form hook, it's before checkout form (so outside the checkout form). For this reason this custom field can't work in this hook.

You can use instead woocommerce_checkout_update_order_meta action hook, making some little changes in your code as there is no $checkout argument available in it.

This will display the field "at the top of the page, before the billing fields"

So your complete code should be now:

/**
 * Add the field to the checkout
 */
add_action( 'woocommerce_checkout_before_customer_details', 'my_custom_checkout_fields' );

function my_custom_checkout_fields() {

    echo '<div id="my_custom_checkout_field" class="col4-set"><h2>' . __('name') . '</h2>';

    woocommerce_form_field( 'developer_name', array(
        'type'          => 'text',
        'class'         => array('developer_name-class form-row form-row-first'),
        'label'         => __('name'),
        'placeholder'   => __('fill in your name'),
        'required'      => true,
    ), WC()->checkout->get_value( 'developer_name' ));

    echo '</div>';

}

/**
 * Process the checkout
 */
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');

function my_custom_checkout_field_process() {
    // Check if set, if its not set add an error.
    if ( ! $_POST['developer_name'] )
        wc_add_notice( __( 'Please fill in your name.' ), 'error' );
}


// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta', 10, 1 );
function my_custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['developer_name'] ) ) {
        update_post_meta( $order_id, 'Developer name', sanitize_text_field( $_POST['developer_name'] ) );
    }
}

// Display the custom-field in orders view
add_action( 'woocommerce_order_details_after_customer_details', 'display_my_custom_field_in_orde_details', 10, 1 );
function display_my_custom_field_in_orde_details( $order ) {

    $developer_name = get_post_meta( $order->get_id(), 'Developer name',  true );

    if ( ! empty( $developer_name ) ):
    ?>
        <table class="woocommerce-table woocommerce-table--customer-details shop_table customer_details">
            <tbody><tr>
                <th>Developer name:</th>
                <td><?php echo $developer_name; ?></td>
            </tr></tbody>
        </table>
    <?php
    endif;
}

This code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested and works for WooCommerce version 3.0+




回答2:


You try this code. Tested Ok

add_action( 'woocommerce_billing_fields', 'my_custom_checkout_fields' );

function my_custom_checkout_fields( $fields ) {

   $fields['billing_developer_name'] = array(
    'label'       => __('Developer name', 'woocommerce'),            
    'placeholder' => _x('Developer name', 'placeholder', 'woocommerce'),  
    'required'    => TRUE,             
    'clear'       => false,             
    'type'        => 'text',              
    'class'       => array('my-css')    
    );

 return $fields;

}

You can arrange it with this snippet

add_filter("woocommerce_checkout_fields", "order_fields");

function order_fields($fields) {

    $order = array(
        "billing_developer_name",
        "billing_first_name", 
        "billing_last_name", 
        "billing_company", 
        "billing_address_1", 
        "billing_address_2", 
        "billing_postcode", 
        "billing_country", 
        "billing_email", 
        "billing_phone"

    );
    foreach($order as $field)
    {
        $ordered_fields[$field] = $fields["billing"][$field];
    }

    $fields["billing"] = $ordered_fields;
    return $fields;

}

See screenshot



来源:https://stackoverflow.com/questions/43715891/required-custom-woocommerce-checkout-fields-dont-validate-entered-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!