I am trying to make checkout faster and my shipping is only based on the postcode so I do not want 'order review' to refresh when address, country, state is change.
I know I need to fiddle with: woocommerce/includes/class-wc-ajax.php
Specifically: update_order_review();
Is there a way to do this by adding code to my themes functions.php rather than comment out core code?
I don't think so that there is a legal way of doing it. But there is a work around to it. You can remove woocommerce default fields from your checkout form and add your custom fields. - This way it will not trigger ajax on its update.
You can add/remove custom fields on checkout this way:
add_filter( 'woocommerce_checkout_fields' , 'vid_remove_billing_postcode_checkout' );
function vid_remove_billing_postcode_checkout( $fields ) {
unset($fields['billing']['billing_postcode']);
$fields['shipping']['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
Related
I've searched to find any solution but nothing worked.
Here what I want to do:
Add new field in checkout page called Shipping show as selectbox filled with Preorder and Non-preorder
If preorder then would show Location field show as selectbox
If non-preorder then would show Location field same as step 2 but different list option.
When Shipping and Location filled correctly, shipping cost would show with correct shipping cost.
Problem
When I filled all required field and Shipping, Location shipping cost wound calculate again. It do AJAX request, but shipping cost keep the same.
But, when I change Name or Street Address shipping cost updated correctly, which is bad behavior. When user click Place Order immediately would POST wrong shipping cost.
Here my Youtube Video to make clear what I ask for help.
What I did to create my own plugin:
Create custom field using hook something like this
public function woocommerce_checkout_fields( $fields )
{
// var_dump(have_rows('location', 'option'));
// die('test');
$options = [];
$options[''] = 'Select Shipping';
$options['pre-order'] = 'Pre Order';
if (!$this->hasPreorderItem()) {
$options['non-pre-order'] = 'Non Pre Order';
}
// Add custom billing shipping
$fields['billing']['billing_shipping'] = array (
'type' => 'select',
'label' => 'Shipping',
'placeholder' => 'Select shipping',
'class' => array ('address-field', 'update_totals_on_change' ),
'required' => true,
'options' => $options
// 'options' => $this->getLocations()
);
$fields['billing']['billing_location_pre_order'] = array (
'type' => 'select',
'label' => 'Location(Pre Order)',
'placeholder' => 'Select Preorder Location',
'class' => array ('address-field', 'update_totals_on_change' ),
'required' => false,
'options' => $this->preorderLocations->getLocations()
// 'options' => $this->getLocations()
);
// Add custom billing location
$fields['billing']['billing_location'] = array (
'type' => 'select',
'label' => 'Location',
'placeholder' => 'Select location',
'class' => array ('address-field', 'update_totals_on_change' ),
'required' => false,
'options' => $this->locations->getLocations()
// 'options' => $this->getLocations()
);
return $fields;
}
Create class to help calculate cost based on Shipping and Location.
What I have tried
Using this answer but no luck. Click here for the question.
Tried to make field to required, as I saw someone said it only update when all required fields filled.
Tried to disable cache in wp-config.php
I found solution from this link
I might help someone that has similar problem. You just need to clear the session. So, WooCommerce would re-calculate and recall your calculate_shipping() function.
To do that add woocommerce_checkout_update_order_review hook. It would look something like this
add_action('woocommerce_checkout_update_order_review', 'action_woocommerce_checkout_update_order_review', 10, 1);
function action_woocommerce_checkout_update_order_review( $posted_data )
{
global $woocommerce;
$packages = $woocommerce->cart->get_shipping_packages();
foreach( $packages as $package_key => $package ) {
$session_key = 'shipping_for_package_'.$package_key;
$stored_rates = WC()->session->__unset( $session_key );
}
}
I'm trying to have the value from 2 custom fields that the user put in through My Account/Edit-Address shown in the same custom fields but in checkout, right now it gets override by old (input) values even though the field (seen through browser inspector) has the new value. How do I stop this?
I'm fairly new to both woocommerce, plugin-making and wordpress. Right now I've not really tried much that made any difference (put the code in different order, changed up the priorities, changed names... As you see, I don't really know what I'm doing).
This is how I made the fields:
add_filter( 'woocommerce_checkout_fields' , 'plugin_add_custom_billing_fields' );
function plugin_add_custom_billing_fields($fields) {
$fields['billing']['billing_org_number'] = array(
'label' => __('Organisationsnummer', 'woocommerce'),
'placeholder' => __('T.ex. 1234-5678', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true,
);
$fields['billing']['billing_org_reference'] = array(
'label' => __('Kostnadsställe/referens', 'woocommerce'),
'placeholder' => __('T.ex. Per Olofsson', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true,
);
return $fields;
}
This is how I save the fields:
function reigel_woocommerce_checkout_update_user_meta( $customer_id, $posted ) {
var_dump($customer_id, $posted);
if (isset($posted['billing_org_number'])) {
$dob = sanitize_text_field( $posted['billing_org_number'] );
update_user_meta( $customer_id, 'billing_org_number', $dob);
}
if (isset($posted['billing_org_reference'])) {
$dob = sanitize_text_field( $posted['billing_org_reference'] );
update_user_meta( $customer_id, 'billing_org_reference', $dob);
}
}
add_action( 'woocommerce_update_user_meta', 'reigel_woocommerce_checkout_update_user_meta', 10, 2 );
As you see, I've been searching through StackOverflow before and got some help from Reigel! Tell me if you need any more code.
The results I want: My value (from database) to be shown in Checkout after edited in My Account/Edit-Address.
Actual results: The old value is shown in Checkout, the new in My Account/Edit-Address.
EDIT: Seems like the plugin for Klarna Checkout is messing up with sessions.
EDIT 2: Yes, it was Klarna. I'll push this problem for a later time because the team discussed and opted to remove the plugin instead.
Need a solution to remove the "Title" and "Add new" button from a post type without jQuery.
You can disable the add new capabilities while passing the parameter in the register post type.
The parameter is :
create_posts' => false
Assuming you have the code like below :
$args = array(
'label' => __( 'Custom Post Type', 'text_domain' ),
'capabilities' => array(
'create_posts' => false
)
);
register_post_type( 'custom_post_type', $args );
In order to remove the title I'm not sure if that is possible,
one solutions would be hiding using css
Best way to remove the title is to use the function remove_post_type_support().
remove_post_type_support('custom_post_type', 'title');
You can add this to your functions.php file by calling it via the init hook.
add_action( 'init', 'remove_custom_post_support' );
function remove_custom_post_support() {
remove_post_type_support( 'custom_post_type', 'title' );
}
I added a custom meta field to my cpt taxonomy with "{$taxonomy}_add_form_fields".
So far it is working fine (add, edit and save) but I cant find this field in the API /wp-json/wp/v2/rest_base.
Is this a filter issue or do i "ADD" this field to the API?
... This answers a slightly different question than the one above ...
You need to enable the REST API where you defined the taxonomy.
Just add 'show_in_rest_api' => true
Something like this:
<?php
add_action( 'init', 'create_book_tax' );
function create_book_tax() {
register_taxonomy(
'genre',
'book',
array(
'label' => __( 'Genre' ),
'rewrite' => array( 'slug' => 'genre' ),
'hierarchical' => true,
'show_in_rest_api' => true // <-- Do This!
)
);
}
?>
You register the meta field calling register_term_meta, observe that using show_in_rest key not only set to true, but at least with an schema description, it is available both in queries to get the data, and to get the schema of that endpoint with OPTIONS method.
register_term_meta('replica', 'nice_field', [
'type' => 'string',
'description' => 'a nice description',
'single' => true,
'show_in_rest' => [
'schema' => [
'type' => 'string',
'format' => 'url',
'context' => ['view', 'edit'],
'readonly' => true,
]
],
]);
Using the schema key its currently documented only for non scalar types, but it's valid for scalar values too.
I had a similar issue. The answers here seem to point to the way to expose the taxonomy itself via the REST API, but not the custom fields created via ${taxonomy}_add_form_fields.
After some more research, I concluded that one should extend the REST API to modify the responses and explicitly add these custom taxonomy fields.
So, in my case, this was the solution:
// Add a custom field to the taxonomy form
function my_add_extra_fields_func()
{
$tpl = '
<div class="form-field form-required">
<label for="link">Field Label</label>
<input type="text" name="link" id="link" />
<p>Some help text</p>
</div>
';
echo $tpl;
}
add_action('taxonomySlug_add_form_fields', 'my_add_extra_fields_func');
// Save the custom field to database in the options table
function my_save_extra_fields_func($term_id)
{
$term_item = get_term($term_id, 'taxonomySlug');
$term_slug = $term_item->slug;
$link = sanitize_text_field($_POST['link']);
update_option('taxonomySlug_link_' . $term_slug, $link);
}
add_action('create_taxonomySlug', 'my_save_extra_fields_func');
/**
* This is the part that addresses the question
* of making the custom field visible in the API
*/
// Expose the taxonomy custom field via REST API
add_action( 'rest_api_init', function () {
register_rest_field( 'taxonomySlug', 'extra_fields', array(
'get_callback' => function( $term_as_arr ) {
$term_slug = $term_as_arr['slug'];
$link = get_option('taxonomySlug_link_' . $term_slug);
return $link;
})
);
});
* taxonomySlug = the slug of my taxonomy
I would like to add custom validation to the phone number in checkout page of woocommerce. How do I do this??
In my opinion there's no need to override default Woocommerce fields, nor use Javascript validation.
You can add a custom validation, that will be added to the Woocommerce's default billing phone field validation, hooking to an action triggered after submitting checkout.
This is the code I just implemented for a client.
// Custom validation for Billing Phone checkout field
add_action('woocommerce_checkout_process', 'custom_validate_billing_phone');
function custom_validate_billing_phone() {
$is_correct = preg_match('/^[0-9]{6,20}$/', $_POST['billing_phone']);
if ( $_POST['billing_phone'] && !$is_correct) {
wc_add_notice( __( 'The Phone field should be <strong>between 6 and 20 digits</strong>.' ), 'error' );
}
}
Of course, instead of my preg_match you can check anything else and adjust your conditional code to your needs.
You can also add custom validation for other default fields, by checking on the right $_POST variable, or your own custom checkout fields, after you correctly set them up, of course, but this is another topic :)
Hope this helps.
BY default woocommerce already have regular expression validation. The easiest way would be to validate it through jquery.
EDIT: Try not to make any changes to the woocommerce core as they will be over ridden on next update. Try this code
// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['shipping']['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}