JQuery conflict (maybe?) Hide/Show Div based on Radio Box - javascript

This is driving me crazy. I have tried every different ways to do this. Trying to show/hive a div based on a radio box selection. Below is my code into my main.js :
$("input[name='payment_method']").click(function () {
if ($(this).attr("id") == "payment_method_cod") {
$("#checkout_insurance").show();
} else {
$("#checkout_insurance").hide();
}
});
HTML:
<div id="checkout_insurance">
<h2>Checkout with Insurance</h2>
</div>
<div id="payment" class="woocommerce-checkout-payment">
<ul class="payment_methods methods">
<li class="payment_method_cod">
<input id="payment_method_cod" type="radio" class="input-radio" name="payment_method" value="cod" data-order_button_text="" checked="checked">
<label for="payment_method_cod">
...
</li>
<li class="payment_method_firstdata">
<input id="payment_method_firstdata" type="radio" class="input-radio" name="payment_method" value="firstdata" data-order_button_text="">
<label for="payment_method_firstdata">
....
</li>
</ul>
</div>
I cant get to work. If I place another cdn of the jQuery on the footer, the function works, however messes up a lot of other stuff. jQuery is being loaded on the header. I am current using jQuery 1.11.3.
Any help will be appreciated.
Thank you!

Use :checked selector to check if the radio element with id payment_method_cod is checked or not.
$('#payment_method_cod:checked') will return true/false based on the condition if the radio button is checked or not and toggle it, when true, the element #checkout_insurance will be shown.
Assuming the id's used in the code are unique.
Demo
$(document).on('change', "input[name='payment_method']", function() {
$("#checkout_insurance").toggle($('#payment_method_cod').is(':checked'));
}).trigger('change');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="checkout_insurance">
<h2>Checkout with Insurance</h2>
</div>
<div id="payment" class="woocommerce-checkout-payment">
<ul class="payment_methods methods">
<li class="payment_method_cod">
<input id="payment_method_cod" type="radio" class="input-radio" name="payment_method" value="cod" data-order_button_text="" checked="checked">
<label for="payment_method_cod">Payment</label>
...
</li>
<li class="payment_method_firstdata">
<input id="payment_method_firstdata" type="radio" class="input-radio" name="payment_method" value="firstdata" data-order_button_text="">
<label for="payment_method_firstdata">FirstData</label>
....
</li>
</ul>
</div>

$("input[name='payment_method']").change(function () {
if ($(this).attr("id") == "payment_method_cod" && $(this).is(':checked')) {
alert('show');
} else {
alert('hide');
}
});
Please use .change() on checkbox use .click() on button.
Try this approach this will select change event on checkbox and check if the id of the checkbox is payment_method_cod it will then show or hide depending on checked property
demo

Changing your code a bit :
$("input[name='payment_method']").click(function () {
var _this = $(this);
if (_this.val() == "cod") {
$("#checkout_insurance").show();
} else {
$("#checkout_insurance").hide();
}
});

Related

