Подсчет checkbox в калькуляторе

194
06 февраля 2020, 00:40

Более менее довел калькулятор до ума. Главная трудность с чекбоксами: Нужно значения выделенных чекбоксов прибавлять к общей сумме с условием: если чекбокс снят, то отнимать от суммы значение. Подскажите как это можно сделать?

И вопрос по радиокнопкам: Если уже выбрана радиокнопка, введена площадь и произошел расчет суммы, при переключении на другу радиокнопку возможно ли пересчитывать сумму исходя из значения актуальной?

$(document).ready(function() { 
  $("#calculator_total span").text("0"); 
 
  var totalSum = 0; 
  var lastFloor = 0; 
  var lastRoof = 0; 
  var lastWalls = 0; 
  var lastService = 0; 
  $('.floor').on("change", function() { 
    if ($(this).prop('checked') == true) { 
      $(".input_size_floor").css('display', 'block'); 
    } 
  }); 
  $("#inputFloor").on("change", function() { 
    var inputFloor = parseInt($(this).val()) * parseInt($("input[name='floor']:checked").val()); 
    if ($(this).val() > 0) { 
      $("#inputFloor").each(function() { 
        totalSum = totalSum - lastFloor; 
        totalSum += inputFloor; 
        lastFloor = inputFloor; 
      }); 
    } 
    $("#calculator_total").find('span').text(totalSum); 
  }); 
  $('.roof').on("change", function() { 
    if ($(this).prop('checked') == true) { 
      $(".input_size_roof").css('display', 'block'); 
    } 
  }); 
  $("#inputRoof").on("change", function() { 
    var inputRoof = parseInt($(this).val()) * parseInt($("input[name='roof']:checked").val()); 
    if ($(this).val() > 0) { 
      $("#inputRoof").each(function() { 
        totalSum = totalSum - lastRoof; 
        totalSum += inputRoof; 
        lastRoof = inputRoof; 
      }); 
    } 
    $("#calculator_total").find('span').text(totalSum); 
  }); 
  $("input[name='service']").click(function() { 
    $("input:checked").each(function() { 
      var strServiceType = parseInt($("input[name='service']").val()); 
      totalSum = strServiceType; 
    }); 
    $("#calculator_total").find('span').text(totalSum); 
  }); 
});
.box_calculator { 
  background: url("./images/box_calculator_bg.jpg"); 
  background-position: center center; 
  background-size: cover; 
  padding-bottom: 80px; 
} 
 
.box_calculator h2 { 
  margin: 40px 0; 
  font-weight: bold; 
  font-size: 42px; 
  color: #004487; 
} 
 
.box_calculator .section { 
  width: 100%; 
  background-color: #fff; 
  border: 3px solid #CD1F40; 
  border-radius: 5px; 
} 
 
.box_calculator .section .left_section { 
  padding: 20px; 
} 
 
.box_calculator .section .left_section .head { 
  margin-bottom: 40px; 
} 
 
.box_calculator .section .left_section .head span { 
  display: block; 
  font-size: 36px; 
} 
 
.box_calculator .section .left_section .wrap { 
  display: table; 
  width: 100%; 
} 
 
.box_calculator .section .left_section .wrap h3 { 
  font-weight: bold; 
  font-size: 22px; 
  color: #383838; 
  margin-bottom: 10px; 
} 
 
.box_calculator .section .left_section .wrap h3 i { 
  color: #CD1F40; 
} 
 
.box_calculator .section .left_section .wrap p { 
  font-size: 18px; 
  color: #383838; 
  margin-bottom: 5px; 
  display: table; 
  padding: 5px; 
} 
 
.box_calculator .section .left_section .wrap p.checked { 
  background-color: #f8ffb0; 
  border: 1px solid #e4eb9f; 
  border-radius: 5px; 
} 
 
.box_calculator .section .left_section .wrap div.input_group, 
.box_calculator .section .left_section .wrap div.help { 
  display: table-cell; 
  width: 50%; 
} 
 
.box_calculator .section .left_section .wrap .content input { 
  margin-right: 5px; 
} 
 
.box_calculator .section .left_section .wrap .help { 
  background-color: #fcfcfc; 
  border: 1px solid #d0d0d0; 
  padding: 10px 10px 3px; 
  border-radius: 5px; 
} 
 
.box_calculator .section .left_section .wrap .help a { 
  font-size: 18px; 
  color: #383838; 
  display: inline-block; 
  border-bottom: 1px dotted #4c4c4c; 
  padding-bottom: 2px; 
  margin-bottom: 7px; 
  margin-left: 5px; 
} 
 
.box_calculator .section .left_section .wrap .help a:hover { 
  transition: all 0.3s ease; 
  color: #005db9; 
  border-color: #005db9; 
} 
 
