Files
ticket_dev/js/common.js
negodiy a3ba651a22 Обновления формы: проверка полиса, автодополнение адресов, улучшения UX
- Перемещена проверка полиса в начало формы (перед телефоном и банком)
- Поля телефона и банка скрыты до успешной проверки полиса
- SMS не отправляется, если полис невалидный
- Добавлено автодополнение адресов через DaData
- Обновлен API ключ DaData
- Изменена метка 'Код документа' на 'Документ, удостоверяющий личность'
- Убраны цифры из отображения типов документов (коды отправляются в n8n)
- Удалены отладочные console.log
- Исправлена логика показа формы после подтверждения SMS
- Улучшена валидация полиса
2025-12-17 13:08:50 +03:00

1372 lines
50 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Функция инициализации автодополнения адресов через DaData
function initAddressSuggestions() {
if (typeof $.fn.suggestions !== 'undefined') {
// Инициализируем автодополнение адресов для поля с классом .js-adres
$('.js-adres').each(function() {
// Проверяем, не инициализировано ли уже
if (!$(this).data('suggestions-initialized')) {
$(this).suggestions({
token: "d2fa8613e186d54c6c62fc321414552353ffdfa8",
type: "ADDRESS",
onSelect: function(suggestion) {
// При выборе адреса заполняем поле
$(this).val(suggestion.value);
}
});
$(this).data('suggestions-initialized', true);
}
});
}
}
$(function() {
$(document).ready(function(){
// Блокируем кнопку "Отправить смс" по умолчанию, пока полис не проверен
$('.js-send-sms').addClass('disabled');
$('.js-send-sms').prop('disabled', true);
// Поля телефона и банка скрыты по умолчанию (через класс d-none в HTML)
$(".js-progress-mask").inputmask("99");
$(".js-inn-mask").inputmask("999999999999");
$(".js-inn-mask2").inputmask("9{10,12}");
$(".js-bank-mask").inputmask({ mask: ["9999 9999 9999 9999", "9999 9999 9999 9999", "9999 9999 9999 9999", "9999 999999 99999"], greedy: false, "placeholder": "*", "clearIncomplete": true });
$(".js-code-mask").inputmask("999999");
$(".js-date-mask").inputmask("99-99-9999",{ "placeholder": "дд-мм-гггг" });
$(".js-doccode-mask").inputmask("99");
$(".js-countrycode-mask").inputmask("999");
// $("#country").countrySelect();
Inputmask.extendDefinitions({
'*': { //masksymbol
"validator": "[0-9\(\)\.\+/ ]"
},
});
$(".js-inndb-mask").inputmask("A9{3,5}-*{6,10}");
$(".js-inndb-mask").keyup(function(){
//if($this)
});
document.querySelector('input').addEventListener('keydown', function (e) {
if (e.which == 9) {
e.preventDefault();
}
});
let month =['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
let days = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];
if($('input[name="birthday"]').length) {
var birthday = datepicker('input[name="birthday"]',
{
customOverlayMonths: month,
customMonths: month,
customDays: days,
maxDate: new Date(),
formatter: (input, date, instance) => {
const value = date.toLocaleDateString()
input.value = value // => '1/1/2099'
},
onSelect: function(dateText, inst) {
let birthday=$('input[name="birthday"]').val();
if(getAge(birthday)<18) {
$("input[data-enableby=birthday]").removeClass('disabled');
$("input[data-disabledby=birthday]").removeClass('disabled');
$("input[data-enableby=birthday]").removeAttr("disabled");
} else {
$("input[data-enableby=birthday]").addClass('disabled');
$("input[data-disabledby=birthday]").addClass('disabled');
$("input[data-enableby=birthday]").attr("disabled","disabled");
}
}
});
}
// Инициализация datepicker для поля даты рейса отправления
if($('input[name="departure_date"]').length) {
var departure_date = datepicker('input[name="departure_date"]',{
customOverlayMonths: month,
customMonths: month,
customDays: days,
maxDate: new Date(),
formatter: (input, date, instance) => {
const value = date.toLocaleDateString()
input.value = value // => '1/1/2099'
}
});
}
// Инициализация datepicker для поля даты наступления страхового случая
if($('input[name="insurence_date"]').length) {
var insurence_date = datepicker('input[name="insurence_date"]',{
customOverlayMonths: month,
customMonths: month,
customDays: days,
maxDate: new Date(),
formatter: (input, date, instance) => {
const value = date.toLocaleDateString()
input.value = value // => '1/1/2099'
}
});
}
var phone = document.querySelectorAll('.js-phone-mask');
$('.js-phone-mask').inputmask('999 999-99-99');
phone.forEach(el => {
const iti = window.intlTelInput(el, {
initialCountry: 'ru',
onlyCountries : ['ru'],
separateDialCode: true,
customContainer: ".form-item",
autoPlaceholder: 'off', // Отключаем автоматический placeholder
allowDropdown: false, // Убираем выпадающий список
utilsScript: "libs/intl-tel-input-master/build/js/utils.js",
});
// Устанавливаем кастомный placeholder без "8", соответствует маске 999 999-99-99
el.setAttribute('placeholder', '912 345-67-89');
});
// Обработчик смены страны отключен, так как выпадающий список убран
// $('.js-phone-mask').on('countrychange', e => {
// let $this = $(e.currentTarget),
// placeholder = $this.attr('placeholder'),
// mask = placeholder.replace(/[0-9]/g, 9);
// $this.val('').inputmask(mask);
// let inputCode = $(".code"),
// flag = document.querySelector(".iti__selected-flag"),
// codeTitle = flag.getAttribute("title");
// inputCode.val(codeTitle);
// });
let index=1;
$('.js-btn-next').on("click",function(e){
e.preventDefault();
// Проверяем, не заблокирована ли кнопка из-за невалидного полиса
if($(this).hasClass('disabled') || $(this).prop('disabled')) {
return false;
}
let isvalid=validate_step(index);
if(isvalid) {
index++;
$('.span-progress .current').text(index);
if(index==3) {
$(this).hide();
$('.btn--submit').show();
} else {
$(this).show();
$('.js-btn-prev').show();
}
$('.form-step').removeClass('active');
$('.form-step[data-step='+index+']').addClass('active');
}
});
$('.js-btn-prev').on("click",function(e){
e.preventDefault();
index--;
if(index==1) {$(this).hide();} else $(this).show();
if(index<1) index=1;
if(index<4) {
$('.btn--submit').hide();
$('.js-btn-next').show();
}
$('.span-progress .current').text(index);
$('.form-step').removeClass('active');
$('.form-step[data-step='+index+']').addClass('active');
});
$('select[name=claim]').on("change",function(e){
if($(this).val()==0) {
$(this).closest('.form-step').find('input[type=text]').addClass('disabled');
$(this).closest('.form-step').find('input[type=file]').addClass('disabled');
$(this).closest('.form-step').find('input[type=file]').parent().addClass('disabled');
} else {
$(this).closest('.form-step').find('input[type=text]').removeClass('disabled');
$(this).closest('.form-step').find('input[type=file]').removeClass('disabled');
$(this).closest('.form-step').find('input[type=file]').parent().removeClass('disabled');
}
});
$('select[name=countryevent]').on("change",function(e){
$('.countryevent').val($(this).find(":selected").text());
});
// Обработка изменения типа события
$('select[name="event_type"]').on('change', function() {
const selectedValue = $(this).val();
// Скрываем все дополнительные поля
$('.connection-fields, .connection-date-fields, .cancel-flight-docs').hide();
// Меняем лейблы в зависимости от выбора
if (selectedValue === 'miss_connection') {
$('#transport_number_label').text('Укажите номер рейса прибытия');
$('#insurence_date_label').text('Дата рейса прибытия');
$('.connection-fields, .connection-date-fields').show();
} else if (selectedValue === 'cancel_flight') {
$('#transport_number_label').text('Номер рейса/поезда/парома');
$('#insurence_date_label').text('Дата наступления страхового случая');
$('.cancel-flight-docs').show();
} else {
$('#transport_number_label').text('Номер рейса/поезда/парома');
$('#insurence_date_label').text('Дата наступления страхового случая');
}
});
function validate_step(step_index){
let inputs=$('.form-step.active').find('input[type="text"], input[type="file"],input[type="email"], textarea.form-input, input[type="checkbox"]');
let all_filled=false;
let res_array=[];
inputs.each(function(e){
let field_fill=false;
if(($(this).val()=='' && !$(this).hasClass('disabled') && !$(this).hasClass('notvalidate') && !$(this).hasClass('error') )) {
$(this).closest('.form-item').find('.form-item__warning').text('Пожалуйста, заполните все обязательные поля');
field_fill=false;
} else {
$(this).closest('.form-item').find('.form-item__warning').text('');
if($(this).attr('type')=='email'){
if(validateEmail($(this).val())) {
field_fill=true;
} else {
field_fill=false;
$(this).closest('.form-item').find('.form-item__warning').text($(this).data('warmes'));
}
} else {
// Специальная валидация для поля банка
if($(this).hasClass('js-bank-autocomplete')) {
var bankId = $(this).closest('.form-item').find('input[name="bank_id"]').val();
if(bankId && bankId !== '') {
field_fill=true;
} else {
field_fill=false;
$(this).closest('.form-item').find('.form-item__warning').text('Пожалуйста, выберите банк из списка');
}
} else {
field_fill=true;
}
}
if($(this).attr('type')=='checkbox'){
if($(this).is(':checked')){
field_fill=true;
$(this).parent().parent().find('.form-item__warning').text();
} else {
field_fill=false;
$(this).parent().parent().find('.form-item__warning').text('Пожалуйста, заполните все обязательные поля');
}
if(($(this).parent().hasClass('js-enable-inputs'))){
field_fill=true;
}
}
}
res_array.push(field_fill);
});
// Проверка валидности полиса теперь выполняется перед отправкой SMS, а не здесь
if((step_index==3) && $('.form-step[data-step='+step_index+']').find('input[type="checkbox"]:checked').length<1) {
$('.form__warning').show();
$('.form__warning').text('Необходимо согласие с политикой обработки персональных данных');
return false;
} else {
$('.form__warning').text('Пожалуйста, заполните все обязательные поля');
}
if(!res_array.includes(false)){
$('.form__warning').hide();
return true;
} else {
$('.form__warning').show();
return false;
}
}
const validateEmail = (email) => {
return email.match(
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
);
};
$('.js-enable-inputs input[type=checkbox]').on("change",function(e){
e.preventDefault();
$(this).closest('.form-item').find('input[type=file]').toggleClass('disabled');
$(this).closest('.form-item').find('input[type=file]+label').toggleClass('disabled');
});
// start sms
function send_sms(){
// ТЕСТОВЫЙ РЕЖИМ - не отправляем реальное SMS
var sended_code = Math.floor(Math.random()*(999999-100000+1)+100000);
// Показываем тестовое модальное окно с кодом
$('#test_sms_code_display').text(sended_code);
$.fancybox.open({
src: '#test_sms_code_modal',
type: 'inline',
afterClose: function() {
// После закрытия тестового окна открываем окно ввода кода
$('.js-code-warning').text('🧪 ТЕСТОВЫЙ РЕЖИМ: Используйте код из предыдущего окна');
$('.js-code-warning').css('color', '#ff6b00');
$.fancybox.open({
src: '#confirm_sms',
type: 'inline'
});
}
});
// Закомментирован реальный запрос к SMS сервису для экономии баланса
/*
var smsFormData = new FormData();
smsFormData.append('smscode',sended_code);
smsFormData.append('phonenumber',$('input[name="phonenumber"]').val());
$.ajax({
url: 'sms-test.php',
method: 'post',
cache: false,
contentType: false,
processData: false,
data: smsFormData,
dataType : 'json',
success: function(data) {
console.log(data);
return false;
},
error: function (jqXHR, exception) {
return false;
}
});
*/
$('.fancybox-close-small').click(function(e) {
$('button[type="submit"]').attr("disabled", false);
$('button[type="submit"]').attr("disabled", false);
$('button[type="submit"]').text("Подать обращение");
});
return sended_code;
}
function countDown(elm, duration, fn){
var countDownDate = new Date().getTime() + (1000 * duration);
var x = setInterval(function() {
var now = new Date().getTime();
var distance = countDownDate - now;
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
elm.innerHTML = minutes + "м " + seconds + "с ";
if (distance < 0) {
clearInterval(x);
fn();
elm.innerHTML = "";
$('.sms-countdown').hide();
}
}, 1000);
}
let sended_code;
$('.js-send-sms').on('click', function(e) {
e.preventDefault();
// Проверка валидности полиса перед отправкой SMS
var indatabase = $('.js-indatabase').val();
if(indatabase == '0' || indatabase == '' || indatabase == undefined) {
$('.form__warning').show();
$('.form__warning').text('Пожалуйста, проверьте полис. Ваш полис не покрывает данный вид обращения.');
return false;
}
// Валидация поля банка перед отправкой SMS
var bankInput = $('.js-bank-autocomplete');
var bankId = $('input[name="bank_id"]').val();
if (!bankInput.val() || !bankId || bankId === '') {
bankInput.closest('.form-item').find('.form-item__warning').text('Пожалуйста, выберите банк из списка');
bankInput.focus();
return false;
} else {
bankInput.closest('.form-item').find('.form-item__warning').text('');
}
// $('.js-send-sms').hide();
sended_code=send_sms();
$('.sms-countdown').show();
$('.modal .js-accept-sms').show();
$('.modal .js-send-sms').hide();
$('.modal .form-item__warning').text("");
countDown(document.querySelector('.sms-countdown .time'), 30, function(){
$('.modal .js-send-sms').show();
$('.sms-checking button.js-accept-sms').hide();
$('.js-code-warning').hide();
})
});
$('.sms-checking .js-accept-sms').on('click', function(e) {
e.preventDefault();
if($('.sms-checking input[type="text"]').val() == sended_code) {
$('.sms-success').removeClass('d-none');
// Проверяем, был ли полис уже проверен
var indatabase = $('.js-indatabase').val();
if(indatabase == '1') {
// Если полис валидный, сразу показываем форму для заполнения
$('.db-success').removeClass('d-none');
$('.form-step[data-step=1]').removeClass('disabled');
// Инициализируем автодополнение адресов после показа формы
setTimeout(function() {
initAddressSuggestions();
}, 500);
}
// Если полис не проверен, форма останется скрытой
$('.modal .js-send-sms').show();
$('.sms-check .form-item > .js-send-sms').hide();
$.fancybox.close();
$.fancybox.close();
$('.sms-check').addClass("disabled");
$('.sms-check .form-item__warning')
.addClass('form-item__warning--success')
.text("Вы успешно подтвердили номер");
} else {
$('.modal .form-item__warning').text("Неверный код");
$('.sms-success').addClass('d-none');
}
});
$('.form.active form').submit(function(e){
if(!validate_step(index)){ e.preventDefault(); } else {
e.preventDefault();
$('button[type="submit"]').attr("disabled", true);
if(1) {
$('.js-code-warning').text('');
$('.js-code-warning').hide();
$('.js-send-sms').hide();
$.fancybox.open({
src: '#confirm_sms',
type: 'inline'
});
$('.loader-wrap').removeClass('d-none');
$('button[type="submit"]').attr("disabled", false);
$('button[type="submit"]').text("Данные отправляются...");
var formData = new FormData();
let fileIndex = 0; // Счетчик для правильной индексации файлов
// Отправляем файлы напрямую как бинарные данные (без предварительной загрузки через fileupload_v2.php)
jQuery.each(jQuery('input[type=file].js-attach').not('.disabled'), function(i, file) {
if(!$(this).hasClass('disabled')) {
// Используем field-type или name для группировки файлов
let field_name=jQuery(this).data('field-type') || jQuery(this).attr('name');
let docname=jQuery(this).data('docname');
// Отправляем файлы напрямую как бинарные данные в submit.php
jQuery.each(jQuery(this)[0].files, function(i, file) {
formData.append(field_name+'-'+i, file);
});
// УБРАНО: старая система загрузки через fileupload_v2.php
// Теперь файлы отправляются напрямую в submit.php как бинарные данные
// n8n будет обрабатывать файлы сам
}
});
jQuery.each(jQuery('.js-append'), function(i, file) {
let ws_name=jQuery(this).data('ws_name');
let ws_type=jQuery(this).data('ws_type');
let val="";
if(jQuery(this).attr('type') == 'checkbox'){
if(jQuery(this).is(':checked')){
val=jQuery(this).val();
}
} else {
val=jQuery(this).val();
}
let array={
ws_name : ws_name,
ws_type: ws_type,
field_val : val
};
formData.append('appends[]',JSON.stringify(array));
});
formData.append('lastname',jQuery('[name="lastname"]').val());
formData.append('getservice',jQuery('[name="getservice"]').val()); //Если есть агент посредник
let sub_dir=jQuery('input[name=sub_dir]').val();
formData.append('sub_dir',sub_dir);
for (var pair of formData.entries()) {
console.log(pair[0]+ ', ' + pair[1]);
}
$.ajax({
url: 'submit.php',
method: 'post',
cache: false,
contentType: false,
processData: false,
data: formData,
dataType: 'json',
success: function(data) {
console.log(data);
$('.loader-wrap').addClass('d-none');
$.fancybox.close();
$.fancybox.open({
src: '#success_modal',
type: 'inline'
});
setTimeout(function(){
$.fancybox.close();
},30)
setTimeout(function(){
window.location.href = "https://lexpriority.ru/ok";
},30)
$('button[type="submit"]').text("Отправить");
},
error: function (jqXHR, exception) {
console.log(jqXHR);
if (jqXHR.status === 0) {
alert('Not connect. Verify Network.');
} else if (jqXHR.status == 404) {
alert('Requested page not found (404).');
} else if (jqXHR.status == 500) {
alert('Internal Server Error (500).');
} else if (exception === 'parsererror') {
} else if (exception === 'timeout') {
alert('Time out error.');
} else if (exception === 'abort') {
alert('Ajax request aborted.');
} else {
alert('Uncaught Error. ' + jqXHR.responseText);
}
}
});
return false;
} else {
$('.js-code-warning').text('Неверный код');
return false;
}
}
});
});
$('input[name=place],input[name=place_adres],input[name=place_inn]').keyup(function(e){
var sourceInput = $(this);
var query = $(this).val();
var settings = {
"url": "https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/party",
"method": "POST",
"timeout": 0,
"headers": {
"Authorization": "Token d2fa8613e186d54c6c62fc321414552353ffdfa8",
"Content-Type": "application/json",
"Cookie": "__ddg1_=BoLd7l5yOCjL9tr6qUth"
},
"data": JSON.stringify({
"query": query
}),
};
$('.autocomplete__item').remove();
var address_array = [];
$.ajax(settings).done(function (response) {
for(let i=0; i<response.suggestions.length; i++) {
$('<div class="autocomplete__item" data-address="'+response.suggestions[i].data.address.value+'" data-inn="'+response.suggestions[i].data.inn+'">'+response.suggestions[i].value+'</div>').appendTo(sourceInput.closest('.form-item').find('.form-item__dropdown'));
}
});
});
$(document).on('click', '.autocomplete__item', function() {
let currentAutocompleteItem=$(this);
let prefix = $(this).closest('.autocomplete').data('groupename');
$('.'+prefix+'_name').val(currentAutocompleteItem.text());
$('.'+prefix+'_adres').val(currentAutocompleteItem.attr('data-address'));
$('.'+prefix+'_inn').val(currentAutocompleteItem.attr('data-inn'));
currentAutocompleteItem.closest('.form-item').find('.form-item__dropdown').empty();
});
// Автоподстановка банков из API
let banksList = []; // Кэш списка банков
let banksLoading = false; // Флаг загрузки
// Загрузка списка банков через прокси на сервере (обход CORS)
function loadBanksList() {
if (banksLoading) return; // Предотвращаем множественные запросы
banksLoading = true;
$.ajax({
url: 'load_banks.php', // PHP скрипт на сервере для обхода CORS
method: 'GET',
dataType: 'json',
timeout: 15000, // 15 секунд таймаут
success: function(data) {
banksLoading = false;
if (Array.isArray(data)) {
banksList = data;
console.log('Загружено банков:', banksList.length);
// Убираем предупреждение об ошибке, если оно было
$('.js-bank-autocomplete').closest('.form-item').find('.form-item__warning').text('');
} else if (data && data.error) {
console.error('Ошибка от сервера:', data.error);
showBanksLoadError('Ошибка сервера: ' + data.error);
} else {
console.error('Неверный формат данных:', data);
showBanksLoadError('Неверный формат данных от сервера');
}
},
error: function(jqXHR, exception) {
banksLoading = false;
console.error('Ошибка загрузки списка банков:', exception, jqXHR);
var errorMsg = 'Не удалось загрузить список банков';
if (jqXHR.status === 0) {
errorMsg += ' (нет соединения)';
} else if (jqXHR.status === 404) {
errorMsg += ' (файл прокси не найден)';
} else if (jqXHR.status === 500) {
errorMsg += ' (ошибка сервера)';
} else if (exception === 'timeout') {
errorMsg += ' (превышено время ожидания)';
}
showBanksLoadError(errorMsg);
}
});
}
// Показать ошибку загрузки банков
function showBanksLoadError(message) {
var bankInput = $('.js-bank-autocomplete');
if (bankInput.length) {
var warningText = message || 'Не удалось загрузить список банков. Пожалуйста, обновите страницу или введите название банка вручную.';
bankInput.closest('.form-item').find('.form-item__warning')
.text(warningText)
.css('color', '#dc3545');
}
}
// Загружаем банки при загрузке страницы
$(document).ready(function() {
// Небольшая задержка, чтобы убедиться, что DOM готов
setTimeout(function() {
loadBanksList();
}, 100);
});
// Популярные банки (показываются первыми)
var popularBanks = ['Сбербанк', 'ВТБ', 'Альфа-Банк', 'Тинькофф', 'Райффайзен Банк', 'Газпромбанк', 'Россельхозбанк', 'ПСБ', 'МКБ', 'ЮМани'];
// Функция для сортировки банков (популярные вверху)
function sortBanks(banks) {
return banks.sort(function(a, b) {
var aIndex = popularBanks.findIndex(function(name) {
return a.bankName.indexOf(name) !== -1;
});
var bIndex = popularBanks.findIndex(function(name) {
return b.bankName.indexOf(name) !== -1;
});
if (aIndex === -1 && bIndex === -1) return 0;
if (aIndex === -1) return 1;
if (bIndex === -1) return -1;
return aIndex - bIndex;
});
}
// Автоподстановка банков
$('.js-bank-autocomplete').on('input keyup', function(e) {
var sourceInput = $(this);
var query = $(this).val().toLowerCase().trim();
var dropdown = sourceInput.closest('.form-item').find('.form-item__dropdown');
// Очищаем предыдущие результаты
dropdown.empty();
// Если запрос пустой, показываем больше банков (30) с популярными вверху
if (query.length === 0) {
var sortedBanks = sortBanks(banksList.slice());
showBanksDropdown(sortedBanks.slice(0, 30), dropdown, sourceInput, banksList.length, true);
return;
}
// Фильтруем банки по запросу
var filteredBanks = banksList.filter(function(bank) {
return bank.bankName.toLowerCase().indexOf(query) !== -1;
});
// Показываем результаты (максимум 50 при поиске)
showBanksDropdown(filteredBanks.slice(0, 50), dropdown, sourceInput, filteredBanks.length, false);
});
// Функция для отображения выпадающего списка банков
function showBanksDropdown(banks, dropdown, sourceInput, totalCount, showHint) {
dropdown.empty();
if (banks.length === 0) {
dropdown.append('<div class="autocomplete__item" style="padding: 10px; color: #999;">Банки не найдены</div>');
return;
}
banks.forEach(function(bank) {
var item = $('<div class="autocomplete__item" data-bank-id="' + bank.bankId + '" data-bank-name="' + bank.bankName + '" style="cursor: pointer;">' + bank.bankName + '</div>');
dropdown.append(item);
});
// Добавляем подсказку внизу списка
if (showHint && totalCount > banks.length) {
var hint = $('<div class="autocomplete__hint" style="padding: 12px 15px; background: #f8f9fa; border-top: 1px solid #e9ecef; font-size: 12px; color: #6c757d; text-align: center; border-radius: 0 0 4px 4px;">' +
'<strong>Показано ' + banks.length + ' из ' + totalCount + ' банков</strong><br>' +
'Начните вводить название банка для поиска по всем ' + totalCount + ' банкам'
+ '</div>');
dropdown.append(hint);
} else if (!showHint && totalCount > banks.length) {
var hint = $('<div class="autocomplete__hint" style="padding: 10px 15px; background: #f8f9fa; border-top: 1px solid #e9ecef; font-size: 12px; color: #6c757d; text-align: center;">' +
'Найдено: ' + totalCount + ' банков. Показано ' + banks.length + '. Уточните запрос для более точного поиска.'
+ '</div>');
dropdown.append(hint);
}
}
// Обработчик выбора банка - используем mousedown для надежности
$(document).on('mousedown', '.form-item__dropdown .autocomplete__item', function(e) {
e.preventDefault();
e.stopPropagation();
var selectedItem = $(this);
var bankId = selectedItem.attr('data-bank-id');
var bankName = selectedItem.attr('data-bank-name');
var formItem = selectedItem.closest('.form-item');
// Проверяем, что это не подсказка
if (selectedItem.hasClass('autocomplete__hint')) {
return false;
}
// Заполняем поля
var bankInput = formItem.find('.js-bank-autocomplete');
var bankIdInput = formItem.find('input[name="bank_id"]');
bankInput.val(bankName);
bankIdInput.val(bankId);
// Очищаем выпадающий список
formItem.find('.form-item__dropdown').empty();
// Убираем предупреждение
formItem.find('.form-item__warning').text('');
// Убираем фокус с input
bankInput.blur();
console.log('Банк выбран:', bankName, 'ID:', bankId);
return false;
});
// Дублируем обработчик на click для совместимости
$(document).on('click', '.form-item__dropdown .autocomplete__item', function(e) {
e.preventDefault();
e.stopPropagation();
var selectedItem = $(this);
// Проверяем, что это не подсказка
if (selectedItem.hasClass('autocomplete__hint')) {
return false;
}
// Если mousedown не сработал, обрабатываем здесь
var bankId = selectedItem.attr('data-bank-id');
var bankName = selectedItem.attr('data-bank-name');
var formItem = selectedItem.closest('.form-item');
if (bankId && bankName) {
formItem.find('.js-bank-autocomplete').val(bankName);
formItem.find('input[name="bank_id"]').val(bankId);
formItem.find('.form-item__dropdown').empty();
formItem.find('.form-item__warning').text('');
}
return false;
});
// При фокусе показываем список банков
$('.js-bank-autocomplete').on('focus', function() {
var sourceInput = $(this);
var dropdown = sourceInput.closest('.form-item').find('.form-item__dropdown');
var query = $(this).val().toLowerCase().trim();
if (banksList.length === 0) {
// Если банки еще не загружены, пробуем загрузить
loadBanksList();
return;
}
if (query.length === 0) {
var sortedBanks = sortBanks(banksList.slice());
showBanksDropdown(sortedBanks.slice(0, 30), dropdown, sourceInput, banksList.length, true);
} else {
// Триггерим событие input для фильтрации
$(this).trigger('input');
}
});
// Скрываем выпадающий список при потере фокуса (с задержкой для клика)
$('.js-bank-autocomplete').on('blur', function(e) {
var sourceInput = $(this);
var dropdown = sourceInput.closest('.form-item').find('.form-item__dropdown');
// Увеличиваем задержку, чтобы клик успел обработаться
setTimeout(function() {
// Проверяем, не кликнули ли мы на элемент списка или внутри dropdown
var activeElement = document.activeElement;
var relatedTarget = e.relatedTarget;
// Если фокус перешел на элемент из dropdown, не скрываем
if (relatedTarget && $(relatedTarget).closest('.form-item__dropdown').length) {
return;
}
if (!$(activeElement).hasClass('autocomplete__item') &&
!$(activeElement).closest('.form-item__dropdown').length) {
dropdown.empty();
}
}, 200);
});
// Предотвращаем blur при клике на dropdown
$(document).on('mousedown', '.form-item__dropdown', function(e) {
// Останавливаем всплытие, чтобы blur не сработал на input
e.stopPropagation();
});
// Инициализация автодополнения адресов при загрузке страницы
setTimeout(function() {
initAddressSuggestions();
}, 1000);
// $('input[name=db_birthday],input[name=db_inn]').keyup(function(e){
$(document).on('click', '.js-check-in', function(e) {
e.preventDefault();
let birthday=$('input[name=birthday]').val();
let police_number=$('input[name=police_number]').val();
if(police_number.slice(0,1)=="Е"){
police_number=police_number.replace(/Е/g, 'E');
}
if(police_number.slice(0,1)=="А"){
police_number=police_number.replace(/А/g, 'A');
}
let dbdata={
"action" : "user_verify",
'birthday' : birthday.replace(/-/g, '.'),
'inn' : police_number
}
$.ajax({
url: 'database.php',
method: 'post',
data: dbdata,
// dataType : 'json',
success: function(data) {
let res=JSON.parse(data);
if(res.success=="true"){
// Полис валидный - показываем успешное сообщение
$('.js-result').html(res.message);
$('.js-result').removeClass("danger");
$('.js-result').addClass("form-item__warning--success");
$('input[name=insured_from]').val(res.result.insured_from.replace(/\./g, '-'));
$('input[name=insured_to]').val(res.result.insured_to.replace(/\./g, '-'));
$('.js-indatabase').val('1');
$('.form-item--polis').find('input[type=file]').addClass("notvalidate");
$('.form-item--polis').find('input[type=file]').addClass("disabled");
$('.form-item--polis').addClass('d-none');
// Показываем поля телефона и банка после успешной проверки полиса
$('.policy-validated-fields').removeClass('d-none');
// Разблокируем кнопку "Отправить смс" если полис валидный
$('.js-send-sms').removeClass('disabled');
$('.js-send-sms').prop('disabled', false);
$('.form__warning').hide();
// Если SMS уже подтверждено, сразу показываем форму для заполнения
if($('.sms-success').is(':visible') || !$('.sms-success').hasClass('d-none')) {
$('.db-success').removeClass('d-none');
$('.form-step[data-step=1]').removeClass('disabled');
}
// Инициализируем автодополнение адресов после проверки полиса
setTimeout(function() {
initAddressSuggestions();
}, 500);
} else {
// Полис невалидный - показываем ошибку
$('.js-result').html(res.message);
$('.js-result').removeClass("form-item__warning--success");
$('.js-result').addClass("danger");
$('.js-indatabase').val('0');
$('.form-item--polis').find('input[type=file]').removeClass("notvalidate");
$('.form-item--polis').find('input[type=file]').removeClass("disabled");
$('.form-item--polis').removeClass('d-none');
// Скрываем поля телефона и банка, если полис невалидный
$('.policy-validated-fields').addClass('d-none');
// Блокируем кнопку "Отправить смс" если полис невалидный
$('.js-send-sms').addClass('disabled');
$('.js-send-sms').prop('disabled', true);
$('.form__warning').show();
$('.form__warning').text('Ваш полис не покрывает данный вид обращения. Пожалуйста, проверьте полис.');
}
return false;
},
error: function (jqXHR, exception) {
$('.js-result').html(exception);
return false;
}
});
});
$('input[name=birthday]').on("change input", function (e) {
console.log("Date changed: ", e.target.value);
let birthday=$(this).val();
if(getAge(birthday)<18) {
$("input[data-enableby=birthday]").removeClass('disabled');
$("input[data-disabledby=birthday]").removeClass('disabled');
$("input[data-enableby=birthday]").removeAttr("disabled");
} else {
$("input[data-enableby=birthday]").addClass('disabled');
$("input[data-disabledby=birthday]").addClass('disabled');
$("input[data-enableby=birthday]").attr("disabled","disabled");
}
});
$('input[name=lastname],input[name=firstname],input[name=patronymic]').keyup(function(e){
let full_name=$('input[name=lastname]').val()+" "+$('input[name=firstname]').val()+" "+$('input[name=patronymic]').val();
$("input[data-enableby=birthday]").val(full_name);
});
function getAge(dateString) {
var today = new Date();
var birthDate = new Date(dateString.replace( /(\d{2})-(\d{2})-(\d{4})/, "$2/$1/$3"));
var age = today.getFullYear() - birthDate.getFullYear();
var m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
return age;
}
// Загрузка файлов
function declOfNum(number, words) {
return words[(number % 100 > 4 && number % 100 < 20) ? 2 : [2, 0, 1, 1, 1, 2][(number % 10 < 5) ? Math.abs(number) % 10 : 5]];
}
function updateSize(elem) {
var filesQty = elem[0].files.length;
if(filesQty>10) {
elem.closest('.form-item').find('.form-item__warning').text("Разрешено не более 10 файлов");
return;
}
elem.closest('.form-item').find('.form-item__warning').text('');
let file_status=[];
var formats = ['pdf','jpg','png','gif','jpeg'];
for(var i=0; i<filesQty; i++) {
var file = elem[0].files[i],
ext = "не определилось",
parts = file.name.split('.');
if (parts.length > 1) ext = parts.pop();
if(!formats.includes(ext)) {
elem.closest('.form-item').find('.form-item__warning').append('<div> Файл '+file.name+' не подходит по формату. Доступные форматы: .pdf, .jpg, .png, .gif </div>');
elem.addClass('error');
file_status.push(false);
} else {
// elem.closest('.form-item').find('.form-item__warning').text();
if((file.size/1024/1024) > 5){
file_status.push(false);
elem.closest('.form-item').find('.form-item__warning').append('<div>Размер файла '+file.name+' превышает 5 Мб. </div>');
} else {
elem.removeClass('error');
file_status.push(true);
}
}
}
// ОТКЛЮЧЕНО: старая система загрузки файлов через fileupload_v2.php
// Файлы теперь отправляются напрямую в submit.php как бинарные данные
if(file_status.every(val => val === true))
{
// upload_file(elem); // ОТКЛЮЧЕНО - файлы отправляются напрямую при submit формы
$('.form__action').find('.js-btn-next').removeClass('disabled');
} else {
$('.form__action').find('.js-btn-next').addClass('disabled');
}
}
function upload_file(thisfile) {
let formData = new FormData();
let field_name=thisfile.data('crmname') || thisfile.data('field-type');
let docname=thisfile.data('docname');
console.log('=== UPLOAD_FILE FUNCTION ===');
console.log('Uploading for field:', field_name, 'docname:', docname);
console.log('File input element:', thisfile[0]);
console.log('Files in input:', thisfile[0].files);
console.log('Field type:', thisfile.data('field-type'));
console.log('Form item:', thisfile.closest('.form-item')[0]);
let sub_dir=jQuery('input[name=sub_dir]').val();
jQuery.each(thisfile[0].files, function(i, file) {
formData.append(field_name+'-'+i, file);
});
thisfile.closest('.form-item').find('.suсcess-upload').remove();
formData.append('lastname',jQuery('input[name=lastname]').val());
formData.append('files_names[]',field_name);
formData.append('docs_names[]',docname);
formData.append('sub_dir',sub_dir);
thisfile.closest('.form-item').append("<p class='info-upload'></p>");
// for (var pair of formData.entries()) {
// console.log(pair[0]+ ', ' + pair[1]);
// }
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
// Upload progress
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with upload progress
let complete=Math.round(percentComplete * 100);
console.log(complete);
thisfile.closest('.form-item').find(".info-upload").text("Загружено "+complete+" %");
}
}, false);
// Download progress
xhr.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
// Do something with download progress
console.log(percentComplete);
}
}, false);
return xhr;
},
url: 'https://form.clientright.ru/fileupload_v2.php',
method: 'post',
cache: false,
contentType: false,
processData: false,
data: formData,
// dataType : 'json',
beforeSend : function (){
$('.form__action').find('.js-btn-next').addClass('disabled');
$('.form__action').find('.btn--submit').addClass('disabled');
},
success: function(data) {
let res=JSON.parse(data);
if(res.success=="true"){
console.log(res);
// thisfile.closest('.form-item').append("<p class='suсcess-upload'>Файл успешно загружен на сервер.</p>");
thisfile.attr('data-uploadurl',res.empty_file);
thisfile.attr('data-uploadurl_real',res.real_file);
// thisfile.closest('.form-item').append("<p class='suсcess-upload'>"+res.message+"</p>");
thisfile.closest('.form-item').find('.info-upload').remove();
$('.form__action').find('.js-btn-next').removeClass('disabled');
$('.form__action').find('.btn--submit').removeClass('disabled');
} else {
}
return false;
},
error: function (jqXHR, exception) {
return false;
}
});
}
function formatBytes(bytes, decimals = 2) {
if (!+bytes) return '0 Bytes'
const k = 1024
const dm = decimals < 0 ? 0 : decimals
const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
}
var fileIdCounter = 0;
jQuery('.js-attach').each(function() {
var fieldType = $(this).data('field-type'); // Получаем тип поля
let filethis = $(this);
// Создаем изолированное хранилище файлов для каждого поля
var fieldFiles = {
filesToUpload: [],
fieldType: fieldType
};
filethis.change(function (evt) {
var output = [];
let elem= $(this);
let currentFieldFiles = fieldFiles; // Используем изолированное хранилище
let currentFormItem = elem.closest('.form-item');
// Очищаем предупреждения только для текущего поля
currentFormItem.find('.form-item__warning').text('');
let file_status=[];
var formats = ['pdf','jpg','png','gif','jpeg'];
console.log('=== FILE UPLOAD START ===');
console.log('Processing files for field type:', currentFieldFiles.fieldType);
console.log('Field element:', elem[0]);
console.log('Form item:', currentFormItem[0]);
console.log('Files to process:', evt.target.files);
console.log('Current fieldFiles state:', currentFieldFiles);
if(evt.target.files.length>10) {
elem.closest('.form-item').find('.form-item__warning').text("Разрешено не более 10 файлов");
return;
}
// Очищаем предыдущий список файлов для этого поля
currentFormItem.find('.fileList').empty();
currentFieldFiles.filesToUpload = [];
for (var i = 0; i < evt.target.files.length; i++) {
fileIdCounter++;
var file = evt.target.files[i];
var fileId = "fileid_" + fileIdCounter;
console.log(file);
let ext = "не определилось";
let parts = file.name.split('.');
if (parts.length > 1) ext = parts.pop();
if(!formats.includes(ext)) {
elem.closest('.form-item').find('.form-item__warning').append('<div> Файл '+file.name+' не подходит по формату. Доступные форматы: .pdf, .jpg, .png, .gif </div>');
elem.addClass('error');
file_status.push(false);
} else {
// elem.closest('.form-item').find('.form-item__warning').text();
if((file.size/1024/1024) > 5){
file_status.push(false);
elem.closest('.form-item').find('.form-item__warning').append('<div>Размер файла '+file.name+' превышает 5 Мб. </div>');
} else {
elem.removeClass('error');
file_status.push(true);
var removeLink = "<a class=\"removefile\" href=\"#\" data-fileid=\"" + fileId + "\"></a>";
output.push("<li><strong>", file.name, "</strong> <span class='size'> ", formatBytes(file.size) , " </span> ", removeLink, "</li> ");
currentFieldFiles.filesToUpload.push({
id: fileId,
file: file
});
}
}
//evt.target.value = null;
// elem.closest('.form-item').find('.upload-action').removeClass('d-none');
};
currentFormItem.find(".fileList").append(output.join(""));
let container = new DataTransfer();
for (var i = 0, len = currentFieldFiles.filesToUpload.length; i < len; i++) {
container.items.add(currentFieldFiles.filesToUpload[i].file);
}
elem[0].files = container.files;
if(file_status.every(val => val === true))
{
console.log('=== FILE UPLOAD SUCCESS ===');
console.log('Uploading files for field type:', currentFieldFiles.fieldType);
console.log('Final fieldFiles state:', currentFieldFiles);
console.log('Files in DataTransfer:', elem[0].files);
// upload_file(elem); // ОТКЛЮЧЕНО - файлы отправляются напрямую при submit формы
$('.form__action').find('.js-btn-next').removeClass('disabled');
} else {
console.log('=== FILE UPLOAD FAILED ===');
console.log('File status:', file_status);
$('.form__action').find('.js-btn-next').addClass('disabled');
}
});
// Обработчик удаления файлов с доступом к fieldFiles через замыкание
$(this).closest('.form-item').on("click", ".removefile", function (e) {
let elem = $(this);
e.preventDefault();
var fileId = elem.data("fileid");
// Находим соответствующий input файла для этого .form-item
let fileInput = elem.closest('.form-item').find('input[type="file"].js-attach');
let fieldType = fileInput.data('field-type');
console.log('=== REMOVE FILE ===');
console.log('Removing file with ID:', fileId);
console.log('From field type:', fieldType);
console.log('Current fieldFiles:', fieldFiles);
// Используем fieldFiles из замыкания
for (var i = 0; i < fieldFiles.filesToUpload.length; ++i) {
if (fieldFiles.filesToUpload[i].id === fileId) {
fieldFiles.filesToUpload.splice(i, 1);
console.log('File removed from fieldFiles');
break;
}
}
elem.parent().remove();
if(fieldFiles.filesToUpload.length == 0) {
elem.closest('.form-item').find('.upload-action').addClass('d-none');
elem.closest('.form-item').find('.suсcess-upload').text('');
} else {
let container = new DataTransfer();
for (var i = 0, len = fieldFiles.filesToUpload.length; i < len; i++) {
container.items.add(fieldFiles.filesToUpload[i].file);
}
fileInput[0].files = container.files;
updateSize(fileInput);
}
});
});
// End Загрузка файлов
});