[enhancement] [website] numeric attribute selector, smart selection of variant based on attribute combinations
diff --git a/erpnext/templates/generators/item.html b/erpnext/templates/generators/item.html
index 4bd521d..acbcedf 100644
--- a/erpnext/templates/generators/item.html
+++ b/erpnext/templates/generators/item.html
@@ -29,7 +29,8 @@
<div class="item-attribute-selectors">
{% if has_variants %}
{% for d in attributes %}
- <div class="item-view-attribute"
+ {% if attribute_values[d.attribute] -%}
+ <div class="item-view-attribute {% if (attribute_values[d.attribute] | len)==1 -%} hidden {%- endif %}"
style="margin-bottom: 10px;">
<h6 class="text-muted">{{ _(d.attribute) }}</h6>
<select class="form-control"
@@ -37,12 +38,17 @@
data-attribute="{{ d.attribute }}">
{% for value in attribute_values[d.attribute] %}
<option value="{{ value }}"
- {% if selected_attributes and selected_attributes[d.attribute]==value -%} selected {%- endif %}>
+ {% if selected_attributes and selected_attributes[d.attribute]==value -%}
+ selected
+ {%- elif disabled_attributes and value in disabled_attributes.get(d.attribute, []) -%}
+ disabled
+ {%- endif %}>
{{ _(value) }}
</option>
{% endfor %}
</select>
</div>
+ {%- endif %}
{% endfor %}
{% endif %}
</div>
diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js
index 2345de4..e28f351 100644
--- a/erpnext/templates/includes/product_page.js
+++ b/erpnext/templates/includes/product_page.js
@@ -64,8 +64,23 @@
});
});
- $("[itemscope] .item-view-attribute select").on("change", function() {
- var item_code = encodeURIComponent(get_item_code());
+ $("[itemscope] .item-view-attribute .form-control").on("change", function() {
+ try {
+ var item_code = encodeURIComponent(get_item_code());
+ } catch(e) {
+ // unable to find variant
+ // then chose the closest available one
+
+ var attribute = $(this).attr("data-attribute");
+ var attribute_value = $(this).val()
+ var item_code = update_attribute_selectors(attribute, attribute_value);
+
+ if (!item_code) {
+ msgprint(__("Please select some other value for {0}", [attribute]))
+ throw e;
+ }
+ }
+
if (window.location.search.indexOf(item_code)!==-1) {
return;
}
@@ -83,10 +98,8 @@
function get_item_code() {
if(window.variant_info) {
- attributes = {};
- $('[itemscope]').find(".item-view-attribute select").each(function() {
- attributes[$(this).attr('data-attribute')] = $(this).val();
- });
+ var attributes = get_selected_attributes();
+
for(var i in variant_info) {
var variant = variant_info[i];
var match = true;
@@ -106,3 +119,53 @@
return item_code;
}
}
+
+function update_attribute_selectors(selected_attribute, selected_attribute_value) {
+ // find the closest match keeping the selected attribute in focus and get the item code
+
+ var attributes = get_selected_attributes();
+
+ var previous_match_score = 0;
+ var matched;
+ for(var i in variant_info) {
+ var variant = variant_info[i];
+ var match_score = 0;
+ var has_selected_attribute = false;
+
+ console.log(variant);
+
+ for(var j in variant.attributes) {
+ if(attributes[variant.attributes[j].attribute]===variant.attributes[j].attribute_value) {
+ match_score = match_score + 1;
+
+ if (variant.attributes[j].attribute==selected_attribute && variant.attributes[j].attribute_value==selected_attribute_value) {
+ has_selected_attribute = true;
+ }
+ }
+ }
+
+ if (has_selected_attribute && (match_score > previous_match_score)) {
+ previous_match_score = match_score;
+ matched = variant;
+ }
+ }
+
+ if (matched) {
+ for (var j in matched.attributes) {
+ var attr = matched.attributes[j];
+ $('[itemscope]')
+ .find(repl('.item-view-attribute .form-control[data-attribute="%(attribute)s"]', attr))
+ .val(attr.attribute_value);
+ }
+
+ return matched.name;
+ }
+}
+
+function get_selected_attributes() {
+ var attributes = {};
+ $('[itemscope]').find(".item-view-attribute .form-control").each(function() {
+ attributes[$(this).attr('data-attribute')] = $(this).val();
+ });
+ return attributes;
+}