455 lines
18 KiB
JavaScript
455 lines
18 KiB
JavaScript
var newFiles = {};
|
|
var sl = {};
|
|
|
|
function checkAll(el) {
|
|
const objectKey = el.dataset.objectKey;
|
|
sl[objectKey] = [];
|
|
all('#' + objectKey + ' .file-img [data-del]', e => {
|
|
e.checked = el.checked === true;
|
|
if (el.checked) {
|
|
if (e.dataset.del) {
|
|
sl[objectKey].push(e.dataset.del);
|
|
}
|
|
e.parentNode.addClass('checked');
|
|
} else {
|
|
e.parentNode.removeClass('checked');
|
|
}
|
|
})
|
|
updateActionButtons(objectKey);
|
|
}
|
|
|
|
function checkSingle(e) {
|
|
const objectKey = e.dataset.objectKey;
|
|
sl[objectKey] = sl[objectKey] || [];
|
|
if (e.checked) {
|
|
if (e.dataset.del) {
|
|
sl[objectKey].push(e.dataset.del);
|
|
}
|
|
e.parentNode.addClass('checked');
|
|
} else {
|
|
one('#' + e.dataset.objectKey + ' .all-files input').checked = false;
|
|
e.parentNode.removeClass('checked');
|
|
if (e.dataset.del) {
|
|
const f = sl[objectKey].indexOf(e.dataset.del);
|
|
sl[objectKey].splice(f, 1);
|
|
}
|
|
}
|
|
updateActionButtons(objectKey);
|
|
}
|
|
|
|
function updateActionButtons(id) {
|
|
let checkedCounter = 0;
|
|
let checkedCounterUploaded = 0;
|
|
all('#' + id + ' .file-img input', c => {
|
|
if (c.checked === true)
|
|
checkedCounter++;
|
|
|
|
if (c.checked === true && c.dataset.del)
|
|
checkedCounterUploaded++;
|
|
})
|
|
const btnDelete = one('#' + id + ' .btnDelete');
|
|
const delCount = one('#' + id + ' .delCount');
|
|
const btnEdit = one('#' + id + ' .btnEdit');
|
|
if (btnDelete) {
|
|
if (checkedCounter > 0) {
|
|
btnDelete.removeClass('disabled');
|
|
delCount.innerHTML = '(' + checkedCounter + ')'
|
|
} else {
|
|
btnDelete.addClass('disabled');
|
|
delCount.innerHTML = '(0)'
|
|
}
|
|
}
|
|
if (btnEdit) {
|
|
if (checkedCounterUploaded === 1) {
|
|
btnEdit.removeClass('disabled');
|
|
} else {
|
|
btnEdit.addClass('disabled');
|
|
}
|
|
}
|
|
}
|
|
|
|
function addFileImage(e) {
|
|
const max_file_size = one('#' + e.dataset.objectKey + ' .max_file_size').value;
|
|
const error_message = one('#' + e.dataset.objectKey + ' .error_message').value;
|
|
const file = document.createElement('input');
|
|
let filesContainer = one('#' + e.dataset.objectKey + ' .files-container');
|
|
newFiles[e.dataset.objectKey] = newFiles[e.dataset.objectKey] || [];
|
|
file.type = 'file';
|
|
file.name = e.dataset.objectKey
|
|
file.multiple = !e.dataset.singleFile;
|
|
//file.accept = 'image/jpeg, image/png'
|
|
file.click();
|
|
file.addEventListener('change', function () {
|
|
var cIndex = 0;
|
|
for (let i = 0; i < this.files.length; i++) {
|
|
const f = this.files[i];
|
|
if (f.size > max_file_size * (1024 * 1024)) {
|
|
flash.error(error_message);
|
|
}
|
|
else if(f.type !== 'image/jpeg' && f.type !== 'image/jpg' && f.type !== 'image/png') {
|
|
flash.error('Позволените формати са jpeg и png')
|
|
}
|
|
else {
|
|
filesContainer.style.display = 'flex';
|
|
const fileContainer = one('file-img', filesContainer);
|
|
const imgId = e.dataset.objectKey + '_' + cIndex;
|
|
cIndex++;
|
|
const img = new Image();
|
|
img.src = URL.createObjectURL(f);
|
|
img.id = imgId;
|
|
const check = document.createElement('input')
|
|
check.type = 'checkbox';
|
|
check.setAttribute('data-del', '');
|
|
check.setAttribute('data-id', imgId);
|
|
check.setAttribute('data-object-key', e.dataset.objectKey)
|
|
check.addEventListener('click', e => {
|
|
checkSingle(check);
|
|
})
|
|
fileContainer.appendChild(img);
|
|
fileContainer.appendChild(check);
|
|
one('crops', fileContainer);
|
|
const progress = one('progress', fileContainer);
|
|
img.addEventListener('load', function () {
|
|
fileContainer.addClass('visible');
|
|
check.focus();
|
|
});
|
|
img.addEventListener('click', () => {
|
|
editSingleFileImage(img);
|
|
})
|
|
orderItem(fileContainer, function (img_id, order_index) {
|
|
newFiles[img_id][3] = order_index.toString();
|
|
})
|
|
newFiles[imgId] = [f, progress, e.dataset.objectKey, fileContainer.dataset.index, check];
|
|
if (e.dataset.singleFile) {
|
|
e.addClass('disabled');
|
|
}
|
|
}
|
|
}
|
|
uploadAllFilesByAttach(e.dataset.objectKey, cIndex, e.dataset.editMode);
|
|
});
|
|
}
|
|
|
|
function removeFileImage(el) {
|
|
let checkedCounter = 0;
|
|
let forDelete = [];
|
|
all('#' + el.dataset.objectKey + ' .file-img input', c => {
|
|
if (c.checked === true) {
|
|
checkedCounter++;
|
|
forDelete.push(c);
|
|
}
|
|
});
|
|
let message = '';
|
|
if (checkedCounter > 1) {
|
|
message = 'Сигурни ли сте, че истате да премахнете тези ' + checkedCounter + ' изображения';
|
|
} else {
|
|
message = 'Сигурни ли сте, че искате да премахнете 1 изображение';
|
|
}
|
|
modal.confirm(message, function () {
|
|
forDelete.forEach(fd => {
|
|
fd.parentNode.remove();
|
|
delete newFiles[fd.dataset.id];
|
|
});
|
|
el.querySelector('.delCount').innerHTML = '(0)';
|
|
el.addClass('disabled');
|
|
one('#' + el.dataset.objectKey + ' .btnEdit').addClass('disabled');
|
|
if (sl[el.dataset.objectKey].length > 0) {
|
|
let del_ids = JSON.stringify(sl[el.dataset.objectKey]);
|
|
request({
|
|
url: '/delete-file-cms/',
|
|
post: {
|
|
del_ids: del_ids
|
|
},
|
|
done: r => {
|
|
if (r.success) {
|
|
flash.success(r.success, true);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
const addButton = one('#' + el.dataset.objectKey + ' [data-single-file]');
|
|
if (all('#' + el.dataset.objectKey + ' .file-img input').length === 0) {
|
|
one('#' + el.dataset.objectKey + ' .files-container').style.display = 'none';
|
|
if (addButton.dataset.singleFile) {
|
|
addButton.removeClass('disabled');
|
|
}
|
|
}
|
|
one('#' + el.dataset.objectKey + ' .all-files input').checked = false;
|
|
})
|
|
}
|
|
|
|
function uploadAllFilesByAttach(object_key, for_upload, editMode) {
|
|
|
|
console.log(newFiles);
|
|
const
|
|
newFilesIds = Object.keys(newFiles),
|
|
media_key = one('[name="media_key"]').value,
|
|
model_class = one('[name="model_class"]').value,
|
|
model_id = one('[name="model_id"]').values
|
|
|
|
if (newFilesIds.length > 0) {
|
|
var cc = 0;
|
|
all(`#${object_key} .file-img`).forEach(e => {
|
|
e.addClass('no-events');
|
|
})
|
|
newFilesIds.forEach(id => {
|
|
if (newFiles[id][5] === undefined) {
|
|
const f = newFiles[id][0];
|
|
const progressBar = newFiles[id][1];
|
|
const object_key = newFiles[id][2];
|
|
const order_index = newFiles[id][3];
|
|
const check = newFiles[id][4];
|
|
let formData = new FormData();
|
|
console.log(object_key);
|
|
formData.append('media_key', media_key);
|
|
formData.append('model_class', model_class);
|
|
formData.append('object_key', object_key);
|
|
formData.append('order_index', order_index);
|
|
formData.append('model_id', model_id);
|
|
formData.append(id, f);
|
|
if (editMode) {
|
|
formData.append('has_article', 1)
|
|
}
|
|
request({
|
|
url: '/upload-file-cms/',
|
|
post: formData,
|
|
progress: percentage => {
|
|
if (progressBar) {
|
|
progressBar.style.width = percentage + '%'
|
|
if (percentage < 100) {
|
|
progressBar.parentNode.addClass('disabled')
|
|
} else {
|
|
if (progressBar) {
|
|
if (progressBar.parentNode)
|
|
progressBar.parentNode.removeClass('disabled')
|
|
progressBar.remove()
|
|
}
|
|
}
|
|
}
|
|
},
|
|
done: data => {
|
|
check.setAttribute('data-del', data.id);
|
|
check.setAttribute('data-file-type', data.fileType)
|
|
check.setAttribute('data-src-raw', data.srcRaw)
|
|
check.setAttribute('data-media-key', data.mediaKey)
|
|
check.setAttribute('data-file-name', data.fileName)
|
|
check.setAttribute('data-crop-files', '[]')
|
|
newFiles[id][5] = 'uploaded';
|
|
cc++
|
|
if (for_upload === cc) {
|
|
all(`#${object_key} .file-img`).forEach(e => {
|
|
e.removeClass('disabled');
|
|
e.removeClass('no-events');
|
|
})
|
|
}
|
|
}
|
|
})
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function editSingleFileImage(e) {
|
|
const check = e.parentNode.querySelector('input');
|
|
editFileSelectedImage(check, check.dataset.objectKey)
|
|
}
|
|
function editFileImage(e) {
|
|
const check = one('#' + e.dataset.objectKey + ' .file-img input:checked');
|
|
editFileSelectedImage(check, e.dataset.objectKey)
|
|
}
|
|
function editFileSelectedImage(check, objectKey) {
|
|
const bufferFiles = {};
|
|
const allowed_resolutions = JSON.parse(one('#' + objectKey + ' .allowed_resolutions').value);
|
|
const cropFiles = JSON.parse(check.dataset.cropFiles);
|
|
const img = document.createElement('img');
|
|
img.src = check.dataset.srcRaw;
|
|
img.style.height = '100%';
|
|
img.style.width = 'auto';
|
|
let aspectRation = 1;
|
|
let rez = '1:1';
|
|
if (allowed_resolutions.length > 0) {
|
|
aspectRation = allowed_resolutions[0][0] / allowed_resolutions[0][1];
|
|
rez = allowed_resolutions[0][0] + ':' + allowed_resolutions[0][1];
|
|
}
|
|
|
|
|
|
const cropContainer = document.createElement('div');
|
|
cropContainer.addClass('crop-container');
|
|
const cropImgContainer = one('crop-container-img', cropContainer);
|
|
const cropsContainer = one('crops-container', cropContainer);
|
|
const select = document.createElement('select');
|
|
|
|
cropImgContainer.addClass('invisible')
|
|
const options = [];
|
|
allowed_resolutions.forEach(r => {
|
|
options.push('<option data-rez="' + r[0] + ':' + r[1] + '" value="' + (r[0] / r[1]) + '">Резолюция ' + r[0] + ':' + r[1] + '</option>');
|
|
});
|
|
select.innerHTML = options.join('');
|
|
cropsContainer.innerHTML = '';
|
|
|
|
select.addEventListener('change', function () {
|
|
cropper.setAspectRatio(parseFloat(this.value));
|
|
const s = select.querySelector('option[value="' + this.value + '"]');
|
|
rez = s.dataset.rez;
|
|
});
|
|
cropsContainer.appendChild(select);
|
|
const cropBtn = one('btn-ib btn-default', cropsContainer);
|
|
cropBtn.innerHTML = '<i class="la la-crop"></i> Изрежи';
|
|
cropImgContainer.appendChild(img);
|
|
const cropsImgContainer = one('crops-img-container', cropsContainer);
|
|
|
|
cropsContainer.addClass('disabled');
|
|
const cropper = new Cropper(img, {
|
|
autoCrop: false,
|
|
aspectRatio: aspectRation,
|
|
viewMode: 0,
|
|
ready() {
|
|
this.cropper.crop();
|
|
cropImgContainer.removeClass('invisible')
|
|
cropImgContainer.removeClass('invisible')
|
|
cropsContainer.removeClass('disabled')
|
|
},
|
|
});
|
|
|
|
cropBtn.addEventListener('click', function () {
|
|
const modalBtnConfirm = one('.modal-button-confirm');
|
|
modalBtnConfirm.removeClass('disabled');
|
|
const existCrop = one('[data-row-rez="' + rez + '"]');
|
|
if (existCrop) {
|
|
if (existCrop.querySelector('img'))
|
|
existCrop.querySelector('img').remove();
|
|
if (existCrop.querySelector('canvas'))
|
|
existCrop.querySelector('canvas').remove();
|
|
const canvas = cropper.getCroppedCanvas();
|
|
existCrop.prepend(canvas);
|
|
canvas.toBlob(function (blob) {
|
|
bufferFiles[rez] = new File([blob], check.dataset.fileName, {type: check.dataset.fileType});
|
|
}, check.dataset.fileType, 0.5)
|
|
} else {
|
|
createCanvasCropRow(cropper, cropsImgContainer, rez, canvas => {
|
|
canvas.toBlob(function (blob) {
|
|
bufferFiles[rez] = new File([blob], check.dataset.fileName, {type: check.dataset.fileType});
|
|
}, check.dataset.fileType, 0.5)
|
|
}, del_rez => {
|
|
delete bufferFiles[rez];
|
|
if (Object.keys(bufferFiles).length === 0) {
|
|
modalBtnConfirm.addClass('disabled');
|
|
}
|
|
})
|
|
}
|
|
});
|
|
Object.keys(cropFiles).forEach(k => {
|
|
createImageCropRow(cropFiles[k], cropsImgContainer, k, check);
|
|
})
|
|
modal.confirm(cropContainer,
|
|
() => {
|
|
const keyRez = Object.keys(bufferFiles);
|
|
check.checked = false;
|
|
check.parentNode.removeClass('checked');
|
|
updateActionButtons(check.dataset.objectKey);
|
|
const form = one('form');
|
|
form.addClass('form-wait');
|
|
const waitingType = !one('.waiting-tape') ? one('waiting-tape', document.body) : null;
|
|
const fd = new FormData();
|
|
fd.append('object_key', check.dataset.objectKey);
|
|
fd.append('media_key', check.dataset.mediaKey);
|
|
fd.append('file_name', check.dataset.fileName);
|
|
fd.append('resolutions', JSON.stringify(keyRez));
|
|
keyRez.forEach(rez => {
|
|
const file = bufferFiles[rez];
|
|
fd.append(rez, file);
|
|
});
|
|
request({
|
|
url: '/upload-crop/',
|
|
post: fd,
|
|
done: r => {
|
|
if (r.resolutions) {
|
|
const crops = check.parentNode.querySelector('.crops');
|
|
crops.innerHTML = '';
|
|
r.resolutions.forEach(rez => {
|
|
const cr = document.createElement('span');
|
|
cr.innerHTML = rez;
|
|
crops.appendChild(cr);
|
|
})
|
|
}
|
|
if (r.files) {
|
|
check.setAttribute('data-crop-files', JSON.stringify(r.files))
|
|
}
|
|
form.removeClass('form-wait');
|
|
waitingType.remove();
|
|
flash.success('Изображението с резолюцията ' + keyRez.join(', ') + ' е актуализирано успешно', true);
|
|
}
|
|
})
|
|
},
|
|
() => {
|
|
},
|
|
{
|
|
width: '80%',
|
|
height: '75%'
|
|
},
|
|
() => {
|
|
const modalBtnConfirm = one('.modal-button-confirm');
|
|
modalBtnConfirm.addClass('disabled');
|
|
}
|
|
);
|
|
|
|
}
|
|
|
|
function createCanvasCropRow(cropper, cropsImgContainer, rez, callback, callbackDel) {
|
|
const canvas = cropper.getCroppedCanvas();
|
|
const cropsImgRow = one('crops-img-row', cropsImgContainer);
|
|
const cropsImgRez = one('crops-img-rez', cropsImgRow);
|
|
cropsImgRez.innerHTML = rez;
|
|
const cropsImgDel = one('crops-img-del btn-ib btn-default', cropsImgRow);
|
|
cropsImgDel.innerHTML = '<i class="la la-trash"></i>';
|
|
cropsImgDel.title = 'Изтрий резолюцията';
|
|
cropsImgDel.addEventListener('click', function () {
|
|
cropsImgDel.parentNode.remove();
|
|
callbackDel(rez);
|
|
flash.success('Резолюцията е изтрита');
|
|
})
|
|
cropsImgRow.prepend(canvas);
|
|
cropsImgRow.setAttribute('data-row-rez', rez);
|
|
callback(canvas);
|
|
}
|
|
|
|
function createImageCropRow(src, cropsImgContainer, rez, check) {
|
|
const img = new Image();
|
|
img.src = src + '?t=' + (new Date().getTime());
|
|
const cropsImgRow = one('crops-img-row', cropsImgContainer);
|
|
const cropsImgRez = one('crops-img-rez', cropsImgRow);
|
|
cropsImgRez.innerHTML = rez;
|
|
const cropsImgDel = one('crops-img-del btn-ib btn-default', cropsImgRow);
|
|
cropsImgDel.innerHTML = '<i class="la la-trash"></i>';
|
|
cropsImgDel.title = 'Изтрий резолюцията';
|
|
cropsImgDel.addEventListener('click', function () {
|
|
cropsImgDel.parentNode.remove();
|
|
request({
|
|
url: '/delete-crop/',
|
|
post: {
|
|
del_id: check.dataset.del,
|
|
rez: rez
|
|
},
|
|
done: r => {
|
|
if (r.resolutions) {
|
|
const crops = check.parentNode.querySelector('.crops');
|
|
crops.innerHTML = '';
|
|
r.resolutions.forEach(rez => {
|
|
const cr = document.createElement('span');
|
|
cr.innerHTML = rez;
|
|
crops.appendChild(cr);
|
|
})
|
|
}
|
|
if (r.files) {
|
|
check.setAttribute('data-crop-files', JSON.stringify(r.files))
|
|
}
|
|
flash.success('Резолюцията е изтрита', true);
|
|
}
|
|
})
|
|
})
|
|
cropsImgRow.prepend(img);
|
|
cropsImgRow.setAttribute('data-row-rez', rez);
|
|
}
|
|
|
|
//region [ORDER]
|
|
orderItems('.file-img', '/update-file-indexes/');
|
|
//endregion
|