WooCommerce Checkout add default value to Billing fields if custom checkbox checked - wordpress

I've already created a custom checkbox field in the checkout page with a name of billng_anonymouse, now I want when a customer checks this checkbox it should add a default value to billing_first_name and billing_last_name.
currently, I'm using this function to add a default value for billing fields
function zk_set_checkout_field_input_value_default($fields) {
$fields['billing']['billing_first_name']['default'] = 'First';
$fields['billing']['billing_last_name']['default'] = 'Last';
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'zk_set_checkout_field_input_value_default' );
but the problem is the default values are always there, how to show them using an IF function only if the checkbox is checked.

You can use custom_attributes in woocommerce_checkout_fields so you have a value stored in attribute to use on checkbox check and uncheck. try the below code.
function zk_set_checkout_field_input_value_default($fields) {
$fields['billing']['billing_first_name']['custom_attributes'] = array( 'data-default' => 'First' );
$fields['billing']['billing_last_name']['custom_attributes'] = array('data-default'=>'Last' );
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'zk_set_checkout_field_input_value_default' );
function add_custom_checkout_field( $checkout ) {
$current_user = wp_get_current_user();
$billng_anonymouse = $current_user->billng_anonymouse;
woocommerce_form_field( 'billng_anonymouse', array(
'type' => 'checkbox',
'class' => array( 'form-row-wide' ),
'label' => 'Billng anonymouse'
), $checkout->get_value( 'billng_anonymouse' ) );
}
add_action( 'woocommerce_before_checkout_billing_form', 'add_custom_checkout_field' );
function add_custom_js(){
?>
<script type="text/javascript">
(function($){
$(document).on('change', '#billng_anonymouse', function(event) {
if( $(this).is(':checked') ){
$('#billing_first_name').val($('#billing_first_name').data('default'));
$('#billing_last_name').val($('#billing_last_name').data('default'));
}else{
$('#billing_first_name').val('');
$('#billing_last_name').val('');
}
});
})(jQuery);
</script>
<?php
}
add_action( 'woocommerce_after_checkout_form', 'add_custom_js', 10, 1 );
Tested and works.

Related

Set user registration date while creating account during Woocommerce order

When user completes the order, I want to save the user selected value as user registration date. I know it can be achived with this code:
wp_update_user(
[
'ID' => $user_id,
'user_registered' => $user->user_registered,
]
);
But how I can make it work with the rest of my code? How I can save this data as the registration date? I know how to save the order meta etc. but I've never did something like this.
add_action( 'woocommerce_before_checkout_registration_form', 'custom_checkout_fields_before_billing_details', 20 );
function custom_checkout_fields_before_billing_details(){
$domain = 'woocommerce';
$checkout = WC()->checkout;
echo '<div id="custom_checkout_field">';
woocommerce_form_field( '_custom_field_name', array(
'type' => 'text',
'label' => __('SELECT DATE', $domain ),
'placeholder' => __('DATE"', $domain ),
'class' => array('custom-field-class form-row-wide'),
'required' => false, // or false
), $checkout->get_value( '_custom_field_name' ) );
echo '</div>';
echo '<script>jQuery(document).ready(function( $ ) {$( "#_custom_field_name").datepicker();});</script>';
}
// Save custom checkout fields the data to the order
add_action( 'woocommerce_checkout_create_order', 'custom_checkout_field_update_meta', 10, 2 );
function custom_checkout_field_update_meta( $order, $data ){
if( isset($_POST['_custom_field_name']) && ! empty($_POST['_custom_field_name']) )
$order->update_meta_data( '_custom_field_name', sanitize_text_field( $_POST['_custom_field_name'] ) );
}
add_action( 'wp_enqueue_scripts', 'enqueue_datepicker' );
function enqueue_datepicker() {
if ( is_checkout() ) {
// Load the datepicker script (pre-registered in WordPress).
wp_enqueue_script( 'jquery-ui-datepicker' );
// You need styling for the date picker. For simplicity, I've linked to Google's hosted jQuery UI CSS.
wp_register_style( 'jquery-ui', '//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css' );
wp_enqueue_style( 'jquery-ui' );
}
}

Add custom field to product inventory tab and display value on single product page where meta ends

