Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Математика в JS (https://javascript.ru/forum/misc/85214-matematika-v-js.html)

Сергей Ракипов 14.05.2023 03:55

Математика в JS
 
Есть вот такая верстка

<style>

body {
  font-family: monospace;
  font-size: .8rem;
}

main {
  max-width: 720px;
  margin: 0 auto;
}

section{
  max-width: 480px;
  margin: 0px auto 0px;
}
.total_all {
  margin: 40px 0px 40px 0px;
  font-size: 2rem;
}
.summa__1 {
  margin: 40px 0px 0px 0px;
  font-size: 1.2rem;
}
.number_1 {
  padding: 0px 0px 0px 20px;
}
.summa__2 {
  margin: 40px 0px 0px 0px;
  font-size: 1.2rem;
}
.number_2 {
  padding: 0px 0px 0px 20px;
}
.summa__3 {
  margin: 40px 0px 0px 0px;
  font-size: 1.2rem;
}
.number_3 {
  padding: 0px 0px 0px 20px;
}
.summa__4 {
  margin: 40px 0px 0px 0px;
  font-size: 1.2rem;
}
.number_4 {
  padding: 0px 0px 0px 20px;
}
</style>
<body>

<section>

	<div class="total_all">32 000</div>

	<div class="summa__1">
		<label class="container">8 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_1">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_1">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_1">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_1">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>

	<div class="summa__2">
		<label class="container">8 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_2">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_2">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_2">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_2">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>

	<div class="summa__3">
		<label class="container">8 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_3">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_3">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_3">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_3">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>

	<div class="summa__4">
		<label class="container">8 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_4">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_4">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_4">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>
	<div class="number_4">
		<label class="container">2 000
			<input type="checkbox" checked="checked">
			<span class="checkmark"></span>
		</label>
	</div>

</section>

<script>
const num = parseInt(document.querySelector('.total_all').innerHTML.replace(/\s/g, ''));
const summa__1 = parseInt(document.querySelector('.summa__1>.container').innerHTML.replace(/\s/g, ''));
const number_1 = parseInt(document.querySelector('.number_1>.container').innerHTML.replace(/\s/g, ''));
</script>
</body>

Сергей Ракипов 14.05.2023 04:00

То есть у меня цифры из блока должны плюсоваться или минусоваться в зависимости от того в каком состоянии чекбокс, если он выбран то его плюсуют если не выбран то он минусуется

К примеру есть четыре блока по 2 000 в сумме 8 000 если убрать у кого то чекбокс то будет минус 2 000

И есть четыре блока по 8 000 в сумме 32 000 если убрать чекбок у блока где 8 000 то и от 32 000 сминусуется.

рони 14.05.2023 11:12

суммирование выбранного
 
Сергей Ракипов,
если ещё изменить разметку, то код можно будет сократить.

<!DOCTYPE HTML>
<html>
<head>
    <title>Untitled</title>
</head>
<body>
    <style>
        body {
            font-family: monospace;
            font-size: .8rem;
        }
        main {
            max-width: 720px;
            margin: 0 auto;
        }
        section {
            max-width: 480px;
            margin: 0px auto 0px;
        }
        .total_all {
            margin: 40px 0px 40px 0px;
            font-size: 2rem;
        }
        .summa {
            margin: 40px 0px 0px 0px;
            font-size: 1.2rem;
        }
        .number {
            padding: 0px 0px 0px 20px;
        }
        .summa>.container {
            margin-left: 20px;
        }
        .summa>.container input {
            margin-left: 15px;
        }
    </style>
    <body>
        <section>
            <div class="total_all"></div>
            <div class="summa">
                <label class="container">
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
            </div>
            <div class="summa">
                <label class="container">
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
            </div>
            <div class="summa">
                <label class="container">
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
            </div>
            <div class="summa">
                <label class="container">
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
                <div class="number">
                    <label class="container">2 000
            <input type="checkbox" checked="checked">
            <span class="checkmark"></span>
        </label>
                </div>
            </div>
        </section>
        <script>
            const section = document.querySelector('section');
            const total = document.querySelector('.total_all');
            const digits = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ")
            section.addEventListener('change', function() {
                let num = 0;
                for (const div of document.querySelectorAll('.summa')) {
                    const checked = div.querySelector('input:first-child').checked;
                    let n = [...div.querySelectorAll('.number :checked')].reduce((n, {
                        previousSibling
                    }) => n + +previousSibling.data.replace(/\s/g, ''), 0)
                    for (const el of div.querySelector(':first-child').childNodes)
                        if (el.nodeType === 3) el.remove()
                    div.querySelector(':first-child').prepend(digits(n));
                    if (checked) num += n
                }
                total.textContent = digits(num);
            })
            let event = new Event("change");
            section.dispatchEvent(event);
        </script>
    </body>
</body>
</html>

Сергей Ракипов 14.05.2023 22:29

Спасибо! От всего сердце спасибо.

Цитата:

Сообщение от рони
если ещё изменить разметку, то код можно будет сократить.

вот это я не понял как понять изменить разметку?

рони 14.05.2023 23:37

Цитата:

Сообщение от Сергей Ракипов
как понять изменить разметку?

добавить элементы для показа чисел
<span class="num">2000...8000</span>

Сергей Ракипов 14.05.2023 23:47

рони,
А как сделать что бы когда я 8 000 убираю чекбокс что бы и у нижних 2 000 тоже убирались. А то выглядит так что 8 000 убрал а внизу чекбоксы остались

рони 15.05.2023 01:16

Цитата:

Сообщение от Сергей Ракипов
8 000 убираю чекбокс что бы и у нижних 2 000 тоже убирались

<!DOCTYPE HTML>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        body {
            font-family: monospace;
            font-size: .8rem;
        }
        main {
            max-width: 720px;
            margin: 0 auto;
        }
        section {
            max-width: 480px;
            margin: 0px auto 0px;
        }
        .total_all {
            margin: 40px 0px 40px 0px;
            font-size: 2rem;
        }
        .sum label {
            display: block;
            width: 150px;
            text-align: right;
        }
        .sum {
            font-size: 1.2rem;
            display: flex;
            flex-direction: column;
            justify-content: center;
        }
        .all .num {
            color: red;
        }
    </style>
</head>
<body>
    <section>
        <div class="total_all"></div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
    </section>
    <script>
        const section = document.querySelector('section');
        const total = document.querySelector('.total_all');
        const digits = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ")
        section.addEventListener('change', function({
            target
        }) {
            let input = target.closest('input');
            if (input) {
                let all = target.closest('.all input');
                if (all) target.closest('.sum').querySelectorAll('.number input').forEach(input => (input.checked = all.checked))
                else if (target.checked) target.closest('.sum').querySelector('.all input').checked = true;
                else target.closest('.sum').querySelector('.all input').checked = target.closest('.sum').querySelector('.number :checked')
            }
            let num = 0;
            for (const div of document.querySelectorAll('.sum')) {
                const checked = div.querySelector('.all input').checked;
                let n = [...div.querySelectorAll('.number')].reduce((n, label) => {
                        let input = label.querySelector('input');
                        let up = +label.querySelector('.num').textContent.replace(/\s/g, '');
                        return input.checked ? n + up : n
                    }
                    , 0)
                div.querySelector('.all .num').textContent = digits(n);
                if (checked) num += n
            }
            total.textContent = digits(num);
        })
        let event = new Event("change");
        section.dispatchEvent(event);
    </script>
</body>
</html>

Сергей Ракипов 15.05.2023 02:19

рони,
Красота!!!

Сергей Ракипов 15.05.2023 03:22

рони,
А получается что если мне нужно два section на одной странице оно не будет работать, можно как то сделать что если я два section использую на оной странице они работают не зависимо. можно не section а какой то класс то есть если у них общий класс то это и будут границы работы этого скрипта

Сергей Ракипов 15.05.2023 03:38

рони,
То есть я могу сделать это, но код просто в два раза увеличится, так как я просто поменяю название переменных и классов.

рони 15.05.2023 07:40

Цитата:

Сообщение от Сергей Ракипов
если мне нужно два section

хоть десять, добавьте цикл по секциям(классам)
заменить на for в строку 132, и уточнить переменные согласно этому циклу - строка 133 и подобные, и всё.

рони 15.05.2023 08:00

Цитата:

Сообщение от рони
добавьте цикл по секциям(классам)

<!DOCTYPE HTML>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        body {
            font-family: monospace;
            font-size: .8rem;
        }
        main {
            max-width: 720px;
            margin: 0 auto;
        }
        .calculation {
            max-width: 480px;
            margin: 0px auto 0px;
            display: flex;
            flex-direction: column;
        }
        .total_all {
            margin: 10px auto;
            font-size: 2rem;
        }
        .sum label {
            display: block;
            text-align: right;
            margin: 0 auto;
        }
        .sum {
            font-size: 1.2rem;
            display: flex;
            flex-direction: column;
            margin: 5px auto;

        }
        .all .num {
            color: red;
        }
    </style>
</head>
<body>
    <section class="calculation">
        <div class="total_all"></div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
    </section>
        <section class="calculation">
        <div class="total_all"></div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
            <span class="num"></span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
            <label class="number">
            <span class="num">2 000</span>
            <input type="checkbox" checked="checked">
            </label>
        </div>
    </section>
    <script>
        const digits = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
        for(const section of document.querySelectorAll('.calculation'))  {
        const total = section.querySelector('.total_all');

        section.addEventListener('change', function({
            target
        }) {
            let input = target.closest('input');
            if (input) {
                let all = target.closest('.all input');
                if (all) target.closest('.sum').querySelectorAll('.number input').forEach(input => (input.checked = all.checked))
                else if (target.checked) target.closest('.sum').querySelector('.all input').checked = true;
                else target.closest('.sum').querySelector('.all input').checked = target.closest('.sum').querySelector('.number :checked')
            }
            let num = 0;
            for (const div of section.querySelectorAll('.sum')) {
                const checked = div.querySelector('.all input').checked;
                let n = [...div.querySelectorAll('.number')].reduce((n, label) => {
                        let input = label.querySelector('input');
                        let up = +label.querySelector('.num').textContent.replace(/\s/g, '');
                        return input.checked ? n + up : n
                    }
                    , 0)
                div.querySelector('.all .num').textContent = digits(n);
                if (checked) num += n
            }
            total.textContent = digits(num);
        })
        let event = new Event("change");
        section.dispatchEvent(event);}
    </script>
</body>
</html>

Сергей Ракипов 16.05.2023 02:56

рони,
:thanks: спасибо, вы столько раз мне подарили чувства благодарности в течении не одного года, спасибо!!

Сергей Ракипов 16.05.2023 13:43

Не получается у меня сложить конечный результат.

<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        body {
            font-family: monospace;
            font-size: .8rem;
        }

        main {
            max-width: 720px;
            margin: 0 auto;
        }

        .calculation {
            max-width: 480px;
            margin: 0px auto 0px;
            display: flex;
            flex-direction: column;
        }

        .total_all {
            margin: 10px auto;
            font-size: 2rem;
        }

        .sum label {
            display: block;
            text-align: right;
            margin: 0 auto;
        }

        .sum {
            font-size: 1.2rem;
            display: flex;
            flex-direction: column;
            margin: 5px auto;

        }

        .all .num {
            color: red;
        }
        .details{
            font-size: .8;
            color: grey;
        }
    </style>
</head>

<body>
    <section class="calculation">
        <p>С прошлой встречи 10 000</p>
        <p>Приход</p>
        <div class="total_all">

        </div>
        <p>Итого</p>
        <div class="total_minus">
            22 000
        </div>
        <div class="sum">
            <label class="all">
                <span class="num"></span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">2 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">2 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">1 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">1 000</span>
                <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="all">
                <span class="num"></span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">2 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">2 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">1 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">1 000</span>
                <input type="checkbox" checked="checked">
            </label>
        </div>
    </section>
    <section class="calculation">
        <p>Итого 22 000</p>
        <p>Расходы</p>
        <div class="total_all">

        </div>
        <div class="total">

        </div>
        Остаток после расходов
        <div class="total_plus">
        14 000
        </div>
        <div class="sum">
            <label class="all">
                <span class="num"></span>
                <input type="checkbox" checked="checked">
            </label>
            Командировка 
            <label class="number">
                <span class="num">4 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <div class="details">
                Проезд
                <label class="number">
                    <span class="num">2 000</span>
                    <input type="checkbox" checked="checked">
                </label>
                Проживание
                <label class="number">
                    <span class="num">2 000</span>
                    <input type="checkbox" checked="checked">
                </label>
            </div>
   
        </div>
        <div class="sum">
            <label class="all">
                <span class="num"></span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">1 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">1 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">1 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">1 000</span>
                <input type="checkbox" checked="checked">
            </label>
        </div>
    </section>
    <script>
        const digits = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
        for (const section of document.querySelectorAll('.calculation')) {
            const total = section.querySelector('.total_all');

            section.addEventListener('change', function ({

                target

            }) {

                console.log("target", target);
                let input = target.closest('input');
                console.log("input", input);

                if (input) {

                    let all = target.closest('.all input');

                    console.log("all", all);

                    if (all) { 
                        let sum = target.closest('.sum').querySelectorAll('.number input').forEach(input => (input.checked = all.checked)); 
                        console.log("sum1", sum)
                    }

                    else if (target.checked) {
                        let sum = target.closest('.sum').querySelector('.all input').checked = true
                        console.log("sum2", sum)
                    }

                    else {
                        let sum = target.closest('.sum').querySelector('.all input')
                        target.closest('.sum').querySelector('.all input').checked = target.closest('.sum').querySelector('.number :checked')
                        console.log("sum3", sum)
                    }

                }

                let num = 0;
                console.log("section", section);

                for (const div of section.querySelectorAll('.sum')) {

                    const checked = div.querySelector('.all input').checked;
                    let n = [...div.querySelectorAll('.number')].reduce((n, label) => {

                        let input = label.querySelector('input');

                        let up = Number(label.querySelector('.num').textContent.replace(/\s/g, ''));
                        return input.checked ? n + up : n
                        
                    }
                        , 0)
                    div.querySelector('.all .num').textContent = digits(n);
   
                    if (checked) num += n
                }
                total.textContent = digits(num);
            })
            let event = new Event("change");
            section.dispatchEvent(event);
        }
    </script>
</body>

</html>


Вот первый блок section он отображает ПРИХОД и если я нажимаю галочки то и в блоке total_minus происходят изменения то есть убираю 2 000 то в total_minus становится 20 000

А во втором блоке тоже самое только если я убираю расходы то в блоке total_plus происходит измение к примеру я убираю галочку 1 000 то и в total_plus становится 15 000

И еще пункт который расписывает так же галочками более подробно то есть командировочные 4 000 в них входит 2 000 проезд и 2 000 проживание измение на галочках так же меняет все цифры.

Сергей Ракипов 18.05.2023 06:02

Я вроде разорался в коде, и начал делать все правильно. Но ломается, а ошибки нет.
Я заново его написал, с теми задачами которые я поставил. Но он не работает до конца. То есть он не возращает сумму когда поставил галочку. Там конечно нужно дальше код писать, но принцип понятен.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
  body{
    font-size: 1rem;
    font-family: 'Courier New', Courier, monospace;
  }
  .calculation {
    margin: 0px auto 0px;
    max-width: 280px;
  }
  .total {
    margin: 20px 0px 20px 0px;
    font-size: 1.2rem;
  }
  .balance {
    padding: 5px 0px 5px 0px;
  }
  .arrival {
    padding: 5px 0px 5px 0px;
  }
  .total_amount {
    padding: 5px 0px 5px 0px;
  }
  .aumont {
    margin: 20px 0px 20px 0px;
    font-weight: 900;
  }
  .aumont_title {
  }
  .number {
  }
  .sum {
  }
  .checkbox {
  }
  .details_block {
    padding: 10px 0px 0px 20px;
    color: grey;
    font-size: .8rem;
    font-weight: 400;
  }
  .details {
    padding: 5px 0px 5px 0px;
  }
  .description {
  }
  </style>
</head>

<body>
  <div class="calculation">
    <div class="total">
      <div class="balance">
        <div class="balance_title">
          Остаток с прошлого собрания 
        </div>
        <div class="balance_sum">
          10 000
        </div>    
      </div>
      <div class="arrival">
        <div class="arrival_title">
          Приход на текущее собрания
        </div>
        <div class="arrival_sum">
          
        </div>
      </div>
      <div class="total_amount">
        <div class="total_amount_title">
          Общая сумма 
        </div>
        <div class="total_amount_sum">
          22 000
        </div>
      </div>
    </div>

    <div class="aumont summa">
      <div class="aumont_title">
        Предстовитель №1
      </div>
      <label class="all_sum number">
        <span class="sum">
          6 000
        </span>
        <input type="checkbox" checked="checked" class="checkbox">
      </label>
      <div class="details_block">
        <div class="details">
          <label class="number_details">
            <span class="sum_details">3 000</span>
            <input type="checkbox" checked="checked" class="checkbox">
          </label>
          <div class="description">
            Проезд
          </div>
        </div>
        <div class="details">
          <label class="number_details">
            <span class="sum_details">3 000</span>
            <input type="checkbox" checked="checked" class="checkbox">
          </label>
          <div class="description">
            Проживание
          </div>
        </div>
      </div>
    </div>
    <div class="aumont summa">
      <div class="aumont_title">
        Предстовитель №2
      </div>
      <label class="all_sum number">
        <span class="sum">
          4 000
        </span>
        <input type="checkbox" checked="checked" class="checkbox">
      </label>
      <div class="details_block">
        <div class="details">
          <label class="number_details">
            <span class="sum_details">2 000</span>
            <input type="checkbox" checked="checked" class="checkbox">
          </label>
          <div class="description">
            Проезд
          </div>
        </div>
        <div class="details">
          <label class="number_details">
            <span class="sum_details">2 000</span>
            <input type="checkbox" checked="checked" class="checkbox">
          </label>
          <div class="description">
            Проживание
          </div>
        </div>
      </div>
    </div>
    <div class="aumont summa">
      <div class="aumont_title">
        Предстовитель № 3
      </div>
      <label class="all_sum number">
        <span class="sum">
          2 000
        </span>
        <input type="checkbox" checked="checked" class="checkbox">
      </label>
      <div class="details_block">
        <div class="details">
          <label class="number_details">
            <span class="sum_details">1 000</span>
            <input type="checkbox" checked="checked" class="checkbox">
          </label>
          <div class="description">
            Проезд
          </div>
        </div>
        <div class="details">
          <label class="number_details">
            <span class="sum_details">1 000</span>
            <input type="checkbox" checked="checked" class="checkbox">
          </label>
          <div class="description">
            Проживание
          </div>
        </div>
      </div>
    </div>

  </div>

  <script>

  const balanceSum = document.querySelector(".balance_sum");
  // const arrivalSum = document.querySelector(".arrival_sum");
  const totalAmountSum = document.querySelector(".total_amount_sum");
  // const calculation = document.querySelectorAll(".calculation");
  const sum = document.querySelectorAll(".sum");
  const sumDetails = document.querySelectorAll(".sum_details");


  const digits = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");

  for (const calculation of document.querySelectorAll('.calculation')) {

    const arrivalSum = document.querySelector(".arrival_sum");

    calculation.addEventListener('change', function ({
      target
    }) {
      let input = target.closest('input');
      if (input) {
        let all_sum = target.closest('.all_sum input');
        if (all_sum) target.closest('.summa').querySelectorAll('.number input').forEach(input => (input.checked = all_sum.checked))
        else if (target.checked) target.closest('.summa').querySelector('.all_sum input').checked = true;
        else target.closest('.summa').querySelector('.all_sum input').checked = target.closest('.summa').querySelector('.number :checked')
      }
      let sum = 0;
      for (const div of calculation.querySelectorAll('.summa')) {
        const checked = div.querySelector('.all_sum input').checked;
        let n = [...div.querySelectorAll('.number')].reduce((n, label) => {
          let input = label.querySelector('input');
          let up = + label.querySelector('.sum').textContent.replace(/\s/g, '');
          return input.checked ? n + up : n
        }
          , 0)
        div.querySelector('.all_sum .sum').textContent = digits(n);
        if (checked) sum += n
      }
      arrivalSum.textContent = digits(sum);
    })
    let event = new Event("change");
    calculation.dispatchEvent(event);
  }

  </script>
</body>

</html>


Почему сумма не возвращается когда поставил галочку?

Сергей Ракипов 18.05.2023 07:26

Все решил проблему, разбираюсь дальше

рони 18.05.2023 07:54

Сергей Ракипов,
:victory:

Сергей Ракипов 19.05.2023 07:02

Вот я все понимаю как оно работает и знаю из за чего у меня не получается. Но не получается сложить математику.

<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        body {
            font-family: monospace;
            font-size: 1rem;
        }

        main {
            max-width: 720px;
            margin: 0 auto;
        }

        section {
            max-width: 480px;
            margin: 0px auto 0px;
        }

        .total_all {
            margin: 40px 0px 40px 0px;
            font-size: 2rem;
        }

        .sum label {
            display: block;
            width: 150px;
            text-align: right;
        }

        .sum {
            display: flex;
            flex-direction: column;
            justify-content: center;
            padding: 0px 0px 0px 0px;
        }

        .all {
            padding: 10px 0px 10px 0px;
        }

        .all .num {}

        .color {
            color: rebeccapurple;
        }

        .podrobnee {
            padding: 0px 0px 0px 20px;
        }

        .razdel {
            padding: 30px 0px 30px 0px;
        }
    </style>
</head>

<body>
    <section class="section">
        <div class="total_all"></div>
        <div class="sum razdel">
            <label class="all color">
                <span class="num"></span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">4 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="num">4 000</span>
                <input type="checkbox" checked="checked">
            </label>
        </div>

        <div class="sum">

            <label class="all  color">
                <span class="num"></span>
                <input type="checkbox" checked="checked">
            </label>

            <label class="number">
                <span class="num">2 000</span>
                <input type="checkbox" checked="checked">
            </label>

            <div class="sum">
                <label class="all">
                    <span class="num"></span>
                    <input type="checkbox" checked="checked">
                </label>

                <div class="podrobnee">
                    <label class="number">
                        <span class="num">3 000</span>
                        <input type="checkbox" checked="checked">
                    </label>
                    <label class="number">
                        <span class="num">3 000</span>
                        <input type="checkbox" checked="checked">
                    </label>
                </div>
            </div>
        </div>
    </section>
    <script>
        const section = document.querySelector('.section');
        const total = document.querySelector('.total_all');
        const digits = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ")


        section.addEventListener('change', function ({
            target
        }) {
            let input = target.closest('input');
            if (input) {
                let all = target.closest('.all input');
                if (all) target.closest('.sum').querySelectorAll('.number input').forEach(input => (input.checked = all.checked))
                else if (target.checked) target.closest('.sum').querySelector('.all input').checked = true;
                else target.closest('.sum').querySelector('.all input').checked = target.closest('.sum').querySelector('.number :checked')
            }
            let num = 0;
            for (const div of document.querySelectorAll('.sum')) {
                const checked = div.querySelector('.all input').checked;
                let n = [...div.querySelectorAll('.number')].reduce((n, label) => {
                    let input = label.querySelector('input');
                    let up = +label.querySelector('.num').textContent.replace(/\s/g, '');
                    return input.checked ? n + up : n
                }
                    , 0)
                div.querySelector('.all .num').textContent = digits(n);
                if (checked) num += n
            }
            total.textContent = digits(num);
        })
        let event = new Event("change");
        section.dispatchEvent(event);
    </script>
</body>

</html>


То есть у меня all лишний раз складывает.
Итоговая сумма должна быть 16 000 но получается 22 000 из за того что all лишний раз сложился. И я пробую по разному но у меня не получается правильно сложить.

рони 19.05.2023 09:28

Сергей Ракипов,
слишком много зависимостей ... :(

Сергей Ракипов 19.05.2023 10:36

Цитата:

Сообщение от рони (Сообщение 551930)
Сергей Ракипов,
слишком много зависимостей ... :(

то есть для этих целей лучше другой написать, просто это не все задачи которые я ставил.

рони 19.05.2023 11:07

Сергей Ракипов,
да другой код, другой подход. некий объект например, и отображать его "текущее дерево состояний"

Сергей Ракипов 19.05.2023 17:48

Вот такая структура будет нормальная, тут просто структура верстки.

<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        body {
            font-size: 1.2rem;
            font-family: 'Courier New', Courier, monospace;
            font-weight: 900;
        }

        .calculator {
            max-width: 320px;
            margin: 0px auto 0px;
            display: flex;
            flex-direction: column;
        }

        .total_amount {
            max-width: 320px;
            margin: 20px auto 20px;
            color: #F288B4;
        }

        .level_one {
            color: #946FF2;
            padding: 10px 0px 10px 10px;
            margin: 0px 0px 20px 0px;
            border-left: solid 1px #946FF2;
        }

        .sum_all_level_one {
            display: block;
            padding: 0px 0px 2px 0px;
        }

        .num_level_one {}

        .level_two {
            color: #F47B5E;
            display: flex;
            flex-direction: column;
            padding: 0px 0px 0px 10px;
            border-left: solid 1px #F47B5E;
        }

        .num_level_two {}

        .level_three {
            color: #F2C463;
            display: flex;
            flex-direction: column;
            padding: 0px 0px 0px 10px;
            border-left: solid 1px #F2C463;
        }
    </style>
</head>

<body>

    <div class="total_amount">
        16 000
    </div>
    <div class="calculator">

        <div class="level_one">

            <label class="sum_all_level_one">
                <span class="num_level_one">
                    8 000
                </span>
                <input type="checkbox" checked="checked" class="checkbox level__1">
            </label>

            <div class="level_two">

                <label class="number">
                    <span class="num_level_two">
                        4 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

                <label class="number">
                    <span class="num_level_two">
                        4 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

            </div>

        </div>
        <div class="level_one">

            <label class="sum_all_level_one">
                <span class="num_level_one">
                    8 000
                </span>
                <input type="checkbox" checked="checked" class="checkbox level__1">
            </label>

            <div class="level_two">

                <label class="number">
                    <span class="num_level_two">
                        2 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

            </div>

            <div class="level_two">

                <label class="number">
                    <span class="num_level_two sum_all_level_two">
                        6 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

                <div class="level_three">

                    <label class="number">
                        <span class="num_level_two">
                            3 000
                        </span>
                        <input type="checkbox" checked="checked" class="checkbox level__3">
                    </label>

                    <label class="number">
                        <span class="num_level_two">
                            3 000
                        </span>
                        <input type="checkbox" checked="checked" class="checkbox  level__3">
                    </label>

                </div>

            </div>

        </div>
    </div>
    <script>
        const calculator = document.querySelector('.calculator');
        const levelOne = document.querySelector('.level_one');
  
 
        calculator.addEventListener('change', function ({
            target
        }) {
            console.log(target);  
            console.log(target.className);

            if(target.classList.contains("level__1")){

                console.log("Клик level_one");

                let levelOneChildren = target.querySelectorAll(".level_two")
                // let levelOneChildren = levelOne.childNodes
                // let levelOneChildren = levelOne.children
                console.log(levelOneChildren)
            }

        })
    </script>
</body>

</html>

Сергей Ракипов 19.05.2023 17:59

И как при клике на чекбокс вывести имена детей

рони 19.05.2023 21:06

Сергей Ракипов,
let levelOneChildren = target.closest('.level_one').querySelectorAll(".level_two")

Сергей Ракипов 20.05.2023 06:17

рони,
А почему так?

<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        body {   
            background-color: #27405C;      
            font-size: 15px;
            font-family: 'Courier New', Courier, monospace;
            font-weight: bold;
        }
        label{
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .calculator {
            max-width: 110px;
            margin: 0px auto 0px;
            display: flex;
            flex-direction: column;
        }

        .total_amount {
            max-width: 220px;
            margin: 20px auto 20px;
            color: #946FF2;
        }

        .level_one {
            color: #2189FF;
            padding: 10px 0px 10px 10px;
            margin: 0px 0px 10px 0px;
            border-left: solid 1px #2189FF;
        }

        .sum_all_level_one {

            padding: 0px 0px 2px 0px;
        }

        .num_level_one {}

        .level_two {
            color: #1D76DB;
            display: flex;
            flex-direction: column;
            padding: 0px 0px 0px 10px;
            border-left: solid 1px #1D76DB;
        }

        .num_level_two {}

        .level_three {
            color: #619DE1;
            display: flex;
            flex-direction: column;
            padding: 0px 0px 0px 10px;
            border-left: solid 1px #619DE1;
        }
    </style>
</head>

<body>

    <div class="total_amount">
        21 000
    </div>
    <div class="calculator">

        <div class="level_one">

            <label class="sum_all_level_one">
                <span class="num_level_one">
                    8 000
                </span>
                <input type="checkbox" checked="checked" class="checkbox level__1">
            </label>

            <div class="level_two">

                <label class="number">
                    <span class="num_level_two">
                        3 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

                <label class="number">
                    <span class="num_level_two">
                        5 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

            </div>

        </div>
        <div class="level_one">

            <label class="sum_all_level_one">
                <span class="num_level_one">
                    13 000
                </span>
                <input type="checkbox" checked="checked" class="checkbox level__1">
            </label>

            <div class="level_two">

                <label class="number">
                    <span class="num_level_two">
                        4 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

            </div>

            <div class="level_two">

                <label class="number">
                    <span class="num_level_two sum_all_level_two">
                        9 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

                <div class="level_three">

                    <label class="number">
                        <span class="num_level_two">
                            1 500
                        </span>
                        <input type="checkbox" checked="checked" class="checkbox level__3">
                    </label>

                    <label class="number">
                        <span class="num_level_two">
                            7 500
                        </span>
                        <input type="checkbox" checked="checked" class="checkbox  level__3">
                    </label>

                </div>

            </div>

        </div>
    </div>
    <script>

        const calculator = document.querySelector('.calculator');
        const levelOne = document.querySelector('.level_one');
  
 
        calculator.addEventListener('change', function ({
            target
        }) { 
            console.log(target.className);

            if(target.classList.contains("level__1")){

            console.log("Click: level_1");

            let levelOneChildren = target.closest('.level_one').querySelectorAll(".level_two label.number")

            // let levelOneChildren = levelOne.childNodes
            // let levelOneChildren = levelOne.children
            console.log(levelOneChildren);
        }

            if(target.classList.contains("level__2")){

                console.log("Click: level_2");

                let levelTwoChildren = target.closest('.level_two').querySelectorAll(".level_three label.number")

                // let levelOneChildren = levelOne.childNodes
                // let levelOneChildren = levelOne.children
                console.log(levelTwoChildren);
        }
        
        })

    </script>
</body>

</html>


При клике level__1 где 13 000 я получаю 4 детей а по идее мне нужно 2 детей level_two label.number где 4 000 и 9 000 а по итогу получаю 4 детей где 4 000 9 000 1 500 7 500

voraa 20.05.2023 08:43

Потому, что querySelectorAll получает не детей, а всех потомков, которые вложены в элемент.

Сергей Ракипов 20.05.2023 08:46

Цитата:

Сообщение от voraa (Сообщение 551973)
Потому, что querySelectorAll получает не детей, а всех потомков, которые вложены в элемент.

А как детей получить?

рони 20.05.2023 09:28

Сергей Ракипов,
идти по кратчайшему к нужным элементам!
let levelOneChildren = target.closest('.level_one').querySelectorAll(".le vel_two > label.number")

Сергей Ракипов 20.05.2023 09:33

Цитата:

Сообщение от рони (Сообщение 551975)
Сергей Ракипов,
идти по кратчайшему к нужным элементам!
let levelOneChildren = target.closest('.level_one').querySelectorAll(".le vel_two > label.number")

Ну я почти так и сделал

Сергей Ракипов 20.05.2023 09:34

Вот отмечание чек боксов работает так как нужно, но там ошибка и я ее не понимаю

<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        body {   
            background-color: #27405C;      
            font-size: 15px;
            font-family: 'Courier New', Courier, monospace;
            font-weight: bold;
        }
        label{
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .calculator {
            max-width: 110px;
            margin: 0px auto 0px;
            display: flex;
            flex-direction: column;
        }

        .total_amount {
            max-width: 220px;
            margin: 20px auto 20px;
            color: #946FF2;
        }

        .level_one {
            color: #2189FF;
            padding: 10px 0px 10px 10px;
            margin: 0px 0px 10px 0px;
            border-left: solid 1px #2189FF;
        }

        .sum_all_level_one {

            padding: 0px 0px 2px 0px;
        }

        .num_level_one {}

        .level_two {
            color: #1D76DB;
            display: flex;
            flex-direction: column;
            padding: 0px 0px 0px 10px;
            border-left: solid 1px #1D76DB;
        }

        .num_level_two {}

        .level_three {
            color: #619DE1;
            display: flex;
            flex-direction: column;
            padding: 0px 0px 0px 10px;
            border-left: solid 1px #619DE1;
        }
    </style>
</head>

<body>

    <div class="total_amount">
        21 000
    </div>
    <div class="calculator">

        <div class="level_one">

            <label class="all__1 sum_all_level_one">
                <span class="num_level_one">
                    8 000
                </span>
                <input type="checkbox" checked="checked" class="checkbox level__1">
            </label>

            <div class="level_two">

                <label class="number">
                    <span class="num_level_two">
                        3 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

                <label class="number">
                    <span class="num_level_two">
                        5 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

            </div>

        </div>
        <div class="level_one">

            <label class="all__1 sum_all_level_one">
                <span class="num_level_one">
                    13 000
                </span>
                <input type="checkbox" checked="checked" class="checkbox level__1">
            </label>

            <div class="level_two">

                <label class="number">
                    <span class="num_level_two">
                        4 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

            </div>

            <div class="level_two">

                <label class="all__2 number">
                    <span class="num_level_two sum_all_level_two">
                        9 000
                    </span>
                    <input type="checkbox" checked="checked" class="checkbox level__2">
                </label>

                <div class="level_three">

                    <label class="number">
                        <span class="num_level_three">
                            1 500
                        </span>
                        <input type="checkbox" checked="checked" class="checkbox level__3">
                    </label>

                    <label class="number">
                        <span class="num_level_three">
                            7 500
                        </span>
                        <input type="checkbox" checked="checked" class="checkbox  level__3">
                    </label>

                </div>

            </div>

        </div>
    </div>

    <script>
     
        const totalAmount = document.querySelector('.total_amount');
        const calculator = document.querySelector('.calculator');
        const levelOne = document.querySelector('.level_one');
        const levelTwo = document.querySelector('.level_two');
        const levelThree = document.querySelector('.level_three');
  
        calculator.addEventListener('change', function ({
            target
        }) { 

            let input = target.closest('input');

            console.log(input)

            if (input) {

                let all__1 = target.closest('.all__1 input');

                if (all__1) target.closest('.level_one').querySelectorAll('.number input').forEach(input => (input.checked = all__1.checked));

                else if (target.checked) target.closest('.level_one').querySelector('.all__1 input').checked = true;

                else target.closest('.level_one').querySelector('.all__1 input').checked = target.closest('.level_one').querySelectorAll('.number :checked');

            }

            if (input) {

                let all__2 = target.closest('.all__2 input');

                if (all__2) target.closest('.level_two').querySelectorAll('.number input').forEach(input => (input.checked = all__2.checked));

                else if (target.checked) target.closest('.level_two').querySelector('.all__2 input').checked = true;

                else target.closest('.level_two').querySelector('.all__2 input').checked = target.closest('.level_two').querySelectorAll('.number :checked');

            }

            if(target.classList.contains("level__1")){

            console.log("Click: level_1");

            let levelOneChildren = target.closest('.level_one').querySelectorAll(".level_two .num_level_two")

            console.log(levelOneChildren);
        }

            if(target.classList.contains("level__2")){

                console.log("Click: level_2");

                let levelTwoChildren = target.closest('.level_two').querySelectorAll(".level_three .num_level_three")

                console.log(levelTwoChildren);
        }
        
        })

    </script>
</body>

</html>

voraa 20.05.2023 11:15

<!DOCTYPE HTML>
<html>
 
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        body {  
            background-color: #27405C;     
            font-size: 16px;
            font-family: 'Courier New', Courier, monospace;
            font-weight: bold;
        }
        
        .calculator {
            max-width: 200px;
            margin: 0px auto 0px;
        }
        
        label{
            display: flex;
            align-items: center;
            justify-content: space-between;
        }
 
 
        .total_amount {
            font-size: 1.5em;
            margin: 20px auto 20px;
            color: #946FF2;
        }
        
        .sum {
			margin-top: 8px;
		}
        .sum>.number,
        .sum>.sum {
			margin-left: 15px;
        }
        
        
 
    </style>
</head>
 
<body>
 
    <div class="sum calculator">
		<div class="total total_amount">
			<span class="value"></span>
		</div>
    

		<div class="sum">
	 
			<label class="total">
				<span class="value"></span>
				<input type="checkbox" checked="checked">
			</label>
	 	 
			<label class="number">
				<span class="value">3 000</span>
				<input type="checkbox" checked="checked">
			</label>
	 
			<label class="number">
				<span class="value">5 000</span>
				<input type="checkbox" checked="checked">
			</label>
	 
		</div>
		<div class="sum">
	 
			<label class="total">
				<span class="value"></span>
				<input type="checkbox" checked="checked">
			</label>
	 
			<label class="number">
				<span class="value">4 000</span>
				<input type="checkbox" checked="checked">
			</label>
	 
			<div class="sum">
	 
				<label class="total">
					<span class="value"></span>
					<input type="checkbox" checked="checked">
				</label>
	 
				<label class="number">
					<span class="value">1 500</span>
					<input type="checkbox" checked="checked">
				</label>
	 
				<label class="number">
					<span class="value">7 500</span>
					<input type="checkbox" checked="checked">
				</label>
	 
			</div>
	 
		</div>
    </div>
    <script>
   
        const digits = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
    
        const getValue = (elem) => {
			if (elem.classList.contains('number')) {
				return elem.querySelector('input').checked
					? +elem.querySelector('.value').textContent.replace(/\s/g, '')
					: 0

			} else if (elem.classList.contains('sum')) {
				sum(elem);
				const total = elem.querySelector(':scope>.total');
				return total.querySelector('input').checked
					? +total.querySelector('.value').textContent.replace(/\s/g, '')
					: 0
			}
        }
        
		const sum = (elem) => {
			const total = elem.querySelector('.total');
			const sumElems = [...elem.querySelectorAll(':scope>.sum,:scope>.number')];
			const s = sumElems.reduce((a, el) => a + getValue(el), 0);
			total.querySelector('.value').textContent = digits(s);
		}
		
		const setCheckedSum = (elem, checked) => {			
			const total = elem.querySelector('.total');
			const elems = [...elem.querySelectorAll(':scope>.sum,:scope>.number')];
			if (total) {
				total.querySelector('input').checked = checked;
			}
			elems.forEach (el => {
				if (el.classList.contains('number')) {
					el.querySelector('input').checked = checked;
				} else if (el.classList.contains('sum')) {
					setCheckedSum(el, checked);
				}
			})
		}
		
		const testChecked = (elem) => {
			if (elem.classList.contains('number'))
				return elem.querySelector('input').checked;
				
			const total = elem.querySelector('.total');
			const elems = [...elem.querySelectorAll(':scope>.sum,:scope>.number')];
			const checked = elems.reduce ((ch, el) => testChecked(el) || ch, false)
			const input = total.querySelector('input');
			if (input) input.checked = checked;
			return checked;	
		}
		
        const calculator = document.querySelector('.calculator');
        
        sum(calculator);
        
        calculator.addEventListener('change', ev => {
			const {target} = ev;
			const el = target.closest('.total');
			if (el) {
				const sum = el.closest('.sum');
				setCheckedSum(sum, target.checked);
			} else {
				testChecked(calculator);
			}
			sum(calculator);
       })

		
    </script>
</body>
 
</html>

рони 20.05.2023 12:05

voraa,
:victory:

Сергей Ракипов 20.05.2023 12:09

voraa,
я же правильно понял что она работает по принципу
<!-- общая сумма sum > sum > sum -->

Сергей Ракипов 20.05.2023 13:03

Я тут не много дописал код и у меня вопрос

<!DOCTYPE HTML>
<html>

<head>
	<title>Untitled</title>
	<meta charset="utf-8">
	<style>
		body {
			background-color: #27405C;
			font-size: 16px;
			font-family: 'Courier New', Courier, monospace;
			font-weight: bold;
		}
		.history_plus{
			font-size: 1.5em;
			margin: 20px auto 20px;
			color: #946FF2;
		}
		.future_plus{
			font-size: 1.5em;
			margin: 20px auto 20px;
			color: #946FF2;
		}
		.history_minus{
			font-size: 1.5em;
			margin: 20px auto 20px;
			color: #946FF2;
		}
		.future_minus{
			font-size: 1.5em;
			margin: 20px auto 20px;
			color: #946FF2;
		}
		.calculator {
			max-width: 200px;
			margin: 0px auto 0px;
		}

		label {
			display: flex;
			align-items: center;
			justify-content: space-between;
		}


		.total_amount {
			font-size: 1.5em;
			margin: 20px auto 20px;
			color: #946FF2;
		}

		.sum {
			margin-top: 8px;
		}

		.sum>.number,
		.sum>.sum {
			margin-left: 15px;
		}
	</style>
</head>

<body>

	<div class="sum calculator">
		<div class="history_minus">
			38 000
		</div>
		<div class="total total_amount">
			<span class="value"></span><!-- общая сумма sum > sum > sum   -->
		</div>
		<div class="future_minus">
			<!-- 17 000 -->
		</div>

		<div class="sum">

			<label class="total">
				<span class="value"></span><!-- общая сумма  -->
				<input type="checkbox" checked="checked">
			</label>

			<label class="number">
				<span class="value">3 000</span>
				<input type="checkbox" checked="checked">
			</label>

			<label class="number">
				<span class="value">5 000</span>
				<input type="checkbox" checked="checked">
			</label>

		</div>
		<div class="sum">

			<label class="total">
				<span class="value"></span><!-- общая сумма sum > sum   -->
				<input type="checkbox" checked="checked">
			</label>

			<label class="number">
				<span class="value">4 000</span>
				<input type="checkbox" checked="checked">
			</label>

			<div class="sum">

				<label class="total">
					<span class="value"></span><!-- общая сумма sum  -->
					<input type="checkbox" checked="checked">
				</label>

				<label class="number">
					<span class="value">1 500</span>
					<input type="checkbox" checked="checked">
				</label>

				<label class="number">
					<span class="value">7 500</span>
					<input type="checkbox" checked="checked">
				</label>

			</div>

		</div>

	</div>
	<script>

		const historyPlus = document.querySelector(".history_plus");
		const historyMinus = document.querySelector(".history_minus");
		const futurePlus = document.querySelector(".future_plus");
		const futureMinus = document.querySelector(".future_minus");
		const totalAmount = document.querySelector(".total_amount");

		const digits = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");

		const getValue = (elem) => {
			if (elem.classList.contains('number')) {
				return elem.querySelector('input').checked
					? +elem.querySelector('.value').textContent.replace(/\s/g, '')
					: 0

			} else if (elem.classList.contains('sum')) {
				sum(elem);
				const total = elem.querySelector(':scope>.total');
				return total.querySelector('input').checked
					? +total.querySelector('.value').textContent.replace(/\s/g, '')
					: 0
			}
		}

		const sum = (elem) => {
			const total = elem.querySelector('.total');
			const sumElems = [...elem.querySelectorAll(':scope>.sum,:scope>.number')];
			const s = sumElems.reduce((a, el) => a + getValue(el), 0);
			total.querySelector('.value').textContent = digits(s);
		}

		const setCheckedSum = (elem, checked) => {
			const total = elem.querySelector('.total');
			const elems = [...elem.querySelectorAll(':scope>.sum,:scope>.number')];
			if (total) {
				total.querySelector('input').checked = checked;
			}
			elems.forEach(el => {
				if (el.classList.contains('number')) {
					el.querySelector('input').checked = checked;
				} else if (el.classList.contains('sum')) {
					setCheckedSum(el, checked);
				}
			})
		}

		const testChecked = (elem) => {
			if (elem.classList.contains('number'))
				return elem.querySelector('input').checked;

			const total = elem.querySelector('.total');
			const elems = [...elem.querySelectorAll(':scope>.sum,:scope>.number')];
			const checked = elems.reduce((ch, el) => testChecked(el) || ch, false)
			const input = total.querySelector('input');
			if (input) input.checked = checked;
			return checked;
		}

		const calculator = document.querySelector('.calculator');

		sum(calculator);

		calculator.addEventListener('change', ev => {
			const { target } = ev;
			const el = target.closest('.total');
			if (el) {
				const sum = el.closest('.sum');
				setCheckedSum(sum, target.checked);
			} else {
				testChecked(calculator);
			}
			sum(calculator);

			const result = Number(historyMinus.textContent.replace(/\s/g, '')) - Number(totalAmount.textContent.replace(/\s/g, ''));

			futureMinus.textContent = digits(result);

		})


	</script>
</body>

</html>


Не большую часть которая просто минусует суммы.
Как мне сделать так что бы блок futureMinus сразу же отображался при загрузки старинцы, а не ждал пока кликнут на чекбокс

voraa 20.05.2023 13:48

Я не могу что то делать и обдумывать, когда задача ставится по кускам.
Только начинаешь понимать и придумываешь алгоритм, как оказывается надо еще что то, к чему данный алгоритм не очень подходит.
Да и постановку задачи надо излагать четче.
Я так и не понял, что должно быть в futureMinus

Я просто на данном примере показал, как с помощью querySelectorAll искать непосредственно детей (через :scope>)
И то что для данной задачи, где одинаковые блоки информации вложены друг в друга нужна рекурсия.

рони 20.05.2023 13:54

voraa,
есть некая базовое число -- вычисленные суммы должны вычитаться из этого числа.

voraa 20.05.2023 14:00

Цитата:

Сообщение от рони
вычисленные суммы должны вычитаться из этого числа.

суммы или сумма?

рони 20.05.2023 14:04

voraa,
строка 149
<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        body {
            background-color: #27405C;
            font-size: 16px;
            font-family: 'Courier New', Courier, monospace;
            font-weight: bold;
        }

        .history_plus {
            font-size: 1.5em;
            margin: 20px auto 20px;
            color: #946FF2;
        }

        .future_plus {
            font-size: 1.5em;
            margin: 20px auto 20px;
            color: #946FF2;
        }

        .history_minus {
            font-size: 1.5em;
            margin: 20px auto 20px;
            color: #946FF2;
        }

        .future_minus {
            font-size: 1.5em;
            margin: 20px auto 20px;
            color: #946FF2;
        }

        .calculator {
            max-width: 200px;
            margin: 0px auto 0px;
        }

        label {
            display: flex;
            align-items: center;
            justify-content: space-between;
        }


        .total_amount {
            font-size: 1.5em;
            margin: 20px auto 20px;
            color: #946FF2;
        }

        .sum {
            margin-top: 8px;
        }

        .sum>.number,
        .sum>.sum {
            margin-left: 15px;
        }
    </style>
</head>

<body>
    <div class="sum calculator">
        <div class="history_minus">
            38 000
        </div>
        <div class="total total_amount">
            <span class="value"></span>
            <!-- общая сумма sum > sum > sum   -->
        </div>
        <div class="future_minus">
            <!-- 17 000 -->
        </div>
        <div class="sum">
            <label class="total">
                <span class="value"></span><!-- общая сумма  -->
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="value">3 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="value">5 000</span>
                <input type="checkbox" checked="checked">
            </label>
        </div>
        <div class="sum">
            <label class="total">
                <span class="value"></span><!-- общая сумма sum > sum   -->
                <input type="checkbox" checked="checked">
            </label>
            <label class="number">
                <span class="value">4 000</span>
                <input type="checkbox" checked="checked">
            </label>
            <div class="sum">
                <label class="total">
                    <span class="value"></span><!-- общая сумма sum  -->
                    <input type="checkbox" checked="checked">
                </label>
                <label class="number">
                    <span class="value">1 500</span>
                    <input type="checkbox" checked="checked">
                </label>
                <label class="number">
                    <span class="value">7 500</span>
                    <input type="checkbox" checked="checked">
                </label>
            </div>
        </div>
    </div>
    <script>
        const historyPlus = document.querySelector(".history_plus");
        const historyMinus = document.querySelector(".history_minus");
        const futurePlus = document.querySelector(".future_plus");
        const futureMinus = document.querySelector(".future_minus");
        const totalAmount = document.querySelector(".total_amount");
        const numHistoryMinus = Number(historyMinus.textContent.replace(/\s/g, ''));

        const digits = n => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");

        const getValue = (elem) => {
            if (elem.classList.contains('number')) {
                return elem.querySelector('input').checked ?
                    +elem.querySelector('.value').textContent.replace(/\s/g, '') :
                    0

            } else if (elem.classList.contains('sum')) {
                sum(elem);
                const total = elem.querySelector(':scope>.total');
                return total.querySelector('input').checked ?
                    +total.querySelector('.value').textContent.replace(/\s/g, '') :
                    0
            }
        }

        const sum = (elem) => {
            const total = elem.querySelector('.total');
            const sumElems = [...elem.querySelectorAll(':scope>.sum,:scope>.number')];
            const s = sumElems.reduce((a, el) => a + getValue(el), 0);
            total.querySelector('.value').textContent = digits(s);
            futureMinus.textContent = digits(numHistoryMinus - s);
        }

        const setCheckedSum = (elem, checked) => {
            const total = elem.querySelector('.total');
            const elems = [...elem.querySelectorAll(':scope>.sum,:scope>.number')];
            if (total) {
                total.querySelector('input').checked = checked;
            }
            elems.forEach(el => {
                if (el.classList.contains('number')) {
                    el.querySelector('input').checked = checked;
                } else if (el.classList.contains('sum')) {
                    setCheckedSum(el, checked);
                }
            })
        }

        const testChecked = (elem) => {
            if (elem.classList.contains('number'))
                return elem.querySelector('input').checked;

            const total = elem.querySelector('.total');
            const elems = [...elem.querySelectorAll(':scope>.sum,:scope>.number')];
            const checked = elems.reduce((ch, el) => testChecked(el) || ch, false)
            const input = total.querySelector('input');
            if (input) input.checked = checked;
            return checked;
        }

        const calculator = document.querySelector('.calculator');

        sum(calculator);

        calculator.addEventListener('change', ev => {
            const {
                target
            } = ev;
            const el = target.closest('.total');
            if (el) {
                const sum = el.closest('.sum');
                setCheckedSum(sum, target.checked);
            } else {
                testChecked(calculator);
            }
            sum(calculator);
        })
    </script>
</body>

</html>

voraa 20.05.2023 14:06

Ну сделать функцию
const substract = () => {
const result = Number(historyMinus.textContent.replace(/\s/g, '')) - Number(totalAmount.textContent.replace(/\s/g, ''));
 
            futureMinus.textContent = digits(result);
}

И вызывать ее после строк 189 и200

Ну можно и так - впихнуть это в sum.

Сергей Ракипов 20.05.2023 18:06

voraa,
А как пофиксить вот этот



то есть когда 9 000 выбирается то итоговой сумме не видны изменения
Снять все галочки и нажать только на 9 000

https://postimg.cc/9R6HwvWF



почему то через img картинка не вставилась, прямая ссылка на картинку


Часовой пояс GMT +3, время: 14:04.