Last active
October 1, 2021 06:45
-
-
Save b-aleksei/6656dce5c99344ecf74d3ded80275bc3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
const fileLoaderContainers = document.querySelectorAll('.file-loader'); | |
const renderFileLoader = function(fileLoaderContainer) { | |
const wrapper = fileLoaderContainer.querySelector('.file-loader__wrapper'); | |
const btnAdd = fileLoaderContainer.querySelector('.js-fileloader-open'); | |
if (!wrapper || !btnAdd) { | |
return; | |
} | |
const inputFileLoader = wrapper.querySelector('.file-loader__item'); | |
const inputTemplate = inputFileLoader.cloneNode(true); | |
const maxLoaders = 10; | |
const limitBiteSize = 18000000; | |
const testImg = function(str) { | |
return /\.(png|jpe?g|pdf|doc|docx)$/i.test(str); | |
}; | |
const setError = function(message) { | |
if (btnAdd) { | |
btnAdd.dataset.errorMess = message; | |
} | |
}; | |
const isFileSizeCorrect = function(ctx) { | |
const inputs = ctx.querySelectorAll('.file-loader-js'); | |
let size = 0; | |
inputs.forEach(function(i) { | |
if (i.files.length) { | |
size += i.files[0].size; | |
} | |
}); | |
return size < limitBiteSize; | |
}; | |
const renderNewInputAttr = function(attr) { | |
const inputs = wrapper.querySelectorAll('.file-loader-js'); | |
const lastInput = inputs[inputs.length - 1]; | |
const regExpNumber = /\d+/; | |
const regExpName = /\D+/; | |
const currentNumber = +lastInput[attr].match(regExpNumber)[0]; | |
const currentName = lastInput[attr].match(regExpName)[0]; | |
return currentName + (currentNumber + 1); | |
}; | |
const addFileLoader = function() { | |
const id = renderNewInputAttr('id'); | |
const name = renderNewInputAttr('name'); | |
const loaderItem = inputTemplate.cloneNode(true); | |
const input = loaderItem.querySelector('input'); | |
input.id = id; | |
input.name = name; | |
wrapper.append(loaderItem); | |
btnAdd.setAttribute('for', id ); | |
}; | |
const formatSize = function(number) { | |
let unitSize = ' Байт'; | |
let divider = 1; | |
if (number > 1000000) { | |
unitSize = ' Мб'; | |
divider = 1000000; | |
} else if (number > 1000) { | |
unitSize = ' Кб'; | |
divider = 1000; | |
} | |
return (number / divider).toFixed(1) + unitSize; | |
}; | |
wrapper.addEventListener('change', function(e) { | |
const target = e.target; | |
const parent = target.parentElement; | |
let errorMess = ''; | |
if (!target.files.length) return; | |
if (!testImg(target.files[0].name)) { | |
target.value = ''; | |
errorMess = 'Некорректный тип файла'; | |
} else if (!isFileSizeCorrect(wrapper)) { | |
target.value = ''; | |
errorMess = 'файлы превышают лимит 18мб'; | |
} else { | |
if (wrapper.childElementCount < maxLoaders) { | |
const sizeEl = parent.querySelector('.file-loader__size'); | |
const output = parent.querySelector('.file-loader__output'); | |
if (sizeEl) { | |
sizeEl.innerText = formatSize(target.files[0].size); | |
} | |
if (output) { | |
output.innerText = target.files[0].name; | |
} | |
parent.classList.remove('unvisible'); | |
addFileLoader(); | |
} | |
} | |
target.setCustomValidity(errorMess); | |
setError(errorMess); | |
}); | |
}; | |
fileLoaderContainers.forEach(f => renderFileLoader(f)); | |
})(); | |
/* | |
<form class="file-loader support__form-item"> | |
<i class="file-loader__note support__form-item">Вы можете прикрепить к обращению не более 10 файлов в формате .png, .jpeg, .pdf или .doc общим весом не более 18 мб</i> | |
<div class="file-loader__wrapper support__form-item"> | |
<div class="file-loader__item support__form-item unvisible"> | |
<input name="fileLoader1" id="fileLoader1" type="file" class="file-loader-js visually-hidden" accept=".png, .jpg, .jpeg, .pdf, .doc, .docx" aria-label="загрузить файл"> | |
<div class="file-loader__view"> | |
<output class="file-loader__output"></output> | |
<small class="file-loader__size"></small> | |
</div> | |
<button class="file-loader__remove" onclick="this.parentElement.remove()" type="button"></button> | |
</div> | |
</div> | |
<label for="fileLoader1" class="support__form-item js-fileloader-open file-loader__btn" data-error-mess="">Добавить ещё документ</label> | |
</form> | |
.visually-hidden { | |
position: absolute; | |
width: 1px; | |
height: 1px; | |
margin: -1px; | |
border: 0; | |
clip: rect(0 0 0 0); | |
overflow: hidden; | |
} | |
.file-loader__wrapper { | |
display: flex; | |
flex-direction: column; | |
} | |
.file-loader__item { | |
position: relative; | |
display: flex; | |
padding: 10px 0; | |
align-items: center; | |
justify-content: space-between; | |
&:not(:first-child) { | |
border-top: 1px solid #C5C5C5; | |
} | |
} | |
.file-loader__btn { | |
position: relative; | |
align-items: center; | |
justify-content: center; | |
padding: 6px 16px 9px; | |
color: #0A5C6D; | |
cursor: pointer; | |
background: #eee | |
&::after { | |
position: absolute; | |
top: 100%; | |
left: 0; | |
content: attr(data-error-mess); | |
font-size: 12px; | |
color: #f32727; | |
background: none; | |
} | |
} | |
.file-loader__view { | |
display: flex; | |
flex-direction: column; | |
} | |
.file-loader__size { | |
font-size: 12px; | |
line-height: 15px; | |
color: #8F9BA3; | |
} | |
.file-loader__remove { | |
position: relative; | |
width: 40px; | |
height: 40px; | |
cursor: pointer; | |
background: none; | |
border: none; | |
&::before, | |
&::after { | |
content: ""; | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
width: 17px; | |
height: 2px; | |
background: #828E97; | |
} | |
&::before { | |
transform: translate(-50%, -50%) rotate(-45deg); | |
} | |
&::after { | |
transform: translate(-50%, -50%) rotate(45deg); | |
} | |
} | |
.unvisible { | |
visibility: hidden; | |
position: absolute; | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment