237 lines
9.7 KiB
JavaScript
237 lines
9.7 KiB
JavaScript
define(['jquery', 'mage/translate'], function ($, $t) {
|
||
'use strict';
|
||
|
||
return function (config, element) {
|
||
var $root = $(element),
|
||
rawConfig = $root.find('[data-role="parameter-config"]').text(),
|
||
data = rawConfig ? JSON.parse(rawConfig) : {},
|
||
products = data.products || [],
|
||
applicationOptions = data.applicationOptions || [],
|
||
messages = data.messages || {},
|
||
maximum = 6,
|
||
selected = [],
|
||
mode = 'key',
|
||
keyParameters = [
|
||
'Density(g/cm3) (unit to be confirmed)',
|
||
'Heat Distortion Temperature(°C)',
|
||
'Tensile Strength (XY) (MPa)',
|
||
'Elongation at Break (XY) (%)',
|
||
'Flexural Strength (XY) (MPa)',
|
||
'Flexural Modulus (XY) (MPa)',
|
||
'IZOD Impact Strength (XY) (kJ/m²)',
|
||
'Extruder Temperature(°C)',
|
||
'Bed Temperature(°C)',
|
||
'Fan Speed(%)',
|
||
'Printing Speed(mm/s) (high-speed printing parameter)',
|
||
'Printing Recommendation',
|
||
'Drying'
|
||
],
|
||
$seriesList = $root.find('[data-role="series-list"]'),
|
||
$selectedMaterials = $root.find('[data-role="selected-materials"]'),
|
||
$notice = $root.find('[data-role="material-notice"]'),
|
||
$selectionCount = $root.find('[data-role="selection-count"]'),
|
||
$comparisonCount = $root.find('[data-role="comparison-count"]'),
|
||
$resultCount = $root.find('[data-role="result-count"]'),
|
||
$placeholder = $root.find('[data-role="comparison-placeholder"]'),
|
||
$tableWrap = $root.find('[data-role="comparison-table-wrap"]'),
|
||
$head = $root.find('[data-role="comparison-head"]'),
|
||
$body = $root.find('[data-role="comparison-body"]');
|
||
|
||
function selectedBase() {
|
||
return $root.find('[data-role="base-filter"]:checked').val() || '';
|
||
}
|
||
|
||
function productsForBase() {
|
||
var base = selectedBase();
|
||
return $.grep(products, function (product) { return product.base === base; });
|
||
}
|
||
|
||
function primaryApplication(product) {
|
||
return product.applications && product.applications.length ? product.applications[0] : 'other';
|
||
}
|
||
|
||
function applicationLabel(value) {
|
||
var option = applicationOptions.find(function (item) { return item.value === value; });
|
||
return option ? option.label : $t('Other Series');
|
||
}
|
||
|
||
function isSelected(id) {
|
||
return $.inArray(id, selected) !== -1;
|
||
}
|
||
|
||
function findProduct(id) {
|
||
return products.find(function (product) { return product.id === id; });
|
||
}
|
||
|
||
function renderSeries() {
|
||
var baseProducts = productsForBase(), groups = {};
|
||
$.each(baseProducts, function (_, product) {
|
||
var application = primaryApplication(product);
|
||
groups[application] = groups[application] || [];
|
||
groups[application].push(product);
|
||
});
|
||
|
||
$seriesList.empty();
|
||
$.each(applicationOptions, function (_, option) {
|
||
var groupProducts = groups[option.value] || [];
|
||
if (!groupProducts.length) {
|
||
return;
|
||
}
|
||
renderSeriesRow(option.label, groupProducts);
|
||
delete groups[option.value];
|
||
});
|
||
$.each(groups, function (application, groupProducts) {
|
||
renderSeriesRow(applicationLabel(application), groupProducts);
|
||
});
|
||
|
||
$resultCount.text(baseProducts.length);
|
||
updateSelection();
|
||
}
|
||
|
||
function renderSeriesRow(label, groupProducts) {
|
||
var $row = $('<div/>', {'class': 'esun-parameter-comparison__series-row'}),
|
||
$label = $('<div/>', {'class': 'esun-parameter-comparison__series-name'}),
|
||
$products = $('<div/>', {'class': 'esun-parameter-comparison__series-products'});
|
||
|
||
$label.append($('<strong/>', {text: label}), $('<span/>', {text: groupProducts.length}));
|
||
$.each(groupProducts, function (_, product) {
|
||
$('<button/>', {
|
||
type: 'button',
|
||
'class': 'esun-parameter-comparison__product' + (isSelected(product.id) ? ' is-selected' : ''),
|
||
text: product.name,
|
||
title: product.name,
|
||
disabled: !isSelected(product.id) && selected.length >= maximum,
|
||
'data-role': 'material-option',
|
||
'data-id': product.id
|
||
}).appendTo($products);
|
||
});
|
||
$row.append($label, $products).appendTo($seriesList);
|
||
}
|
||
|
||
function updateSelection() {
|
||
$selectionCount.text(selected.length);
|
||
$comparisonCount.text(selected.length);
|
||
$selectedMaterials.empty();
|
||
$.each(selected, function (_, id) {
|
||
var product = findProduct(id), $pill;
|
||
if (!product) {
|
||
return;
|
||
}
|
||
$pill = $('<span/>', {'class': 'esun-parameter-comparison__selected-pill'});
|
||
$pill.append(
|
||
$('<span/>', {text: product.name}),
|
||
$('<button/>', {
|
||
type: 'button',
|
||
text: '×',
|
||
'aria-label': $t('Remove %1').replace('%1', product.name),
|
||
'data-role': 'remove-material',
|
||
'data-id': id
|
||
})
|
||
).appendTo($selectedMaterials);
|
||
});
|
||
renderComparison();
|
||
}
|
||
|
||
function removeMaterial(id) {
|
||
selected = $.grep(selected, function (selectedId) { return selectedId !== id; });
|
||
$notice.text('');
|
||
renderSeries();
|
||
}
|
||
|
||
function parameterIsVisible(name, values) {
|
||
if (mode === 'key' && $.inArray(name, keyParameters) === -1) {
|
||
return false;
|
||
}
|
||
if (mode === 'differences') {
|
||
return values.filter(function (value, index, array) {
|
||
return array.indexOf(value) === index;
|
||
}).length > 1;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function renderComparison() {
|
||
var selectedProducts = $.map(selected, findProduct),
|
||
groups = data.parameterGroups || {};
|
||
$head.empty();
|
||
$body.empty();
|
||
|
||
if (selectedProducts.length < 1) {
|
||
$placeholder.show();
|
||
$tableWrap.hide();
|
||
return;
|
||
}
|
||
|
||
$tableWrap.toggleClass('is-single', selectedProducts.length === 1);
|
||
|
||
var $headerRow = $('<tr/>').append($('<th/>', {text: $t('Parameter')}));
|
||
$.each(selectedProducts, function (_, product) {
|
||
var $name = $('<span/>', {text: product.name}),
|
||
$remove = $('<button/>', {
|
||
type: 'button', text: '×',
|
||
'aria-label': $t('Remove %1').replace('%1', product.name),
|
||
'data-role': 'remove-material', 'data-id': product.id
|
||
});
|
||
$headerRow.append($('<th/>').append($name, $remove));
|
||
});
|
||
$head.append($headerRow);
|
||
|
||
$.each(groups, function (groupName, parameters) {
|
||
var rows = [];
|
||
$.each(parameters, function (_, parameterName) {
|
||
var values = $.map(selectedProducts, function (product) {
|
||
var value = product.groups[groupName] && product.groups[groupName][parameterName];
|
||
return value === undefined || value === null || value === ''
|
||
? (messages.missingValue || '—') : String(value);
|
||
});
|
||
if (!parameterIsVisible(parameterName, values)) {
|
||
return;
|
||
}
|
||
var $row = $('<tr/>').append($('<th/>', {scope: 'row', text: parameterName}));
|
||
$.each(values, function (_, value) { $row.append($('<td/>').text(value)); });
|
||
rows.push($row);
|
||
});
|
||
if (rows.length) {
|
||
$body.append($('<tr/>', {'class': 'esun-parameter-comparison__group-row'})
|
||
.append($('<th/>', {colspan: selectedProducts.length + 1, text: groupName})));
|
||
$.each(rows, function (_, row) { $body.append(row); });
|
||
}
|
||
});
|
||
|
||
$placeholder.hide();
|
||
$tableWrap.show();
|
||
}
|
||
|
||
$root.on('change', '[data-role="base-filter"]', function () {
|
||
selected = [];
|
||
$notice.text('');
|
||
renderSeries();
|
||
});
|
||
$root.on('click', '[data-role="material-option"]', function () {
|
||
var id = $(this).data('id');
|
||
if (isSelected(id)) {
|
||
removeMaterial(id);
|
||
return;
|
||
}
|
||
if (selected.length >= maximum) {
|
||
$notice.text($t('You can compare up to 6 materials.'));
|
||
return;
|
||
}
|
||
selected.push(id);
|
||
$notice.text('');
|
||
renderSeries();
|
||
});
|
||
$root.on('click', '[data-role="remove-material"]', function () {
|
||
removeMaterial($(this).data('id'));
|
||
});
|
||
$root.on('click', '[data-role="comparison-mode"]', function () {
|
||
mode = $(this).data('mode');
|
||
$root.find('[data-role="comparison-mode"]').removeClass('is-active');
|
||
$(this).addClass('is-active');
|
||
renderComparison();
|
||
});
|
||
|
||
renderSeries();
|
||
};
|
||
});
|