• HTML
  • JavaScript
  • PHP

Как на сайте создать калькулятор услуг?

Здравствуйте! Скажите, а как можно реализовать калькулятор услуг на сайте с капчей и отправкой информации на email? Выбор услуг нужно отмечать просто установкой галочки.

Возможно, уже имеются готовые скрипты?

Ответы: 7

Аноним
Аноним

Код файла style.css:

#chekboxes {
  padding-top: 9px;
}

label {
  display: block;
}

label ˜ label {
  padding-left: 5px;
}

.label {
  vertical-align: top;
  padding: 0, 3px, 0, 0;
}

.checkbox {
  display: none;
}

.checkbox-custom {
  display: inline-block;
  position: relative;
  width: 10px;
  height: 10px;
  border: 2px solid #ccc;
  border-radius: 3px;
}

.label {
  font-family: GOTHAPROREG;
  font-size: 14px;
  color: #333;
  white-space: pre-wrap;
}

.checkbox:checked + .checkbox-custom::before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 2;
  left: 0;
  margin: auto;
  background: url(2832.png) no-repeat !important;
  border-radius: 2px;
  width: 14px;
  height: 24px;
}

.checkbox:disabled + .checkbox-custom {
  display: inline-block;
  position: relative;
  width: 20px;
  height: 20px;
  border: 2px solid #ccc;
  background: gray;
  border-radius: 3px;
}
Аноним
Аноним

Например, элементы checkbox:

<div class="checkbox">
  <label>
    <input type="checkbox" value="200"> Нажми на меня
  </label>
</div>
<div class="checkbox">
  <label>
    <input type="checkbox" value="300"> Нажми на меня
  </label>
</div>
<!-- Элемент, в которой будем выводить результат -->
<p id="result"></p>

Ну и сам скрипт, который будет считать:

<script>
$(function(){
  $('input[type="checkbox"]').click(function(){
    var result = 0;
    $('input[type="checkbox"]:checked').each(function(){
      result += parseInt($(this).val());
    });
    $('#result').text(result);
  });
});
</script>

Также можно дать идентификаторы элементам и используя вышеприведённый код добавить их в массив.

После этого необходимо добавить результат в объект formData (для отправки его на сервер):
formData.append('result', $('#result').text());
После этого можно получить данные на сервере ($_POST['result']) и отправить их на почту.
Аноним
Аноним

Спасибо. Заработало. Цену (окончательную) отправляет. А вот добиться отправки отмеченных позиций так и не смог. Если направите в нужном направлении буду благодарен.

Аноним
Аноним

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

HTML-код:
<div class="checkbox">
  <label>
    <input id="id1" type="checkbox" value="200"> Услуга 1
  </label>
</div>
<div class="checkbox">
  <label>
    <input id="id2" type="checkbox" value="300"> Услуга 2
  </label>
</div>
JavaScript, который необходимо добавить в script.js:
// массив позиций
var positions = [];
// перебираем все установленные позиции
$('input[type="checkbox"]:checked').each(function(){
  // добавляем их в массив
  positions.push({
    'id': $(this).attr('id'),
    'value': $(this).val()
  });
});
Также его необходимо добавить в formData для его отправки на сервер:
formData.append('positions', JSON.stringify(positions));
На сервере получаем позиции и перебираем их:
$positions = json_decode($_POST['positions'],true);
$positionsToMail = '';
foreach($positions as $position) {
  $positionsToMail .= 'id='.$position['id'].' , value='.$position['value'].'<br>';
}
После этого помещаем полученный результат в тело письма.
$output .= $positionsToMail;
Аноним
Аноним

HTML:

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="utf-8">
  <title>Форма обратной связи</title>
  <link href="feedback/css/jquery-ui-1.8.18.custom.css" rel="stylesheet">
  <link href="feedback/css/bootstrap.min.css" rel="stylesheet">
  <link href="style.css" rel="stylesheet">