I'm using the following code in my theme functions.php file to add a additional data field to the product inventory tab:
// Add Custom Field to woocommerce inventory tab for product
add_action('woocommerce_product_options_inventory_product_data', function() {
woocommerce_wp_text_input([
'id' => '_number_in_package',
'label' => __('Number of Pages', 'txtdomain'),
'type' => 'number',
]);
});
add_action('woocommerce_process_product_meta', function($post_id) {
$product = wc_get_product($post_id);
$num_package = isset($_POST['_number_in_package']) ? $_POST['_number_in_package'] : '';
$product->update_meta_data('_number_in_package', sanitize_text_field($num_package));
$product->save();
});
add_action('woocommerce_product_meta_start', function() {
global $post;
$product = wc_get_product($post->ID);
$num_package = $product->get_meta('_number_in_package');
if (!empty($num_package)) {
printf('<div class="custom-sku">%s: %s</div>', __('Number of Pages', 'txtdomain'), $num_package);
}
});
add_filter('woocommerce_product_data_tabs', function($tabs) {
$tabs['additional_info'] = [
'label' => __('Additional info', 'txtdomain'),
'target' => 'additional_product_data',
'class' => ['hide_if_external'],
'priority' => 25
];
return $tabs;
});
However, on the single product page, the custom field is added before category and ISBN. I want to place the custom field at the end after the product ISBN. Any advice?
Some comments/suggestions regarding your code attempt
To save fields you can use the woocommerce_admin_process_product_object hook, opposite the outdated woocommerce_process_product_meta hook
WooCommerce contains by default no ISBN field, but it looks like the woocommerce_product_meta_end hook will answer your question
So you get:
// Add custom field
function action_woocommerce_product_options_inventory_product_data() {
woocommerce_wp_text_input( array(
'id' => '_number_in_package',
'label' => __( 'Number of Pages', 'woocommerce' ),
'description' => __( 'This is a custom field, you can write here anything you want.', 'woocommerce' ),
'desc_tip' => 'true',
'type' => 'number'
) );
}
add_action( 'woocommerce_product_options_inventory_product_data', 'action_woocommerce_product_options_inventory_product_data' );
// Save custom field
function action_woocommerce_admin_process_product_object( $product ) {
// Isset
if ( isset( $_POST['_number_in_package'] ) ) {
// Update
$product->update_meta_data( '_number_in_package', sanitize_text_field( $_POST['_number_in_package'] ) );
}
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );
// Display on single product page
function action_woocommerce_product_meta_end() {
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Get meta
$number = $product->get_meta( '_number_in_package' );
// NOT empty
if ( ! empty ( $number ) ) {
echo '<p>' . $number . '</p>';
}
}
}
add_action( 'woocommerce_product_meta_end', 'action_woocommerce_product_meta_end', 10 );

Add checkbox to product inventory tab in WooCommerce and have the checkbox checked by default

I got this snippet in here to add checkbox custom field which is auto set and it’s working fine.
// Displaying quantity setting fields on admin product pages
add_action( 'woocommerce_product_options_pricing', 'add_custom_field_product_options_pricing' );
function add_custom_field_product_options_pricing() {
global $product_object;
echo '</div><div class="options_group">';
$values = $product_object->get_meta('_cutom_meta_key');
woocommerce_wp_checkbox( array( // Checkbox.
'id' => '_cutom_meta_key',
'label' => __( 'Custom label', 'woocommerce' ),
'value' => empty($values) ? 'yes' : $values,
'description' => __( 'Enable this to make something.', 'woocommerce' ),
) );
}
// Save quantity setting fields values
add_action( 'woocommerce_admin_process_product_object', 'save_custom_field_product_options_pricing' );
function save_custom_field_product_options_pricing( $product ) {
$product->update_meta_data( '_cutom_meta_key', isset($_POST['_cutom_meta_key']) ? 'yes' : 'no');
}
My question: how to move this checkbox to be on the inventory tab and have the checkbox checked by default?
I’ve tried changing :
add_action( 'woocommerce_product_options_pricing', 'add_custom_field_product_options_pricing' );
to:
add_action( 'woocommerce_product_options_inventory_product_data', 'add_custom_field_product_options_pricing' );
AND
add_action( 'woocommerce_admin_process_product_object', 'save_custom_field_product_options_pricing' );
to:
add_action( 'woocommerce_process_product_meta', 'save_custom_field_product_options_pricing' );
But to no avail. Any advice?
woocommerce_admin_process_product_object replaces the outdated woocommerce_process_product_meta hook so you should definitely not replace it with it
To have the checkbox checked by default you can add value to the args from woocommerce_wp_checkbox()
So you get:
// Add checkbox
function action_woocommerce_product_options_inventory_product_data() {
global $product_object;
// Get meta
$value = $product_object->get_meta( '_cutom_meta_key' );
// Checkbox
woocommerce_wp_checkbox( array(
'id' => '_cutom_meta_key', // Required, it's the meta_key for storing the value (is checked or not)
'label' => __( 'Custom label', 'woocommerce' ), // Text in the editor label
'desc_tip' => false, // true or false, show description directly or as tooltip
'description' => __( 'Enable this to make something', 'woocommerce' ), // Provide something useful here
'value' => empty( $value ) ? 'yes' : $value // Checked by default
) );
}
add_action( 'woocommerce_product_options_inventory_product_data', 'action_woocommerce_product_options_inventory_product_data', 10, 0 );
// Save Field
function action_woocommerce_admin_process_product_object( $product ) {
// Update meta
$product->update_meta_data( '_cutom_meta_key', isset( $_POST['_cutom_meta_key'] ) ? 'yes' : 'no' );
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );

