+7(863)285-04-66

info@promtechautomat.ru

г. Ростов-на-Дону. Социалистическая 74

Front-end разработка визуальной части калькулятора стоимости монтажа кабельных лотков

texnicheskoe Рисунок 1 - Вид калькулятора (Front-end)

Интерфейс разработан под стилистику сайта. Были взяты цвета, шрифты и т. д. гармонирующие между собой и стилями сайта. Стили (CSS) и javascript код были написаны в отдельных файлах для более быстрой и правильной загрузки сайта. По этой же причине была подключена библиотека jQuery (javascript библиотека). Используется flex разметка для того, чтобы вёрстка отображалась на всех экранах и устройствах читабельно и красиво.

Для разработки front-end стороны были использованы знания такие как: HTML5.0 (язык гипертекстовой разметки), CSS3 (каскадные таблицы стилей), Javascript (, jQuery. Так как в прошлом калькуляторе уже создали “calculate.css” то используем его стили и классы:

                              .wrapper-calculater .form-calculator,
                                .wrapper-calculater .form-parser {
                                    width: 100%;
                                    padding: 10px;
                                    display: flex;
                                    -webkit-box-flex: flex;
                                    -webkit-box-align: center;
                                    -webkit-box-direction: normal;
                                    align-items: center;
                                    justify-content: center;
                                    flex-flow: row wrap;
                                }
                                .wrapper-calculater {
                                    width: 100%;
                                    margin: 10px 0;
                                    display: flex;
                                    -webkit-box-flex: flex;
                                    -webkit-box-align: start;
                                    -webkit-box-direction: normal;
                                    align-items: flex-start;
                                    justify-content: center;
                                    flex-flow: row wrap;
                                }
                                .wrapper-calculater .form-calculator .promtex-group,
                                .wrapper-calculater .form-parser .promtex-group {
                                    display: flex;
                                    align-items: flex-start;
                                    -webkit-box-flex: flex;
                                    -webkit-box-align: stretch;
                                    -webkit-box-orient: horizontal;
                                    -moz-box-flex: flex;
                                    -moz-box-align: start;
                                    -moz-box-orient: horizontal;
                                    justify-content: space-between;
                                    flex-flow: column wrap;
                                    margin: 5px 0;
                                }
                                .wrapper-calculater .form-calculator .promtex-uzo {
                                    display: none;
                                }
                                .wrapper-calculater .form-calculator .promtex-submit-wrapper,
                                .wrapper-calculater .form-parser .promtex-submit-wrapper {
                                    width: 100%;
                                    display: flex;
                                    align-items: center;
                                    justify-content: center;
                                    margin: 10px auto;
                                }
                                .wrapper-calculater .form-calculator .promtex-group label,
                                .wrapper-calculater .form-parser .promtex-group label {
                                    margin-bottom: 5px;
                                    font-weight: 600;
                                    font-size: 17px;
                                }
                                .select-promtex, .wrapper-calculater .form-calculator .promtex-group input,
                                .wrapper-calculater .form-parser .promtex-group input {
                                    font-size: 16px;
                                    font-weight: 400;
                                    width: 99%;
                                    display: block;
                                    padding: 4px;
                                    border: none;
                                    background-color:bisque;
                                }
                                .wrapper-calculater .form-calculator .promtex-group-radiobtn,
                                .wrapper-calculater .form-parser .promtex-group-radiobtn {
                                    flex-flow: row wrap;
                                    justify-content: flex-start;
                                }
                                .wrapper-calculater .form-calculator .promtex-group-radiobtn label,
                                .wrapper-calculater .form-parser .promtex-group-radiobtn label {
                                    display: inline-block;
                                    width: 100%;
                                }
                                .wrapper-calculater .form-calculator .promtex-group-radiobtn input,
                                .wrapper-calculater .form-parser .promtex-group-radiobtn input {
                                    width: 5%;
                                    margin-right: 4px;
                                    margin-top: 6px;
                                }
                                #width_schits_second {
                                    display: none;
                                }
                                .main_calculate {
                                    width: 100%;
                                    max-width: 1000px;
                                }
                                .calc-promtex-block {
                                    display: flex;
                                    align-items: flex-start;
                                    justify-content: space-between;
                                    flex-flow: row wrap;
                                }
                                .calc-promtex-block a {
                                    display: block;
                                    width: 47%;
                                }
                                .calc-promtex-block p {
                                    width: 50%;
                                    padding-right: 5px;
                                }
                                .promtex-submit-wrapper .parser-run-btn,
                                .calc-promtex-btn {
                                    padding: 10px 15px;
                                    border-radius: 15px;
                                    border: none;
                                    background: linear-gradient(#2165a1 75%, #e4e2 10% , #2165a1 25%);
                                    -webkit-background-clip: border-box;
                                    -moz-background-clip: content-box;
                                    color: #fff;
                                    margin: 10px auto;
                                    cursor: pointer;
                                }
                                .promtex-submit-wrapper .calc-promtex-btn {
                                    margin: 10px;
                                }
                                #vstroikas {
                                    display: none;
                                }
                                .calc-promtex-btn:hover,
                                .promtex-submit-wrapper .parser-run-btn:hover,
                                .calc-promtex-btn::-moz-focus-inner,
                                .calc-promtex-btn::-webkit-inner-spin-button {
                                    background: #919191;
                                    -webkit-animation: normal;
                                    -webkit-backdrop-filter: #919191;
                                }
                                .wrapper .content .main_calculate .entry {
                                    padding-left: 0;
                                    padding: 10px;
                                }
                                .promtex-result-wrapper h4 {
                                    font-size: 22px;
                                    font-weight: 700;
                                    display: block;
                                    width: 100%;
                                    text-align: center;
                                    padding-bottom: 10px;
                                }
                                .promtex-result-wrapper {
                                    width: 100%;
                                    margin: 10px 0;
                                    padding: 10px;
                                    display: block;
                                    background-color: #f3f3f2;
                                    border: 1px solid #2165a1;
                                    border-radius: 5px;
                                }
                                .podpiska {
                                    font-size: 12px;
                                    text-align: right;
                                }
                                .promtex-result,
                                .promtex-result-parser {
                                    width: 100%;
                                    padding: 10px;
                                    margin: -10px;
                                    display: none;
                                    align-items: flex-start;
                                    justify-content: flex-start;
                                    flex-flow: column wrap;
                                }
                                .promtex-result span,
                                .promtex-result-parser span {
                                    text-align: center;
                                    width: 100%;
                                }
                                .slabotok {
                                    display: none;
                                }
                                .promtex-table tr td ul {
                                    list-style: none;
                                    color: inherit;
                                    width: 100%;
                                }
                                .promtex-table tr td ul li {
                                    list-style: none;
                                    width: 100%;
                                }
                                .promtex-table tr td ul li span a {
                                    margin-left: 3px;
                                    text-decoration: none;
                                    color: inherit;
                                    font-weight: 600;
                                    cursor: not-allowed;
                                }
                                .promtex-table tr td ul li span {
                                    width: 100%;
                                    margin: 0 3px;
                                }
                                .modal-message {
                                    display: none;
                                    position: absolute;
                                    top: 45%;
                                    left: 45%;
                                    background-color: #fff;
                                    color: #000;
                                    border-radius: 15px;
                                    padding: 10px;
                                }
                                .invalid {
                                    border: 1px solid #850808;
                                }
                                .valid {
                                    border: 1px solid #0e680533;
                                }
                                .disable {
                                    background: #a11c1c;
                                }
                                .disable:hover {
                                    background: #a11c1c;
                                }
                                
                                .entry .promtex-vacancies-item {
                                    width: 100%;
                                    padding: 10px;
                                    flex-flow: column wrap;
                                }
                                .entry .promtex-vacancies-item p {
                                    padding: 3px;
                                    margin-bottom: 5px;
                                    line-height: 1.25;
                                    width: 100%;
                                }
                                .entry .promtex-vacancies-item .ul-flex {
                                    width: 100%;
                                    margin: 3px auto;
                                    display: flex;
                                    align-items: flex-start;
                                    justify-content: flex-start;
                                    flex-flow: row wrap;
                                }
                                .promtex-vacancies-item a {
                                    display: inline;
                                }
                                #pars-table {
                                    width: 93%;
                                    margin: 0 auto;
                                    word-wrap: break-word;
                                    text-align: center;
                                    font-size: 13px;
                                }
                                #pars-table thead tr th {
                                    padding: 3px;
                                    text-align: center;
                                    border: 1px solid #919191;
                                }
                                .calc-cancel {
                                    background: linear-gradient(#a95e5ebf 75%, #e2bee222 10% , #a95e5ebf 25%);
                                    color: #fff;
                                }
                                
                                .img-responsive {
                                    width: 100%;
                                    display: block;
                                    height: auto;
                                }
                                .wrapper-entry-content {
                                    display: flex;
                                    align-items: flex-start;
                                    justify-content: center;
                                    flex-flow: row wrap;
                                    padding: 10px;
                                    position: relative;
                                }
                                .wrapper-entry-content p {
                                    width: 100%;
                                    line-height: 1.35;
                                    padding: 0;
                                    margin: 0 0 5px;
                                }
                                .wrapper-entry-content a {
                                    text-decoration: none;
                                }
                                .wrapper-entry-content a .img-title {
                                    text-align: center;
                                    padding-top: 0;
                                    text-decoration: none;
                                    color: #000;
                                    margin-bottom: 10px;
                                }
                                .wrapper-entry-content pre {
                                    background-color: #2165a1;
                                    color: #fff;
                                    width: 100%;
                                    height: auto;
                                    max-height: 300px;
                                    overflow: auto;
                                    cursor: text;
                                    margin: 10px 0;
                                }
                                .entry .wrapper-entry-content .view-code {
                                    width: auto;
                                    max-width: 100vh;
                                    height: 500px;
                                    max-height: 100%;
                                    overflow: auto;
                                    overflow-x: scroll;
                                    background: #2165a1;
                                    display: block;
                                    position: absolute;
                                    left: 0;
                                    top: 0;
                                    z-index: 999;
                                }
                                .entry .wrapper-entry-content .code {
                                    width: 100%;
                                    padding: 5px 0;
                                    background-color: #919191;
                                    border: 0.5px solid #2165a1;
                                    margin-bottom: 10px;
                                }
                                .entry .wrapper-entry-content ol {
                                    width: 100%;
                                }
                                .entry .wrapper-entry-content ol li:before {
                                    color: inherit;
                                    font-weight: 600;
                                }
                                .promtex-li-span {
                                    width: 100%;
                                    display: block;
                                    padding: 3px 5px;
                                    line-height: 1.25;
                                }
                                .entry .wrapper-entry-content h3 {
                                    margin-right: auto;
                                    line-height: 1.35;
                                    margin-top: 10px;
                                }
                                .table-container {
                                    min-width: 320px;
                                    max-width: 100%;
                                    padding: 0 15px;
                                    box-sizing: border-box;
                                    padding: 10px;
                                }
                                .table-container table {
                                    border-collapse: collapse;
                                    width: 100%;
                                    margin: 0;
                                    margin-bottom: 10px;
                                }
                                .table-container table td,
                                .table-container table th {
                                    padding: 5px;
                                    border: 1px solid #cbbdbd;
                                }
                                .table-container tr:nth-child(even){
                                    background-color: #2165a1;
                                    color: #fff;
                                }
                                .fade {
                                    display: block;
                                }
                                .hide {
                                    display: none;
                                }
                                .table-container td a {
                                    color: inherit;
                                }
                                .table-container td a:hover {
                                    color: #850808;
                                }
                                @media only screen and (max-width: 720px) {
                                    .table-container table thead {
                                        display: none;
                                    }
                                    .table-container table tr {
                                        display: block;
                                    }
                                    .table-container table td {
                                        display: flex;
                                        justify-content: space-between;
                                        font-size: 14px;
                                    }
                                    .table-container table td::before {
                                        content: attr(data-label);
                                        font-weight: bold;
                                        margin-right: 20px;
                                    }
                                }
                                @media only screen and (min-width: 768px) {
                                    .entry .promtex-vacancies-item .ul-flex li {
                                        width: 45%;
                                    }
                                    .table-container {
                                        width: 100%;
                                    }
                                    .table-container .table-title {
                                        margin-top: 5px;
                                        margin-bottom: 2px;
                                    }
                                    .entry .promtex-vacancies-item .ul-flex >:last-child {
                                        width: 100%;
                                    }
                                    .wrapper-calculater .form-calculator .promtex-group,
                                    .wrapper-calculater .form-parser .promtex-group {
                                        width: 100%;
                                        margin: 5px;
                                    }
                                    .wrapper-calculater .form-calculator,
                                    .wrapper-calculater .form-parser {
                                        width: 45%;
                                        margin: 0 auto;
                                    }
                                    .header nav ul li:hover > ul {
                                        display: block;
                                        width: 300px;
                                    }
                                    .promtex-result-wrapper {
                                        width: 50%;
                                        margin: 10px auto;
                                    }
                                    .wrapper-calculater {
                                        flex-flow: column wrap;
                                    }
                                }                            

После этого согласуем внешний вид формы калькулятора для ввода и выбора данных. Для защиты от ошибок со стороны пользователя или иных угроз. Используем выпадающие списки и числовые поля ввода (input type=”number” ).

Также для защиты делаем проверку данных и производим все расчёты на серверной стороне.

  1. Тип лотка (нужно вначале выбрать тип лотка, чтобы можно было понимать какие лотки брать из базы данных)
  2. Количество углов.
  3. Длина прямых участков (в метрах, цена берётся за 1 м, но в магазинах идёт покупка от 3 метров)
  4. Ширина (берется в мм, от 50 мм до 600 мм)
  5. Высота (мм, от 35 до 100)
  6. Наличие крышки (да или нет).
  7. Покрытие лотка ( берем два покрытия горячеоцинкованное или холодное цинкование).

Теперь посмотрим на визуальность (рисунок 1). Все поля данных идут строго по порядку, чтобы все данные были заполнены поочерёдно.

Проверка всех выбранных и введенных данных. Также неактивность кнопки пока не будут добавлены или выбраны все необходимые для расчета данные. Также если нужно очистить данные есть кнопка для этого, если вы ошиблись или выбор сделан неправильный.

validate-calculator Рисунок 2 - Пример работы валидации формы

Происходит валидация на javascript языке, с помощью и упрощением разработки библиотеки jQuery. Вот код валидации:

                                  $('#height_lotka').on('blur', function () {
                                  if ($(this).find(':selected').index() == 0) {
                                      $(this).removeClass('valid');
                                      $(this).addClass('invalid');
                                      $('.calc-lotki-result').addClass('disable');
                                      $('.calc-lotki-result').prop('disabled',true);
                                  } else {
                                      $(this).removeClass('invalid');
                                      $(this).addClass('valid');
                                  } 
                              });
                              $('#width_lotka').on('blur', function (){
                                  if ($(this).find(':selected').index() == 0) {
                                      $(this).removeClass('valid');
                                      $(this).addClass('invalid');
                                      $('.calc-lotki-result').addClass('disable');
                                      $('.calc-lotki-result').prop('disabled',true);
                                  } else {
                                      $(this).removeClass('invalid');
                                      $(this).addClass('valid');
                                  } 
                              });
                              $('#type_lotok').on('blur', function (){
                                  if ($(this).find(':selected').index() == 0) {
                                      $(this).removeClass('valid');
                                      $(this).addClass('invalid');
                                      $('.calc-lotki-result').addClass('disable');
                                      $('.calc-lotki-result').prop('disabled',true);
                                  } else {
                                      $(this).removeClass('invalid');
                                      $(this).addClass('valid');
                                  } 
                              });
                              $('#type_lotok').on('change', function (){
                                  if ($(this).val() == 1) {
                                      $('#width_lotka').prop('selectedIndex', 0);
                                      $('#height_lotka').prop('selectedIndex', 0);
                                      $('#h-2').removeClass('hide');
                                      $('#h-3').removeClass('hide');
                                      $('#w-1').removeClass('hide');
                                      $('#w-2').removeClass('hide');
                                      $('#w-3').removeClass('hide');
                                      $('#w-4').removeClass('hide');
                                      $('#w-5').removeClass('hide');
                                      $('#w-6').removeClass('hide');
                                      $('#w-7').removeClass('hide');
                                      $('#w-8').removeClass('hide');
                                      $('#w-9').removeClass('hide');
                                      $('#h-5').removeClass('hide');
                                      $('#h-1').removeClass('hide');
                                      $('#h-5').addClass('hide');
                                      $('#h-1').addClass('hide');
                                      // При выборе ширины меньше 100
                                      $('#width_lotka').on('blur', function (){
                                          if ($('#width_lotka').val() == 9) {
                                              $('#h-3').addClass('hide');
                                              $('#h-4').addClass('hide');
                                          } else {
                                              $('#h-3').removeClass('hide');
                                              $('#h-4').removeClass('hide');
                                          }
                                          if ($('#width_lotka').val() == 1) {
                                              $('#h-2').addClass('hide');
                                              $('#h-4').addClass('hide');
                                          } else {
                                              $('#h-2').removeClass('hide');
                                              $('#h-4').removeClass('hide');
                                          }
                                      });
                                  } else if ($(this).val() == 2) {
                                      $('#height_lotka').prop('selectedindex', 0);
                                      $('#width_lotka').prop('selectedIndex', 0);
                                      $('#h-5').removeClass('hide');
                                      $('#h-1').removeClass('hide');
                                      $('#h-5').addClass('hide');
                                      $('#w-9').addClass('hide');
                                      $('#w-1').addClass('hide');
                                  } else if ($(this).val() == 3) {
                                      $('#width_lotka').prop('selectedIndex', 0);
                                      $('#height_lotka').prop('selectedIndex', 0);
                                      $('#h-5').removeClass('hide');
                                      $('#w-9').removeClass('hide');
                                      $('#w-1').removeClass('hide');
                                      $('#h-2').removeClass('hide');
                                      $('#h-3').removeClass('hide');
                                      $('#w-1').removeClass('hide');
                                      $('#w-2').removeClass('hide');
                                      $('#w-3').removeClass('hide');
                                      $('#w-4').removeClass('hide');
                                      $('#w-5').removeClass('hide');
                                      $('#w-6').removeClass('hide');
                                      $('#w-7').removeClass('hide');
                                      $('#w-8').removeClass('hide');
                                      $('#w-9').removeClass('hide');
                                      $('#h-5').removeClass('hide');
                                      $('#h-1').addClass('hide');
                                      $('#w-9').addClass('hide');
                                      $('#w-1').addClass('hide');
                                      $('#w-2').addClass('hide');
                                      $('#w-3').addClass('hide');
                                      $('#w-9').addClass('hide');
                                      $('#h-5').addClass('hide');
                                  } else if ($(this).val() == 4) {
                                      $('#width_lotka').prop('selectedIndex', 0);
                                      $('#height_lotka').prop('selectedIndex', 0);
                                      $('#w-9').removeClass('hide');
                                      $('#w-1').removeClass('hide');
                                      $('#w-2').removeClass('hide');
                                      $('#w-3').removeClass('hide');
                                      $('#h-5').removeClass('hide');
                                      $('#h-1').addClass('hide');
                                      $('#height_lotka').on('blur', function (){
                                          if ($('#height_lotka').val() == 3) {
                                              $('#w-9').addClass('hide');
                                          } else {
                                              $('#w-9').removeClass('hide');
                                          }
                                      });
                                  } else {
                                      $('#height_lotka').find(':selected').index().each(function (){
                                          $(this).fadeIn();
                                          $(this).removeClass('hide');
                                      });
                                      $('#width_lotka').find(':selected').index().each(function (){
                                          $(this).fadeIn();
                                          $(this).removeClass('hide');
                                      });
                                  }
                              });
                          
                              $('#pokryitie_lotka').on('blur', function (){
                                  if ($(this).find(':selected').index() == 0) {
                                      $(this).removeClass('valid');
                                      $(this).addClass('invalid');
                                      $('.calc-lotki-result').addClass('disable');
                                      $('.calc-lotki-result').prop('disabled',true);
                                  } else {
                                      $(this).removeClass('invalid');
                                      $(this).addClass('valid');
                                      $('.calc-lotki-result').removeClass('disable');
                                      $('.calc-lotki-result').prop('disabled',false);
                                  }
                              });                            

После отправки данных на сервер, по полученным данным идет выбор данных о лотке, крышке, углах и их цены, потом используются формулы, приведенные в статье, где описано техническое задание. Вывод результатов осуществляем в таком порядке:

  1. Тип лотка
  2. Длина прямых участков (если выбран 1 или 2 метра , то в расчётах берётся 3)
  3. Стоимость 1-ого угла
  4. Стоимость 1 метра лотка
  5. Сумма стоимости работ
  6. Общая сумма
result-lotki Рисунок 3 - Пример вывода результатов расчетов