</head>
<body>
<div class="container">
  <div class="row">
    <div class="col-sm-6 col-sm-offset-3 col-md-9 col-md-offset-0">
      <!-- Контейнер, содержащий форму обратной связи -->
      <div class="panel panel-info">
        <!-- Заголовок контейнера -->
        <div class="panel-heading">
          <h3 class="panel-title text-center">Форма обратной связи</h3>
        </div>
        <!-- Содержимое контейнера -->
        <div class="panel-body">
          <!-- Сообщение, отображаемое в случае успешной отправки данных -->
          <div class="alert alert-success hidden" id="msgSubmit" role="alert">
            <strong>Внимание!</strong> Ваше сообщение отправлено.
          </div>
          <!-- Форма обратной связи -->
          <form enctype="multipart/form-data" id="messageForm">
            <div class="row">
              <div class="col-sm-12" id="error" style="color: #ff0000; margin-top: 5px; margin-bottom: 5px;"></div>
              <!-- Имя и email пользователя -->
              <div class="col-sm-6">
                <!-- Имя пользователя -->
                <div class="form-group has-feedback">
                  <label class="control-label" for="name">Введите ваше имя:</label>
                  <input class="form-control" id="name" maxlength="30" minlength="2" name="name" placeholder="Например, Иван Иванович"
                         required="required" type="text" value="">
                  <span class="glyphicon form-control-feedback"></span>
                </div>
              </div>
              <div class="col-sm-6">
                <!-- Email пользователя -->
                <div class="form-group has-feedback">
                  <label class="control-label" for="email">Введите адрес email:</label>
                  <input class="form-control" id="email" maxlength="30" name="email" placeholder="Например, ivan@mail.ru" required="required"
                         type="email" value="">
                  <span class="glyphicon form-control-feedback"></span>
                </div>
              </div>
            </div>
            <div class="container" id="chekboxes">
              <div class="col-sm-6 col-md-2">
                <label for="cbox1">
                  <input class="checkbox" id="cbox1" type="checkbox" value="0">
                  <span class="checkbox-custom"></span>
                  <span class="label color">cbox1</span>
                </label>
                <label for="cbox11">
                  <input class="checkbox" id="cbox11" type="checkbox" value="5000">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox11</span>
                </label>
                <label for="cbox12">
                  <input class="checkbox" id="cbox12" type="checkbox" value="120000">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox12</span>
                </label>
                <label for="cbox13">
                  <input class="checkbox" id="cbox13" type="checkbox" value="60000">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox13</span>
                </label>
              </div>
              <div class="col-sm-6 col-md-2">
                <label for="cbox2">
                  <input class="checkbox" id="cbox2" type="checkbox" value="0">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox2</span>
                </label>
                <label for="cbox21">
                  <input class="checkbox" id="cbox21" type="checkbox" value="20000">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox21</span>
                </label>
                <label for="cbox22">
                  <input class="checkbox" id="cbox22" type="checkbox" value="35000">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox22</span>
                </label>
                <label for="cbox23">
                  <input class="checkbox" id="cbox23" type="checkbox" value="30000">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox23</span>
                </label>
              </div>
              <div class="col-md-2">
                <label for="cbox3">
                  <input class="checkbox" id="cbox3" type="checkbox" value="0">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox3</span>
                </label>
                <label for="cbox31">
                  <input class="checkbox" id="cbox31" type="checkbox" value="5000">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox31</span>
                </label>
                <label for="cbox32">
                  <input class="checkbox" id="cbox32" type="checkbox" value="15000">
                  <span class="checkbox-custom"></span>
                  <span class="label">cbox32</span>
                </label>
              </div>
              <div class="col-sm-6 col-xs-offset-1 col-md-10">
                <p>Итого от <span id="sum1">0</span>
                  <i aria-hidden="true" class="fa fa-rub"></i></p>
              </div>
            </div>
            <!-- Сообщение пользователя -->
            <hr style="margin-top: 3px; margin-bottom: 3px;">
            <!-- Капча к форме -->
            <!-- Изображение, содержащее код CAPTCHA-->
            <img id="img-captcha" src="/feedback/captcha.php" alt="">
            <!--Элемент, запрашивающий новый код CAPTCHA-->
            <div class="btn btn-default" id="reload-captcha"><i class="glyphicon glyphicon-refresh"></i> Обновить</div>
            <!--Блок для ввода кода CAPTCHA-->
            <div class="form-group has-feedback col-md-7">
              <label class="control-label" for="text-captcha" id="label-captcha">Пожалуйста, введите указанный на изображении
                код:</label>
              <input autocomplete="off" class="form-control" id="text-captcha" maxlength="6" minlength="6" name="captcha"
                     required="required" type="text" value="">
              <span class="glyphicon form-control-feedback"></span>
            </div>
            <!-- Кнопка, отправляющая форму по технологии AJAX -->
            <button class="btn btn-primary pull-right" name="send-message" type="submit">Отправить сообщение</button>
          </form><!-- Конец формы -->
        </div>
      </div><!-- Конец контейнера -->
    </div>
  </div>
