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

Здравствуйте Александр, скажите пожалуйста, а можно ли реализовать калькулятор услуг на сайте, с капчей и отправкой запроса на email. Выбор услуг просто установкой галочки.
Возможно уже такие скрипты и есть, но что то я так и не нашел подходящего.


   Вопросы 0    150 0

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

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

      "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 не менял пока что.
      1. Booba # 0
        Это я сделал, вот тольна примере обратной связи без файлов. Вписал туда список «товаров» — получил итого, но вот как добиться того, чтобы он выводил полученный итог и выбранные пункты пока не смог. Если не трудно помогите доработать.
        1. Александр Мальцев # 0
          Это можно организовать на базе формы обратной связи, которую можно взять со страницы: itchief.ru/lessons/php/pop-up-feedback-form
          Только поля заменить на необходимые элементы. Ну и конечно если нужны расчёты и некоторый результат, то написать небольшой скрипт на JavaScript.

          Вы должны авторизоваться, чтобы оставлять комментарии.