Allow order to be fully editable while using a custom order status in WooCommerce

I have a bug with the edit quantity in an order while using a custom status. The edit arrow seems to have disappeared?
Is there another value I can include while registering a custom order status?
Here is my code:
// Register new status 'To order'
function register_new_on_hold_order_status2() {
register_post_status( 'wc-to-order', array(
'label' => 'To order',
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'To order (%s)', 'To order (%s)' )
) );
}
add_action( 'init', 'register_new_on_hold_order_status2' );
// Add to list of WC Order statuses
function add_on_hold_new_to_order_statuses2( $order_statuses ) {
$new_order_statuses = array();
// add new order status after processing
foreach ( $order_statuses as $key => $status ) {
$new_order_statuses[ $key ] = $status;
if ( 'wc-processing' === $key ) { // Here we Define after which to be added
$new_order_statuses['wc-to-order'] = 'To order';
}
}
return $new_order_statuses;
}
add_filter( 'wc_order_statuses', 'add_on_hold_new_to_order_statuses2' );
This is not a bug, certain order statuses such as processing do not allow the order to be editable. To change this you can use the wc_order_is_editable hook
So you get:
function filter_wc_order_is_editable( $editable, $order ) {
// Compare
if ( $order->get_status() == 'your-status' ) {
$editable = true;
}
return $editable;
}
add_filter( 'wc_order_is_editable', 'filter_wc_order_is_editable', 10, 2 );
Note: use woocommerce_register_shop_order_post_statuses
opposite init while registering a custom order status as applied in the 2nd part of this answer

Woocommerce not saving form field

i cannot figure out what i am missing.
I created a custom textfield at the woocommerce checkout with a predefined value. Function is pretty standard:
function one_more_field(){
$product_name='';
global $product;
foreach( WC()->cart->get_cart() as $cart_item ){
$productvariation = $cart_item['variation_id'];
}
woocommerce_form_field( 'variatie', array(
'type' => 'text',
'value' => $productvariation,
),
$productvariation );
}
add_action( 'woocommerce_after_checkout_billing_form', 'one_more_field' );
I can see the field in the checkout and the variation ID is nicely inserted.
Then step 2: saving the value to the user meta data:
function reigel_woocommerce_checkout_update_user_meta( $customer_id, $posted ) {
$dob4 = 'test';
if (isset($posted['variatie'])) {
$dob4 = $posted['variatie'];
update_user_meta( $customer_id, 'variatie', $dob4);
}
add_action( 'woocommerce_checkout_update_user_meta', 'reigel_woocommerce_checkout_update_user_meta', 10, 2 );
However, the value is not saved to the user meta data.
What am i missing here?
Oh it turns out to be very straightforward: just add required => yes to the array of field arguments and it is saved. Cant really understand why though...
So new code (step 1) is:
function one_more_field(){
$product_name='';
global $product;
foreach( WC()->cart->get_cart() as $cart_item ){
$productvariation = $cart_item['variation_id'];
}
woocommerce_form_field( 'variatie', array(
'type' => 'text',
'value' => $productvariation,
'required' => 'true'
),
$productvariation );
}
add_action( 'woocommerce_after_checkout_billing_form', 'one_more_field' );

Resources