Woocommerce: delivery method change event handler not fired

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?
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.
let methods = jQuery('.shipping_method’); // change the last apostrophe on this line
Secondly, in the change event handler this refers to the Element object which has no val() method. You need to call it on a jQuery object, so use $(this).val() instead.
Lastly, bind() is deprecated and should not be used. Use on() 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 the each() loop, as you can bind event handlers to a collection of Elements in a single jQuery object. Try this:
jQuery(document).ready(function($) {
$('.shipping_method').on('change', function() {
console.log('Change event fired for ' + $(this).val());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<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'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.
#Rory: Awesome! Yes, your advice works great!
Just so you know there's a way to get which shipping method is clicked using a WooCommerce hook:
function prefix_detect_chosen_shipping_method(){
if ( ! defined( 'DOING_AJAX' ) ){
return;
}
$chosen_method = WC()->session->get( 'chosen_shipping_methods' );
if( ! is_array( $chosen_method ) ){
return;
}
$chosen_method = $chosen_method[0];
// Do something with the chosen method.
}
add_action( 'woocommerce_cart_calculate_fees', 'prefix_detect_chosen_shipping_method', 10, 2 );
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:
(function( $ ) {
'use strict';
$( document ).ready( function(){
$( document.body ).on( 'updated_checkout', () =>{
let prefixShippingMethods = document.querySelectorAll('#shipping_method .shipping_method');
for (const prefixShippingMethod of prefixShippingMethods ){
// We have to check for the hidden type as well because if only one shipping method is available WC doesn't show radio buttons.
if( lpacShippingMethod.checked || lpacShippingMethod.type === 'hidden' ){
// Do something now that you know which method is checked
// NOTE! The shipping method name will not be exact, you will have to use indexOf() for comparisons
if( prefixShippingMethod.value.indexOf('local_pickup') ){
//This will happen when Local Pickup is selected
}
}
}
});
});
})( jQuery );
You can clean up JS as you wish, I couldn't detect this event in vanilla JS, thats why I'm using jQuery here.

knockout radio button checked status not updated in UI

In my knockout application, I'm trying to handle a few radio inputs in a forEach loop.
The click event updated the checked properties, but the same is not reflected in the UI of the radio button.
Below ID is the entire Dropdown html :
<ul class="dropdown-menu padding-left padding-right customscroll" data-bind="stoppropgattion:'ss'">
<!--ko foreach:MyPlans-->
<li>
<div class="radio radio-adv">
<label data-bind="attr:{for:$data.Id_$index}" for="cs_plan">
<input class="access-hide" id="cs_plan" data-bind="value:$data.Selected,checked:$data.Selected,attr:{id:$data.Id_$index,name:true},click:UpdatedSelectedPlan" name="Plan" type="radio" />
<span> <!--ko text:$data.Name--><!--/ko--><!--ko if:$data.IsDefault--><span> (Default)</span><!--/ko--></span><span class="circle"></span><span class="circle-check"></span>
</label>
</div>
</li>
<!--/ko-->
</ul>
And on clicking I'm updating the selected response also:
UpdatedSelectedPlan = function (data, event) {
selF.MyPlans.filter(function (elem) {
elem.Selected(false);
});
data.Selected(true);
}
Selected value is updated properly, but the same is not reflected in the UI.
When the Dropdown loads the correct radio is shown as selected, but on click the clicked radio is not getting changed UI wise even though selected value is updated .
Please guide
Thanks
Shruti Nair
use "change" event instead of "click". Radio and checkbox have change trigger.
function vm(){
var self = this;
self.MyPlans = ko.observableArray([
{Id:1, Name:'A', Selected:ko.observable(false), IsDefault:true},
{Id:2, Name:'B', Selected:ko.observable(false), IsDefault:false},
{Id:3, Name:'C', Selected:ko.observable(false), IsDefault:false},
{Id:4, Name:'D', Selected:ko.observable(false), IsDefault:false},
{Id:5, Name:'E', Selected:ko.observable(true), IsDefault:false},
]);
self.UpdatedSelectedPlan = function (data, event) {
self.MyPlans().filter(function (elem) {
elem.Selected(false);
});
data.Selected(true);
}
}
ko.applyBindings(new vm())
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<!--ko foreach:MyPlans-->
<li>
<div class="radio radio-adv">
<label data-bind="attr:{for:$data.Id_$index}" for="cs_plan">
<input class="access-hide" id="cs_plan" data-bind="checked:$data.Selected,value:$data.Selected, attr:{id:$data.Id_$index,name:true},event:{change:$parent.UpdatedSelectedPlan}" name="Plan" type="radio" />
<span> <!--ko text:$data.Name--><!--/ko--><!--ko if:$data.IsDefault--><span> (Default)</span><!--/ko--></span><span class="circle"></span><span class="circle-check"></span>
selected ? <span data-bind="text:Selected"></span>
</label>
</div>
</li>
<!--/ko-->
</ul>
Added return true to the method and it worked.
UpdatedSelectedPlan = function (data, event) {
selF.MyPlans.filter(function (elem) {
elem.Selected(false);
});
data.Selected(true);
return true;
}

Javascript click function only work once

I have a dropdown menu with a submit function that executes, if any children from the dropdown is clicked.
Now I want to prevent the submit function to a special li element, because there should be insert a tracking id in a popup iFrame.
With the following code it works so far on the first dropdown menu and prevent the submit function, but it wont work on all following dropdown's.
Maybe someone has a short solution for me?
<script type="text/javascript">
$(document).ready(function() {
$('.track').click(function(){
stopPropagation();
});
$('.dropdown li').click(function() {
document.getElementById('opt').value = $(this).data('value');
$('#options').submit();
});
$("#options").submit(function() {
if (confirm('are you sure?')){
return true;
} else {
return false;
}
});
});
</script>
<form name="" action="" method="post" id="options">
<input type="hidden" name="update" id="opt" value="">
<div id="item-select-option">
<div class="dropdown">
Options <span class="caret"></span>
<ul id="selector" class="dropdown-menu pull-right" role="menu">
<li data-value="paid">paid</li>
<li data-value="shipped">shipped</li>
<li class="track">track</li>
</ul>
</div>
</div>
</form>
Problem: You've several elements with the id track/options when the id attribute should be unique in same document, so when you attach event to the id just the first element with this id that will be attached.
Suggested solution :
Use class instead of id's, like :
<form name="" action="" method="post" class="options">
.....
<li class="track">
track
</li>
</form>
Then you js should be like :
$('.track').click(function(event){
event.stopPropagation();
});
$(".options").submit(function() {
if (confirm('are you sure?')){
return true;
} else {
return false;
}
});
NOTE : The event should be present in anonymous function function(event).
Hope this helps.

Retrieve the previously checked checkboxes on page refresh using localStorage

I have an html code where the checkboxes are checked and onclick of a button the values of checkboxes are sent accross a function. When the user checks a checkbbox the corresponding chidren checkboxes are also checked. If i refresh the page I want to retrieve the previously checked checkboxes. I tried using localStorage to store the checkbox values .
localStorage.setItem("check", check);
Then in another function tried to retrieve it by doing
localStorage.getItem("check");
if(check){
$("input[name='favorites']").attr("checked", "checked");
$(check)
.closest('li')
.find('input:checkbox')
.prop('checked', $(this).prop('checked') );
}
But this does not work . I need to retrieve only the checkboxes which were checked previously on page refresh.
My complete code with demo
html
<ul class="test_ex">
<li>
<input type="checkbox" id="chckBox" class="parent" /> <a class="ref">Fruits</a>
<ul class="example">
<li>
<input type="checkbox" id="chckBox" class="child" /> <a class="ref"> Apple </a>
</li>
<li>
<input type="checkbox" id="chckBox" class="child" /> <a class="ref"> Orange </a>
</li>
</ul>
<ul class="test_ex_sample">
<li>
<input type="checkbox" id="chckBox" class="parent" /> <a class="ref">Birds</a>
<ul class="example">
<li>
<input type="checkbox" id="chckBox" class="child" /> <a class="ref"> Peacock </a>
</li>
<li>
<input type="checkbox" id="chckBox" class="child" /> <a class="ref">Parrot </a>
</li>
</ul>
<ul class="example">
<li>
<input type="checkbox" id="chckBox" class="parent" /> <a class="ref"> Food </a>
<ul class="example">
<li>
<input type="checkbox" id="chckBox" class="child" /> <a class="ref">Bread </a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<input type="button" id="testB" value="OK" />
javascript
$(function() {
// Clicking on an <input:checkbox> should check any children checkboxes automatically
$('input:checkbox').change( fnTest );
// Clicking the OK button should run submit(), pop up displays all checked boxes
$('#testB').click( submit );
});
function fnTest(check) {
// Set all child checkboxes to the same value
$(check)
.closest('li')
.find('input:checkbox')
.prop('checked', $(this).prop('checked') );
}
function submit(check) {
// When you click OK, dipslay the label for each checkbox
var checked = [];
$('input:checkbox:checked').each(function() {
checked.push( $(this).next('a').text() );
});
alert("You have selected:\n\n - " + checked.join("\n - ") );
}
Updated Fiddle
Try changing this code and see if it works for you:
$(function() {
// Clicking on an <input:checkbox> should check any children checkboxes automatically
$('.ref').each(function(){
var $t = $(this);
$t.siblings('input').attr('data-name',$t.text());
});
$('input:checkbox').change( fnTest );
// Clicking the OK button should run submit(), pop up displays all checked boxes
$('#testB').click( submit );
display();
});
function fnTest(e) {
// Set all child checkboxes to the same value
$(this)
.closest('li')
.find('input:checkbox')
.prop('checked', $(this).prop('checked') );
}
function submit(check) {
// When you click OK, dipslay the label for each checkbox
var checked = [];
$('input:checked').each(function() {
checked.push( $(this).attr('data-name'));
});
alert("You have selected:\n\n - " + checked.join("\n - ") );
localStorage.setItem("prevChecked",checked.join('|'));
}
function display(){
var test=localStorage.getItem("prevChecked");
alert(test);
var results = test.split('|');
for (var r=0, len=results.length; r<len; r++ ) {
$('input[data-name="'+results[r]+'"]').prop('checked', true);
}
}
UPDATED
See this fiddle:
http://jsfiddle.net/3a050r6r/6/
Assign the localStorage to a variable while doing a get like this
var check = localStorage.getItem("check");
Edited :
$(function() {
// Clicking on an <input:checkbox> should check any children checkboxes automatically
$('input:checkbox').change( fnTest );
// Clicking the OK button should run submit(), pop up displays all checked boxes
$('#testB').click( submit );
display();
});
function fnTest(e) {
// Set all child checkboxes to the same value
alert($(this).attr("id"));
localStorage.setItem("prevChecked",$(this).attr("id"));
localStorage.setItem("checkedState",$(this).prop('checked'));
$(this)
.closest('li')
.find('input:checkbox')
.prop('checked', $(this).prop('checked') );
}
function submit(check) {
// When you click OK, dipslay the label for each checkbox
var checked = [];
$('input:checkbox:checked').each(function() {
//localStorage.setItem("prevChecked",check);
checked.push( $(this).next('a').text() );
});
alert("You have selected:\n\n - " + checked.join("\n - ") );
}
function display(){
if(localStorage.getItem("checkedState")!="false")
{
var test=localStorage.getItem("prevChecked");
alert(test);
alert($("#"+test).closest('li').html());
$("#"+test).closest('li')
.find('input:checkbox')
.prop('checked', localStorage.getItem("checkedState") );
}
}
Link to your updated fiddle :
http://jsfiddle.net/3a050r6r/36/

Couldn't get the binded values into the list

<div id="list1" class="dropdown-check-list"> <span class="anchor">Select State</span>
<ul class="items" data-bind="foreach:carTypes" onchange="GetSelectedValut1()">
<li>
<label>
<input id="items1" type="checkBox" /><span id="vv1" data-bind="text:text,value:text"></span>
</label>
</li>
</ul>
</div>
Want all the values of the cartypes when i check the box. geting only one (top most one) value here.
Here is my javascript code:
function GetSelectedValut1() {
if (document.getElementById('items1').checked) {
var list_value = document.getElementById("vv1").value;
document.getElementById("vall1").innerHTML = list_value;
} else document.getElementById("vall1").innerHTML = "";
}
want all the values of the cartypes when i check the box. geting only one(top most one) value here. my event to get the values is it sufficient here.

Categories

Resources