WooCommerce 购物车和结账中运输方式的额外承运人字段

Woocommerce 结帐页面答案代码中的运输承运人自定义字段验证的启发,我使用以下代码显示运输公司的选择字段(仅当我选择特定的运输方式时才显示该字段)

add_action( 'woocommerce_after_shipping_rate', 'carrier_custom_fields', 20, 2 );

function carrier_custom_fields( $method, $index ) {

    if( ! is_checkout()) return; // Only on the checkout page


    $customer_carrier_method = 'flat_rate:14';


    if( $method->id != $customer_carrier_method ) return; // Mostrar solo para "flat_rate:14"


    $chosen_method_id = WC()->session->chosen_shipping_methods[ $index ];


    // If the chosen shipping method is 'flat_rate: 14', we will show

    if($chosen_method_id == $customer_carrier_method ):


    echo '<div class="custom-carrier2">';


    woocommerce_form_field( 'carrier_name1', array(

        'type'          => 'select',

        'class'         => array('carrier_name2-class form-row-wide'),

        'label'         => __('<strong>Shipping Company</strong>'),

        'required'      => 'true',

        'options'       => array(

            '1'                     => '', // no data means that the field is not selected

            'Shipping Company 1'    => 'Shipping Company 1',

            'Shipping Company 2'    => 'Shipping Company 2',

            'Shipping Company 3'    => 'Shipping Company 3',

            'Shipping Company 4'    => 'Shipping Company 4'

        )

    ), WC()->checkout->get_value( 'carrier_name1' ) );


    echo '</div>';

    endif;

}


// Validate the custom selection field

add_action('woocommerce_checkout_process', 'carrier_checkout_process');

function carrier_checkout_process() {

    if( isset( $_POST['carrier_name1'] ) && empty( $_POST['carrier_name1'] ) )

        wc_add_notice( ( "<strong>Shipping Company</strong> it is a required field." ), "error" );

}


问题是它只显示在结帐页面上,我希望它在购物车页面中显示它,将购物车页面上选定的值保留到结帐页面。


我想我发现了一些内容,表明购物车和支付页面之间所选数据的传输是通过 Ajax 完成的,但我不熟悉 Ajax,也不知道如何实现这一点。


慕的地10843
浏览 67回答 1
1回答

MM们

