Как удалить из массива значение чекнутого input?
Есть небольшой калькулятор стоимости, который работает через input:radio, ибо услуги можно выбирать только из двух типов. Нашёл скрипт, который позволяет при клике анчекать radio, но теперь никак не могу сообразить, что написать, чтобы при анчеке удалялось значение чекнутого инпута. Вот код. https://jsfiddle.net/TomatoBrain/1sz9yvmf/5/
<div class="price">
<div class="container">
<div class="price__title">
<h2><span class="light">Рассчитайте</span> стоимость депиляиции
и шугаринга <span class="light">необходимых зон</span> </h2>
</div>
<div class="row">
<div class="price--flex flexWrap">
<div class="col-xl-9 col-lg-12 col-md-12 col-sm-12">
<div class="price__calc">
<div class="price__calc-switch">
<div class="price__tabs">
<div class="price__tab1" id="price__tab1">
<div class="price__calc-main">
<div class="price__calc-row ptxtsm price__calc-row-title">
<p class="bold ">Название</p>
<p class="bold ">Время</p>
<p class="bold price__calc-row-title--column">Шугаринг
<br>
<span>(выберите)</span>
</p>
<p class="bold price__calc-row-title--column">Депиляция воском
<br>
<span>(выберите)</span>
</p>
</div>
<div class="price__calc-row ptxtsm">
<p>Подмышки</p>
<p>5-10 минут</p>
<div>
<input type="radio" name="1" id="1" value="8" />
<label for="1">8 руб</label>
</div>
<div>
<input type="radio" name="1" id="01" value="8" />
<label for="01">8 руб</label>
</div>
</div>
<div class="price__calc-row ptxtsm">
<p>Бикини классика (контур трусиков)</p>
<p>10-20 минут</p>
<div>
<input type="radio" name="2" id="2" value="16" />
<label for="2">16 руб</label>
</div>
<div>
<input type="radio" name="2" id="02" value="16" />
<label for="02">18 руб</label>
</div>
</div>
<div class="price__calc-row ptxtsm">
<p>Среднее бикини (+лобок)</p>
<p>10-20 минут</p>
<div>
<input type="radio" name="3" id="3" value="18" />
<label for="3">18 руб</label>
</div>
<div>
<input type="radio" name="3" id="03" value="18" />
<label for="03">18 руб</label>
</div>
</div>
<div class="price__calc-row ptxtsm">
<p>Глубокое бикини</p>
<p>15-45 минут</p>
<div>
<input type="radio" name="4" id="4" value="22" />
<label for="4">22 руб</label>
</div>
<div>
<input type="radio" name="4" id="04" value="22" />
<label for="04">22 руб</label>
</div>
</div>
<div class="price__calc-row ptxtsm">
<p>Голени с коленом</p>
<p>10-20 минут</p>
<div>
<input type="radio" name="5" id="5" value="17" />
<label for="5">17 руб</label>
</div>
<div>
<input type="radio" name="5" id="05" value="15" />
<label for="05">15 руб</label>
</div>
</div>
<div class="price__calc-blur">
<img src="img/dep/price/blur.png" alt="">
</div>
</div>
<div class="price__calc-total mbtxt flexWrap">
<p>Итоговая стоимость:</p>
<div class="price__calc-total--wraper">
<div class="price__calc-total-descr flexWrap">
<div class="price__calc-total-full flexWrap">
<p>Стандартная стоимость</p>
<p class=" tbig"><s class="price__calc-total--js">35 руб</s></p>
</div>
<div class="price__calc-total-discount flexWrap">
<p>Со скидкой на первую
процедуру - 15%</p>
<p class="tbig roze price__calc-discount--js">28 руб</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
$(".price__calc-row input").each(function () {
let totalSum = 0;
$(this).change(function () {
let total = [];
$(".price__calc-row input:checked").each(function () {
total.push(Number($(this).val()));
});
let index = total.indexOf(Number($(this).val()));
function totalSumFunc() {
for (let i = 0; i < total.length; i++) {
totalSum += total[i];
}
}
totalSumFunc();
$(".price__calc-total--js").html(totalSum + "руб");
let discount = totalSum - (totalSum / 100) * 15;
discount = discount.toFixed(1);
$(".price__calc-discount--js").html(discount + "руб");
totalSum = 0;
});
});
$(document).ready(function () {
$("input:radio:checked").data("check", true);
$("input:radio").click(function () {
$("input[name='" + $(this).attr("name") + "']:radio")
.not(this)
.removeData("check");
$(this).data("check", !$(this).data("check"));
$(this).prop("checked", $(this).data("check"));
});
});
Небольшое пояснение. Я при изменении состояния радио кнопки проверяю чекнутые кнопки и пробрасываю их value в массив, который потом считаю и вывожу пользователю.
Ответы (1 шт):
Я бы вообще не думал в таком ключе: "при анчеке удалялось значение чекнутого инпута"
Если на каждое событие бежать и менять ДОМ, то можно очень бысто запутаться и чего-то не учесть -- обработчиков и элементов много.
Лучше попытаться понять, какое у этого калькулятора минимальное состояние, например объект, с парой ключ-значение на каждую услугу.
Состояние хранить вообще не в ДОМ-е.
Любое действие будет менять состояние, ему должно быть не разрешено менять ДОМ.
А ДОМ (отображение) должен определяться только состоянием.
Должен существовать некий механизм синхронизации, который проверяет, соответствует ли состояние и ДОМ друг-другу, и если нет -- исправляет ДОМ.
Такую синхронизацию можно делать вручную -- просто одна функция, которая проверяет все динамические элементы ДОМ-а по очереди и исправляет их. И запускать ее, например, в конце обработки каждого события.
Но задачу синхронизации гораздо удобней решать используя какую-то Virtual DOM библиотеку, например React.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title> Сферический калькулятор в вакууме </title>
</head>
<body>
<div class="calcContainer"></div>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script>
"use strict"
const e = React.createElement
function Radio({state,setState,stKey,value,label}){
return e("div",{},
e("input",{
type: "radio",
checked: state[stKey]===value,
onChange: ev => setState(st=>({ ...st, [stKey]: value })),
}),
label
)
}
function initState(){ return { width: 1, height: 1 } }
function Calc(){
const [state,setState] = React.useState(initState)
const square = state.width * state.height
const price = square * 7
return e("div",{},[
e("div",{key:"title"}, "Сферический калькулятор в вакууме"),
e("div",{key:"price"}, "Стоимость: "+price+ " EUR"),
e("div",{key:"width"}, "Ширина:",
e(Radio,{ key: 1, state, setState, stKey: "width", value: 1, label: "узкий" }),
e(Radio,{ key: 2, state, setState, stKey: "width", value: 2, label: "широкий" }),
),
e("div",{key:"height"}, "Ширина:",
e(Radio,{ key: 1, state, setState, stKey: "height", value: 1, label: "низкий" }),
e(Radio,{ key: 2, state, setState, stKey: "height", value: 2, label: "высокий" }),
),
e("div",{key:"pic", style: {
width: (state.width * 100)+"px",
height: (state.height * 100)+"px",
backgroundColor: square === 1 ? "red" : square === 2 ? "yellow" : "green",
}}),
])
}
ReactDOM.render(e(Calc), document.querySelector('.calcContainer'))
</script>
</body>
</html>