Files
Fedor 9245768987 🚀 CRM Files Migration & Real-time Features
 Features:
- Migrated ALL files to new S3 structure (Projects, Contacts, Accounts, HelpDesk, Invoice, etc.)
- Added Nextcloud folder buttons to ALL modules
- Fixed Nextcloud editor integration
- WebSocket server for real-time updates
- Redis Pub/Sub integration
- File path manager for organized storage
- Redis caching for performance (Functions.php)

📁 New Structure:
Documents/Project/ProjectName_ID/file_docID.ext
Documents/Contacts/FirstName_LastName_ID/file_docID.ext
Documents/Accounts/AccountName_ID/file_docID.ext

🔧 Technical:
- FilePathManager for standardized paths
- S3StorageService integration
- WebSocket server (Node.js + Docker)
- Redis cache for getBasicModuleInfo()
- Predis library for Redis connectivity

📝 Scripts:
- Migration scripts for all modules
- Test pages for WebSocket/SSE/Polling
- Documentation (MIGRATION_*.md, REDIS_*.md)

🎯 Result: 15,000+ files migrated successfully!
2025-10-24 19:59:28 +03:00

1045 lines
34 KiB
JavaScript
Raw Permalink 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.

$(function() {
$(document).ready(function(){
// DEBUG_MODE загружается из debug-config.js
$(".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)
});
$(".js-bik-mask").inputmask("999999999");
$(".js-rs-mask").inputmask("99999999999999999999");
$(".js-ks-mask").inputmask("99999999999999999999");
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: 'aggressive',
utilsScript: "libs/intl-tel-input-master/build/js/utils.js",
});
});
$('.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();
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 {
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);
});
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(){
var sended_code = Math.floor(Math.random()*(999999-100000+1)+100000);
// Режим отладки - не отправляем реальную SMS
if (!DEBUG_MODE) {
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;
}
});
} else {
console.log('🔧 DEBUG MODE: SMS отключена. Код:', sended_code);
}
//alert(sended_code);
if (DEBUG_MODE) {
$('.js-code-warning').text('🔧 РЕЖИМ ОТЛАДКИ: Введите любой 6-значный код');
} else {
$('.js-code-warning').text('Код отправлен на ваш номер телефона');
}
$.fancybox.open({
src: '#confirm_sms',
type: 'inline'
});
$('.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) {
// $('.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();
var enteredCode = $('.sms-checking input[type="text"]').val();
var isCodeValid = false;
// В режиме отладки принимаем любой 6-значный код
if (DEBUG_MODE) {
isCodeValid = enteredCode.length === 6 && /^\d+$/.test(enteredCode);
if (isCodeValid) {
console.log('🔧 DEBUG MODE: Код принят (любой 6-значный):', enteredCode);
}
} else {
isCodeValid = enteredCode == sended_code;
}
if(isCodeValid) {
$('.sms-success').removeClass('d-none');
$('.form-step[data-step=1]').removeClass('disabled');
$('.modal .js-send-sms').show();
$('.sms-check .form-item > .js-send-sms').hide();
$.fancybox.close();
$.fancybox.close();
$('.sms-check').addClass("disabled");
if (DEBUG_MODE) {
$('.sms-check .form-item__warning').text("🔧 DEBUG: Номер подтвержден (без SMS)");
} else {
$('.sms-check .form-item__warning').text("Вы успешно подтвердили номер");
}
} else {
if (DEBUG_MODE) {
$('.modal .form-item__warning').text("🔧 DEBUG: Введите любой 6-значный код");
} 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; // Счетчик для правильной индексации файлов
jQuery.each(jQuery('input[type=file].js-attach').not('.disabled'), function(i, file) {
if(!$(this).hasClass('disabled')) {
let field_name=jQuery(this).data('crmname');
let docname=jQuery(this).data('docname');
let upload_url=jQuery(this).attr('data-uploadurl');
let upload_url_real=jQuery(this).attr('data-uploadurl_real');
jQuery.each(jQuery(this)[0].files, function(i, file) {
formData.append(field_name+'-'+i, file);
});
if(upload_url) { // Если файл загрузился и получили ответ от upload тогда добавляем в форму
formData.append('upload_urls[]',upload_url);
formData.append('upload_urls_real[]',upload_url_real);
formData.append('files_names[]',field_name);
formData.append('docs_names[]',docname);
if(jQuery(this).data('doctype')=="ticket") {
formData.append('docs_ticket_files_ids[]',fileIndex);
} else {
formData.append('docs_ticket_files_ids[]','simple');
}
fileIndex++; // Увеличиваем счетчик только для файлов с upload_url
}
}
});
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: 'https://form.clientright.ru/server_webservice2.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();
// ✅ Токен DaData загружается из .env через env-config.js.php
var settings = {
"url": DADATA_API_URL,
"method": "POST",
"timeout": 0,
"headers": {
"Authorization": "Token " + DADATA_TOKEN,
"Content-Type": "application/json"
},
"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();
});
// $(document).ready(function(){
// setTimeout(function() {
// var $form = $(".form form");
// createSuggestions($form);
// }, 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) {
console.log(data);
let res=JSON.parse(data);
if(res.success=="true"){
$('.db-success').removeClass("d-none");
$('.js-result').html(res.message);
$('.js-result').removeClass("danger");
$('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');
} else {
$('.db-success').removeClass("d-none");
$('.js-result').html(res.message);
$('.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');
}
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);
}
}
}
if(file_status.every(val => val === true))
{
upload_file(elem);
$('.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);
$('.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 Загрузка файлов
});