up
This commit is contained in:
365
assets/js/edit.js
Normal file
365
assets/js/edit.js
Normal file
@@ -0,0 +1,365 @@
|
||||
let historyStates = [];
|
||||
let currentStateIndex = -1;
|
||||
|
||||
|
||||
const $toggleEditModeButton = $('#toggleEditMode');
|
||||
const $tabBar = $('#tabBar');
|
||||
const $textOptions = $('#textOptions');
|
||||
const $imageOptions = $('#imageOptions');
|
||||
const $BoxOptions = $('#BoxOptions');
|
||||
const $textColorInput = $('#textColor');
|
||||
const $textBackgroundInput = $('#textBackground');
|
||||
const $textContentInput = $('#textContent');
|
||||
const $imageURLInput = $('#imageURL');
|
||||
const $imageUploadInput = $('#imageUpload');
|
||||
const $logoSizeInput = $('#logoSize');
|
||||
const $sizeValueSpan = $('#sizeValue');
|
||||
const $lineHeightInput = $('#lineHeight');
|
||||
let currentElement = null;
|
||||
let isEditMode = false;
|
||||
|
||||
|
||||
$(window).scroll(function () {
|
||||
|
||||
if ($(window).scrollTop() > 100) {
|
||||
$(".mode-edit").addClass('fixed');
|
||||
}
|
||||
else {
|
||||
$(".mode-edit").removeClass('fixed');
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
$toggleEditModeButton.on('click', function () {
|
||||
isEditMode = !isEditMode;
|
||||
$('.editable-element').toggleClass('editable', isEditMode);
|
||||
$toggleEditModeButton.html(isEditMode ? '<i class="fas fa-sign-out-alt"></i> Thoát chỉnh sửa' : '<i class="far fa-edit"></i> Chỉnh sửa');
|
||||
$tabBar.hide();
|
||||
});
|
||||
|
||||
$imageUploadInput.on('change', function (event) {
|
||||
const file = event.target.files[0];
|
||||
if (!file) return;
|
||||
const reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
currentElement.find('img').attr('src', reader.result);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
|
||||
$textColorInput.on('input', function (e) {
|
||||
updateTextColor($(this).val());
|
||||
});
|
||||
|
||||
$textBackgroundInput.on('input', function (e) {
|
||||
updateBackgroundColor($(this).val());
|
||||
});
|
||||
|
||||
$logoSizeInput.on('input', function () {
|
||||
$sizeValueSpan.text(`${$logoSizeInput.val()}px`);
|
||||
currentElement.find('img').css('width', `${$logoSizeInput.val()}px`);
|
||||
});
|
||||
|
||||
$lineHeightInput.on('input', function () {
|
||||
if (currentElement && currentElement.data('type') === 'title') {
|
||||
currentElement.find('.title').css('line-height', `${$lineHeightInput.val()}px`);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function startEditing(event, button) {
|
||||
if (!isEditMode) return;
|
||||
event.stopPropagation();
|
||||
currentElement = $(button).closest('.editable-element');
|
||||
$tabBar.show();
|
||||
setupOptions();
|
||||
}
|
||||
|
||||
function setupOptions() {
|
||||
if (currentElement.data('type') === 'box') {
|
||||
$BoxOptions.show();
|
||||
$textOptions.hide();
|
||||
$imageOptions.hide();
|
||||
const $title = currentElement.find('.title');
|
||||
$('#BackgroundColor').val(extractColor(currentElement, 'bg'));
|
||||
$('#InputCodeBg').val(extractColor(currentElement, 'bg'));
|
||||
$('#changeInputBg').val(extractColor(currentElement, 'bg'));
|
||||
$textContentInput.val($title.text().trim());
|
||||
$textColorInput.val(extractColor($title, 'text'));
|
||||
$textBackgroundInput.val(extractColor($title, 'bg'));
|
||||
$lineHeightInput.val(parseFloat($title.css('line-height')));
|
||||
$('#fontSize').val(parseFloat($title.css('font-size')));
|
||||
$('#fontFamily').val($title.css('font-family'));
|
||||
$('#BgcolorCode').val(extractColor($title, 'bg'));
|
||||
$('#colorCodeTitle').val(extractColor($title, 'text'));
|
||||
$('#borderColorBg').val(extractColor(currentElement, 'border'))
|
||||
} else if (currentElement.data('type') === 'title') {
|
||||
$textOptions.show();
|
||||
$BoxOptions.hide();
|
||||
$imageOptions.hide();
|
||||
|
||||
const $title = currentElement.find('.title');
|
||||
$textContentInput.val($title.text().trim());
|
||||
$textColorInput.val(extractColor($title, 'text'));
|
||||
$textBackgroundInput.val(extractColor($title, 'bg'));
|
||||
$lineHeightInput.val(parseFloat($title.css('line-height')));
|
||||
$('#fontSize').val(parseFloat($title.css('font-size')));
|
||||
$('#fontFamily').val($title.css('font-family'));
|
||||
$('#BgcolorCode').val(extractColor($title, 'bg'));
|
||||
$('#colorCodeTitle').val(extractColor($title, 'text'));
|
||||
$('#borderColorBg').val(extractColor($title, 'bg'))
|
||||
} else if (currentElement.data('type') === 'background') {
|
||||
|
||||
} else {
|
||||
$imageOptions.show();
|
||||
$textOptions.hide();
|
||||
$BoxOptions.hide();
|
||||
|
||||
const $img = currentElement.find('img');
|
||||
|
||||
$imageURLInput.attr('src', $img.attr('src'));
|
||||
$imageUploadInput.val('');
|
||||
|
||||
const $logoImage = currentElement.find('img');
|
||||
$logoSizeInput.val($logoImage.width());
|
||||
$sizeValueSpan.text(`${$logoImage.width()}px`);
|
||||
}
|
||||
}
|
||||
|
||||
function applyChanges() {
|
||||
if (!currentElement) return;
|
||||
if (currentElement.data('type') === 'title') {
|
||||
updateTextStyles();
|
||||
} else if (currentElement.data('type') === 'image') {
|
||||
updateImage();
|
||||
} else if (currentElement.data('type') === 'background') {
|
||||
updateBgStyles()
|
||||
}
|
||||
saveCurrentState()
|
||||
$tabBar.hide();
|
||||
}
|
||||
|
||||
function updateTextStyles() {
|
||||
const $title = currentElement.find('h2');
|
||||
$title.text($textContentInput.val());
|
||||
updateClass($title, 'text', $textColorInput.val());
|
||||
updateClass($title, 'bg', $textBackgroundInput.val());
|
||||
}
|
||||
|
||||
function updateImage() {
|
||||
const $img = currentElement.find('img');
|
||||
$img.attr('src', $imageURLInput.val() || $img.attr('src'));
|
||||
}
|
||||
|
||||
function updateBgStyles() {
|
||||
updateClass(currentElement, 'bg', $('#changeInputBg').val());
|
||||
updateClass(currentElement, 'bg', $('#InputCodeBg').val());
|
||||
}
|
||||
|
||||
|
||||
function updateTextColor(color) {
|
||||
if (!currentElement) return;
|
||||
updateClass(currentElement.find('h2'), 'text', color);
|
||||
}
|
||||
|
||||
function updateBackgroundColor(color) {
|
||||
if (!currentElement) return;
|
||||
updateClass(currentElement.find('h2'), 'bg', color);
|
||||
}
|
||||
|
||||
function updateClass($element, type, color) {
|
||||
const className = type === 'text' ? `text-[${color}]` : `bg-[${color}]`;
|
||||
const regex = new RegExp(`^${type}-\\[#[0-9A-Fa-f]{3,6}\\]$`);
|
||||
$element.attr('class', function (i, c) {
|
||||
return c.split(' ').filter(cls => !regex.test(cls)).concat(className).join(' ');
|
||||
});
|
||||
}
|
||||
|
||||
function extractColor($element, type) {
|
||||
const regex = new RegExp(`${type}-\\[([#0-9A-Fa-f]+)\\]`);
|
||||
const match = $element.attr('class').match(regex);
|
||||
return match ? match[1] : '#000000';
|
||||
}
|
||||
|
||||
function formatText(command, value) {
|
||||
let $title = '';
|
||||
if (currentElement.data('type') === 'title' || currentElement.data('type') == 'box') {
|
||||
$title = currentElement.find('.title');
|
||||
} else {
|
||||
$title = currentElement;
|
||||
}
|
||||
switch (command) {
|
||||
case 'size':
|
||||
$title.css('font-size', `${value}px`);
|
||||
break;
|
||||
case 'bold':
|
||||
$title.toggleClass('font-bold');
|
||||
break;
|
||||
case 'italic':
|
||||
$title.toggleClass('italic');
|
||||
break;
|
||||
case 'underline':
|
||||
$title.toggleClass('underline');
|
||||
break;
|
||||
case 'line-through':
|
||||
$title.toggleClass('line-through');
|
||||
break;
|
||||
case 'justifyLeft':
|
||||
$title.removeClass('text-center text-right text-justify').addClass('text-left');
|
||||
break;
|
||||
case 'justifyCenter':
|
||||
$title.removeClass('text-left text-right text-justify').addClass('text-center');
|
||||
break;
|
||||
case 'justifyRight':
|
||||
$title.removeClass('text-left text-center text-justify').addClass('text-right');
|
||||
break;
|
||||
case 'justifyFull':
|
||||
$title.removeClass('text-left text-center text-right').addClass('text-justify');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function updateColorPicker(event, type) {
|
||||
const textColor = $("#textColor");
|
||||
const textCodeColor = $("#colorCodeTitle");
|
||||
const BgColor = $("#textBackground");
|
||||
let element = '';
|
||||
if (currentElement.data('type') === 'title') {
|
||||
element = currentElement.find('.title');
|
||||
|
||||
} else {
|
||||
element = currentElement;
|
||||
}
|
||||
|
||||
if (type === 'text') {
|
||||
const isValidHex = /^#([0-9A-F]{3}){1,2}$/i.test(textCodeColor.val());
|
||||
if (isValidHex) {
|
||||
textColor.val(textCodeColor.val());
|
||||
element.css('color', textCodeColor.val());
|
||||
} else {
|
||||
alert("Vui lòng nhập mã màu hợp lệ (ví dụ: #FF5733).");
|
||||
}
|
||||
} else if (type === 'background') {
|
||||
const isValidHex = /^#([0-9A-F]{3}){1,2}$/i.test($(event.target).val());
|
||||
if (isValidHex) {
|
||||
BgColor.val($(event.target).val());
|
||||
element.css('background', $(event.target).val());
|
||||
} else {
|
||||
alert("Vui lòng nhập mã màu hợp lệ (ví dụ: #FF5733).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function syncColorInputs(event, type) {
|
||||
const inputColorText = $('#colorCodeTitle');
|
||||
let inputBg = '';
|
||||
let Bg = '';
|
||||
if (currentElement.data('type') === 'title') {
|
||||
inputBg = $('#BgcolorCode');
|
||||
bg = $(currentElement).find('.title');
|
||||
} else {
|
||||
inputBg = $('#InputCodeBg');
|
||||
bg = $(currentElement);
|
||||
}
|
||||
|
||||
if (type == 'text') {
|
||||
inputColorText.val($(event.target).val());
|
||||
} else {
|
||||
inputBg.val($(event.target).val());
|
||||
bg.css('background', $(event.target).val());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function updatePosition(event, action) {
|
||||
$('.edit-position').removeClass('active')
|
||||
$(event.target).addClass('active');
|
||||
console.log(action)
|
||||
if (action == 'left') {
|
||||
currentElement.find('.title').css({ 'margin': 'auto auto auto 0', 'justify-content': 'start' });
|
||||
} else if (action == 'center') {
|
||||
currentElement.find('.title').css({ 'margin': '0 auto', 'justify-content': 'center' });
|
||||
} else if (action == 'right') {
|
||||
console.log('aaa', currentElement)
|
||||
currentElement.find('.title').css({ 'margin': 'auto 0 auto auto', 'justify-content': 'end' });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateSizeBox(type, value) {
|
||||
if (type == 'width') {
|
||||
currentElement.find('.title').css('width', value + 'px')
|
||||
} else if (type == 'height') {
|
||||
currentElement.find('.title').css('height', value + 'px')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateBoderRadius(type, key, value) {
|
||||
let element = '';
|
||||
if (key == 'background') {
|
||||
element = currentElement;
|
||||
} else if (key == 'text') {
|
||||
element = currentElement.find('.title');
|
||||
}
|
||||
|
||||
if (type == 'top-left') {
|
||||
element.css('border-top-left-radius', value + 'px');
|
||||
} else if (type == 'top-right') {
|
||||
element.css('border-top-right-radius', value + 'px');
|
||||
} else if (type == 'bottom-left') {
|
||||
element.css('border-bottom-left-radius', value + 'px');
|
||||
} else if (type == 'bottom-right') {
|
||||
element.css('border-bottom-right-radius', value + 'px');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateBorder(type, key, value) {
|
||||
let element = '';
|
||||
if (key == 'background') {
|
||||
element = currentElement;
|
||||
} else if (key == 'text') {
|
||||
element = currentElement.find('.title');
|
||||
}
|
||||
|
||||
if (type == 'border-width') {
|
||||
element.css('border-width', value + 'px');
|
||||
} else if (type == 'border-color') {
|
||||
element.css('border-color', value);
|
||||
} else if (type == 'border-style') {
|
||||
element.css('border-style', value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function saveCurrentState() {
|
||||
// Lưu HTML hiện tại của giao diện
|
||||
const currentHTML = document.documentElement.innerHTML;
|
||||
|
||||
// Nếu không ở cuối mảng (khi đã dùng nút back hoặc forward), loại bỏ các trạng thái phía sau
|
||||
if (currentStateIndex < historyStates.length - 1) {
|
||||
historyStates = historyStates.slice(0, currentStateIndex + 1);
|
||||
}
|
||||
|
||||
// Lưu trạng thái mới và cập nhật chỉ số trạng thái hiện tại
|
||||
historyStates.push(currentHTML);
|
||||
currentStateIndex++;
|
||||
}
|
||||
|
||||
|
||||
function goBack() {
|
||||
if (currentStateIndex > 0) {
|
||||
currentStateIndex--;
|
||||
document.documentElement.innerHTML = historyStates[currentStateIndex];
|
||||
}
|
||||
}
|
||||
|
||||
function goForward() {
|
||||
if (currentStateIndex < historyStates.length - 1) {
|
||||
currentStateIndex++;
|
||||
document.documentElement.innerHTML = historyStates[currentStateIndex];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user