.box_calculator .section .left_section .wrap .input_size_floor, 
.box_calculator .section .left_section .wrap .input_size_roof, 
.box_calculator .section .left_section .wrap .input_size_walls { 
  display: none; 
  margin-top: 10px; 
} 
 
.box_calculator .section .left_section .wrap .input_size_floor p, 
.box_calculator .section .left_section .wrap .input_size_roof p, 
.box_calculator .section .left_section .wrap .input_size_walls p { 
  font-size: 22px; 
  margin-bottom: 10px; 
} 
 
.box_calculator .section .left_section .wrap .input_size_floor td, 
.box_calculator .section .left_section .wrap .input_size_roof td, 
.box_calculator .section .left_section .wrap .input_size_walls td { 
  font-size: 20px; 
} 
 
.box_calculator .section .left_section .wrap .input_size_floor input, 
.box_calculator .section .left_section .wrap .input_size_roof input, 
.box_calculator .section .left_section .wrap .input_size_walls input { 
  border: 1px solid #0053a5; 
  border-radius: 5px; 
  font-size: 20px; 
  background-color: #004487; 
  color: #fff; 
  font-weight: bold; 
  text-align: center; 
  padding: 5px; 
} 
 
.box_calculator .section .left_section ul { 
  margin-bottom: 40px !important; 
} 
 
.box_calculator .section .left_section ul .nav-item { 
  margin-right: 20px; 
} 
 
.box_calculator .section .left_section ul .nav-item a { 
  font-weight: bold; 
  font-size: 22px; 
  padding: 15px; 
  border: 1px solid #004487; 
  background-color: #fafafa; 
  color: #004487; 
} 
 
.box_calculator .section .left_section ul .nav-item a.active { 
  transition: all 0.3s ease; 
  background-color: #004487; 
  color: #fff; 
  -webkit-box-shadow: 0px 0px 5px 1px rgba(0, 68, 135, 0.7); 
  -moz-box-shadow: 0px 0px 5px 1px rgba(0, 68, 135, 0.7); 
  box-shadow: 0px 0px 5px 1px rgba(0, 68, 135, 0.7); 
} 
 
.box_calculator .section .left_section ul .nav-item:last-child { 
  margin: 0; 
} 
 
.box_calculator .section .right_section { 
  display: table; 
  width: 100%; 
  height: 100%; 
  border-left: 2px dashed #004487; 
  background-color: #fff; 
  padding: 25px 20px; 
} 
 
.box_calculator .section .right_section .section_content { 
  display: table-cell; 
} 
 
.box_calculator .section .right_section .section_content #total_head { 
  text-align: center; 
  font-size: 42px; 
  text-transform: uppercase; 
  font-weight: bold; 
  color: #383838; 
  margin-bottom: 10px; 
} 
 
.box_calculator .section .right_section .section_content #calculator_total { 
  text-align: center; 
  font-size: 28px; 
  text-transform: uppercase; 
  color: #383838; 
  margin-bottom: 10px; 
} 
 
.box_calculator .section .right_section .section_content #calculator_total span { 
  font-weight: bold; 
  font-size: 48px; 
  color: #004487; 
} 
 
.box_calculator .section .right_section .section_content #calculator_total i { 
  font-weight: 300; 
  font-size: 28px; 
} 
 
.box_calculator .section .right_section .section_content p { 
  font-size: 18px; 
  margin-top: 20px; 
  text-align: center; 
} 
 
.box_calculator .section .right_section .section_content #calculator_submit { 
  text-align: center; 
} 
 
.box_calculator .section .right_section .section_content #calculator_submit button { 
  background-color: #CD1F40; 
  padding: 10px; 
  color: #fff; 
  font-size: 22px; 
  border: 1px solid #b91f3e; 
  border-radius: 5px; 
  margin-top: 20px; 
  cursor: pointer; 
} 
 
.box_calculator .section .right_section .section_content #calculator_submit button:hover { 
  background-color: #004487; 
  border: 1px solid #004487; 
  color: #fff; 
  transition: all 0.3s ease; 
  -webkit-box-shadow: 0px 0px 5px 1px rgba(0, 68, 135, 0.7); 
  -moz-box-shadow: 0px 0px 5px 1px rgba(0, 68, 135, 0.7); 
  box-shadow: 0px 0px 5px 1px rgba(0, 68, 135, 0.7); 
} 
 
.box_calculator .section .right_section .section_content #calc_phone { 
  border: 1px solid #DADADA; 
  padding: 10px; 
  font-size: 18px; 
  width: 100%; 
  text-align: center; 
  color: #383838; 
} 
 
