I'm building off an existing woocommerce wordpress extension, and I'm converting the product variation (size, color etc) dropdown menus into radio boxes. The trickiness is that when a user selects an option from the drop-down list, it triggers something that automatically updates the product inventory and price via ajax.
I used this to convert the inputs into radios (from here):
$('.variations select').each(function(i, select){
var $select = jQuery(select);
$select.find('option').each(function(j, option){
var $option = jQuery(option);
// Create a radio:
var $radio = jQuery('<input type="radio" />');
// Set name and value:
$radio.attr('name', $select.attr('name')).attr('value', $option.val());
// Set checked if the option was selected
if ($option.attr('selected')) $radio.attr('checked', 'checked');
// Insert radio before select box:
$select.before($radio);
$radio.wrap('<div class="vari-option fix" />');
// Insert a label:
$radio.before(
$("<label />").attr('for', $select.attr('name')).text($option.text())
);
});
Then I've used this
$(':radio').click(function(){
$(this).parent().parent().find('label').removeClass('checked');
$(this).siblings('label').addClass('checked');
$choice = $(this).attr('value');
$('.variations select option[value=' + $choice + ']').attr('selected',true);
});
So that when a radio is selected, it mirrors the event on the dropdown option. That works fine, but it's not triggering the refresh of the product info. My guess is there's a difference between changing the 'selected' attribute of a dropdown option and physically clicking on the same option. Any guess at what event might be triggering that ajax function that I'm not taking into account? And a solution that ideally doesn't involve modifying woocommerce's original code? I've tried using .click() on the select option but it made no difference.
Programmatically changing the value of an element doesn't trigger the change event, and I would assume that programmatically setting the selected attribute/property on an <option> also wouldn't trigger the change event on the containing <select> element.
Fortunately, you can easily trigger that event programmatically using jQuery:
$('.variations select option[value=' + $choice + ']').attr('selected',true).parent().trigger('change');
The .parent() call returns a jQuery object containing the <select> element, then .trigger('change') triggers any event handlers bound to the change event on that object.
Related
I have attached a JS Fiddle link here:
http://jsfiddle.net/p0b4j5o8/18/
If you check the fiddle link, you will see that I have written JavaScript/jQuery code (a function named add_mitigator()) in the HTML section.
When I used to write the code in the JavaScript section, Firebug used to trigger an error stating function add_mitigator() isn't defined.
But when I wrote the same in the HTML section instead, it runs with no problem. I am not much accustomed with JS Fiddle. How can I write a function in function_name() format in the fiddle?
In my JS Fiddle, there is a dropdown (chosen multiple) with options 1 to 10. When I click on the add_mitigator link, it creates/appends a new chosen dropdown.
Suppose I have three dropdowns, then if I select 2 from dropdown 1, then the other dropdowns will have 2 removed from their options. When I will unselect the 2 from the first dropdown, then 2 will again be available in the other two dropdowns. This should act vice-versa. When 2 is selected from any dropdown, then it is unavailable for all other dropdowns.
How can I achieve this?
By calling the function below on the select box change event the options will be disabled/enabled as per your requirements.
function disableSelectedValues() {
var cssOptions = [];
$(".input_field.criteria_countries option").removeAttr("disabled");
$.each($(".input_field.criteria_countries"), function(index, select) {
cssOptions = [];
var values = $(select).val();
if (values) {
for (var i = 0; i < values.length; i++) {
cssOptions.push("option[value=" + values[i] + "]");
}
}
console.log("test");
if (cssOptions.length) {
// disable all options with the selected values
$(".input_field.criteria_countries "
+ cssOptions.join(",.input_field.criteria_countries ")).attr("disabled", true);
// enable all options with the selected values for the current select
$(select).find(cssOptions.join()).removeAttr("disabled");
}
});
}
With .chosen you can listen to onchange events with .chosen().change();.
In the .chosen().change() event you then need to tell all of the select boxes to update once a value has changed. By using .trigger("chosen:updated"); on the select box selectors whenever a change event is fired, the select boxes will update.
NOTE that you will need to call the disableSelectedValues() function whenever you add a select box to have its options disabled on creation.
http://jsfiddle.net/p0b4j5o8/22/
I'm working on a dynamic select box with php and jquery, i have 4 select boxes, the content of the first one is loaded in the page load.
When i choose one of the items in the first select box, the seconde one get data from database related to the first select box...and so on
But the problem is : when the select box contain only one item, the change() function of jquery doesn't work $('#MySelectId').change(function(){ //......});
Any suggestions ?
I'm working with PHP, jQuery v1.6.4 and jQuery Chosen Plugin.
If your select box only contains 1 item this item is already selected so if you select it again the value doesn't change so no change event is fired. Add a placeholder like "Please select item" or something which is selected by default.
Try something like
$('#MySelectId').on('change', 'select', function() {
alert('changed');
}).click(function(){
if($('#MySelectId select option').length == 1) {
$('#MySelectId select').change();
}
});
Fiddle
or you can try with jquery bind if you are not using 1.7.x + version.
$('#MySelectId').bind('change', function() {
alert('changed');
}).click(function(){
if($('#MySelectId select option').length == 1) {
$('#MySelectId select').change();
}
});
test here
check this post also
for this custom select box, what needs to be done to display an image which is associated to an option value in the select box placeholder.
http://jsfiddle.net/6eCFz/
in this code, how to use the data-attribute, first, to show an image associated with an option value as the selected value and second, to display tick marks when dropdown is opened to indicate the selected value.
Additionally, there are minor bugs:
a code for unique selection, for two select box filled with same options, does not seem to work.
$("#c_id1").change(function(){
$("#c_id2 option:hidden").show();
if($(this).val().length ){
$("#c_id2 option[value=" + $(this).val() + "]").hide();
}
});
$("#c_id2").change(function(){
$("#c_id1 option:hidden").show();
if($(this).val().length ){
$("#c_id1 option[value=" + $(this).val() + "]").hide();
}
});
http://jsfiddle.net/73epV/ - (vanilla script as proof-of-concept)
also, it does not ensures uniqueness onLoad
after triggering the dropdown, if mouse is moved away without first hovering over the option list, the dropdown does not close.
lots of love for any help :)
thanks
I have a select option box that is dynamically populated, so if I change the select some other boxes are filled, and I can delete them too.
Which also deletes the option from the select box, this works fine, but when I delete the options and I have just one left in the box, there seem to be no way to fire the option.
$("#email_name").on("change", function(){
var componentkeys = myDailyemail.getKeys($("#Component").val());
$.each(componentkeys, function(kIndex, kItem) {
$("#key").append($("<option/>").val(kItem).text(kItem.toUpperCase()));
});
});
You can automatically trigger a change event after you populated the select element, making it as if the user already selected the first option.
$("#email_name").on("change", function(){
var componentkeys = myDailyemail.getKeys($("#Component").val());
$.each(componentkeys, function(kIndex, kItem) {
$("#key").append($("<option/>").val(kItem).text(kItem.toUpperCase()));
});
$("#key").trigger("change"); // trigger key
}).trigger("change"); // trigger email_name
I wasn't sure what you wanted to trigger so I entered both possibilities.
You can use .trigger() to fire events manually.
Insert following, where needed.
$("#email_name").trigger('change');
I programmed a select box for a client which come to find out gets re-scripted by a third-party JavaScript function into a bunch of divs and spans, then finally a hidden element which contains the selected value from choosing the div/span element. There is another select box which I programmed just underneath this select box which is dependent on the value of the first select box (i.e. the user chooses a country, then if the country contains regions such as USA and Canada, a state select box appears). In any case, I thought it would be best to just add an onChange event to the newly created hidden element from the first select box and then write my own JavaScript function which would show/hide the second select box based on the hidden elements value when it changed as a result of selecting the country (the third party JavaScript already updates the hidden element value with the newly selected country value). I've tried doing this in jQuery and just straight JavaScript API, however nothing seems to work. Just FYI, when the third party javascript rescripts my select box into div/span's and a hidden input field, the hidden input field does not have an id attribute, so I reference the element through its name (collected_data[7][0]). Here's the code I tried thus far:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("input-country").change(function(e){
console.log("testA");
});
})
jQuery("input-country").change(function(e){
console.log("testB");
});
jQuery(document).ready(function(){
jQuery(document.forms['myForm']['collected_data[7][0]']).change(function(e){
console.log("testC");
});
})
jQuery(document.forms['myForm']['collected_data[7][0]']).change(function(e){
console.log("testD");
});
document.forms['myForm']['collected_data[7][0]'].onchange = function(){
console.log("testE");
};
document.getElementById('input-country').onchange = function(){
console.log("testF");
}
jQuery(document.forms['myForm']['collected_data[7][0]']).live('change',function(){
console.log("testG " + jQuery(this).val())
});
jQuery('input-country').live('change',function(){
console.log("testH " + jQuery(this).val())
});
jQuery(document).ready(function(){
jQuery(document.forms['myForm']['collected_data[7][0]']).live('change',function(){
console.log("testI " + jQuery(this).val())
});
})
jQuery(document).ready(function(){
jQuery('input-country').live('change',function(){
console.log("testJ " + jQuery(this).val())
});
})
</script>
You won't get "change" events when the hidden element is changed programatically by somebody's JavaScript code. Those are only generated by the browser when there's actually user action. What would be better would be for the 3rd-party JavaScript to explicitly call ".change()" (the jQuery method) on the hidden select.
A hidden element is clearly never going to be a target for user interaction.
'input-country' is not a valid selector. Further, the change event requires focus gain, value change, focus loss (blur)--hidden inputs will not have such a sequence of events, so you must manually trigger change on them when you change their values.