Created
April 5, 2016 20:00
-
-
Save psalz/4bae0b7318d1d4c03be9e6d76601834a to your computer and use it in GitHub Desktop.
Woocommerce Composite Products: Detect single choice attributes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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