Оценок: 2
Простой калькулятор стоимости на jQuery

Простой калькулятор стоимости на jQuery

Здесь напишем небольшой калькулятор, который будет выполнять подсчет стоимости работ, услуг, еще чего-то (подробности ниже).

Есть таблица, в которой список работ и цены к ним, примерно вот такая:

Услуга Кол-во ед. изм. Цена (р)
Написать статью 1000 зн. 50
Вбить гвоздь 5 шт. 100
Подумать 10 мин. 150
Выдернуть гвоздь 1 шт 20

И ее вид в коде:

<table border="1" cellpadding="5" cellspacing="0" width="100%">
<tr>
	<td>Услуга</td>
	<td>Кол-во</td>
	<td>ед. изм.</td>
	<td>Цена (р)</td>
</tr>
<tr>
	<td>Написать статью</td>
	<td>1000</td>
	<td>зн.</td>
	<td>50</td>
</tr>
<tr>
	<td>Вбить гвоздь</td>
	<td>5</td>
	<td>шт.</td>
	<td>100</td>
</tr>
<tr>
	<td>Подумать</td>
	<td>10</td>
	<td>мин.</td>
	<td>150</td>
</tr>
<tr>
	<td>Выдернуть гвоздь</td>
	<td>1</td>
	<td>шт</td>
	<td>20</td>
</tr>
</table>

Здесь есть несколько работ, с разными единицами измерения (что вообще не важно), разным минимальным количеством, ценой.

Что нужно сделать (небольшое ТЗ)

  1. Сделать количество в виде поля, с возможностью ввода произвольного значения
  2. В поле "Количество" должны быть кнопки +/- для изменения значения с заданным интервалом, шагом (для одних работ добавлять +1, для других +5, +20 и т.д.)
  3. Шаг может отличаться от минимального количества. Например: стоимость "Написание статьи" минимально указана за 1000 знаков, а в дальнейшем нужно добавлять +200 знаков за шаг.
  4. Произвольно вводимые значения должны соответствовать указанному шагу. Т.е. при шаге "5" и попытке указать вручную "2", значение должно автоматом меняться на "5".
  5. После таблицы должна быть сумма "Итого"

Что будем делать

  1. Добавить поле input для ввода количества
  2. Добавить в таблицу "Шаг" (этого параметра у нас нет). Можно в виде скрытого поля, видимого значения, или атрибута. Здесь уж как удобнее. Я буду делать атрибутом для поля ввода количества
  3. К input добавить +/-
  4. Добавить классы элементам с данными (в данном случае - ячейки таблицы, но это могут быть и блоки)
  5. Написать небольшой скрипт, чтобы это работало

Реализация. Шаг 1

Для начала добавлю в талицу классы и недостающее поле. Получится так:

<table border="1" cellpadding="5" cellspacing="0" width="100%" class="calc">
<tr>
	<td>Услуга</td>
	<td>Кол-во</td>
	<td>ед. изм.</td>
	<td>Цена (р)</td>
</tr>
<tr class="t-row">
	<td>Написать статью</td>
	<td>
		<div class="inp-group">
		<input type="text" name="write_art" value="0" class="quant form-control" data-step="200" data-price="10" data-min="1000" />
		<span class="plus minpl">+</span>
		<span class="minus minpl">-</span>
		</div>
	</td>
	<td>знаков</td>
	<td class="price">0</td>
</tr>
<tr class="t-row">
	<td>Вбить гвоздь</td>
	<td>
		<div class="inp-group">
		<input type="text" name="gvozd" value="0" class="quant form-control" data-step="5" data-price="20" data-min="5" />
		<span class="plus minpl">+</span>
		<span class="minus minpl">-</span>
		</div>
	</td>
	<td>шт.</td>
	<td class="price">0</td>
</tr>
<tr class="t-row">
	<td>Подумать</td>
	<td>
		<div class="inp-group">
		<input type="text" name="dumat" value="0" class="quant form-control" data-step="1" data-price="15" data-min="10" />
		<span class="plus minpl">+</span>
		<span class="minus minpl">-</span>
		</div>
	</td>
	<td>мин.</td>
	<td class="price">0</td>
</tr>
<tr class="t-row">
	<td>Выдернуть гвоздь</td>
	<td>
		<div class="inp-group">
		<input type="text" name="gvozd_o" value="0" class="quant form-control" data-step="1" data-price="20" data-min="1" />
		<span class="plus minpl">+</span>
		<span class="minus minpl">-</span>
		</div>
	</td>
	<td>шт</td>
	<td class="price">0</td>
</tr>
</table>
<p class="text-center result">Итого:<br /><span class="val">0</span> руб.</p>

Что здесь для чего и почему:

  • Вместо количества появилось поле "quant" с атрибутами data-step (шаг), data-price (цена шага), data-min (минимальное количество)
  • Строкам добавлен класс "t-row" для нахождения родителя в js. Добавил для легкой переделки из таблицы в блоки (можно было обращаться и к тегу "tr")
  • Для всей таблицы добавлен класс "calc". Таких таблиц на странице может быть сколько угодно, используем этот класс, соблюдаем структуру и все будет работать одним скриптом
  • Цена установлена = 0 и добавлен класс "price" - для нахождения блока скриптом