.box_calculator .section .right_section .section_content #calc_phone:focus { 
  -webkit-box-shadow: 0px 0px 2px 2px rgba(184, 0, 0, 0.8); 
  -moz-box-shadow: 0px 0px 2px 2px rgba(184, 0, 0, 0.8); 
  box-shadow: 0px 0px 2px 2px rgba(184, 0, 0, 0.8); 
} 
 
.box_calculator .section .right_section .section_content #status_message { 
  margin-top: 20px; 
  position: relative; 
} 
 
.box_calculator .section .right_section .section_content #status_message .alert-danger { 
  color: #721c24; 
  background-color: #f8d7da; 
  border-color: #f5c6cb; 
  position: absolute; 
  width: 100%; 
  text-align: center; 
} 
 
.box_calculator .section .right_section .section_content #status_message .alert-success { 
  text-align: center; 
} 
 
.tip { 
  padding: 20px; 
} 
 
.tip .tip_title { 
  margin-bottom: 20px; 
  font-size: 36px; 
  font-weight: bold; 
} 
 
.tip .tip_title i { 
  color: #CD1F40; 
} 
 
.tip .tip_content p { 
  font-size: 22px; 
  line-height: 1.5; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" /> 
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script> 
 
<div id="calculator_form" class="box_calculator"> 
  <div class="container"> 
    <div class="row"> 
      <h2><i class="far fa-ellipsis-v-alt"></i> Калькулятор стоимости ремонта</h2> 
    </div> 
    <div class="section row"> 
      <div class="col-lg-8 p-0"> 
        <div class="left_section"> 
          <div class="head"> 
            <span>Рассчитайте стоимость ремонта</span> 
          </div> 
          <ul class="nav nav-pills mb-3" id="pills-tab" role="tablist"> 
            <li class="nav-item"> 
              <a class="nav-link" id="pills-floor-tab" data-toggle="pill" href="#pills-floor" role="tab" aria-controls="pills-floor" aria-selected="false">Полы</a> 
            </li> 
            <li class="nav-item"> 
              <a class="nav-link" id="pills-roof-tab" data-toggle="pill" href="#pills-roof" role="tab" aria-controls="pills-roof" aria-selected="false">Потолки</a> 
            </li> 
            <li class="nav-item"> 
              <a class="nav-link active show" id="pills-service-tab" data-toggle="pill" href="#pills-service" role="tab" aria-controls="pills-service" aria-selected="true">Электрика и сантехника</a> 
            </li> 
          </ul> 
          <div class="tab-content" id="pills-tabContent"> 
            <div class="tab-pane fade" id="pills-floor" role="tabpanel" aria-labelledby="pills-floor-tab"> 
              <div class="wrap"> 
                <div class="input_group floor content"> 
                  <h3>Выберите тип пола:</h3> 
                  <p class="checked"><input class="floor" type="radio" name="floor" value="1500">Плитка</p> 
                  <p><input class="floor" type="radio" name="floor" value="1500">Ламинат</p> 
                  <p><input class="floor" type="radio" name="floor" value="1500">Паркетная доска</p> 
                  <p><input class="floor" type="radio" name="floor" value="1500">Линолеум</p> 
                  <p><input class="floor" type="radio" name="floor" value="1500">Ковролин</p> 
                  <p><input class="floor" type="radio" name="floor" value="1500">Половая доска</p> 
                  <p><input class="floor" type="radio" name="floor" value="1500">Пробковое покрытие</p> 
                  <p><input class="floor" type="radio" name="floor" value="1500">Теплый пол</p> 
                  <div class="input_size_floor" style="display: block;"> 
                    <p><strong>Площадь пола:</strong></p> 
                    <input size="3" maxlength="3" type="text" id="inputFloor" name="inputFloor" value="0"> кв.м. 
                  </div> 
                </div> 
              </div> 
            </div> 
            <div class="tab-pane fade" id="pills-roof" role="tabpanel" aria-labelledby="pills-roof-tab"> 
              <div class="wrap"> 
                <div class="input_group roof content"> 
                  <h3>Выберите тип потолка:</h3> 
                  <p><input class="roof" type="radio" name="roof" value="350">Натяжной</p> 
                  <p><input class="roof" type="radio" name="roof" value="800">Гипсокартонный</p> 
                  <p><input class="roof" type="radio" name="roof" value="1200">Подвесной</p> 
                  <p><input class="roof" type="radio" name="roof" value="850">Армстронг</p> 
                  <p><input class="roof" type="radio" name="roof" value="920">Реечный</p> 
                  <p><input class="roof" type="radio" name="roof" value="670">Грильято</p> 
                  <p><input class="roof" type="radio" name="roof" value="225">Кассетный</p> 
                  <p><input class="roof" type="radio" name="roof" value="1350">Покраска</p> 
                  <div class="input_size_roof"> 
                    <p><strong>Площадь пола:</strong></p> 
                    <input size="3" maxlength="3" type="text" id="inputRoof" name="inputRoof" value="0"> кв.м. 
                  </div> 
                </div> 
              </div> 
            </div> 
            <div class="tab-pane fade active show" id="pills-service" role="tabpanel" aria-labelledby="pills-service-tab"> 
              <div class="wrap"> 
                <div class="input_group service content"> 
                  <h3>Выберите тип работ:</h3> 
                  <p class="checked"><input class="service" type="checkbox" name="service" value="350">Установка выключателей</p> 
                  <p class="checked"><input class="service" type="checkbox" name="service" value="800">Установка электрического щитка</p> 
                  <p class="checked"><input class="service" type="checkbox" name="service" value="1200">Установка автомата</p> 
                  <p><input class="service" type="checkbox" name="service" value="850">Установка розеток</p> 
                  <p><input class="service" type="checkbox" name="service" value="920">Разводка труб водоснабжения</p> 
                  <p><input class="service" type="checkbox" name="service" value="670">Установка полотенцесушителя</p> 
                  <p><input class="service" type="checkbox" name="service" value="225">Установка унитаза</p> 
                  <p><input class="service" type="checkbox" name="service" value="1350">Установка ванны</p> 
                </div> 
              </div> 
            </div> 
          </div> 
        </div> 
      </div> 
      <div class="col-lg-4 p-0"> 
        <div class="right_section"> 
          <div class="section_content"> 
            <div id="total_head">Итого</div> 
            <div id="calculator_total"><span id="calculator_sum">350</span><i class="far fa-ruble-sign"></i></div> 
            <p>Получите скидку <span class="text_bold rem_red">25%</span> при заказе ремонта под ключ.</p> 
            <p id="val_phone"><input type="checkbox" id="calc_key" name="calc_key" value="Ремонт под ключ"> Ремонт под ключ</p> 
            <p><input type="tel" id="calc_phone" name="calc_phone" placeholder="Введите ваш номер телефона"></p> 
            <div id="calculator_submit"><button class="submit" type="button">Отправить расчет</button></div> 
            <div id="status_message"></div> 
          </div> 
        </div> 
      </div> 
    </div> 
  </div> 
</div>

Answer 1

Обернем чекбоксы в контейнер, делегируем обработчик "onchange" и при каждом изменении суммируем чекнутые. Думаю Вам не составит труда сумму из моего примера прибавлять/отнимать от Вашего результата :)

