Показать сообщение отдельно
  #2 (permalink)  
Старый 28.04.2019, 10:20
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

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

А более разумно, это:

1) Иметь наборы из зависимых радио кнопок, а уже картинки, не картинки будут их "оформлением", это дело техники. Это могут быть и костомизированные списки. В общем любой из зависимых наборов позволяющий выбрать одно из значений.

2) Переменные для расчетов могут содержать сами элементы выбора, но если переменные описаны как отдельные данные, то выгоднее иметь не отдельно именованные переменные, а объекты свойства которых, это есть связи между ними и свойствами дома: тип фундамента, перекрытие цоколя и так далее. А каждое такое свойство описывает соответствующий набор, каждое значение которого связано с конкретной кнопкой. И если значения для одно и многоэтажных домов различны для каждого свойства, значит и такие связи этажность => значение должны быть описаны в объекте переменных.

3) Если расчет каждого из свойств дома (тип фундамента, перекрытие цоколя, ...), это однотипная операция умножения площади на выбранное значение в каждом из свойств, и затем суммирование полученного, то весь расчет это обычный обход циклом всех выбранных радио кнопок в группах свойств, получение соответствующего значения выбранной кнопке в группе из объекта переменных, умножение, суммирование.

<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<style>
</style>
<script type="text/javascript">
$(function() {
    var data = {
        base : [0, 3200, 4100, 4800, 5350], //Фундамент
        roof_base : [2100, 4600, 1600] //Перекрытие цоколя     
	};
    
    $('#calc').click(function() {
        var square = this.form.square.value, //выбранная площадь
            total = 0; //сумма
        
        //расчет
        $(':radio:checked', this.form).each(function() {
            //по имени кнопки и ее значению выбираем значение из data
            //умножаем на площадь, отображаем и суммируем
            var set = data[this.name][this.value] * square;
            $(this).closest('.block_stroy').find('p span').text(set);
            total += set;
        });
        
        //итого
        $('#total span').text(total);
    })
});
</script>
</head>
<body>

<form method="post">
    <div class="calc_row">
        <label class="pl_pola">Площадь дома, м2</label>
        <input type="number" step="1" min="0" max="1000" value="100" name="square">
    </div>
                    
    <div class="block_stroy">
        <h2>Фундамент</h2>
        <p class="cena">Стоимость: <span>0</span> руб.</p>
        <label><input type="radio" value="0" name="base" checked="" /> Без фундамента</label>
        <label><input type="radio" value="1" name="base" /> Свайно-ростверковый</label>
        <label><input type="radio" value="2" name="base" /> Блоки ФБС</label>
        <label><input type="radio" value="3" name="base" /> Ленточный железобетонный</label>
        <label><input type="radio" value="4" name="base" /> Плитный</label>
    </div>
                    
    <div class="block_stroy">
        <h2>Перекрытие цоколя</h2>
        <p class="cena">Стоимость: <span>0</span> руб.</p>
        <label><input type="radio" value="0" name="roof_base" checked="" /> Плиты перекрытия (ЖБИ)</label>
        <label><input type="radio" value="1" name="roof_base" /> Монолитное железобетонное</label>
        <label><input type="radio" value="2" name="roof_base" /> Деревянное утепленное</label>
    </div>
    
    <div id="total">
        <p>Итого: <span></span></p>
    </div>
      				
    <p style="text-align: center;">
        <button id="calc" type="button" class="btn-button">Рассчитать стоимость дома</button>
    </p>
</form>

</body>
</html>


Если для одно и многоэтажных домов значения переменных отличны, то их можно описать так в data:

var data = {
        //Фундамент
        base : [
            [0, 3200, 4100, 4800, 5350], //один этаж
            [0, 4200, 5100, 5800, 6350], //два этажа
            ... //и т.д.
        ],
        roof_base ....


Выбор типа здания, это тоже радио кнопки, значение которых будет индексом массива соответствующего набора свойств. В расчете получив все выбранные кнопки $(':radio:checked', this.form), берем значение первой кнопки этого набора определяющего тип дома и сохраняем его как переменную, а обходим в цикле срез этого набора начиная со второй кнопки.

var square = this.form.square.value, //выбранная площадь
    chk = $(':radio:checked', this.form), //набор выбранного
    floors = chk.val(), //тип дома
    total = 0; //сумма
        
    chk.slice(1).each(function() {
        //по имени кнопки и ее значению, и по типу этажа как индексу набора выбираем значение из data
        //умножаем на площадь, отображаем и суммируем
        var set = data[this.name][floors][this.value] * square;
        $(this).closest('.block_stroy').find('p span').text(set);
        total += set;
    });


Если же тип здания это некий коэффициент, то его описывать в data для каждого из свойств своим набором. Но в таком случае вообще лучше отказать от объекта описывающего значения (data) и прописывать их непосредственно в радио кнопках.

Вот с таким подходом писать надо, а то что у вас, это сложности с сопровождением, изменением и т.п., так как такой код труден для восприятия, хотя кажется, что так проще.

Последний раз редактировалось laimas, 28.04.2019 в 10:38.
Ответить с цитированием