[英]Extra HTML for shipping methods in WooCommerce cart and checkout
[英]Extra carrier field for shipping methods in WooCommerce cart and checkout
靈感來自Woocommerce 結帳頁面答案代碼中的運輸承運人自定義字段驗證,我使用以下代碼顯示與運輸公司的 select 字段(此字段僅在我選擇特定運輸方式時顯示) :
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" );
}
// Save custom fields to sort metadata
add_action( 'woocommerce_checkout_update_order_meta', 'carrier_update_order_meta', 30, 1 );
function carrier_update_order_meta( $order_id ) {
if( isset( $_POST['carrier_name1'] ))
update_post_meta( $order_id, 'carrier_name1', sanitize_text_field( $_POST['carrier_name1'] ) );
}
問題是它只顯示在結帳頁面上,我希望它顯示在購物車頁面中,將購物車頁面上的選定值保留到結帳頁面。
我想我發現了一些內容,表明購物車和付款頁面之間的所選數據傳輸是通過 Ajax 完成的,但我對 Ajax 不熟練,我不知道如何進行這項工作。
要在購物車和結帳頁面上使用此功能,您將需要使用 jQuery、Ajax 和 WC Session 變量的一些附加代碼:
最終更新- 為了使代碼更加動態,我們從自定義 function 開始,它將處理所有必需的設置:
// Custom function that handle your settings
function carrier_settings(){
return array(
'targeted_methods' => array('flat_rate:14'), // Your targeted shipping method(s) in this array
'field_id' => 'carrier_name', // Field Id
'field_type' => 'select', // Field type
'field_label' => '', // Leave empty value if the first option has a text (see below).
'label_name' => __("Carrier company","woocommerce"), // for validation and as meta key for orders
'field_options' => array(
// The option displayed at first ( or keep an empty value '',)
__("Choose a carrier company", "woocommerce"),
// The carrier companies below (one by line)
'Company name 1',
'Company name 2',
'Company name 3',
'Company name 4',
),
);
}
然后我們可以在需要的任何 function 上加載該設置。
現在 Select 字段與運營商公司在購物車和結帳頁面上顯示特定運輸方式:
// Display the custom checkout field
add_action( 'woocommerce_after_shipping_rate', 'carrier_company_custom_select_field', 20, 2 );
function carrier_company_custom_select_field( $method, $index ) {
extract( carrier_settings() ); // Load settings and convert them in variables
$chosen = WC()->session->get('chosen_shipping_methods'); // The chosen methods
$value = WC()->session->get($field_id);
$value = WC()->session->__isset($field_id) ? $value : WC()->checkout->get_value('_'.$field_id);
$options = array(); // Initializing
if( ! empty($chosen) && $method->id === $chosen[$index] && in_array($method->id, $targeted_methods) ) {
echo '<div class="custom-carrier">';
// Loop through field otions to add the correct keys
foreach( $field_options as $key => $option_value ) {
$option_key = $key == 0 ? '' : $key;
$options[$option_key] = $option_value;
}
woocommerce_form_field( $field_id, array(
'type' => $field_type,
'label' => '', // Not required if the first option has a text.
'class' => array('form-row-wide ' . $field_id . '-' . $field_type ),
'required' => true,
'options' => $options,
), $value );
echo '</div>';
}
}
The Ajax part: The jQuery sender + PHP WordPress admin Ajax receiver code for the selected carrier company:
// jQuery code (client side) - Ajax sender
add_action( 'wp_footer', 'carrier_company_script_js' );
function carrier_company_script_js() {
// Only cart & checkout pages
if( is_cart() || ( is_checkout() && ! is_wc_endpoint_url() ) ):
// Load settings and convert them in variables
extract( carrier_settings() );
$js_variable = is_cart() ? 'wc_cart_params' : 'wc_checkout_params';
// jQuery Ajax code
?>
<script type="text/javascript">
jQuery( function($){
if (typeof <?php echo $js_variable; ?> === 'undefined')
return false;
$(document.body).on( 'change', 'select#<?php echo $field_id; ?>', function(){
var value = $(this).val();
$.ajax({
type: 'POST',
url: <?php echo $js_variable; ?>.ajax_url,
data: {
'action': 'carrier_name',
'value': value
},
success: function (result) {
console.log(result); // Only for testing (to be removed)
}
});
});
});
</script>
<?php
endif;
}
// The Wordpress Ajax PHP receiver
add_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() {
if ( isset($_POST['value']) ){
// Load settings and convert them in variables
extract( carrier_settings() );
if( empty($_POST['value']) ) {
$value = 0;
$label = 'Empty';
} else {
$value = $label = esc_attr( $_POST['value'] );
}
// Update session variable
WC()->session->set( $field_id, $value );
// Send back the data to javascript (json encoded)
echo $label . ' | ' . $field_options[$value];
die();
}
}
然后在結帳頁面上,字段驗證並將所選承運公司保存到訂單中:
// Conditional function for validation
function has_carrier_field(){
$settings = carrier_settings();
return array_intersect(WC()->session->get( 'chosen_shipping_methods' ), $settings['targeted_methods']);
}
// Validate the custom selection field
add_action('woocommerce_checkout_process', 'carrier_company_checkout_validation');
function carrier_company_checkout_validation() {
// Load settings and convert them in variables
extract( carrier_settings() );
if( has_carrier_field() && isset( $_POST[$field_id] ) && empty( $_POST[$field_id] ) )
wc_add_notice(
sprintf( __("Please select a %s as it is a required field.","woocommerce"),
'<strong>' . $label_name . '</strong>'
), "error" );
}
// Save custom field as order meta data
add_action( 'woocommerce_checkout_create_order', 'save_carrier_company_as_order_meta', 30, 1 );
function save_carrier_company_as_order_meta( $order ) {
// Load settings and convert them in variables
extract( carrier_settings() );
if( has_carrier_field() && isset( $_POST[$field_id] ) && ! empty( $_POST[$field_id] ) ) {
$order->update_meta_data( '_'.$field_id, $field_options[esc_attr($_POST[$field_id])] );
WC()->session->__unset( $field_id ); // remove session variable
}
}
在管理訂單頁面、客戶訂單和 email 通知上顯示所選承運人:
// Display custom field in admin order pages
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'admin_order_display_carrier_company', 30, 1 );
function admin_order_display_carrier_company( $order ) {
// Load settings and convert them in variables
extract( carrier_settings() );
$carrier = $order->get_meta( '_'.$field_id ); // Get carrier company
if( ! empty($carrier) ) {
// Display
echo '<p><strong>' . $label_name . '</strong>: ' . $carrier . '</p>';
}
}
// 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 ){
// Load settings and convert them in variables
extract( carrier_settings() );
$carrier = $order->get_meta( '_'.$field_id ); // Get carrier company
if( ! empty($carrier) ) {
$new_total_rows = [];
// Loop through order total rows
foreach( $total_rows as $key => $values ) {
$new_total_rows[$key] = $values;
// Inserting the carrier company under shipping method
if( $key === 'shipping' ) {
$new_total_rows[$field_id] = array(
'label' => $label_name,
'value' => $carrier,
);
}
}
return $new_total_rows;
}
return $total_rows;
}
所有代碼都在您的活動子主題(或主題)的functions.php文件上。 測試和工作。
其他相關主題:
在購物車頁面(用於選擇的特定運輸方式) :
在結帳頁面頁面(用於選擇的特定運輸方式) :
在客戶訂單上(電子郵件通知和管理訂單頁面) :
您能告訴我如何更改它,以便代替選擇字段是文本字段嗎? '文本區域'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.