WooCommerce:结账validation失败后更新自定义字段

在我的项目中,我正在定制一些WooCommercefunction。
我的“运输方式”是:
交货
带走

我还在结帐页面添加了一个自定义字段,该字段是填充了有效的传递时间(大小写为“1”)或者用于带走(案例“2”)。

可能会发生用户选择2. take away在购物车页面中2. take away ,然后选择有效时间为“2”的时间,但随后更改为1. delivery并且所选时间可能不再有效,选项列表和自定义现场标签。

当然我正在使用woocommerce_checkout_process挂钩通过wc_add_notice()警告用户,但即使触发了woocommerce_checkout_fields挂钩(我创建选择列表的位置), 值也不会更新。

我认为有一个AJAX调用仅与发货方法有关,并且不会更新其他结账字段,尽管触发了woocommerce_checkout_fields挂钩。

如何更新自定义字段? 我需要一些js / jquery / AJAX吗?

或者:自定义字段是否可以与送货方式相关(并通过AJAX更新)? 怎么样?

编辑

自定义字段代码:

 add_filter( 'woocommerce_checkout_fields', 'fty_filter_checkout_fields' ); function my_filter_checkout_fields($fields) { $must_deliver = WC()->cart->shipping_total > 0.0; // true=deliver, false=take away // some complex code to calculate time lists omitted, samples array instead: $delivery_time_list = array( "deliver 10:00", "deliver 11:00", "deliver 12:00", "deliver 13:00" ); $takeaway_time_list = array( "takeaway 10:00", "takeaway 10:30", "takeaway 11:00", "takeaway 11:30", "takeaway 12:00", "takeaway 12:30", "takeaway 13:00", "takeaway 13:30" ); // add the new conditional field if($must_deliver) { $fields['my_delivery_datetime'] = array( 'my_delivery_time' => array( 'type' => 'select', 'options' => $delivery_time_list, 'required' => true, 'label' => __('Delivery time') ) ); } else { $fields['my_delivery_time'] = array( 'my_delivery_time' => array( 'type' => 'select', 'options' => $takeaway_time_list, 'required' => true, 'label' => __('Take away time') ) ); } return $fields; } 

validation代码的想法:

 add_action('woocommerce_checkout_process', 'my_checkout_date_time_validation', 30, 1); function my_checkout_date_time_validation($doh) { $time = filter_input(INPUT_POST, 'my_delivery_time'); $shipping = filter_input(INPUT_POST, 'shipping_method', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY); if(strpos($time, "deliver")!==FALSE && strpos($shipping[0], "local_pickup")!==FALSE) { wc_add_notice('Please re-select take away time', 'error'); } else if(strpos($time, "takeaway")!==FALSE && strpos($shipping[0], "distance_based_rate")!==FALSE) { wc_add_notice('Please re-select delivery time', 'error'); } } 

这是关于运输方式;

 add_action( 'woocommerce_flat_rate_shipping_add_rate', 'add_distance_based_delivery_rate', 10, 2 ); function add_distance_based_delivery_rate( $method, $rate ) { $new_rate = $rate; $new_rate['id'] .= ':' . 'distance_based_rate'; $new_rate['label'] = 'delivery'; // Rename to 'Rushed Shipping'. // incredibly complex code used to calculate delivery costs omitted $dist_cost = 1000; $new_rate['cost'] += $dist_cost; $method->add_rate( $new_rate ); } 

感谢名单!

提供的代码几乎没有用…我做了很多改动和优化。 我的所有代码都经过评论,它在WooCommerce 3+上进行了测试,非常有效。

您将不得不添加 “用于计算省略的交付成本的极其复杂的代码”…


1)有条件的结账的JAVASCRIPT现场活动
获取客户实时事件(浏览器端)的唯一方法是javascript / jQuery。 所以这并不容易,因为WooCommerce在结帐页面上已经使用了很多javascript / jQuery / Ajax ……

我已将javascript代码包含在hooked函数中,但您应将其保存在单独的文件中并使用经典的WordPress注册脚本函数注册此脚本文件,如此线程中所示:

结帐字段:隐藏和显示现有字段

2)使用现有的可用运输方法 (动态价格计算):
您无需创建任何运费。 您可以使用:

  • local_pickup可用于“TAKE WAY”的方法
  • flat_rate “交付”的可用方法(动态价格计算)

对于每个送货区域,在Woocommerce>设置>送货中启用,设置和重命名(标签名称) 2种方法:

在此处输入图像描述

对于统一费率,您可以设置任何最小金额(将被您的计算覆盖)……

