Skip to content

Instantly share code, notes, and snippets.

@psalz
Created April 5, 2016 20:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save psalz/4bae0b7318d1d4c03be9e6d76601834a to your computer and use it in GitHub Desktop.
Save psalz/4bae0b7318d1d4c03be9e6d76601834a to your computer and use it in GitHub Desktop.
Woocommerce Composite Products: Detect single choice attributes
"use strict";
(function ($) {
/**
* Detects all component attributes that have only a single value option and adds the '.single-choice' class
* to the respective table row. Additionally, a <span> with the class '.single-choice-label' is added, containing
* the options name.
*
* If executed twice, the previous changes are reverted first (in order to account for possible scenario changes).
* Default values or previous selections are saved and restored if the option becomes available again.
*
* Tested with Woocommerce Composite Products 3.6.1
*
* @param component The WC_CP_Component to be modified
*/
function detect_single_choice_attributes(component) {
// reset all (potential) previous changes first
reset_single_choice_changes(component);
var variations = component.$component_summary_content.data('product_variations');
var attributes = {};
// count the number of available values per attribute
for (var i = 0; i < variations.length; ++i) {
for (var a in variations[i].attributes) {
if (variations[i].attributes.hasOwnProperty(a)) {
var attribute_value = variations[i].attributes[a];
attributes[a] = attributes[a] || {};
attributes[a][attribute_value] = attributes[a][attribute_value] + 1 || 1;
}
}
}
// determine "non-choices" (i.e. attributes with only a single possible value)
var single_choice_attributes = {};
for (var a in attributes) {
if (attributes.hasOwnProperty(a)) {
for (var v in attributes[a]) {
if (attributes[a].hasOwnProperty(v) && attributes[a][v] === variations.length) {
single_choice_attributes[a] = v;
break;
}
}
}
}
// add "single-choice" class to attribute table rows and inject attribute label
for (var a in single_choice_attributes) {
if (single_choice_attributes.hasOwnProperty(a)) {
var value = single_choice_attributes[a];
var $select = component.$component_summary_content.find('select[data-attribute_name=' + a + ']');
// store original value (e.g. default value) for reset (see above)
var originalValue = $select.find('option:selected').val();
$select.data('original_attribute_value', originalValue);
// cause woocommerce to recompute available options within <select>
$select.trigger('focusin');
var $selectTd = $select.parent();
var $tr = $selectTd.parent();
$select.val(value);
var valueLabel = $select.find('option:selected').text();
$tr.addClass('single-choice');
$selectTd.prepend($('<span class="single-choice-label">' + valueLabel + '</span>'));
// inform woocommerce about the change
$select.trigger('change');
}
}
}
function reset_single_choice_changes(component) {
var $attributeOptions = component.$component_summary_content.find('.attribute-options.single-choice');
$attributeOptions.removeClass('single-choice');
$attributeOptions.find('.single-choice-label').remove();
// restore previous value in select
var $select = $attributeOptions.find('select');
var originalValue = $select.data('original_attribute_value');
if (originalValue) {
// cause woocommerce to recompute available options within <select>
$select.trigger('focusin');
$select.val(originalValue);
}
}
function handle_reload_product_variations(event) {
detect_single_choice_attributes(event.data.component);
}
$(document).ready(function() {
$('.composite_data').on('wc-composite-initializing', function (event, composite) {
composite.actions.add_action('active_scenarios_updated', function() {
var components = composite.api.get_components();
for (var i = 0; i < components.length; ++i) {
var $content = components[i].$component_summary_content;
$content.off('reload_product_variations', handle_reload_product_variations);
$content.one('reload_product_variations', { component: components[i] }, handle_reload_product_variations);
}
});
});
});
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment