Reputation: 164
Hello I'm trying to display the custom checkout field in the admin order details page. My Custom field is Delivery Option
and it allows the user to pick the to pick a value from checkbox. I use the code below following the similar topics about this, but it seems something is wrong with my code.
add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_additional_field', 20 );
function checkout_shipping_additional_field()
{
$domain = 'wocommerce';
$default = 'option 1';
echo '<tr class="additional-shipping-fields"><th>' . __('Delivery Time', $domain) . '</th><td>';
// Add a custom checkbox field
woocommerce_form_field( 'custom_radio_field', array(
'type' => 'select',
'class' => array( 'form-row-wide' ),
'options' => array(
'option 1' => __('10:04 : 13:04 ', $domain),
),
'default' => $default,
), $default );
echo '</td></tr>';
}
//update order meta
add_action('woocommerce_checkout_update_order_meta', 'gon_update_order_meta_business_address');
function gon_update_order_meta_business_address( $order_id ) {
if ($_POST['custom_radio_field']) update_post_meta( $order_id, 'Business Address?',
esc_attr($_POST['custom_radio_field']));
}
// Display field value on the admin order edit page
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'custom_checkout_field_display_admin_order_meta', 10, 1 );
function custom_checkout_field_display_admin_order_meta( $order ){
$delivery_time = get_post_meta( $order->get_id(), 'Delivery Time', true );
if( ! empty( $delivery_time ) )
echo '<p><strong>'.__('Delivery Time', 'woocommerce').': </strong> ' . $delivery_time . '</p>';
}
Upvotes: 2
Views: 2464
Reputation: 1455
Based on @LoicTheAztec answer, if you want multiple fields without re-writing the functions for every field (DRY), you can use this class (by adding it to your functions.php):
/**
* Add a custom field to the woocommerce checkout page
* https://stackoverflow.com/q/52098807/
*/
class WOO_Add_Checkout_Field
{
public function __construct($options)
{
$this->field_name = $options['field_name'];
$this->label = $options['label'];
$this->placeholder = $options['placeholder'];
$this->required = $options['required'];
if ($this->field_name && $this->label && $this->placeholder) {
add_action('woocommerce_after_order_notes', [$this, 'customise_checkout_field']);
add_action('woocommerce_checkout_update_order_meta', [$this, 'custom_checkout_field_update_order_meta'], 10, 1);
add_action('woocommerce_admin_order_data_after_billing_address', [$this, 'display_custom_field_on_order_edit_pages'], 10, 1);
} else {
die("Error in WOO_Add_Checkout_Field \$options: \n\n" . var_dump($options));
}
}
public function customise_checkout_field($checkout)
{
echo '<div id="customise_checkout_field">';
// echo '<h2>' . __('Heading') . '</h2>';
woocommerce_form_field($this->field_name, array(
'type' => 'text',
'class' => array(
'my-field-class form-row-wide'
),
'label' => $this->label,
'placeholder' => $this->placeholder,
'required' => $this->required,
), $checkout->get_value($this->field_name));
echo '</div>';
}
public function custom_checkout_field_update_order_meta($order_id)
{
if (!empty($_POST[$this->field_name]))
update_post_meta($order_id, $this->field_name, $_POST[$this->field_name]);
else
update_post_meta($order_id, $this->field_name, 0);
}
public function display_custom_field_on_order_edit_pages($order)
{
$field = $order->get_meta($this->field_name);
if (!empty($field)) {
echo '<p><strong style="display:block" title="' . $this->placeholder . '">' . $this->label . ': </strong><span>';
echo $field;
echo '</span></p>';
}
}
}
And use it as many times as you'd like:
$my_custom_field_1 = new WOO_Add_Checkout_Field([
'field_name' => 'my_custom_field_1',
'label' => __('My First Field'),
'placeholder' => __('Please write something in field 1...'),
'required' => false,
]);
$my_custom_field_2 = new WOO_Add_Checkout_Field([
'field_name' => 'my_custom_field_2',
'label' => __('My Second Field'),
'placeholder' => __('Please write something in field 2...'),
'required' => false,
]);
$my_custom_field_3 = new WOO_Add_Checkout_Field([
'field_name' => 'my_custom_field_3',
'label' => __('My Third Field'),
'placeholder' => __('Please write something in field 3...'),
'required' => false,
]);
// and so on...
Please note:
Upvotes: 0
Reputation: 253773
There is some mistakes, so I have revisited your code. I have also replaced some hooks. Try the following:
// HERE set your the options array for your select field.
function delivery_time_options(){
$domain = 'woocommerce';
return array(
'1' => __('10:04 : 13:04 ', $domain),
'2' => __('14:04 : 16:04 ', $domain), // <== Added for testing
);
}
// Display a custom select field after shipping total line
add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_additional_field', 20 );
function checkout_shipping_additional_field(){
$domain = 'woocommerce';
echo '<tr class="additional-shipping-fields"><th>' . __('Delivery Time', $domain) . '</th><td>';
// Add a custom select field
woocommerce_form_field( 'delivery_time', array(
'type' => 'select',
'class' => array( 'form-row-wide' ),
'options' => delivery_time_options(),
), '' );
echo '</td></tr>';
}
// Save custom field as order meta data
add_action('woocommerce_checkout_create_order', 'save_custom_field_order_meta', 22, 2 );
function save_custom_field_order_meta( $order, $data ) {
if ( isset($_POST['delivery_time']) ) {
$options = delivery_time_options(); // Get select options array
$option_key = esc_attr($_POST['delivery_time']); // The selected key
$order->update_meta_data( '_delivery_time', $options[$option_key] ); // Save
}
}
// Display a custom field value on the admin order edit page
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_custom_meta_data_in_backend_orders', 10, 1 );
function display_custom_meta_data_in_backend_orders( $order ){
$domain = 'woocommerce';
$delivery_time = $order->get_meta('_delivery_time');
if( ! empty( $delivery_time ) )
echo '<p><strong>'.__('Delivery Time', $domain).': </strong> ' . $delivery_time . '</p>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Upvotes: 2