I've got problem with validating checkbox in WooCommerce custom checkout field. I've seen this but it doesn't really help me. Custom field is generated inside form, so It should work good. I don't know if there is a need to put something more than my code in this particular case... I've tried few more hooks, but It doesn't made any effect.
add_action('woocommerce_review_order_before_submit', 'my_required_checkout_field');
function my_required_checkout_field( ) {
woocommerce_form_field( 'przetwarzanie_danych_do_zamowienia', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('REQUIRED ONE.'),
'required' => true,
), WC()->checkout->get_value( 'przetwarzanie_danych_do_zamowienia' ));
}
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
global $woocommerce;
}
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['przetwarzanie_danych_do_zamowienia']) update_post_meta( $order_id, 'Oświadczenie o zapoznaniu się z regulaminem', esc_attr($_POST['przetwarzanie_danych_do_zamowienia']));
}
you are not adding the condition when your check box is not checked you have empty function my_custom_checkout_field_process so here is full working code:
add_action('woocommerce_review_order_before_submit', 'my_required_checkout_field');
function my_required_checkout_field()
{
woocommerce_form_field('przetwarzanie_danych_do_zamowienia', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('REQUIRED ONE.'),
'required' => true,
), WC()->checkout->get_value('przetwarzanie_danych_do_zamowienia'));
}
/**
* Process the checkout
**/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process()
{
// Check if set, if its not set add an error.
if (!$_POST['przetwarzanie_danych_do_zamowienia']) {
wc_add_notice(__('Please select required box'), 'error');
}
}
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta($order_id)
{
if ($_POST['przetwarzanie_danych_do_zamowienia']) {
update_post_meta($order_id, 'Oświadczenie o zapoznaniu się z regulaminem', esc_attr($_POST['przetwarzanie_danych_do_zamowienia']));
}
}
Related
I am searching for a while now to achieve what I am describing to my title.
This is the code I am using right now to my child theme's functions.php file:
//--------------------add custom fields to billing section--------------------------------------------
add_filter( 'woocommerce_checkout_fields' , 'display_checkbox_and_new_checkout_field', 20 );
function display_checkbox_and_new_checkout_field( $fields ) {
$fields['billing']['checkbox_trigger'] = array(
'type' => 'checkbox',
'label' => __('Επιθυμώ Τιμολόγιο', 'woocommerce'),
'class' => array('form-row-wide'),
'clear' => true
);
$fields['billing']['afm_field'] = array(
'label' => __('ΑΦΜ Εταιρείας', 'woocommerce'),
'placeholder' => _x('καταχωρείστε το ΑΦΜ σας...', 'placeholder', 'woocommerce'),
//'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
//toggle feature for the custom field that I need to make required after checkbox is clicked
add_action( 'woocommerce_after_checkout_form', 'conditionally_hide_show_new_field', 9999 );
function conditionally_hide_show_new_field() {
wc_enqueue_js( "
jQuery('input#checkbox_trigger').change(function(){
if (! this.checked) {
// HIDE IF NOT CHECKED
jQuery('#afm_field_field').hide();
jQuery('#afm_field_field').removeClass('validate-required');
} else {
// SHOW IF CHECKED
jQuery('#afm_field_field').show();
jQuery('#afm_field_field').addClass('validate-required');
}
}).change();
");
}
I have already tried the following also but it seems to not working:
add_filter( 'woocommerce_checkout_process' , 'if_checked_make_afm_required', 20 );
function if_checked_make_afm_required() {
$step = WC()->session->get( 'post_data' );
if ( isset($step['checkbox_trigger']) ) {
$fields['billing']['afm_field']['required'] = true;
} else {
$fields['billing']['afm_field']['required'] = false;
}
}
I would really appreciate it if anyone could help here. Thanks in advance!
How to add custom field in shipping method using woocommerce wordpress
Please see my screenshot
Please try this code.
if ( ! function_exists( 'dimative_shipping_instance_form_fields_filters' ) ) {
/**
* Shipping Instance form add extra fields.
*
* #param array $settings Settings.
* #return array
*/
function dimative_shipping_instance_form_add_extra_fields( $settings ) {
$settings['shipping_extra_field_title'] = array(
'title' => esc_html__( 'Shipping method title', 'zincheco' ),
'type' => 'text',
'placeholder' => esc_html__( 'Please add shipping method title', 'zincheco' ),
'description' => '',
);
$settings['shipping_extra_field_description'] = array(
'title' => esc_html__( 'Shipping method description', 'zincheco' ),
'type' => 'textarea',
'placeholder' => esc_html__( 'Please add your shipping method description', 'zincheco' ),
'description' => '',
);
return $settings;
}
/**
* Shipping instance form fields.
*/
function dimative_shipping_instance_form_fields_filters() {
$shipping_methods = WC()->shipping->get_shipping_methods();
foreach ( $shipping_methods as $shipping_method ) {
add_filter( 'woocommerce_shipping_instance_form_fields_' . $shipping_method->id, 'dimative_shipping_instance_form_add_extra_fields' );
}
}
add_action( 'woocommerce_init', 'dimative_shipping_instance_form_fields_filters' );
}
In case if someone is looking how to get the value using #Өлзийбат-Нансалцог code example. I was able to retrieve it this way:
//Get Shipping rate object
//$method->id is the ID of the shipping method.
//In my case I used that in cart-shipping.php template
$WC_Shipping_Rate = new WC_Shipping_Rate($method->id);
// Returned value is flat_rate:1
$shipping_rate_id = $WC_Shipping_Rate->get_id();
//Replacing : with underscore to have the id in format of flat_rate_1
$shipping_rate_id = str_replace(':', '_', $shipping_rate_id);
//Get the description field value
//Since the value is stored inside options table use get_option() method
get_option('woocommerce_'.$shipping_rate_id.'_settings')['shipping_extra_field_description']
Here is the code for getting the value.
if ( ! function_exists( 'dimative_shipping_method_description' ) ) {
/**
* Function will print shipping method description.
*
* #param object $method Shipping method object.
* #param int $index Shipping method index.
* #return void
*/
function dimative_shipping_method_description( $method, $index ) {
$dimative_method_fields = get_option( 'woocommerce_' . $method->method_id . '_' . $method->instance_id . '_settings' );
$dimative_method_allowed_html = array(
'p' => array(
'class' => array(),
),
'strong' => array(),
'b' => array(),
'a' => array(
'href' => array(),
),
'span' => array(
'class' => array(),
),
);
// Shipping method custom description.
if ( $dimative_method_fields['shipping_extra_field_description'] ) {
?>
<div class="method-description"><?php echo wp_kses( $dimative_method_fields['shipping_extra_field_description'], $dimative_method_allowed_html ); ?></div>
<?php
}
}
add_action( 'woocommerce_after_shipping_rate', 'dimative_shipping_method_description', 1, 2 );
}
I have an Ajax checkout on my woocommerce installation and I am trying to capture the custom fields on the checkout. I am using below code to try to capture the field called add_gift_box, the field appears fine on my checkout page.
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['add_gift_box']) {
update_post_meta( $order_id, '_add_gift_box', esc_attr($_POST['add_gift_box']));
}
}
When I press "place order" button it creates a new order but the value of this field does not get saved in the database. I don't think even the hook gets fired. As I said everything is being handled by Ajax. The checkout page is one page checkout.
I need help sorting this out. Thanks in advance.
UPDATE
I am setting the field as follows:
add_action( 'woocommerce_after_checkout_billing_form', 'add_box_option_to_checkout' );
function add_box_option_to_checkout( $checkout ) {
woocommerce_form_field( 'add_gift_box', array(
'type' => 'radio',
'class' => array('add_gift_box form-row-wide'),
'label_class' => array('checkbox'),
'input_class' => array('input-checkbox'),
'required' => true,
'options' => array(
'option_1' => 'option1</br>' ,
'option_2' =>'option2</br>',
'option_3' =>'option3</br>',
'option_4' =>'option4</br>',
'option_5' =>'option5</br>',
'option_6' =>'option6</br>',
'option_7' =>'option7</br>',
),
'label' => __('Select Option'),
'placeholder' => __(''),
), $checkout->get_value( 'add_gift_box' ));
}
here is a plugin to add custom field on checkout page woocomerce https://wordpress.org/plugins/woo-custom-checkout-field/
or if you want to add by code you can follow codding from here
https://www.cloudways.com/blog/custom-field-woocommerce-checkout-page/
add_action('woocommerce_after_order_notes', 'customise_checkout_field');
function customise_checkout_field($checkout)
{
echo '<div id="customise_checkout_field"><h2>' . __('Heading') . '</h2>';
woocommerce_form_field('customised_field_name', array(
'type' => 'text',
'class' => array(
'my-field-class form-row-wide'
) ,
'label' => __('Customise Additional Field') ,
'placeholder' => __('Guidence') ,
'required' => true,
) , $checkout->get_value('customised_field_name'));
echo '</div>';
}
Do you have a plugin activated which creates the order by hooking into woocommerce_create_order filter? I don't see any other reason why add_gift_box isn't saved or why woocommerce_checkout_update_order_meta isn't firing.
The original code from includes/class-wc-checkout.php is
/**
* Action hook to adjust order before save.
* #since 3.0.0
*/
do_action( 'woocommerce_checkout_create_order', $order, $data );
// Save the order.
$order_id = $order->save();
do_action( 'woocommerce_checkout_update_order_meta', $order_id, $data );
So, you could create log files in your themes directory to see which hooks are firing like this:
add_action('woocommerce_checkout_update_order_meta', function ($order_id) {
file_put_contents(__DIR__ . '/woocommerce_checkout_update_order_meta.log', 'woocommerce_checkout_update_order_meta fired for order id ' . $order_id);
});
add_action('woocommerce_checkout_create_order', function () {
file_put_contents(__DIR__ . '/woocommerce_checkout_create_order.log', 'woocommerce_checkout_create_order fired');
});
I'm adding custom special fields to the checkout page through
add_filter('woocommerce_checkout_fields', custom_woocommerce_checkout_fields');
function custom_woocommerce_checkout_fields(){
... //other code
$fields = array("field_1", ..., "field_n"); //pseudocode
foreach ($fields as $key => $field) {
$class = $i % 2 == 0 ? array('form-row-first') : array('form-row-last');
woocommerce_form_field($key, array(
'type' => 'text',
'class' => $class,
'label' => $labels[$i],
'placeholder' => __('placeholder cm', 'woothemes'),
'validate' => false,
'required' => true,
'custom_attributes' => array('disabled' => true)
), $field);
$i++;
}
}
and it works perfectly. My goal is now to save this information to the user meta once he concludes the order whether is already registered or not.
To achieve this I'm using
add_action('woocommerce_checkout_update_user_meta','checkout_update_user_fields');
function checkout_update_user_fields($user_id){
if($user_id){
foreach ($fields as $field) { //the fields are the same as before
if (!empty($_POST[$field])) {
update_user_meta($user_id, $field, sanitize_text_field($_POST[$field]));
}
}
}
}
The issue is that the $_POST variable does not contain the custom fields that I inserted inside the checkout form.
Why is this happening? How can I achieve this?
I feel like the most stupid man in the world; disabled input are not posted.
Hope this will save time to someone
Basically I want to create a custom handler to unserialize a db field called birthday.
I've managed to correctly output the field serialized using the default views_handler_field. Unfortunately When I try to create a custom handler, I get this message:
Error: handler for drappsprofiles > birthday doesn't exist!
Here's the file structure:
all/modules/drapps/drappsprofile/
|->drappsprofiles.views.inc
|->drappsprofiles.module
|->drappsprofiles.install
|->drappsprofiles.info
|->drappsprofiles.inc
|->drappsprofiles_handler_field_birthday.inc
here's drappsprofiles.module
/**
* VIEWS2 MODULE
* Implementation hook_views_api
**/
function drappsprofiles_views_api() {
$info['api'] = 2;
return $info;
}
/*****************************************************************************
* INCLUDES
**/
// Loads Google Apps Profile Integration
module_load_include('inc', 'drappsprofiles');
(...)
here's drappsprofiles.views.inc
/**
*
* Implementation of hook_views_handlers().
*
**/
function drappsprofiles_views_handlers() {
return array(
'handlers' => array(
'drappsprofiles_handler_field_birthday' => array(
'parent' => 'views_handler_field',
)
)
);
}
/**
* Implementation of hook_views_data().
*
* #return array
**/
function drappsprofiles_views_data() {
(...)
$data['drappsprofiles']['birthday'] = array(
'title' => t('Birthday'),
'help' => t('Users birthday'),
'field' => array(
'handler' => 'drappsprofiles_handler_field_birthday',
'click sortable' => FALSE,
),
);
return $data;
}
drappsprofiles_handler_field_birthday.inc
<?php
/**
*
* Custom views handler for Birthday
*
*/
class drappsprofiles_handler_field_birthday extends views_handler_field {
function render($values) {
$val = unserialize($values->{$this->field_alias});
return ($val);
}
}
It seems that drappsprofiles_handler_field_birthday.inc is not being read, although I can't figure out why.
Any help would be appreciated. (I've been around this for 2 weeks!)
Assuming your (...) in .views.inc conceals code like:
$data['drappsprofiles']['table']['group'] = t('drappsprofiles');
$data['drappsprofiles']['table']['base'] = array(
'field' => 'birthday',
);
$data['drappsprofiles']['table']['join'] = array(
'#global' => array(),
);
Which I am assuming it does since your field has a group from which to select it so that it can look for the missing handler..
Then the next thing to look at is still in .views.inc in module_views_handlers() { :
return array(
++ 'info' => array(
++ 'path' => drupal_get_path('module','drappsprofilse'),
++ ),
'handlers' => array(
And beyond that, I hate to say it, but uninstalling and reinstalling the module apparently refreshes recent code tweaks to the .views.inc .. I know I had to a bunch of times, you probably noticed this too.