遍历 html table 并计算值
Iterate through html table and calculates value
目标是人们应该在输入字段中输入一个值,然后 JavaScript 应该乘以一个固定值。
代码应为每一行执行此操作,并且无需刷新即可自动执行此操作。
JavaScript 适用于第一行,但如果我添加循环(前 3 行代码),它就不再适用了。
Table 看起来像这样
<table class="u-table-entity" id="table_gebäck">
<script src="calculation.js"></script>
<colgroup>
<col width="20%">
<col width="2.1%">
<col width="22%">
<col width="21.7%">
<col width="34.2%">
</colgroup>
<tbody class="u-table-alt-grey-5 u-table-body">
<tr style="height: 55px;">
<b>
<td class="u-table-cell u-table-cell-1"><b>Produkt</b><span style="font-weight: 700;"></span>
</td>
<td class="u-table-cell"></td>
<td class="u-table-cell u-table-cell-3"><b>Einzelpreis</b></td>
<td class="u-table-cell u-table-cell-4"><b>Menge</b></td>
<td class="u-table-cell u-table-cell-5"><b>Gesamtpreis</b></td>
</b>
</tr>
<tr style="height: 55px;">
<td class="u-table-cell">Kornspitz</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="1.39" id="basePrice">1,39 €</p>
</td>
<td class="u-table-cell">
<form id="Menge">
<input type="number" min="0" id="quantity" value="0" step="1.0">
</form>
</td>
<td class="u-table-cell">
<form id="sum">
<p><output id="field_sum" for="quantity">0</output> €</p>
</form>
</td>
</tr>
<tr style="height: 55px;">
<td class="u-table-cell">Row 2</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="5.39" id="basePrice">5,39 €</p>
</td>
<td class="u-table-cell">
<form id="Menge">
<input type="number" min="0" id="quantity" value="0" step="1.0">
</form>
</td>
<td class="u-table-cell">
<form id="sum">
<p><output id="field_sum" for="quantity">0</output> €</p>
</form>
</td>
</tr>
</tbody>
</table>
和我目前创建的 JavaScript 代码
var table = document.getElementById("table_gebäck");
for (var i = 0, row; row = table.rows[i]; i++) {
let row = table.rows[i]
(function () {
const basePrice = document.getElementsByClassName("basePrice");
const quantityInput = document.getElementsByClassName("quantity");
const resOutput = document.getElementsByClassName("field_sum");
quantityInput.addEventListener("change", function () {
let currentQuantity = parseFloat(quantityInput.value);
let currentBasePrice = parseFloat(basePrice.getAttribute("value"));
resOutput.textContent = currentQuantity * currentBasePrice;
});
}());
}
编辑
这对我也有帮助
Calculating total price by iterating in the table using JavaScript
除了标记 cleanup/sanitize 任务之外,还可以实现一种 微组件 方法。
一个可行的解决方案也不可知(从)某个 DOM 层次结构可以基于 custom data attributes and dataset
access together with bound handler data ...
function jsonParse(value) {
let result = null;
try {
result = JSON.parse(value);
} catch(exception) {}
return result;
}
function sanitizeFloatValue(value) {
value = parseFloat(value);
return Number.isFinite(value) ? value : null;
}
function updateTotalValueFromBoundContextData(/* evt */) {
const { source, target, baseValue, toFixed } = this;
const totalValue = baseValue * (sanitizeFloatValue(source.value) || 0);
target.value = (typeof toFixed === 'number')
? totalValue.toFixed(toFixed)
: totalValue;
}
function initializeUpdateTotalValue(componentRoot) {
const source = componentRoot
.querySelector('[data-base-value]');
const target = componentRoot
.querySelector('[data-total-value]');
const baseValue = sanitizeFloatValue(source.dataset.baseValue) || 0;
const config = jsonParse(componentRoot.dataset.updateTotalValue) ?? {};
const toFixed = sanitizeFloatValue(config.toFixed);
const context = { source, target, baseValue, toFixed };
source
.addEventListener('input',
updateTotalValueFromBoundContextData.bind(context)
);
// initial update call
updateTotalValueFromBoundContextData.call(context);
}
function main() {
document
.querySelectorAll('[data-update-total-value]')
.forEach(initializeUpdateTotalValue);
}
main();
body { zoom: .8; }
tr, td { margin: 0!important; padding: 0!important; height: unset!important; }
<form name="product-orders">
<!-- <script src="calculation.js"></script> //-->
<table class="u-table-entity">
<colgroup>
<col width="20%">
<col width="2.1%">
<col width="22%">
<col width="21.7%">
<col width="34.2%">
</colgroup>
<tbody class="u-table-alt-grey-5 u-table-body">
<tr style="height: 55px;">
<td class="u-table-cell u-table-cell-1"><b>Produkt</b><span style="font-weight: 700;"></span>
</td>
<td class="u-table-cell"></td>
<td class="u-table-cell u-table-cell-3"><b>Einzelpreis</b></td>
<td class="u-table-cell u-table-cell-4"><b>Menge</b></td>
<td class="u-table-cell u-table-cell-5"><b>Gesamtpreis</b></td>
</tr>
<tr style="height: 55px;" data-update-total-value='{"toFixed": 2}'>
<td class="u-table-cell">Kornspitz</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="1.39">1,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="0" step="1"
name="quantity-Kornspitz"
id="quantity-Kornspitz"
data-base-value="1.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Kornspitz" data-total-value>0</output>
€
</p>
</td>
</tr>
<tr style="height: 55px;" data-update-total-value='{"toFixed": 2}'>
<td class="u-table-cell">Row 2</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="5.39">5,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="0" step="1"
name="quantity-Row_2"
id="quantity-Row_2"
data-base-value="5.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Row_2" data-total-value>0</output>
€
</p>
</td>
</tr>
<tr style="height: 55px;" data-update-total-value>
<td class="u-table-cell">float number calculation</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="1.39">1,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="5" step="1"
name="quantity-Row_3"
id="quantity-Row_3"
data-base-value="1.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Row_3" data-total-value>0</output>
€
</p>
</td>
</tr>
<tr style="height: 55px;" data-update-total-value='{"toFixed": 4}'>
<td class="u-table-cell"><code>toFixed</code> set to 4</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="5.39">5,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="3" step="1"
name="quantity-Row_4"
id="quantity-Row_4"
data-base-value="5.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Row_4" data-total-value>0</output>
€
</p>
</td>
</tr>
</tbody>
</table>
</form>
编辑
"Thank you very much for sharing this But i have no idea how to use it – Setzi138"
好的,那我试试...
首先,OP 需要编写有效的标记,因此任何元素的 id
属性.
永远不会有重复值
其次,这个任务应该尽可能通用地解决。一个例如不应实施任何与特定 DOM 层次结构(或标记)或过于具体的任务(如计算总价)紧密耦合的代码。
因此,必须找到一种解决方案,该解决方案可以轻松适应具有与此处相同任务的其他环境,实际上是... “更新并显示根据基数计算的总值值和当前更改的乘数,每当此乘数值更改时。
以上措辞严谨的要求,为解决方案指明了方向,甚至指明了基石。
主初始化任务首先需要识别每个结构体,然后才能初始化。
一个可行的方法是利用 custom data-*
attributes instead of class
(coupled to layout and styling) and id
(too specific, disqualifies for generic solutions) attributes. In addition one can provide any string based data to a custom attribute which can be accessed via an HTMLElement
's dataset
属性.
尽管该方法声称尽可能与标记无关,但它有一个先决条件。这种 “微组件” 的结构需要有一个根元素和两个其他元素,它们都需要嵌套 under/within 组件根。
一个元素是数量变化的触发器或来源,另一个是更新总值的目标。
利用 [data-*]
属性在 DOM 中访问这些元素也没有缺点,因为解决方案通过 <element >.querySelector
and <element >.querySelectorAll
.
使用现代元素查询
现在唯一剩下的就是正确的命名和实现本身。
...
+++待续+++
...
通过对第一个所示方法的更多迭代,人们最终可以提供基于模块的实现高度通用,customizable 和 self-initializing 组件,由于自定义功能,它也可以在 DOM 不允许大规模更改标记的环境中运行...
// utility functions
function parseJSON(value) {
let result = null;
try {
result = JSON.parse(value);
} catch(exception) {}
return result;
}
function sanitizeFloatValue(value) {
value = parseFloat(value);
return Number.isFinite(value) ? value : null;
}
function getCustomKeyFromAttributeSelector(selector) {
return (/\[\s*data-(?<customKey>[^\s\]]+)(?:\s|\])/)
.exec(selector)
?.groups
?.customKey;
}
function getDatasetKeyFromCustomAttributeSelector(selector) {
return getCustomKeyFromAttributeSelector(selector)
?.toLowerCase()
?.replace((/-(\p{Ll})/gu), (match, char) => char.toUpperCase());
}
// component specific module based code
const updateTotalValueModule = (function () {
const DEFAULT_CONFIG = {
calculation: {
baseValue: 0,
toFixed: 2,
},
selectors: {
source: '[data-base-value]',
target: '[data-total-value]',
},
eventType: 'input',
}
const DEFAULT_SELCTOR_COMPONENT = '[data-update-total-value]';
function updateTotalValueFromBoundContextData(/* evt */) {
const { source, target, baseValue, toFixed } = this;
const totalValue = baseValue * (sanitizeFloatValue(source.value) || 0);
target.value = (typeof toFixed === 'number')
? totalValue.toFixed(toFixed)
: totalValue;
}
let currentConfigKey;
function initializeUpdateTotalValue(componentRoot) {
const { // config values.
selectors = DEFAULT_CONFIG.selectors,
eventType = DEFAULT_CONFIG.eventType,
calculation = DEFAULT_CONFIG.calculation
} = (parseJSON(
componentRoot.dataset[currentConfigKey]
) ?? DEFAULT_CONFIG);
const source = componentRoot.querySelector(
selectors.source || DEFAULT_CONFIG.selectors.source
);
const target = source && componentRoot.querySelector(
selectors.target || DEFAULT_CONFIG.selectors.target
);
if (source && target) {
const baseValue = (
calculation.baseValue ||
sanitizeFloatValue(source.dataset[
getDatasetKeyFromCustomAttributeSelector(
selectors.source || DEFAULT_CONFIG.selectors.source
)
]) || 0
);
const toFixed = sanitizeFloatValue(
calculation.toFixed || DEFAULT_CONFIG.calculation.toFixed
);
const context = { source, target, baseValue, toFixed };
source.addEventListener(
eventType,
updateTotalValueFromBoundContextData.bind(context)
);
// initial update call
updateTotalValueFromBoundContextData.call(context);
}
}
function initialize(customAttributeSelector) {
const selector = (typeof customAttributeSelector === 'string')
&& customAttributeSelector
|| DEFAULT_SELCTOR_COMPONENT;
currentConfigKey = getDatasetKeyFromCustomAttributeSelector(selector);
document
.querySelectorAll(selector)
.forEach(initializeUpdateTotalValue);
}
// (module) export(s)
return {
initialize
};
}());
// running the component ...
// ... does target any default-config conform component.
updateTotalValueModule.initialize();
// ... does target any custom specific component.
updateTotalValueModule.initialize('[data-auto-total-price]');
body { zoom: .8; }
tr, td { margin: 0!important; padding: 0!important; height: unset!important; }
<!-- <script src="calculation.js"></script> //-->
<table class="u-table-entity" id="table_gebäck">
<colgroup>
<col width="20%">
<col width="2.1%">
<col width="22%">
<col width="21.7%">
<col width="34.2%">
</colgroup>
<tbody class="u-table-alt-grey-5 u-table-body">
<tr style="height: 55px;">
<td class="u-table-cell u-table-cell-1"><b>Produkt</b><span style="font-weight: 700;"></span>
</td>
<td class="u-table-cell"></td>
<td class="u-table-cell u-table-cell-3"><b>Einzelpreis</b></td>
<td class="u-table-cell u-table-cell-4"><b>Menge</b></td>
<td class="u-table-cell u-table-cell-5"><b>Gesamtpreis</b></td>
</tr>
<tr style="height: 55px;" data-update-total-value ='{"calculation":{"baseValue":1.39,"toFixed":2},"selectors":{"source":"form input[type=\"number\"]","target":"form output"},"eventType":"input"}'>
<td class="u-table-cell">Kornspitz</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p>1,39 €</p>
</td>
<td class="u-table-cell">
<form name="amount_Kornspitz">
<input type="number" value="0" min="0" step="1" id="amount_Kornspitz">
</form>
</td>
<td class="u-table-cell">
<form name="price_total_Kornspitz">
<p>
<output for="amount_Kornspitz">0</output>
€
</p>
</form>
</td>
</tr>
<tr style="height: 55px;" data-auto-total-price='{"calculation":{"toFixed":4},"selectors":{"target":"form output"}}'>
<td class="u-table-cell">Row 2</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p>5,39 €</p>
</td>
<td class="u-table-cell">
<form name="amount_Row_2">
<input type="number" value="5" min="0" step="1" id="amount_Row_2" data-base-value="5.39">
</form>
</td>
<td class="u-table-cell">
<form name="price_total_Row_2">
<p>
<output for="amount_Row_2">0</output>
€
</p>
</form>
</td>
</tr>
</tbody>
</table>
目标是人们应该在输入字段中输入一个值,然后 JavaScript 应该乘以一个固定值。
代码应为每一行执行此操作,并且无需刷新即可自动执行此操作。
JavaScript 适用于第一行,但如果我添加循环(前 3 行代码),它就不再适用了。
Table 看起来像这样
<table class="u-table-entity" id="table_gebäck">
<script src="calculation.js"></script>
<colgroup>
<col width="20%">
<col width="2.1%">
<col width="22%">
<col width="21.7%">
<col width="34.2%">
</colgroup>
<tbody class="u-table-alt-grey-5 u-table-body">
<tr style="height: 55px;">
<b>
<td class="u-table-cell u-table-cell-1"><b>Produkt</b><span style="font-weight: 700;"></span>
</td>
<td class="u-table-cell"></td>
<td class="u-table-cell u-table-cell-3"><b>Einzelpreis</b></td>
<td class="u-table-cell u-table-cell-4"><b>Menge</b></td>
<td class="u-table-cell u-table-cell-5"><b>Gesamtpreis</b></td>
</b>
</tr>
<tr style="height: 55px;">
<td class="u-table-cell">Kornspitz</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="1.39" id="basePrice">1,39 €</p>
</td>
<td class="u-table-cell">
<form id="Menge">
<input type="number" min="0" id="quantity" value="0" step="1.0">
</form>
</td>
<td class="u-table-cell">
<form id="sum">
<p><output id="field_sum" for="quantity">0</output> €</p>
</form>
</td>
</tr>
<tr style="height: 55px;">
<td class="u-table-cell">Row 2</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="5.39" id="basePrice">5,39 €</p>
</td>
<td class="u-table-cell">
<form id="Menge">
<input type="number" min="0" id="quantity" value="0" step="1.0">
</form>
</td>
<td class="u-table-cell">
<form id="sum">
<p><output id="field_sum" for="quantity">0</output> €</p>
</form>
</td>
</tr>
</tbody>
</table>
和我目前创建的 JavaScript 代码
var table = document.getElementById("table_gebäck");
for (var i = 0, row; row = table.rows[i]; i++) {
let row = table.rows[i]
(function () {
const basePrice = document.getElementsByClassName("basePrice");
const quantityInput = document.getElementsByClassName("quantity");
const resOutput = document.getElementsByClassName("field_sum");
quantityInput.addEventListener("change", function () {
let currentQuantity = parseFloat(quantityInput.value);
let currentBasePrice = parseFloat(basePrice.getAttribute("value"));
resOutput.textContent = currentQuantity * currentBasePrice;
});
}());
}
编辑
这对我也有帮助
Calculating total price by iterating in the table using JavaScript
除了标记 cleanup/sanitize 任务之外,还可以实现一种 微组件 方法。
一个可行的解决方案也不可知(从)某个 DOM 层次结构可以基于 custom data attributes and dataset
access together with bound handler data ...
function jsonParse(value) {
let result = null;
try {
result = JSON.parse(value);
} catch(exception) {}
return result;
}
function sanitizeFloatValue(value) {
value = parseFloat(value);
return Number.isFinite(value) ? value : null;
}
function updateTotalValueFromBoundContextData(/* evt */) {
const { source, target, baseValue, toFixed } = this;
const totalValue = baseValue * (sanitizeFloatValue(source.value) || 0);
target.value = (typeof toFixed === 'number')
? totalValue.toFixed(toFixed)
: totalValue;
}
function initializeUpdateTotalValue(componentRoot) {
const source = componentRoot
.querySelector('[data-base-value]');
const target = componentRoot
.querySelector('[data-total-value]');
const baseValue = sanitizeFloatValue(source.dataset.baseValue) || 0;
const config = jsonParse(componentRoot.dataset.updateTotalValue) ?? {};
const toFixed = sanitizeFloatValue(config.toFixed);
const context = { source, target, baseValue, toFixed };
source
.addEventListener('input',
updateTotalValueFromBoundContextData.bind(context)
);
// initial update call
updateTotalValueFromBoundContextData.call(context);
}
function main() {
document
.querySelectorAll('[data-update-total-value]')
.forEach(initializeUpdateTotalValue);
}
main();
body { zoom: .8; }
tr, td { margin: 0!important; padding: 0!important; height: unset!important; }
<form name="product-orders">
<!-- <script src="calculation.js"></script> //-->
<table class="u-table-entity">
<colgroup>
<col width="20%">
<col width="2.1%">
<col width="22%">
<col width="21.7%">
<col width="34.2%">
</colgroup>
<tbody class="u-table-alt-grey-5 u-table-body">
<tr style="height: 55px;">
<td class="u-table-cell u-table-cell-1"><b>Produkt</b><span style="font-weight: 700;"></span>
</td>
<td class="u-table-cell"></td>
<td class="u-table-cell u-table-cell-3"><b>Einzelpreis</b></td>
<td class="u-table-cell u-table-cell-4"><b>Menge</b></td>
<td class="u-table-cell u-table-cell-5"><b>Gesamtpreis</b></td>
</tr>
<tr style="height: 55px;" data-update-total-value='{"toFixed": 2}'>
<td class="u-table-cell">Kornspitz</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="1.39">1,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="0" step="1"
name="quantity-Kornspitz"
id="quantity-Kornspitz"
data-base-value="1.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Kornspitz" data-total-value>0</output>
€
</p>
</td>
</tr>
<tr style="height: 55px;" data-update-total-value='{"toFixed": 2}'>
<td class="u-table-cell">Row 2</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="5.39">5,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="0" step="1"
name="quantity-Row_2"
id="quantity-Row_2"
data-base-value="5.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Row_2" data-total-value>0</output>
€
</p>
</td>
</tr>
<tr style="height: 55px;" data-update-total-value>
<td class="u-table-cell">float number calculation</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="1.39">1,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="5" step="1"
name="quantity-Row_3"
id="quantity-Row_3"
data-base-value="1.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Row_3" data-total-value>0</output>
€
</p>
</td>
</tr>
<tr style="height: 55px;" data-update-total-value='{"toFixed": 4}'>
<td class="u-table-cell"><code>toFixed</code> set to 4</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="5.39">5,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="3" step="1"
name="quantity-Row_4"
id="quantity-Row_4"
data-base-value="5.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Row_4" data-total-value>0</output>
€
</p>
</td>
</tr>
</tbody>
</table>
</form>
编辑
"Thank you very much for sharing this But i have no idea how to use it – Setzi138"
好的,那我试试...
首先,OP 需要编写有效的标记,因此任何元素的 id
属性.
其次,这个任务应该尽可能通用地解决。一个例如不应实施任何与特定 DOM 层次结构(或标记)或过于具体的任务(如计算总价)紧密耦合的代码。
因此,必须找到一种解决方案,该解决方案可以轻松适应具有与此处相同任务的其他环境,实际上是... “更新并显示根据基数计算的总值值和当前更改的乘数,每当此乘数值更改时。
以上措辞严谨的要求,为解决方案指明了方向,甚至指明了基石。
主初始化任务首先需要识别每个结构体,然后才能初始化。
一个可行的方法是利用 custom data-*
attributes instead of class
(coupled to layout and styling) and id
(too specific, disqualifies for generic solutions) attributes. In addition one can provide any string based data to a custom attribute which can be accessed via an HTMLElement
's dataset
属性.
尽管该方法声称尽可能与标记无关,但它有一个先决条件。这种 “微组件” 的结构需要有一个根元素和两个其他元素,它们都需要嵌套 under/within 组件根。 一个元素是数量变化的触发器或来源,另一个是更新总值的目标。
利用 [data-*]
属性在 DOM 中访问这些元素也没有缺点,因为解决方案通过 <element >.querySelector
and <element >.querySelectorAll
.
现在唯一剩下的就是正确的命名和实现本身。
...
+++待续+++
...
通过对第一个所示方法的更多迭代,人们最终可以提供基于模块的实现高度通用,customizable 和 self-initializing 组件,由于自定义功能,它也可以在 DOM 不允许大规模更改标记的环境中运行...
// utility functions
function parseJSON(value) {
let result = null;
try {
result = JSON.parse(value);
} catch(exception) {}
return result;
}
function sanitizeFloatValue(value) {
value = parseFloat(value);
return Number.isFinite(value) ? value : null;
}
function getCustomKeyFromAttributeSelector(selector) {
return (/\[\s*data-(?<customKey>[^\s\]]+)(?:\s|\])/)
.exec(selector)
?.groups
?.customKey;
}
function getDatasetKeyFromCustomAttributeSelector(selector) {
return getCustomKeyFromAttributeSelector(selector)
?.toLowerCase()
?.replace((/-(\p{Ll})/gu), (match, char) => char.toUpperCase());
}
// component specific module based code
const updateTotalValueModule = (function () {
const DEFAULT_CONFIG = {
calculation: {
baseValue: 0,
toFixed: 2,
},
selectors: {
source: '[data-base-value]',
target: '[data-total-value]',
},
eventType: 'input',
}
const DEFAULT_SELCTOR_COMPONENT = '[data-update-total-value]';
function updateTotalValueFromBoundContextData(/* evt */) {
const { source, target, baseValue, toFixed } = this;
const totalValue = baseValue * (sanitizeFloatValue(source.value) || 0);
target.value = (typeof toFixed === 'number')
? totalValue.toFixed(toFixed)
: totalValue;
}
let currentConfigKey;
function initializeUpdateTotalValue(componentRoot) {
const { // config values.
selectors = DEFAULT_CONFIG.selectors,
eventType = DEFAULT_CONFIG.eventType,
calculation = DEFAULT_CONFIG.calculation
} = (parseJSON(
componentRoot.dataset[currentConfigKey]
) ?? DEFAULT_CONFIG);
const source = componentRoot.querySelector(
selectors.source || DEFAULT_CONFIG.selectors.source
);
const target = source && componentRoot.querySelector(
selectors.target || DEFAULT_CONFIG.selectors.target
);
if (source && target) {
const baseValue = (
calculation.baseValue ||
sanitizeFloatValue(source.dataset[
getDatasetKeyFromCustomAttributeSelector(
selectors.source || DEFAULT_CONFIG.selectors.source
)
]) || 0
);
const toFixed = sanitizeFloatValue(
calculation.toFixed || DEFAULT_CONFIG.calculation.toFixed
);
const context = { source, target, baseValue, toFixed };
source.addEventListener(
eventType,
updateTotalValueFromBoundContextData.bind(context)
);
// initial update call
updateTotalValueFromBoundContextData.call(context);
}
}
function initialize(customAttributeSelector) {
const selector = (typeof customAttributeSelector === 'string')
&& customAttributeSelector
|| DEFAULT_SELCTOR_COMPONENT;
currentConfigKey = getDatasetKeyFromCustomAttributeSelector(selector);
document
.querySelectorAll(selector)
.forEach(initializeUpdateTotalValue);
}
// (module) export(s)
return {
initialize
};
}());
// running the component ...
// ... does target any default-config conform component.
updateTotalValueModule.initialize();
// ... does target any custom specific component.
updateTotalValueModule.initialize('[data-auto-total-price]');
body { zoom: .8; }
tr, td { margin: 0!important; padding: 0!important; height: unset!important; }
<!-- <script src="calculation.js"></script> //-->
<table class="u-table-entity" id="table_gebäck">
<colgroup>
<col width="20%">
<col width="2.1%">
<col width="22%">
<col width="21.7%">
<col width="34.2%">
</colgroup>
<tbody class="u-table-alt-grey-5 u-table-body">
<tr style="height: 55px;">
<td class="u-table-cell u-table-cell-1"><b>Produkt</b><span style="font-weight: 700;"></span>
</td>
<td class="u-table-cell"></td>
<td class="u-table-cell u-table-cell-3"><b>Einzelpreis</b></td>
<td class="u-table-cell u-table-cell-4"><b>Menge</b></td>
<td class="u-table-cell u-table-cell-5"><b>Gesamtpreis</b></td>
</tr>
<tr style="height: 55px;" data-update-total-value ='{"calculation":{"baseValue":1.39,"toFixed":2},"selectors":{"source":"form input[type=\"number\"]","target":"form output"},"eventType":"input"}'>
<td class="u-table-cell">Kornspitz</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p>1,39 €</p>
</td>
<td class="u-table-cell">
<form name="amount_Kornspitz">
<input type="number" value="0" min="0" step="1" id="amount_Kornspitz">
</form>
</td>
<td class="u-table-cell">
<form name="price_total_Kornspitz">
<p>
<output for="amount_Kornspitz">0</output>
€
</p>
</form>
</td>
</tr>
<tr style="height: 55px;" data-auto-total-price='{"calculation":{"toFixed":4},"selectors":{"target":"form output"}}'>
<td class="u-table-cell">Row 2</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p>5,39 €</p>
</td>
<td class="u-table-cell">
<form name="amount_Row_2">
<input type="number" value="5" min="0" step="1" id="amount_Row_2" data-base-value="5.39">
</form>
</td>
<td class="u-table-cell">
<form name="price_total_Row_2">
<p>
<output for="amount_Row_2">0</output>
€
</p>
</form>
</td>
</tr>
</tbody>
</table>