const $container = $('#js-cks-container') 
const $result = $('#js-result') 
 
$container.on('change', ':checkbox', function () { 
  let sum = 0 
  $container.find(':checkbox:checked').each(function () { 
    sum += Number(this.value) || 0 // если value не корректно 
  }) 
  $result.text(sum) 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
 
<div id="js-cks-container"> 
  <input type="checkbox" value="10"/> 
  <input type="checkbox" value="10"/> 
  <input type="checkbox" value="10"/> 
  <input type="checkbox" value="10"/> 
  <input type="checkbox" value="10"/> 
</div> 
 
<div id="js-result">0</div>

Answer 2

Вот вам общий случай таких перерасчётов (upd: если на странице несколько калькуляторов, то логичнее производить расчёты отталкиваясь от контейнера):

$('.calc').on('click', function () { 
 let $calc = $(this).parent().find('.calc'), // работаем от контейнера 
 sum = 0; 
  $.each($calc, function (idx) { 
    if ($(this).is(":checked")) { 
      sum = sum + parseInt($(this).val()); 
    } 
    $('#sum').text(sum); 
  }); 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
<div id="calc"> 
  <input type="radio" name="radio-value" class="calc" value="10" /> 
  <input type="radio" name="radio-value" class="calc" value="20" /> 
  <input type="radio" name="radio-value" class="calc" value="30" /> 
  <input type="checkbox" name="checkbox-value[]" class="calc" value="10" /> 
  <input type="checkbox" name="checkbox-value[]" class="calc" value="20" /> 
  <input type="checkbox" name="checkbox-value[]" class="calc" value="30" /> 
 
  <span id="sum">0</span> 
</div>

READ ALSO
Пересборка пакета node.js

Пересборка пакета node.js

Всем доброй ночиПодтянул node-modules для Vue

211
Не получается понять замыкание в JS [дубликат]

Не получается понять замыкание в JS [дубликат]

Самые популярный пример с замыканием - это счетчик:

168
Не отображаются лайк-шары в блоке &ldquo;Поделиться&rdquo; у facebook

Не отображаются лайк-шары в блоке “Поделиться” у facebook

Блок обновлен, прошло более 2 дней с момент последнего клика по facebookПример, страницы https://news

179