</div>

<script src="feedback/js/jquery-1.12.4.min.js"></script>
<script src="feedback/js/bootstrap.min.js"></script>
<script src="feedback/script.js"></script>

</body>
</html>

JavaScript:

"use strict"
var initChekbox = function (id, parent, children, target, expression, disableWhenActive) {
  var o = {
    "el": document.getElementById(id),
    "parent": parent || false,
    "children": [],
    "target": document.getElementById(target),
    "active": false,
    "disable": false,
    "disableWhenActive": disableWhenActive || false,
    "expression": expression || "sum",
    "hasChildren": (children.length > 0) ? true : false,
    "calcRes": function (expression, sum, value) {
      var sum = sum.replace(/\s*/g, '') * 1, // форматируем удаляя лишние пробелы и преобразуем в число
        value = value * 1, result = 0;
      switch (expression) {
        case "sum":
          result = sum + value;
          break;
        case "sub":
          result = sum - value;
          break;
        case "reset":
          result = 0;
          break;
        case "set":
          result = value;
          break;
      }
      result = result.toString().replace(/(\d{1,3}(?=(\d{3})+(?:\.\d|\b)))/g, "\$1 "); // форматирование(отделение тысяч пробелом)
      return result
    },
    "activation": function () {
      if (!this["active"]) {
        this["active"] = true;
        this.el.checked = true
      }
      this.target.textContent = this.calcRes(this.expression, this.target.textContent, this.el.getAttribute("value"));
      if (this.hasChildren) {
        this.children.forEach(function (item) {
          if (!item.active) {
            item.activation()
          }
          
        })
      }
    },
    "deactivation": function () {
      if (this["active"]) {
        this["active"] = false;
        this.el.checked = false
        this.target.textContent = this.calcRes("sub", this.target.textContent, this.el.getAttribute("value"));
      }
      if (this.parent) {
        this.parent["active"] = false;
        this.parent.el.checked = false
      }
      if (this.hasChildren) {
        this.children.forEach(function (item) {
          item.deactivation()
        })
      }
    },
    "disabling": function () {
      if (!this.disable) {
        this.disable = true;
        this.el.disabled = true;
        this.deactivation();
      } else {
        this.disable = false;
        this.el.disabled = false;
      }
    }
  };
  o["children"] = (o.hasChildren) ? children.map(function (item) {
    return initChekbox(item, o, [], o["target"].id)
  }) : false;
  return o
};
// получение свойств объекта
var getPropertyObject = function (o, exclude) {
  var i = [], exclude = exclude | "";
  for (var prop in o) {
    if (o.hasOwnProperty(prop)) {
      i.push(o[prop])
    }
  }
  return i
}
// выбор чекбокса (первый клик)
var activateCheck = function (checkbox) {
  if (cboxes.hasOwnProperty(checkbox)) {
    if (cboxes[checkbox].disableWhenActive) {
      cboxes[checkbox].disableWhenActive.forEach(function (item) {
        if (item != cboxes[checkbox]) {
          item.disabling()
        }
      })
    }
    cboxes[checkbox].activation();
  }
};
// снятие выбора (второй клик)
var deactivateCheck = function (checkbox) {
  if (cboxes.hasOwnProperty(checkbox)) {
    cboxes[checkbox].deactivation();
    if (cboxes[checkbox].disableWhenActive) {
      cboxes[checkbox].disableWhenActive.forEach(function (item) {
        if (item != cboxes[checkbox]) {
          item.disabling()
        }
      })
    }
  }
};
// проверка на выбор
var isCheckActivated = function (checkbox) {
  return (cboxes.hasOwnProperty(checkbox)) ? cboxes[checkbox].active : document.getElementById(checkbox).getAttribute("checked");
};
// инициализация всех чекбоксов
var cboxes = {
  "cbox1": initChekbox("cbox1", undefined, ["cbox11", "cbox12", "cbox13"], "sum1"),
  "cbox2": initChekbox("cbox2", undefined, ["cbox21", "cbox22", "cbox23"], "sum1"),
  "cbox3": initChekbox("cbox3", undefined, ["cbox31", "cbox32"], "sum1"),
};
// добавление дополнительных параметров
// children cbox1
cboxes["cbox11"] = cboxes.cbox1.children[0];
cboxes["cbox12"] = cboxes.cbox1.children[1];
cboxes["cbox13"] = cboxes.cbox1.children[2];
// children cbox2
cboxes["cbox21"] = cboxes.cbox2.children[0];
cboxes["cbox22"] = cboxes.cbox2.children[1];
cboxes["cbox23"] = cboxes.cbox2.children[2];
// children cbox3
cboxes["cbox31"] = cboxes.cbox3.children[0];
cboxes["cbox32"] = cboxes.cbox3.children[1];
// custom event checkbox