如果进行更改 ,则需要刷新运输缓存数据:禁用,保存和启用,为当前运输区域保存这些方法。

3)节省运输时间以订购META数据:
我已经添加了一些代码,它保存在2个自定义元字段中:

  • 一个选择的运输
  • 另一个时间

4)在METABOX中显示CHOSEN SHIPPING类型和时间(在订单编辑页面中):
我还为此添加了一些代码。

在此处输入图像描述


在这里推荐是代码:

 add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' ); function my_custom_checkout_field( $checkout ) { // The 2 Options arrays in imput select $delivery_time_list[''] = $takeaway_time_list[''] = __('Select an hour'); for($h = 10, $i = 0; $i < 8; $i++ ){ if( $i % 2 == 0 ){ $time = $h.':00'; $delivery_time_list[$time] = 'deliver '.$time; } else { $time = $h.':30'; $h++; } $takeaway_time_list[$time] = 'takeaway '.$time; } echo '

' . __('Shipping time options') . '

'; woocommerce_form_field( 'delivery_time', array( 'type' => 'select', 'class' => array('delivery-time form-row-wide'), 'label' => __('Delivery time'), 'options' => $delivery_time_list, ), $checkout->get_value( 'delivery_time' ) ); woocommerce_form_field( 'takeaway_time', array( 'type' => 'select', 'class' => array('takeaway-time form-row-wide'), 'label' => __('Take away time'), 'options' => $takeaway_time_list, ), $checkout->get_value( 'takeaway_time' ) ); echo '
'; $required = esc_attr__( 'required', 'woocommerce' ); ?> shipping time.' ), 'error'); } } ## CALCULATING THE DELIVERY FEE (BASED ON COUNTING THE DIFFERENT DATES For all items) ## add_filter( 'woocommerce_package_rates', 'custom_shipping_flat_rate_cost_calculation', 10, 2 ); function custom_shipping_flat_rate_cost_calculation( $rates, $package ) { ## --- CALCULATIONS Based on CART DATA (if needed) --- ## foreach(WC()->cart->get_cart() as $cart_item ): // HERE your incredibly complex code used to calculate delivery costs endforeach; ## --- CHANGING DYNAMICALLY THE METHODS COSTS --- ## foreach($rates as $rate_key => $rate_values): $method_id = $rate_values->method_id; $rate_id = $rate_values->id; // "DELIVERY" - "local_pickup" method (if needed) if ( 'flat_rate' === $method_id ){ // HERE your incredibly complex code used to calculate delivery costs // Change the price cost $price_excl_tax = $rates[$rate_id]->cost + 2.5; $rates[$rate_id]->cost = number_format($price_excl_tax, 2); $tax_calculation = $rates[$rate_id]->taxes[0] * 0.1; $rates[$rate_id]->taxes[0] = number_format($tax_calculation, 2); } // "TAKE WAY" - "local_pickup" method (if needed) elseif ( 'local_pickup' === $method_id ) { // do something if needed } endforeach; return $rates; } // Save the "shipping time" in order meta data add_action( 'woocommerce_checkout_update_order_meta', 'save_shipping_time_in_order_meta', 100, 1 ); function save_shipping_time_in_order_meta( $order_id ) { // Take away time $takeaway_time = $_POST['takeaway_time']; if ( ! empty( $takeaway_time ) ){ add_post_meta( $order_id, '_shipping_time', $takeaway_time ); add_post_meta( $order_id, '_shipping_type', __('Take away', 'woocommerce' ) ); } // Delivery time $delivery_time = $_POST['delivery_time']; if ( ! empty( $delivery_time ) ){ add_post_meta( $order_id, '_shipping_time', $delivery_time ); add_post_meta( $order_id, '_shipping_type', __('Delivery', 'woocommerce' ) ); } } // Adding shipping time metabox (on right side) to Order edit pages add_action( 'add_meta_boxes', 'add_order_shipping_time_meta_boxe' ); function add_order_shipping_time_meta_boxe(){ add_meta_box( 'woocommerce-order-shipping-time-values', __( 'Shipping type and time', 'woocommerce' ), 'order_shipping_time_values', 'shop_order', 'side', 'default' ); } // Adding content to shipping time metabox to Order edit pages function order_shipping_time_values(){ global $post; $type = get_post_meta($post->ID, '_shipping_type', true); $time = get_post_meta($post->ID, '_shipping_time', true); echo "

Type: $type | time: $time

"; }

代码放在活动子主题(或主题)的function.php文件中,或者放在任何插件文件中。

此代码在WooCommerce 3+上进行测试并正常运行。