Реализация. Пишем скрипт

Т.к. скрипт будет работать с использованием библиотеки jQuery, ее необходимо подключить, что скорее всего уже и так сделано (идет в комплекте с большинством шаблонов, тем, включена как стандартная у многих CMS).

Будет три функции: две будут менять значение input, в зависимости от способа изменения - по кнопкам, или путем ввода с клавиатуры. Третья будет подсчитывать цену и выводить итого.

/*Обрабатываем нажатия на кнопки + и - */
$('.minpl').click(function() {
/*Находим input*/
	$input = $(this).parent().find('.quant');
	var qty = Number($input.val());
/*На случай, если количество не удалось определить (например, пользователь мог оставить поле пустым)*/
	if (isNaN(qty)) qty = 0;
	if ($(this).hasClass('plus')) {
		if (qty == 0) {
			qty = $input.data('min');
		} else {
			qty += $input.data('step');
		}
	} else {
		qty -= $input.data('step');
	}
    var min = $input.data('min');
    if (qty >= min)  {
        $input.val(qty).trigger('input');
    } else {
 		$input.val(0).trigger('input');
	}
/*Передаем функции подсчета, обновления*/
	updateCalc($input);
});
/*Обрабатываем ввод с клавиатуры */
$('.quant').change(function() {
	var qty = $(this).val();
	if (isNaN(qty)) qty = 0;
	var min = $(this).data('min');
	var step = $(this).data('step');
	if (qty > 0)  {
/*Если вдруг число не кратно шагу, увеличиваем (только увеличение) до кратного*/
		qty = Math.ceil(qty/step)*step;
		if (qty < min) {
			qty = min;
		}
        $(this).val(qty).trigger('input');
    } else {
 		$(this).val(0).trigger('input');
	}
	updateCalc($(this));
});
/*Считаем, обновляем значения*/
function updateCalc($input){
	var qty = Number($input.val());
	if (isNaN(qty)) qty = 0;
	$input.parents('.t-row').find('.price').text(qty * $input.data('price')/$input.data('step'));
	var itog = 0;
	$input.parents('.calc').find('.price').each(function(){
		itog += parseInt($(this).text());
	});
	$input.parents('.calc').next().find('.val').text(itog);
}

Шаг последний. Немного оформим в CSS

.inp-group {position: relative;padding-right: 20px;display: block;}
.inp-group .quant {border: 1px solid #636363;box-sizing:border-box;}
.inp-group .minpl {position: absolute;height: 50%;box-sizing: border-box;right: 0px;display: block;text-align: center;width: 20px;line-height: 18px;background: #3d5354;color: #079de6;cursor: pointer;border: 1px solid #636363;}
.inp-group .minpl:hover {background:#354455;}
.inp-group .plus {top: 0px}
.inp-group .minus {bottom: 0px}

Результат

Для удобства публикую через codepen

See the Pen price-calculator by Vladimir (@webrazrab_ru) on CodePen.

Оценок: 2
Надежный хостинг VPS серверов
  • Свои ISO образы
  • VDS с оплатой раз и навсегда
  • Аренда VDS на любой срок, с оплатой по дням
  • Большое разнообразие конфигураций
  • Дата-центры в ЕС и России
+ скидка 10%

Комментарии (6)

  1. Добрый день! Подскажите пожалуйста, что не так у меня в коде ибо в колонке «Кол-во» стоят нули и символами + и — не изменяются. Почему так происходит?

    Юрий 27 марта 2023, 17:29 0
    • Применяю такое подключение

      Юрий 27 марта 2023, 17:33 0
      • Применяю такое подключение:

        Показать код
        <script defer src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

        Юрий 27 марта 2023, 17:34 0
        • Попробуйте убрать «defer»

          Владимир 27 марта 2023, 20:25 0
      • Подскажите пжлста, а как выбранное количество пользователем на сайте отправить на почту через форму обратной связи, что выбрал, я знаю как сделать, а вот выбранное количество и итоговую сумму в этом калькуляторе, как отправить, чтобы пришло письмо на почту и было написано кол-во: столько то, итоговая сумма: столько то?
        ПРОСТОЙ КАЛЬКУЛЯТОР СТОИМОСТИ НА JQUERY

        Полина 24 ноября 2022, 04:47 0
        • Как вариант, можно поля калькулятора сделать частью формы, т.е. внутри form. Я обычно так и делаю.
          Единственное, сейчас только заметил, нужно задать разные имена полям калькулятора. Сейчас поправлю

          Показать код
          
          <form>
          	<table border="1" cellpadding="5" cellspacing="0" width="100%" class="calc">
          	----
          	</table>
          	<div class="form">
          	----
          	</div>
          </form>
          
          Еще можно в updateCalc делать обход всех заполненных полей (each) и заполнять соответствующие поля в находящейся где то в другом месте форме, но мне кажется это лишнее, тем более что форма обычно где то рядом, или появляется в модальном окне. Оба варианта реализуемы при использовании калькулятора внутри form. Даже шаги сделать не проблема.

          Владимир 24 ноября 2022, 14:23 0