为了使其在购物车和结账页面上工作,您将需要一些使用 jQuery、Ajax 和 WC Session 变量的附加代码:最终更新- 为了使代码更加动态,我们从一个自定义函数开始,它将处理所有必需的设置:// Custom function that handle your settingsfunction carrier_settings(){&nbsp; &nbsp; return array(&nbsp; &nbsp; &nbsp; &nbsp; 'targeted_methods' => array('flat_rate:14'), // Your targeted shipping method(s) in this array&nbsp; &nbsp; &nbsp; &nbsp; 'field_id'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=> 'carrier_name', // Field Id&nbsp; &nbsp; &nbsp; &nbsp; 'field_type'&nbsp; &nbsp; &nbsp; &nbsp;=> 'select', // Field type&nbsp; &nbsp; &nbsp; &nbsp; 'field_label'&nbsp; &nbsp; &nbsp; => '', // Leave empty value if the first option has a text (see below).&nbsp; &nbsp; &nbsp; &nbsp; 'label_name'&nbsp; &nbsp; &nbsp; &nbsp;=> __("Carrier company","woocommerce"), // for validation and as meta key for orders&nbsp; &nbsp; &nbsp; &nbsp; 'field_options'&nbsp; &nbsp; => array(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// The option displayed at first ( or keep an empty value '',)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; __("Choose a carrier company", "woocommerce"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // The carrier companies below (one by line)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Company name 1',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Company name 2',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Company name 3',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Company name 4',&nbsp; &nbsp; &nbsp; &nbsp; ),&nbsp; &nbsp; );}然后我们可以将该设置加载到任何需要的函数上。现在,购物车和结帐页面上的“选择”字段中显示了特定运输方式的承运商公司:// Display the custom checkout fieldadd_action( 'woocommerce_after_shipping_rate', 'carrier_company_custom_select_field', 20, 2 );function carrier_company_custom_select_field( $method, $index ) {&nbsp; &nbsp; extract( carrier_settings() ); // Load settings and convert them in variables&nbsp; &nbsp; $chosen&nbsp; = WC()->session->get('chosen_shipping_methods'); // The chosen methods&nbsp; &nbsp; $value&nbsp; &nbsp;= WC()->session->get($field_id);&nbsp; &nbsp; $value&nbsp; &nbsp;= WC()->session->__isset($field_id) ? $value : WC()->checkout->get_value('_'.$field_id);&nbsp; &nbsp; $options = array(); // Initializing&nbsp; &nbsp; if( ! empty($chosen) && $method->id === $chosen[$index] && in_array($method->id, $targeted_methods)&nbsp; ) {&nbsp; &nbsp; &nbsp; &nbsp; echo '<div class="custom-carrier">';&nbsp; &nbsp; &nbsp; &nbsp; // Loop through field otions to add the correct keys&nbsp; &nbsp; &nbsp; &nbsp; foreach( $field_options as $key => $option_value ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $option_key = $key == 0 ? '' : $key;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $options[$option_key] = $option_value;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; woocommerce_form_field( $field_id, array(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'type'&nbsp; &nbsp; &nbsp;=> $field_type,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'label'&nbsp; &nbsp; => '', // Not required if the first option has a text.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'class'&nbsp; &nbsp; => array('form-row-wide ' . $field_id . '-' . $field_type ),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'required' => true,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'options'&nbsp; => $options,&nbsp; &nbsp; &nbsp; &nbsp; ), $value );&nbsp; &nbsp; &nbsp; &nbsp; echo '</div>';&nbsp; &nbsp; }}Ajax 部分:所选运营商公司的 jQuery 发送器 + PHP WordPress 管理 Ajax 接收器代码:// jQuery code (client side) - Ajax sender&nbsp;add_action( 'wp_footer', 'carrier_company_script_js' );function carrier_company_script_js() {&nbsp; &nbsp; // Only cart & checkout pages&nbsp; &nbsp; if( is_cart() || ( is_checkout() && ! is_wc_endpoint_url() ) ):&nbsp; &nbsp; // Load settings and convert them in variables&nbsp; &nbsp; extract( carrier_settings() );&nbsp; &nbsp; $js_variable = is_cart() ? 'wc_cart_params' : 'wc_checkout_params';&nbsp; &nbsp; // jQuery Ajax code&nbsp; &nbsp; ?>&nbsp; &nbsp; <script type="text/javascript">&nbsp; &nbsp; jQuery( function($){&nbsp; &nbsp; &nbsp; &nbsp; if (typeof <?php echo $js_variable; ?> === 'undefined')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; $(document.body).on( 'change', 'select#<?php echo $field_id; ?>', function(){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var value = $(this).val();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $.ajax({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type: 'POST',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url: <?php echo $js_variable; ?>.ajax_url,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'action': 'carrier_name',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'value': value&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; success: function (result) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(result); // Only for testing (to be removed)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; });&nbsp; &nbsp; </script>&nbsp; &nbsp; <?php&nbsp; &nbsp; endif;}// The Wordpress Ajax PHP receiveradd_action( 'wp_ajax_carrier_name', 'set_carrier_company_name' );add_action( 'wp_ajax_nopriv_carrier_name', 'set_carrier_company_name' );function set_carrier_company_name() {&nbsp; &nbsp; if ( isset($_POST['value']) ){&nbsp; &nbsp; &nbsp; &nbsp; // Load settings and convert them in variables&nbsp; &nbsp; &nbsp; &nbsp; extract( carrier_settings() );&nbsp; &nbsp; &nbsp; &nbsp; if( empty($_POST['value']) ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $value = 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $label = 'Empty';&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $value = $label = esc_attr( $_POST['value'] );&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // Update session variable&nbsp; &nbsp; &nbsp; &nbsp; WC()->session->set( $field_id, $value );&nbsp; &nbsp; &nbsp; &nbsp; // Send back the data to javascript (json encoded)&nbsp; &nbsp; &nbsp; &nbsp; echo $label . ' | ' . $field_options[$value];&nbsp; &nbsp; &nbsp; &nbsp; die();&nbsp; &nbsp; }}然后在结帐页面上进行字段验证并将所选承运公司保存到订单中:// Conditional function for validationfunction has_carrier_field(){&nbsp; &nbsp; $settings = carrier_settings();&nbsp; &nbsp; return array_intersect(WC()->session->get( 'chosen_shipping_methods' ), $settings['targeted_methods']);}// Validate the custom selection fieldadd_action('woocommerce_checkout_process', 'carrier_company_checkout_validation');function carrier_company_checkout_validation() {&nbsp; &nbsp; // Load settings and convert them in variables&nbsp; &nbsp; extract( carrier_settings() );&nbsp; &nbsp; if( has_carrier_field() && isset( $_POST[$field_id] ) && empty( $_POST[$field_id] ) )&nbsp; &nbsp; &nbsp; &nbsp; wc_add_notice(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sprintf( __("Please select a %s as it is a required field.","woocommerce"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '<strong>' . $label_name . '</strong>'&nbsp; &nbsp; &nbsp; &nbsp; ), "error" );}// Save custom field as order meta dataadd_action( 'woocommerce_checkout_create_order', 'save_carrier_company_as_order_meta', 30, 1 );function save_carrier_company_as_order_meta( $order ) {&nbsp; &nbsp; // Load settings and convert them in variables&nbsp; &nbsp; extract( carrier_settings() );&nbsp; &nbsp; if( has_carrier_field() && isset( $_POST[$field_id] ) && ! empty( $_POST[$field_id] ) ) {&nbsp; &nbsp; &nbsp; &nbsp; $order->update_meta_data( '_'.$field_id, $field_options[esc_attr($_POST[$field_id])] );&nbsp; &nbsp; &nbsp; &nbsp; WC()->session->__unset( $field_id ); // remove session variable&nbsp; &nbsp; }}在管理订单页面、客户订单和电子邮件通知上显示所选承运商:// Display custom field in admin order pagesadd_action( 'woocommerce_admin_order_data_after_shipping_address', 'admin_order_display_carrier_company', 30, 1 );function admin_order_display_carrier_company( $order ) {&nbsp; &nbsp; // Load settings and convert them in variables&nbsp; &nbsp; extract( carrier_settings() );&nbsp; &nbsp; $carrier = $order->get_meta( '_'.$field_id ); // Get carrier company&nbsp; &nbsp; if( ! empty($carrier) ) {&nbsp; &nbsp; &nbsp; &nbsp; // Display&nbsp; &nbsp; &nbsp; &nbsp; echo '<p><strong>' . $label_name . '</strong>: ' . $carrier . '</p>';&nbsp; &nbsp; }}// Display carrier company after shipping line everywhere (orders and emails)add_filter( 'woocommerce_get_order_item_totals', 'display_carrier_company_on_order_item_totals', 1000, 3 );function display_carrier_company_on_order_item_totals( $total_rows, $order, $tax_display ){&nbsp; &nbsp; // Load settings and convert them in variables&nbsp; &nbsp; extract( carrier_settings() );&nbsp; &nbsp; $carrier = $order->get_meta( '_'.$field_id ); // Get carrier company&nbsp; &nbsp; if( ! empty($carrier) ) {&nbsp; &nbsp; &nbsp; &nbsp; $new_total_rows = [];&nbsp; &nbsp; &nbsp; &nbsp; // Loop through order total rows&nbsp; &nbsp; &nbsp; &nbsp; foreach( $total_rows as $key => $values ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $new_total_rows[$key] = $values;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Inserting the carrier company under shipping method&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( $key === 'shipping' ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $new_total_rows[$field_id] = array(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'label' => $label_name,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'value' => $carrier,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return $new_total_rows;&nbsp; &nbsp; }&nbsp; &nbsp; return $total_rows;}所有代码都位于活动子主题(或主题)的functions.php 文件中。经过测试并有效在购物车页面上&nbsp;(针对所选的特定运输方式):在结帐页面&nbsp;(针对所选的特定运输方式):关于客户订单&nbsp;(电子邮件通知和管理订单页面):
打开App,查看更多内容
随时随地看视频慕课网APP