// обработчик события для чекбоксов
jQuery("#chekboxes").on('click', 'input', function (e) {
  if (!e.target.disabled) {
    var targetId = e.target.id;
    (!isCheckActivated(targetId)) ? activateCheck(targetId) : deactivateCheck(targetId);
  }
})

//после загрузки веб-страницы
$(function () {
  // при нажатии на кнопку "Обновить", выведем новый код капчи
  $('#reload-captcha').click(function () {
    $('#img-captcha').attr('src', '/feedback/captcha.php?id=' + Math.random() + '');
  });
  // при отправке формы messageForm на сервер (id="messageForm")
  $('#messageForm').submit(function (event) {
    // отменим стандартное действие браузера
    event.preventDefault();
    // заведём переменную, которая будет говорить о том валидная форма или нет
    var formValid = true;
    // переберём все элементы управления формы (input и textarea) 
    $('#messageForm input,#messageForm textarea').each(function () {
      //если этот элемент капча, то не проверять его
      if ($(this).attr('id') == 'text-captcha') {
        return true;
      }
      //найти предков, имеющих класс .form-group (для установления success/error)
      var formGroup = $(this).parents('.form-group');
      //найти glyphicon (иконка успеха или ошибки)
      var glyphicon = formGroup.find('.form-control-feedback');
      //валидация данных с помощью HTML5 функции checkValidity
      if (this.checkValidity()) {
        //добавить к formGroup класс .has-success и удалить .has-error
        formGroup.addClass('has-success').removeClass('has-error');
        //добавить к glyphicon класс .glyphicon-ok и удалить .glyphicon-remove
        glyphicon.addClass('glyphicon-ok').removeClass('glyphicon-remove');
      } else {
        //добавить к formGroup класс .has-error и удалить .has-success
        formGroup.addClass('has-error').removeClass('has-success');
        //добавить к glyphicon класс glyphicon-remove и удалить glyphicon-ok
        glyphicon.addClass('glyphicon-remove').removeClass('glyphicon-ok');
        //если элемент не прошёл проверку, то отметить форму как не валидную 
        formValid = false;
      }
    });

    // Проверяем элемент, содержащий код капчи
    // 1. Получаем значение элемента input, содержащего код капчи
    var captcha = $("#text-captcha").val();
    // 2. Если длина кода капчи, которой ввёл пользователь не равно 6,
    // то сразу отмечаем капчу как невалидную (без отправки на сервер)
    if (captcha.length != 6) {
      // получаем элемент, содержащий капчу
      inputCaptcha = $("#text-captcha");
      // найти предка, имеющего класс .form-group (для установления success/error)
      formGroupCaptcha = inputCaptcha.parents('.form-group');
      // найти glyphicon (иконка успеха или ошибки)
      glyphiconCaptcha = formGroupCaptcha.find('.form-control-feedback');
      // добавить к formGroup класс .has-error и удалить .has-success
      formGroupCaptcha.addClass('has-error').removeClass('has-success');
      // добавить к glyphicon класс glyphicon-remove и удалить glyphicon-ok
      glyphiconCaptcha.addClass('glyphicon-remove').removeClass('glyphicon-ok');
    }

    // форма валидна и длина капчи равно 6 символам, то отправляем форму на сервер (AJAX)
    if ((formValid) && (captcha.length == 6)) {
      // получаем имя, которое ввёл пользователь	
      var name = $("#name").val();
      // получаем email, который ввёл пользователь
      var email = $("#email").val();
      // получаем сообщение, которое ввёл пользователь
      var message = $("#message").val();
      // получаем капчу, которую ввёл пользователь
      var captcha = $("#text-captcha").val();
      // объект, посредством которого будем кодировать форму перед отправкой её на сервер
      var formData = new FormData();
      // добавить в formData значение 'name'=значение_поля_name
      formData.append('name', name);
      // добавить в formData значение 'email'=значение_поля_email
      formData.append('email', email);
      // добавить в formData значение 'message'=значение_поля_message
      formData.append('message', message);
      // добавить в formData значение 'captcha'=значение_поля_captcha
      formData.append('captcha', captcha);
      // технология AJAX 
      $.ajax({
        //метод передачи запроса - POST
        type: "POST", //URL-адрес запроса 
        url: "/feedback/verify.php", //передаваемые данные - formData
        data: formData, // Не устанавливать тип контента, т.к. используется FormData
        contentType: false, // не обрабатывать данные formData
        processData: false, // отключить кэширование результатов в браузере
        cache: false, //при успешном выполнении запроса
        success: function (data) {
          // разбираем строку JSON, полученную от сервера
          var $data = JSON.parse(data);
          // устанавливаем элементу, содержащему текст ошибки, пустую строку
          $('#error').text('');
          // если сервер вернул ответ success, то это значит, что данные отправлены
          if ($data.result == "success") {
            // скрываем форму обратной связи
            $('#messageForm').hide();
            // удаляем у элемента, имеющего id=msgSubmit, класс hidden
            $('#msgSubmit').removeClass('hidden');
          } else if ($data.result == "invalidCaptcha") {
            // Если сервер вернул ответ invalidcaptcha, то делаем следующее...
            //получаем элемент, содержащий капчу
            inputCaptcha = $("#text-captcha");
            //найти предка, имеющего класс .form-group (для установления success/error)
            formGroupCaptcha = inputCaptcha.parents('.form-group');
            //найти glyphicon (иконка успеха или ошибки)
            glyphiconCaptcha = formGroupCaptcha.find('.form-control-feedback');
            //добавить к formGroup класс .has-error и удалить .has-success
            formGroupCaptcha.addClass('has-error').removeClass('has-success');
            //добавить к glyphicon класс glyphicon-remove и удалить glyphicon-ok
            glyphiconCaptcha.addClass('glyphicon-remove').removeClass('glyphicon-ok');
            //вывести новый код капча
            $('#img-captcha').attr('src', '/feedback/captcha.php?id=' + Math.random() + '');
            //установить полю ввода капчи пустое значение
            $("#text-captcha").val('');
          } else {
            // Если сервер вернул ответ error, то делаем следующее...
            $('#error').text('Произошли ошибки при отправке формы на сервер.');
          }
        }, error: function (request) {
          $('#error').text('Произошла ошибка ' + request.responseText + ' при отправке данных.');
        }
      });
    }
  });
});
verify.php не менял пока что.
Аноним
Аноним

Это я сделал, вот только на примере формы обратной связи без файлов. Вписал туда список «товаров» и получил итого.

Но, вот как добиться того, чтобы он выводил полученный итог и выбранные пункты, пока не смог. Если не трудно помогите доработать.
Аноним
Аноним

Это можно организовать на базе формы обратной связи, которую можно взять со страницы: /php/popup-feedback-form.

Только поля заменить на необходимые элементы. Ну и конечно если нужны расчёты и некоторый результат, то написать небольшой скрипт на JavaScript.