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

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

Комментарии: 7

  1. Booba
    Booba
    2017-01-18 20:58:23
    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. Александр Мальцев
    Александр Мальцев
    2017-01-19 13:44:45
    Например, элементы 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']) и отправить их на почту.
  • Booba
    Booba
    2017-01-20 22:18:20
    Спасибо. Заработало. Цену(окончательную) отправляет, а вот добиться отправки позиций отмеченных так и не смог, если направите в нужном направлении буду благодарен.
  • Александр Мальцев
    Александр Мальцев
    2017-01-25 11:58:31
    Отправлять лучше наверно не только позиции, но их цену. Наиболее просто это сделать в формате 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;
    
  • Booba
    Booba
    2017-01-18 20:55:47
    <!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
      Booba
      2017-01-18 20:54:03
      Это я сделал, вот тольна примере обратной связи без файлов. Вписал туда список «товаров» — получил итого, но вот как добиться того, чтобы он выводил полученный итог и выбранные пункты пока не смог. Если не трудно помогите доработать.
      1. Александр Мальцев
        Александр Мальцев
        2017-01-16 13:21:12
        Это можно организовать на базе формы обратной связи, которую можно взять со страницы: itchief.ru/lessons/php/pop-up-feedback-form
        Только поля заменить на необходимые элементы. Ну и конечно если нужны расчёты и некоторый результат, то написать небольшой скрипт на JavaScript.