web-mooc/resources/views/admin/certificate/builder.blade.php
2026-01-23 15:10:51 +07:00

848 lines
36 KiB
PHP

<!DOCTYPE html>
<html>
<head>
<title>{{ get_phrase('Certificate') }}</title>
<link rel="stylesheet" type="text/css" href="{{ asset('assets/backend/vendors/bootstrap/bootstrap.min.css') }}" />
<link rel="stylesheet" href="{{ asset('assets/global/jquery-ui-themes-1.13.2/themes/base/jquery-ui.css') }}">
{{-- FlatIcons --}}
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-solid-rounded/css/uicons-solid-rounded.css') }}" />
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-bold-rounded/css/uicons-bold-rounded.css') }}" />
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-bold-straight/css/uicons-bold-straight.css') }}" />
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-regular-rounded/css/uicons-regular-rounded.css') }}" />
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/icons/uicons-thin-rounded/css/uicons-thin-rounded.css') }}" />
<link rel="stylesheet" type="text/css" href="{{ asset('assets/backend/css/style.css') }}">
{{-- Font Awesome untuk ikon tambahan --}}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script type="text/javascript" src="{{ asset('assets/backend/js/jquery-3.7.1.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/global/jquery-ui-1.13.2/jquery-ui.min.js') }}"></script>
<script src="{{ asset('assets/backend/vendors/bootstrap/bootstrap.bundle.min.js') }}"></script>
<style type="text/css">
body {
font-family: 'Inter', 'Segoe UI', Roboto, sans-serif;
background-color: #f8f9fa;
}
.draggable {
border: 2px dashed rgba(255, 255, 255, 0.8);
cursor: move;
background-color: #15b57e33;
top: 0;
transition: all 0.3s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.draggable:hover {
border-color: #15b57e;
box-shadow: 0 6px 12px rgba(21, 181, 126, 0.2);
}
.hidden-position:not(.certificate-layout-module) {
background-color: #ffd3d3 !important;
}
.resizeable-canvas {
width: 400px;
padding: 10px;
box-shadow: 1px 3px 11px -4px #565656;
border-radius: 5px;
}
.certificate-layout-module.resizeable-canvas {
padding: 0px !important;
}
.certificate-layout-module {
background-color: #fff;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
}
.sidebar {
position: fixed;
top: 0;
right: -350px;
bottom: 0;
z-index: 200;
background-color: #ffffff;
width: 350px;
height: 100%;
transition: right 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
box-shadow: -5px 0 25px rgba(0, 0, 0, 0.1);
}
.sidebar.open {
right: 0;
}
.sidebar-header {
width: 100%;
padding: 15px;
background: rgba(0, 17, 81, 1);
color: white;
}
.sidebar-toggle {
position: fixed;
top: 20px;
right: 20px;
z-index: 150;
background: rgba(0, 17, 81, 1);
padding: 10px;
border-radius: 50%;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
transition: transform 0.3s ease;
}
.sidebar-toggle:hover {
transform: scale(1.1);
}
.remove-item {
position: absolute;
top: -10px;
right: -10px;
background-color: #dc3545;
color: white;
border-radius: 50%;
padding: 4px;
height: 24px;
width: 24px;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
z-index: 10;
}
.remove-item:hover {
background-color: #c82333;
transform: scale(1.1);
}
i:not(.fas, .fa, .fab) {
line-height: 1.5em !important;
vertical-align: -0.14em !important;
display: inline-flex !important;
}
.dotted-background {
background-image: radial-gradient(circle, #afafaf 1px, transparent 1px);
background-size: 20px 20px;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
background-color: #f0f2f5;
width: 100%;
height: 100%;
padding: 30px;
}
.cursor-pointer {
cursor: pointer;
}
.sidebar-body {
height: calc(100% - 60px);
overflow-y: auto;
padding: 20px;
}
.font-family-option {
display: flex;
align-items: center;
padding: 8px 12px;
border-radius: 6px;
margin-bottom: 8px;
border: 1px solid #e0e0e0;
transition: all 0.2s ease;
cursor: pointer;
}
.font-family-option:hover {
background-color: #f8f9fa;
border-color: #667eea;
}
.font-family-option.active {
background-color: #e8eeff;
border-color: #667eea;
}
.font-family-preview {
font-size: 14px;
margin-left: 8px;
}
.badge {
margin: 2px;
padding: 6px 10px;
font-size: 12px;
font-weight: 500;
border-radius: 4px;
transition: all 0.2s ease;
cursor: pointer;
}
.badge:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.form-control, .form-select {
border-radius: 8px;
border: 1px solid #dee2e6;
padding: 10px 15px;
transition: all 0.3s ease;
}
.form-control:focus, .form-select:focus {
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.btn {
border-radius: 8px;
padding: 10px 20px;
font-weight: 500;
transition: all 0.3s ease;
}
.btn-ol-btn-light-primary {
background-color: #e8eeff;
color: #667eea;
border: 1px solid #c2d0ff;
}
.btn-ol-btn-light-primary:hover {
background-color: #d5deff;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
}
.btn-ol-btn-primary {
background: rgba(0, 17, 81, 1);
color: white;
border: none;
}
.btn-ol-btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.3);
}
.font-style-options {
display: flex;
gap: 10px;
margin-bottom: 15px;
}
.font-style-btn {
flex: 1;
padding: 8px;
border: 1px solid #dee2e6;
background: white;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
}
.font-style-btn:hover {
border-color: #667eea;
background-color: #f8f9fa;
}
.font-style-btn.active {
background-color: #667eea;
color: white;
border-color: #667eea;
}
.color-picker-container {
position: relative;
}
.color-preview {
width: 30px;
height: 30px;
border-radius: 4px;
border: 1px solid #dee2e6;
cursor: pointer;
}
.font-weight-slider {
width: 100%;
margin: 10px 0;
}
.text-decoration-options {
display: flex;
gap: 10px;
}
.text-decoration-btn {
flex: 1;
padding: 8px;
border: 1px solid #dee2e6;
background: white;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
text-align: center;
}
.text-decoration-btn:hover {
border-color: #667eea;
background-color: #f8f9fa;
}
.text-decoration-btn.active {
background-color: #667eea;
color: white;
border-color: #667eea;
}
.font-option-group {
background: #f8f9fa;
border-radius: 10px;
padding: 15px;
margin-bottom: 20px;
}
.font-option-title {
font-size: 14px;
font-weight: 600;
color: #495057;
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 8px;
}
</style>
</head>
<body>
<a onclick="$('.sidebar').addClass('open')" href="#" class="sidebar-toggle">
<i class="fas fa-sliders-h" style="color: white; font-size: 20px;"></i>
</a>
<div class="sidebar open">
<div class="sidebar-header border-bottom d-flex align-items-center">
<a class="btn text-white" href="#" onclick="$('.sidebar').removeClass('open')">
<i class="fas fa-chevron-right"></i>
</a>
<span class="ms-2 fw-bold">{{ get_phrase('Certificate Designer') }}</span>
<a class="ms-auto btn btn-sm btn-outline-light" href="{{ route('admin.certificate.settings') }}">
<i class="fas fa-arrow-left me-1"></i>{{ get_phrase('Back') }}
</a>
</div>
<div class="sidebar-body">
<div class="card border-0 shadow-sm mb-4">
<div class="card-body">
<h6 class="card-title d-flex align-items-center">
<i class="fas fa-code me-2"></i>{{ get_phrase('Available Variables') }}
</h6>
<div class="d-flex flex-wrap">
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_duration}')">{course_duration}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{certificate_id}')">{certificate_id}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{instructor_name}')">{instructor_name}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{student_name}')">{student_name}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_title}')">{course_title}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{number_of_lesson}')">{number_of_lesson}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{qr_code}')">{qr_code}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_completion_date}')">{course_completion_date}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{certificate_download_date}')">{certificate_download_date}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_level}')">{course_level}</span>
<span class="badge bg-primary cursor-pointer" onclick="addVariableToText('{course_language}')">{course_language}</span>
</div>
</div>
</div>
<div class="card border-0 shadow-sm" id="custom_elem_form">
<div class="card-body">
<h6 class="card-title d-flex align-items-center">
<i class="fas fa-plus-circle me-2"></i>{{ get_phrase('Add New Element') }}
</h6>
<form action="#">
<div class="font-option-group">
<div class="font-option-title">
<i class="fas fa-font"></i>{{ get_phrase('Text Content') }}
</div>
<div class="mb-3">
<label for="certificate_element_content" class="form-label">{{ get_phrase('Enter Text with variables') }}</label>
<textarea name="certificate_element_content"
placeholder="{{ get_phrase('Example: This certifies that {student_name} has completed {course_title}') }}"
id="certificate_element_content"
rows="3"
class="form-control"></textarea>
</div>
</div>
<div class="font-option-group">
<div class="font-option-title">
<i class="fas fa-palette"></i>{{ get_phrase('Font Styling') }}
</div>
<div class="mb-3">
<label for="font_family" class="form-label">{{ get_phrase('Font Family') }}</label>
<div id="font-family-options">
<!-- Font options will be populated by JavaScript -->
</div>
</div>
<div class="mb-3">
<label class="form-label">{{ get_phrase('Font Weight') }}</label>
<input type="range"
class="form-range font-weight-slider"
id="font_weight"
min="100"
max="900"
step="100"
value="400">
<div class="d-flex justify-content-between">
<small>Thin</small>
<small>Normal</small>
<small>Bold</small>
<small>Black</small>
</div>
</div>
<div class="mb-3">
<label class="form-label">{{ get_phrase('Font Style') }}</label>
<div class="font-style-options">
<button type="button" class="font-style-btn" data-style="normal">
<i class="fas fa-font"></i> Normal
</button>
<button type="button" class="font-style-btn" data-style="italic">
<i class="fas fa-italic"></i> Italic
</button>
<button type="button" class="font-style-btn" data-style="oblique">
<i class="fas fa-slash"></i> Oblique
</button>
</div>
</div>
<div class="mb-3">
<label class="form-label">{{ get_phrase('Text Decoration') }}</label>
<div class="text-decoration-options">
<button type="button" class="text-decoration-btn" data-decoration="none">
None
</button>
<button type="button" class="text-decoration-btn" data-decoration="underline">
<u>Underline</u>
</button>
<button type="button" class="text-decoration-btn" data-decoration="overline">
Overline
</button>
<button type="button" class="text-decoration-btn" data-decoration="line-through">
<s>Strike</s>
</button>
</div>
</div>
<div class="mb-3">
<label class="form-label">{{ get_phrase('Text Color') }}</label>
<div class="color-picker-container">
<input type="color"
id="text_color"
value="#000000"
style="position: absolute; opacity: 0; width: 30px; height: 30px; cursor: pointer;">
<div class="color-preview" id="color_preview" style="background-color: #000000;"></div>
</div>
</div>
<div class="mb-3">
<label for="font_size" class="form-label">{{ get_phrase('Font Size') }}: <span id="font_size_value">16</span>px</label>
<input type="range"
class="form-range"
id="font_size"
min="8"
max="72"
step="1"
value="16">
</div>
</div>
<div class="font-option-group">
<div class="font-option-title">
<i class="fas fa-text-height"></i>{{ get_phrase('Text Alignment') }}
</div>
<div class="mb-3">
<div class="d-flex gap-2">
<button type="button" class="btn btn-outline-secondary flex-fill" onclick="setTextAlignment('left')">
<i class="fas fa-align-left"></i>
</button>
<button type="button" class="btn btn-outline-secondary flex-fill" onclick="setTextAlignment('center')">
<i class="fas fa-align-center"></i>
</button>
<button type="button" class="btn btn-outline-secondary flex-fill" onclick="setTextAlignment('right')">
<i class="fas fa-align-right"></i>
</button>
<button type="button" class="btn btn-outline-secondary flex-fill" onclick="setTextAlignment('justify')">
<i class="fas fa-align-justify"></i>
</button>
</div>
</div>
</div>
<div class="mb-4">
<button type="button" class="btn ol-btn-light-primary w-100" onclick="addElemToCertificate()">
<i class="fas fa-plus me-2"></i>{{ get_phrase('Add Element') }}
</button>
</div>
<div class="mb-4">
<button type="button" class="btn ol-btn-primary w-100" onclick="saveTemplate()">
<i class="fas fa-save me-2"></i>{{ get_phrase('Save Template') }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div id="certificate_builder_content" class="builder dotted-background">
{{-- Common style for page builder start --}}
<style>
/* Import Google Fonts for certificate styling */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Pinyon+Script&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Italianno&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Miss+Fajardose&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Great+Vibes&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Dancing+Script:wght@400;500;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;0,800;0,900;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;500;600;700;800;900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@100;300;400;700;900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700;800&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700;900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;500;600;700;800;900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@100;200;300;400;500;600;700;800;900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Source+Serif+Pro:wght@200;300;400;600;700;900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400;500;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Tangerine:wght@400;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Alex+Brush&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Sacramento&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Parisienne&display=swap');
</style>
{{-- Common style for page builder END --}}
@if (get_settings('certificate_builder_content'))
@php
$htmlContent = get_settings('certificate_builder_content');
$newSrc = get_image(get_settings('certificate_template'));
$certificate_builder_content = preg_replace('/(<img[^>]*class=["\']certificate-template["\'][^>]*src=["\'])([^"\']*)(["\'])/i', '${1}' . $newSrc . '${3}', $htmlContent);
@endphp
{!! $certificate_builder_content !!}
@else
<div id="certificate-layout-module" class="certificate-layout-module resizeable-canvas draggable position-relative">
<img class="certificate-template w-100 h-100" src="{{ get_image(get_settings('certificate_template')) }}">
</div>
@endif
</div>
<script>
"use strict";
// Available fonts with categories
const fontOptions = [
{ name: 'Auto', value: 'auto', category: 'default' },
{ name: 'Inter', value: 'Inter, sans-serif', category: 'modern' },
{ name: 'Pinyon Script', value: 'Pinyon Script, cursive', category: 'elegant' },
{ name: 'Italianno', value: 'Italianno, cursive', category: 'script' },
{ name: 'Miss Fajardose', value: 'Miss Fajardose, cursive', category: 'script' },
{ name: 'Great Vibes', value: 'Great Vibes, cursive', category: 'script' },
{ name: 'Dancing Script', value: 'Dancing Script, cursive', category: 'script' },
{ name: 'Playfair Display', value: 'Playfair Display, serif', category: 'serif' },
{ name: 'Montserrat', value: 'Montserrat, sans-serif', category: 'modern' },
{ name: 'Roboto', value: 'Roboto, sans-serif', category: 'modern' },
{ name: 'Lato', value: 'Lato, sans-serif', category: 'modern' },
{ name: 'Open Sans', value: 'Open Sans, sans-serif', category: 'modern' },
{ name: 'Merriweather', value: 'Merriweather, serif', category: 'serif' },
{ name: 'Cinzel', value: 'Cinzel, serif', category: 'decorative' },
{ name: 'Raleway', value: 'Raleway, sans-serif', category: 'modern' },
{ name: 'Source Serif Pro', value: 'Source Serif Pro, serif', category: 'serif' },
{ name: 'Cormorant Garamond', value: 'Cormorant Garamond, serif', category: 'serif' },
{ name: 'Tangerine', value: 'Tangerine, cursive', category: 'script' },
{ name: 'Alex Brush', value: 'Alex Brush, cursive', category: 'script' },
{ name: 'Sacramento', value: 'Sacramento, cursive', category: 'script' },
{ name: 'Parisienne', value: 'Parisienne, cursive', category: 'script' }
];
// Current styling options
let currentFontStyle = 'normal';
let currentTextDecoration = 'none';
let currentTextAlign = 'left';
let currentTextColor = '#000000';
$(document).ready(function() {
initialize();
populateFontOptions();
setupEventListeners();
});
function populateFontOptions() {
const container = $('#font-family-options');
container.empty();
// Group fonts by category
const fontsByCategory = {};
fontOptions.forEach(font => {
if (!fontsByCategory[font.category]) {
fontsByCategory[font.category] = [];
}
fontsByCategory[font.category].push(font);
});
// Create options for each category
Object.keys(fontsByCategory).forEach(category => {
const categoryTitle = category.charAt(0).toUpperCase() + category.slice(1);
const categoryDiv = $(`<div class="mb-3"><small class="text-muted">${categoryTitle} Fonts</small></div>`);
fontsByCategory[category].forEach(font => {
const isActive = font.value === 'auto' ? 'active' : '';
const option = $(`
<div class="font-family-option ${isActive}" data-value="${font.value}">
<input type="radio" name="font_family" value="${font.value}"
id="font_family_${font.value.replace(/\s+/g, '_')}"
${font.value === 'auto' ? 'checked' : ''}>
<label for="font_family_${font.value.replace(/\s+/g, '_')}" class="ms-2 flex-grow-1">${font.name}</label>
<span class="font-family-preview" style="font-family: ${font.value}">Aa</span>
</div>
`);
categoryDiv.append(option);
});
container.append(categoryDiv);
});
// Add click event to font options
$('.font-family-option').click(function() {
$('.font-family-option').removeClass('active');
$(this).addClass('active');
$(this).find('input[type="radio"]').prop('checked', true);
});
}
function setupEventListeners() {
// Font size display
$('#font_size').on('input', function() {
$('#font_size_value').text($(this).val());
});
// Font style buttons
$('.font-style-btn').click(function() {
$('.font-style-btn').removeClass('active');
$(this).addClass('active');
currentFontStyle = $(this).data('style');
});
// Text decoration buttons
$('.text-decoration-btn').click(function() {
$('.text-decoration-btn').removeClass('active');
$(this).addClass('active');
currentTextDecoration = $(this).data('decoration');
});
// Color picker
$('#text_color').on('input', function() {
$('#color_preview').css('background-color', $(this).val());
currentTextColor = $(this).val();
});
// Initialize first button as active
$('.font-style-btn[data-style="normal"]').addClass('active');
$('.text-decoration-btn[data-decoration="none"]').addClass('active');
}
function addVariableToText(variable) {
const textarea = $('#certificate_element_content');
const currentValue = textarea.val();
const cursorPos = textarea[0].selectionStart;
const newValue = currentValue.substring(0, cursorPos) +
variable +
currentValue.substring(cursorPos);
textarea.val(newValue);
textarea.focus();
}
function setTextAlignment(alignment) {
currentTextAlign = alignment;
$('.btn-outline-secondary').removeClass('active');
$(`button[onclick="setTextAlignment('${alignment}')"]`).addClass('active');
}
function saveTemplate() {
var certificate_builder_content = $('#certificate_builder_content').html();
$.ajax({
type: 'POST',
url: "{{ route('admin.certificate.certificate.builder.update') }}",
data: {
certificate_builder_content: certificate_builder_content
},
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
success: function(response) {
$(location).attr('href', response);
console.log(response)
},
error: function(xhr) {
console.error('Error saving template:', xhr);
alert('Error saving template. Please try again.');
}
});
}
function addElemToCertificate() {
var font_family = $("input[type='radio'][name='font_family']:checked").val();
var font_size = $("#font_size").val();
var font_weight = $("#font_weight").val();
var certificate_element_content = $('#certificate_element_content').val();
// Generate unique ID for the element
var elementId = 'elem_' + Date.now() + Math.floor(Math.random() * 1000);
var certificateElem = `
<div id="${elementId}"
class="draggable resizeable-canvas"
style="
padding: 10px !important;
position: absolute;
font-size: ${font_size}px;
font-weight: ${font_weight};
font-style: ${currentFontStyle};
text-decoration: ${currentTextDecoration};
text-align: ${currentTextAlign};
color: ${currentTextColor};
top: 50px;
left: 50px;
min-width: 100px;
min-height: 40px;
font-family: ${font_family};
border-radius: 8px;
z-index: 5;
">
${certificate_element_content}
<div class="remove-item" onclick="$(this).parent().remove(); positionTracking(this.parentNode)">
<i class="fas fa-times"></i>
</div>
</div>`;
if (certificate_element_content.trim() !== '') {
$('#certificate-layout-module').append(certificateElem);
// Reset form
$('#certificate_element_content').val('');
$("#font_size").val(16);
$("#font_size_value").text('16');
$("#font_weight").val(400);
currentTextColor = '#000000';
$('#color_preview').css('background-color', '#000000');
$('#text_color').val('#000000');
// Reset to default font
$('.font-family-option').removeClass('active');
$('.font-family-option[data-value="auto"]').addClass('active').find('input').prop('checked', true);
initialize();
} else {
alert('Please enter some text content.');
}
}
function initialize() {
$(".draggable").draggable({
containment: "#certificate-layout-module",
cursor: "move",
scroll: false
});
$(".resizeable-canvas").resizable({
resize: function(event, ui) {
$(".draggable").draggable("disable");
positionTracking(this);
},
stop: function(event, ui) {
$(".draggable").draggable("enable");
positionTracking(this);
},
handles: "all",
minHeight: 30,
minWidth: 50
});
$(".draggable").on("dragstop", function(e, pos) {
positionTracking(this);
});
}
function positionTracking(e) {
var layoutCanvasOffset = $('#certificate-layout-module').offset();
var layoutCanvasRight = $('#certificate-layout-module').width() + layoutCanvasOffset.left;
var layoutCanvasBottom = $('#certificate-layout-module').height() + layoutCanvasOffset.top;
if ($(e).attr('id') != 'certificate-layout-module') {
var itemOffset = $(e).offset();
var itemRight = $(e).width() + itemOffset.left;
var itemBottom = $(e).height() + itemOffset.top;
if (
layoutCanvasOffset.left < itemOffset.left &&
layoutCanvasOffset.top < itemOffset.top &&
layoutCanvasRight > itemRight &&
layoutCanvasBottom > itemBottom
) {
$(e).removeClass('hidden-position');
$(e).css('border-color', 'rgba(21, 181, 126, 0.5)');
} else {
$(e).addClass('hidden-position');
$(e).css('border-color', '#ff6b6b');
}
} else {
var draggableItems = document.getElementsByClassName("draggable");
for (var i = 0; i < draggableItems.length; i++) {
var item = $(draggableItems.item(i));
if (item.attr('id') == 'certificate-layout-module') continue;
var itemOffset = item.offset();
var itemRight = item.width() + itemOffset.left;
var itemBottom = item.height() + itemOffset.top;
if (
layoutCanvasOffset.left < itemOffset.left &&
layoutCanvasOffset.top < itemOffset.top &&
layoutCanvasRight > itemRight &&
layoutCanvasBottom > itemBottom
) {
item.removeClass('hidden-position');
item.css('border-color', 'rgba(21, 181, 126, 0.5)');
} else {
item.addClass('hidden-position');
item.css('border-color', '#ff6b6b');
}
}
}
}
</script>
</body>
</html>