My HTML code (delivery methods list of radio buttons) is:
<ul id="shipping_method" class="woocommerce-shipping-methods">
<li>
<input type="radio" name="shipping_method[0]" data-index="0" id="shipping_method_0_local_pickup8" value="local_pickup:8" class="shipping_method" checked="checked"><label for="shipping_method_0_local_pickup8">Local pickup</label>
</li>
<li>
<input type="radio" name="shipping_method[0]" data-index="0" id="shipping_method_0_edostavka-package-door-stock7138" value="edostavka-package-door-stock:7:138" class="shipping_method"><label for="shipping_method_0_edostavka-package-door-stock7138">Postamat: <span class="woocommerce-Price-amount amount">265 <span class="woocommerce-Price-currencySymbol">₽</span></span></label>
</li>
<li>
<input type="radio" name="shipping_method[0]" data-index="0" id="shipping_method_0_flat_rate1" value="flat_rate:1" class="shipping_method"><label for="shipping_method_0_flat_rate1">Courier delivery <span class="woocommerce-Price-amount amount">350 <span class="woocommerce-Price-currencySymbol">₽</span></span></label>
</li>
</ul>
It cannot changed (Woocommerce HTML generation). At least I do not want to change it.
My task is add Javascript handlers on selection change event:
jQuery(document).ready(function($){
let methods = jQuery('.shipping_method’);
methods.each(function(index) {
$(this).bind('change', function() {
alert('Change event fired for ' + this.val());
});
});
});
Handlers are not fired when delivery method (radio button with class == ’shipping_method’) changed.
Change handler for whole list of radio also doesn’t work:
methods.bind('change', function() {
alert(this.val());
});
What’s wrong?
3
Answers
@Rory: Awesome! Yes, your advice works great!
Firstly in your JS you’re using the wrong type of apostrophe,
’
instead of'
, which is unsupported in JS, to close the jQuery selector string.Secondly, in the
change
event handlerthis
refers to the Element object which has noval()
method. You need to call it on a jQuery object, so use$(this).val()
instead.Lastly,
bind()
is deprecated and should not be used. Useon()
instead, and make sure you’re using an up to date version of jQuery, ideally at least something 3.x. You also don’t need theeach()
loop, as you can bind event handlers to a collection of Elements in a single jQuery object. Try this:It’s worth noting that both of these issues were visible in the console, which is where you should look first when trying to debug JS logic.
Just so you know there’s a way to get which shipping method is clicked using a WooCommerce hook:
However, this wouldn’t work for me because I needed to fire some javascript based on the selected shipping method. Here’s how I accomplished it using some JavaScript that is present only on the checkout page:
You can clean up JS as you wish, I couldn’t detect this event in vanilla JS, thats why I’m using jQuery here.