I have created custom fields in my WooCommerce checkout page billing form. It all works fine but I am trying to add an h3 element with text in between. So basically I ask for some additional information in the billing form, but I want to give that a heading.
I tried to create a h3 dynamically with Javascript/jQuery and insert before the specific id I want it to be. But this didn't work as I liked and I rather have a server-side solution.
Thanks in advance!
Here's the function where I define my custom fields. I've tried an echo at the beginning but it ends up displaying at the top of the entire form.
// Modify billing fields
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
function custom_override_checkout_fields( $fields ) {
unset($fields['billing']['billing_phone']);
unset($fields['billing']['billing_email']);
//echo '<h3>Wie is de verzender?</h3>';
$fields['billing']['name_sender'] = array(
'label' => __('Uw naam', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
$fields['billing']['email_sender'] = array(
'label' => __('Uw email', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
$fields['billing']['phone_sender'] = array(
'label' => __('Uw telefoonnummer', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
$fields['billing']['anoniem'] = array(
'label' => __('Anoniem verzenden?', 'woocommerce'),
'type' => 'checkbox',
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
A visual explanation:
Visual explanation
You can hook into the woocommerce_form_field_<field_type> filter. This allows us to add HTML output for an additional field type (and in this case we can output HTML for a heading instead) and we can use this new heading "field type" when modifying checkout fields with the woocommerce_checkout_fields filter.
// Add field type to WooCommerce form field
add_filter( 'woocommerce_form_field_heading','sc_woocommerce_form_field_heading', 10, 4 );
function sc_woocommerce_form_field_heading($field, $key, $args, $value) {
$output = '<h3 class="form-row form-row-wide">'.__( $args['label'], 'woocommerce' ).'</h3>';
echo $output;
}
// Modify checkout fields
add_filter( 'woocommerce_checkout_fields','custom_override_checkout_fields' );
function custom_override_checkout_fields( $fields ) {
$fields['billing']['billing_heading_name'] = array(
'type' => 'heading',
'label' => 'Heading here',
);
When modifying fields using the woocommerce_checkout_fields filter you can now place your new heading field in any position you need.
function filter_woocommerce_form_field_radio( $field, $key, $args, $value ) {
// Based on key
if ( $key == 'radio_choice' ) {
if ( ! empty( $args['options'] ) ) {
$field = '<div><h1>Heading</h1><ul>';
foreach ( $args['options'] as $option_key => $option_text ) {
$field .= '<li>';
$field .= '<input type="radio" value="' . esc_attr( $option_key ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '_' . esc_attr( $option_key ) . '" />';
$field .= '<label>' . esc_html( $option_text ) . '</label>';
$field .= '</li>';
}
$field .= '</ul></div>';
}
}
return $field;
}
add_filter( 'woocommerce_form_field_radio', 'filter_woocommerce_form_field_radio', 10, 4 );
Related
I simply don't understand what's happening. I have tried so many examples on stack overflow and not a single one, even when copied and pasted directly are working.
I'm trying to add custom fields to my checkout. This is working however no matter if I write manually into the text box or textarea or have javascript fill in the boxes the 'woocommerce_checkout_process' will always fail as if the box is empty and even if I pull that code out the order will have empty data where the field data should be stored. I have honestly tried every option I have located on the internet. This is infuriating as it seems to be working for everyone else. I don't know if this is a database security issue from my host that I'm unaware of, a bug in the latest version of WooCommerce, an issue with Divi. There have been no solutions, I'm genuinely hoping that someone knows something that I can't locate.
I have also tried with a single field in 'woocommerce_after_order_notes' still to no avail.
The code is as follows and was pulled directly from WC site, I've tried every modification I could find from other forums:
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('Wallet Info') . '</h2>';
woocommerce_form_field( 'checkbox_address', array(
'type' => 'checkbox',
'class' => array('my-field-class form-row-wide'),
'label' => __('I have a Wallet'),
), $checkout->get_value( 'checkbox_address' ));
woocommerce_form_field( 'address_field', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Wallet Address'),
'placeholder' => __('000'),
), $checkout->get_value( 'address_field' ));
woocommerce_form_field( 'chosen_images', array(
'type' => 'textarea',
'class' => array('my-field-class form-row-wide'),
'label' => __('Chosen NFTs from above'),
), $checkout->get_value( 'chosen_images' ));
echo '</div>';
}
/**
* 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['chosen_images'] )
wc_add_notice( __( 'Please enter something into this new shiny field.' ), '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 ( ! empty( $_POST['chosen_images'] ) ) {
update_post_meta( $order_id, 'chosen_images', sanitize_text_field( $_POST['chosen_images'] ) );
}
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('chosen_images').':</strong> ' . get_post_meta( $order->id, 'chosen_images', true ) . '</p>';
}
Thanks in advance. I appreciate anyone who looks into this with me. Cheers!
You need to replace
update_post_meta( $order_id, 'chosen_images', sanitize_text_field( $_POST['chosen_images'] ) );
With
update_post_meta( $order_id, 'chosen_images', sanitize_textarea_field( $_POST['chosen_images'] ) );
sanitize_text_field() is used for type="text" not for texarea.
Full Updated Code
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('Wallet Info') . '</h2>';
woocommerce_form_field( 'checkbox_address', array(
'type' => 'checkbox',
'class' => array('my-field-class form-row-wide'),
'label' => __('I have a Wallet'),
), $checkout->get_value( 'checkbox_address' ));
woocommerce_form_field( 'address_field', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Wallet Address'),
'placeholder' => __('000'),
), $checkout->get_value( 'address_field' ));
woocommerce_form_field( 'chosen_images', array(
'type' => 'textarea',
'class' => array('my-field-class form-row-wide'),
'label' => __('Chosen NFTs from above'),
), $checkout->get_value( 'chosen_images' ));
echo '</div>';
}
/**
* 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['chosen_images'] )
wc_add_notice( __( 'Please enter something into this new shiny field.' ), '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 ( ! empty( $_POST['chosen_images'] ) ) {
update_post_meta( $order_id, 'chosen_images', sanitize_textarea_field( $_POST['chosen_images'] ) );
}
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('chosen_images').':</strong> ' . get_post_meta( $order->id, 'chosen_images', true ) . '</p>';
}
So I have the following code:
/**
Add custom fields to user / checkout - Date + Venue
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
if( have_rows('date_venue', 424) ): $x = 1;
while ( have_rows('date_venue', 424) ) : the_row(); ?>
<?php $dates[] = get_sub_field('date').' - '.get_sub_field('session_time'); ?>
<?php $x++; endwhile;
else : endif;
echo '<div id="bv_custom_checkout_field"><h4>Select Course Date/Venue</h4>';
woocommerce_form_field( 'course_venue', array(
'type' => 'select',
'class' => array('my-class form-row-wide'),
'label' => __('Select Course Date / Venue'),
'placeholder' => __('Course Date/Venue'),
'options' => array(
$dates[0] => __( $dates[0], 'wps' ),
$dates[1] => __( $dates[1], 'wps' ),
$dates[2] => __( $dates[2], 'wps' )
),
),
get_user_meta( get_current_user_id(),'course_venue' , true ) ); echo '</div>';
}
As you can see I have added $dates[] as an array which could range from 2-X options, which will depend on the product ID.
As an example, I have included the options manually, i.e. dates[0], dates[1] etc...
How would I go about looping this and including it within the options array?
It works fine as it is, but it's not dynamic.
Any help is much appreciated!
Thanks to sMyles:
You can use array_flip to set all the keys to the values from $dates, but if you want the value to be passed through translation function you can just build the array using foreach
$options_dates = array();
foreach( (array) $dates as $date ){
$options_dates[ $date ] = __( $date, 'wps' );
}
Then just set 'options' => $options_dates,
This is perfect loop I have follow like this
First I get data from ACF:-
$options_for_variations = array();
if( have_rows('material_sizes_is','option') ):
while( have_rows('material_sizes_is','option') ) : the_row();
$material_name_is = get_sub_field('material_isname');
$options_for_variations[$material_name_is] = __($material_name_is, 'woocommerce' );
endwhile;
endif;
woocommerce_wp_select - then pass array into the wp_select
woocommerce_wp_select(
array(
'id' => '_select[' . $variation->ID . ']',
'label' => __( 'My Select Field', 'woocommerce' ),
'description' => __( 'Choose a value.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_select', true ),
'options' => $options_for_variations,
)
);
I am trying to create a custom image slider using visual composers attach_images but cant quite work out how to get the URLs from the array of image IDs.
Any help would be appreciated.
var_dump($bg_images) returns
string(9) "19,6,1692"
vc_map( array(
"name" => __( "Fading Background Block", "farrat_vc" ),
"base" => "block_background",
"class" => "",
"category" => __( "Farrat Shortcodes", "farrat_vc"),
"as_parent" => array('except' => 'farrat_panel'), // Use only|except attributes to limit child shortcodes (separate multiple values with comma)
"content_element" => true,
"show_settings_on_create" => true,
"is_container" => true,
'admin_enqueue_css' => array(get_template_directory_uri().'/wp-content/themes/unite/inc/css/gallery.css'),
"params" => array(
array(
"type" => "attach_images",
"heading" => __( "Backgroud Images", "farrat_vc" ),
"param_name" => "bg_images",
),
),
"js_view" => 'VcColumnView'
) );
// Hi try this one this is perfectly working
//Param Registration
function designas_partners() {
// Title
vc_map(
array(
'name' => __( 'Clients' ),
'base' => 'designas_partners_content',
'category' => __( 'Easy Component' ),
'params' => array(
array(
"type" => "attach_images",
"heading" => esc_html__( "Add Clients Images", "appcastle-core" ),
"description" => esc_html__( "Add Clients Images", "appcastle-core" ),
"param_name" => "screenshots",
"value" => "",
),
)
)
);
}
add_action( 'vc_before_init', 'designas_partners' );
// Short code
function designas_partners_content_function( $atts, $content ) {
$gallery = shortcode_atts(
array(
'screenshots' => 'screenshots',
), $atts );
$image_ids = explode(',',$gallery['screenshots']);
$return = '
<div class="clients">';
foreach( $image_ids as $image_id ){
$images = wp_get_attachment_image_src( $image_id, 'company_logo' );
$return .='<div class="images"><img src="'.$images[0].'" alt="'.$atts['title'].'"></div>';
$images++;
}
$return .='</div>';
return $return;
}
add_shortcode( 'designas_partners_content', 'designas_partners_content_function' )
I got a neet workaround for this one on the loop, theres no need for the counter, loop over wp_get_attachment_image( $image_id, 'full' ); will get you every information u use on the wordpress panel.
I'll thank to #sushovan bhowmik was looking for this, I think this will help to avoid lots of variables calling the images :)
<?php
function vc_gallery_carrousel($atts, $content) {
// Attributes
$gallery = shortcode_atts(
array(
'carrousel_images' => 'carrousel_images',
),
$atts );
// Attributes in var
$image_ids=explode(',',$gallery['carrousel_images']);
// Output Code
$output .= '<section class="loopclientsimg">';
$output .= '<article>';
$output .= '<div>';
$output .= '<ul>';
foreach( $image_ids as $image_id ){
$output .='<li>';
$output .= wp_get_attachment_image( $image_id, 'full' );
$output .='</li>';
}
$output .= '</ul>';
$output .= '</div>';
$output .= '</article>';
$output .= '</section>';
return $output;
}
add_shortcode( 'vc_img_carrousel', 'vc_gallery_carrousel' );
QUESTION UPDATED AS PEOPLE SEEMED TO MISUNDERSTAND IT:
Using the WooCommerce plugin for WordPress, I'd like to display the product variation names in the Additional Information tab in the same way as weight and dimesions are displayed.
For instance, I have a product that comes in two sizes, 2 litres and 10 litres, therefore it's a variable product with the two product variations '2 litres' and '10 litres'. If I check the box 'display on product page', size is displayed in the Additional Information tab like this: 'Size: 2 litres, 10 litres'.
I want it to work like the weight and dimensions, so when the product variation '2 litres' is selected, the Additional Information tab will display 'Size: 2 litres', and when the product variation '10 litres' is selected, the Additional Information tab will display 'Size: 10 litres'.
Can this be done?
Here is the full code to add all types of custom input fields for Product Variations:
<?php
// Add Variation Settings
add_action( 'woocommerce_product_after_variable_attributes','variation_settings_fields', 10, 3 );
// Save Variation Settings
add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
/**
* Create new fields for variations
*
*/
function variation_settings_fields( $loop, $variation_data, $variation ) {
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_text_field[' . $variation->ID . ']',
'label' => __( 'My Text Field', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_text_field', true )
)
);
// Number Field
woocommerce_wp_text_input(
array(
'id' => '_number_field[' . $variation->ID . ']',
'label' => __( 'My Number Field', 'woocommerce' ),
'desc_tip' => 'true',
'description' => __( 'Enter the custom number here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_number_field', true ),
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
// Textarea
woocommerce_wp_textarea_input(
array(
'id' => '_textarea[' . $variation->ID . ']',
'label' => __( 'My Textarea', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_textarea', true ),
)
);
// Select
woocommerce_wp_select(
array(
'id' => '_select[' . $variation->ID . ']',
'label' => __( 'My Select Field', 'woocommerce' ),
'description' => __( 'Choose a value.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_select', true ),
'options' => array(
'one' => __( 'Option 1', 'woocommerce' ),
'two' => __( 'Option 2', 'woocommerce' ),
'three' => __( 'Option 3', 'woocommerce' )
)
)
);
// Checkbox
woocommerce_wp_checkbox(
array(
'id' => '_checkbox[' . $variation->ID . ']',
'label' => __('My Checkbox Field', 'woocommerce' ),
'description' => __( 'Check me!', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_checkbox', true ),
)
);
// Hidden field
woocommerce_wp_hidden_input(
array(
'id' => '_hidden_field[' . $variation->ID . ']',
'value' => 'hidden_value'
)
);
}
/**
* Save new fields for variations
*
*/
function save_variation_settings_fields( $post_id ) {
// Text Field
$text_field = $_POST['_text_field'][ $post_id ];
if( ! empty( $text_field ) ) {
update_post_meta( $post_id, '_text_field', esc_attr( $text_field ) );
}
// Number Field
$number_field = $_POST['_number_field'][ $post_id ];
if( ! empty( $number_field ) ) {
update_post_meta( $post_id, '_number_field', esc_attr( $number_field ) );
}
// Textarea
$textarea = $_POST['_textarea'][ $post_id ];
if( ! empty( $textarea ) ) {
update_post_meta( $post_id, '_textarea', esc_attr( $textarea ) );
}
// Select
$select = $_POST['_select'][ $post_id ];
if( ! empty( $select ) ) {
update_post_meta( $post_id, '_select', esc_attr( $select ) );
}
// Checkbox
$checkbox = isset( $_POST['_checkbox'][ $post_id ] ) ? 'yes' : 'no';
update_post_meta( $post_id, '_checkbox', $checkbox );
// Hidden field
$hidden = $_POST['_hidden_field'][ $post_id ];
if( ! empty( $hidden ) ) {
update_post_meta( $post_id, '_hidden_field', esc_attr( $hidden ) );
}
}
?>
To get those values on the frontend we just need to use the popular get_post_meta() function.
Reference article at here:
http://www.remicorson.com/woocommerce-custom-fields-for-variations/
Here's a first attempt. There's not a lot to go on in the attributes table, but when an attribute dropdown is changed, it will find the attribute in the additional information tab (where it is listed in default WooCommerce) and change the text to match the label in the dropdown. A problem occurs when the customer switches back to the empty "choose" option, so you'd need to expand this to somehow account for that.
jQuery( document ).ready(function($) {
$( ".variations_form" ).on( 'change', '.variations select', function() {
id = $(this).attr('id');
attribute = toTitleCase( $(this).attr('id').replace("pa_", "") );
selected = $(this).find('option:selected').text();
$('#tab-additional_information').find('.shop_attributes th:contains('+attribute+')').next('td').text(selected);
});
function toTitleCase(str){
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
});
Save the above as somescript.js in your theme's folder. Then add the following to functions.php to properly enqueue the script.
/**
* Proper way to enqueue scripts and styles
*/
function theme_name_scripts() {
wp_enqueue_script( 'script-name', get_template_directory_uri() . '/somescript.js', array('jquery'), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'theme_name_scripts' );
I have the nex version of woocommerce 2.2.4.
I want creat a new field in the order for display the total weight, i try this :
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
global $woocommerce;
echo '<div id="my_custom_checkout_field"><h3>'.$weight = $woocommerce->cart->cart_contents_weight+1.100, ' Kg</h3>';
woocommerce_form_field( 'my_field_name', array(
'type' => '',
'class' => array('my-field-class orm-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => $weight,
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
add_action('woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta');
function custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['my_field_name']) update_post_meta( $order_id, 'weight', esc_attr($_POST['my_field_name']));
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('weight').':</strong> ' . $order->order_custom_fields['weight'][0] . '</p>';
}
My div display corectly the weight but is not save in the order?
Where the problem?
Thank's