I’m trying to modify the checkout page. Using a plugin I was able to replace the two default address lines with a street, house number and ‘extra’ field (they’re all on one line). Below that, you find the postcode and the city field.
However, I want to generate the street and city when the user enters their postcode and housenumber, so I want to switch the fields.
It’s like this:
Street – Housenumber – Extra
Postcode – City
I want it to be:
Postcode – Housnumber – Extra
Street – City
I’m using the regular hook:
add_filter("woocommerce_checkout_fields", "order_fields");
function order_fields($fields) {
$order = array(
"billing_first_name",
"billing_last_name",
"billing_company",
"billing_street",
"billing_house_number",
"billing_house_number_extra",
"billing_postcode",
"billing_city",
"billing_country",
"billing_email",
"billing_phone"
);
foreach($order as $field)
{
$ordered_fields[$field] = $fields["billing"][$field];
}
$fields["billing"] = $ordered_fields;
return $fields;
}
However… trying to move the postcode field is unsuccesful. If I move the postcode and city field together I’m able to move them, but just trying to move the postcode field seperate shows strange behaviour (For instance: switching out the street and postcode field).
What am I missing?
As @XciD said in his answer, the issue isn’t with the actual field ordering, as your
woocommerce_checkout_fields
hook to re-order them is fine. The problem is with WooCommerce’s enqueuedaddress-i18n.js
script, which checks your store’s locale and re-orders the checkout (and account address) fields on the fly based on that (which is pretty annoying, after ostensibly giving you a hook to re-order them in the first place…).Caveat
Unfortunately, there’s no hugely straightforward way around this; I ended up coming up with a fairly hacky inline jQuery shiv to move the fields back into the order I originally set; however it’s worth noting that the WooCommerce team may be completely refactoring all of this with the 2.7 release, so I don’t know how long this will be relevant for.
With that said: on with the hack!
Using
wp_footer
(and assuming we only want to run this on the checkout or the ‘Edit Address’ pages under My Account), this inserts some inline jQuery that listens for the same event as inaddress-18n.js
('country_to_state_changing'
). When that event is triggered, it waits for 50ms before reshuffling the fields and placingpostcode
before your customhouse_number
field. The delay is because both listeners will get triggered at the same time, and it appears that theaddress-i18n.js
takes priority, sosetTimeout
ensures that our custom one does its work a little later.I used this solution with the regular
state
field and it worked just fine. Make sure to check your house_number field ID to make sure the selector is correct, but this should solve your issue too hopefully.Oh! And it’s also worth noting that this will only work if you’re not deferring the jQuery load, but that’s the case with all inline jQuery, including all the stuff WooCommerce inserts into the checkout page.
It will be difficult. It’s because of the class of the input.
First you have to do something like that :
Then you have to find a way to override WooCommerce address-i18n js or write your own js.
https://github.com/woothemes/woocommerce/blob/2.6.1/assets/js/frontend/address-i18n.js#L47
The problem is the
form-row-first form-row-last
class adding some float into the inputs