680 lines
30 KiB
HTML
680 lines
30 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if template %}Edit{% else %}Create{% endif %} Consent Template{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<link href="{% static 'assets/plugins/summernote/summernote-lite.min.css' %}" rel="stylesheet" />
|
|
<link href="{% static 'assets/plugins/bootstrap-tagsinput/bootstrap-tagsinput.css' %}" rel="stylesheet" />
|
|
<style>
|
|
.form-section {
|
|
background: white;
|
|
border-radius: 15px;
|
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
|
|
padding: 2rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
.section-header {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
padding: 1rem 1.5rem;
|
|
border-radius: 10px;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.variable-builder {
|
|
background: #f8f9fa;
|
|
border-radius: 10px;
|
|
padding: 1.5rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.variable-item {
|
|
background: white;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 8px;
|
|
padding: 1rem;
|
|
margin-bottom: 1rem;
|
|
position: relative;
|
|
}
|
|
.variable-tag {
|
|
background: #007bff;
|
|
color: white;
|
|
padding: 0.25rem 0.5rem;
|
|
border-radius: 15px;
|
|
font-size: 0.75rem;
|
|
cursor: pointer;
|
|
margin: 0.25rem;
|
|
display: inline-block;
|
|
}
|
|
.variable-tag:hover {
|
|
background: #0056b3;
|
|
}
|
|
.template-preview {
|
|
border: 2px dashed #dee2e6;
|
|
border-radius: 10px;
|
|
padding: 2rem;
|
|
background: #f8f9fa;
|
|
min-height: 300px;
|
|
}
|
|
.preview-toggle {
|
|
position: sticky;
|
|
top: 20px;
|
|
z-index: 100;
|
|
}
|
|
.form-tabs {
|
|
border-bottom: 2px solid #e9ecef;
|
|
margin-bottom: 2rem;
|
|
}
|
|
.form-tabs .nav-link {
|
|
border: none;
|
|
border-bottom: 3px solid transparent;
|
|
color: #6c757d;
|
|
font-weight: 500;
|
|
padding: 1rem 1.5rem;
|
|
}
|
|
.form-tabs .nav-link.active {
|
|
color: #007bff;
|
|
border-bottom-color: #007bff;
|
|
background: none;
|
|
}
|
|
.auto-save-indicator {
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
z-index: 1050;
|
|
padding: 0.5rem 1rem;
|
|
border-radius: 25px;
|
|
font-size: 0.875rem;
|
|
transition: all 0.3s ease;
|
|
}
|
|
.content-editor {
|
|
min-height: 400px;
|
|
}
|
|
.template-settings {
|
|
background: #e3f2fd;
|
|
border-radius: 10px;
|
|
padding: 1.5rem;
|
|
}
|
|
.quick-insert {
|
|
background: #fff3cd;
|
|
border-radius: 10px;
|
|
padding: 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.insert-button {
|
|
background: #ffc107;
|
|
border: none;
|
|
color: #212529;
|
|
padding: 0.375rem 0.75rem;
|
|
border-radius: 20px;
|
|
font-size: 0.875rem;
|
|
margin: 0.25rem;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
}
|
|
.insert-button:hover {
|
|
background: #e0a800;
|
|
transform: translateY(-1px);
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div id="content" class="app-content">
|
|
<!-- Page Header -->
|
|
<div class="d-flex align-items-center mb-4">
|
|
<div>
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'patients:patient_list' %}">Patients</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'patients:consent_template_list' %}">Consent Templates</a></li>
|
|
<li class="breadcrumb-item active">{% if template %}Edit{% else %}Create{% endif %} Template</li>
|
|
</ol>
|
|
<h1 class="page-header mb-0">
|
|
<i class="fas fa-{% if template %}edit{% else %}plus{% endif %} me-3"></i>
|
|
{% if template %}Edit Template{% else %}Create New Template{% endif %}
|
|
</h1>
|
|
<p class="text-muted mb-0">{% if template %}Modify the existing consent template{% else %}Create a new consent form template for patient care{% endif %}</p>
|
|
</div>
|
|
<div class="ms-auto">
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-secondary" onclick="saveDraft()">
|
|
<i class="fas fa-save me-2"></i>Save Draft
|
|
</button>
|
|
<button type="button" class="btn btn-info" onclick="previewTemplate()">
|
|
<i class="fas fa-eye me-2"></i>Preview
|
|
</button>
|
|
<a href="{% url 'patients:consent_template_list' %}" class="btn btn-secondary">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Auto-save Indicator -->
|
|
<div id="autoSaveIndicator" class="auto-save-indicator bg-success text-white d-none">
|
|
<i class="fas fa-check me-2"></i>Saved
|
|
</div>
|
|
|
|
<form id="templateForm" method="post" enctype="multipart/form-data">
|
|
{% csrf_token %}
|
|
|
|
<!-- Form Tabs -->
|
|
<ul class="nav nav-tabs form-tabs" role="tablist">
|
|
<li class="nav-item">
|
|
<a class="nav-link active" data-bs-toggle="tab" href="#basicInfo" role="tab">
|
|
<i class="fas fa-info-circle me-2"></i>Basic Information
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-bs-toggle="tab" href="#contentEditor" role="tab">
|
|
<i class="fas fa-edit me-2"></i>Content Editor
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-bs-toggle="tab" href="#variables" role="tab">
|
|
<i class="fas fa-code me-2"></i>Variables
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-bs-toggle="tab" href="#settings" role="tab">
|
|
<i class="fas fa-cog me-2"></i>Settings
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-bs-toggle="tab" href="#preview" role="tab">
|
|
<i class="fas fa-eye me-2"></i>Preview
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content">
|
|
<!-- Basic Information Tab -->
|
|
<div class="tab-pane fade show active" id="basicInfo" role="tabpanel">
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-info-circle me-2"></i>Template Information
|
|
</h5>
|
|
</div>
|
|
|
|
<div class="row g-3">
|
|
<div class="col-md-8">
|
|
<label class="form-label">Template Name <span class="text-danger">*</span></label>
|
|
<input type="text" class="form-control" name="name" value="{{ template.name|default:'' }}" required>
|
|
<div class="form-text">Enter a descriptive name for this consent template</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Version</label>
|
|
<input type="text" class="form-control" name="version" value="{{ template.version|default:'1.0' }}">
|
|
<div class="form-text">Template version number</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label">Description</label>
|
|
<textarea class="form-control" name="description" rows="3" placeholder="Describe the purpose and usage of this template">{{ template.description|default:'' }}</textarea>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Category <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="category" required>
|
|
<option value="">Select Category</option>
|
|
<option value="general" {% if template.category == 'general' %}selected{% endif %}>General Consent</option>
|
|
<option value="surgical" {% if template.category == 'surgical' %}selected{% endif %}>Surgical Procedures</option>
|
|
<option value="anesthesia" {% if template.category == 'anesthesia' %}selected{% endif %}>Anesthesia</option>
|
|
<option value="research" {% if template.category == 'research' %}selected{% endif %}>Research Participation</option>
|
|
<option value="treatment" {% if template.category == 'treatment' %}selected{% endif %}>Treatment Consent</option>
|
|
<option value="discharge" {% if template.category == 'discharge' %}selected{% endif %}>Discharge Instructions</option>
|
|
<option value="privacy" {% if template.category == 'privacy' %}selected{% endif %}>Privacy & Data</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Language <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="language" required>
|
|
<option value="">Select Language</option>
|
|
<option value="en" {% if template.language == 'en' %}selected{% endif %}>English</option>
|
|
<option value="ar" {% if template.language == 'ar' %}selected{% endif %}>Arabic</option>
|
|
<option value="ur" {% if template.language == 'ur' %}selected{% endif %}>Urdu</option>
|
|
<option value="hi" {% if template.language == 'hi' %}selected{% endif %}>Hindi</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Status</label>
|
|
<select class="form-select" name="status">
|
|
<option value="draft" {% if template.status == 'draft' %}selected{% endif %}>Draft</option>
|
|
<option value="active" {% if template.status == 'active' %}selected{% endif %}>Active</option>
|
|
<option value="under_review" {% if template.status == 'under_review' %}selected{% endif %}>Under Review</option>
|
|
<option value="archived" {% if template.status == 'archived' %}selected{% endif %}>Archived</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label">Tags</label>
|
|
<input type="text" class="form-control" name="tags" value="{{ template.tags|join:',' }}" data-role="tagsinput" placeholder="Add tags separated by commas">
|
|
<div class="form-text">Add relevant tags to help organize and search templates</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Content Editor Tab -->
|
|
<div class="tab-pane fade" id="contentEditor" role="tabpanel">
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-edit me-2"></i>Template Content
|
|
</h5>
|
|
</div>
|
|
|
|
<!-- Quick Insert Buttons -->
|
|
<div class="quick-insert">
|
|
<h6 class="mb-2">
|
|
<i class="fas fa-magic me-2"></i>Quick Insert
|
|
</h6>
|
|
<button type="button" class="insert-button" onclick="insertText('{{patient_name}}')">Patient Name</button>
|
|
<button type="button" class="insert-button" onclick="insertText('{{patient_id}}')">Patient ID</button>
|
|
<button type="button" class="insert-button" onclick="insertText('{{date}}')">Date</button>
|
|
<button type="button" class="insert-button" onclick="insertText('{{doctor_name}}')">Doctor Name</button>
|
|
<button type="button" class="insert-button" onclick="insertText('{{procedure_name}}')">Procedure Name</button>
|
|
<button type="button" class="insert-button" onclick="insertText('{{hospital_name}}')">Hospital Name</button>
|
|
<button type="button" class="insert-button" onclick="insertText('{{signature_date}}')">Signature Date</button>
|
|
<button type="button" class="insert-button" onclick="insertText('{{witness_name}}')">Witness Name</button>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<label class="form-label">Template Content <span class="text-danger">*</span></label>
|
|
<textarea id="contentEditor" name="content" class="form-control content-editor">{{ template.content|default:'' }}</textarea>
|
|
<div class="form-text">Use the rich text editor to create your consent form content. Insert variables using the buttons above.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Variables Tab -->
|
|
<div class="tab-pane fade" id="variables" role="tabpanel">
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-code me-2"></i>Template Variables
|
|
</h5>
|
|
</div>
|
|
|
|
<div class="variable-builder">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<h6 class="mb-0">Variable Manager</h6>
|
|
<button type="button" class="btn btn-primary btn-sm" onclick="addVariable()">
|
|
<i class="fas fa-plus me-1"></i>Add Variable
|
|
</button>
|
|
</div>
|
|
|
|
<div id="variablesList">
|
|
<!-- Variables will be dynamically added here -->
|
|
</div>
|
|
|
|
<div class="mt-3">
|
|
<h6>Available Variables:</h6>
|
|
<div id="availableVariables">
|
|
<span class="variable-tag" onclick="insertVariable('patient_name')">{{patient_name}}</span>
|
|
<span class="variable-tag" onclick="insertVariable('patient_id')">{{patient_id}}</span>
|
|
<span class="variable-tag" onclick="insertVariable('date')">{{date}}</span>
|
|
<span class="variable-tag" onclick="insertVariable('doctor_name')">{{doctor_name}}</span>
|
|
<span class="variable-tag" onclick="insertVariable('procedure_name')">{{procedure_name}}</span>
|
|
<span class="variable-tag" onclick="insertVariable('hospital_name')">{{hospital_name}}</span>
|
|
<span class="variable-tag" onclick="insertVariable('signature_date')">{{signature_date}}</span>
|
|
<span class="variable-tag" onclick="insertVariable('witness_name')">{{witness_name}}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Settings Tab -->
|
|
<div class="tab-pane fade" id="settings" role="tabpanel">
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-cog me-2"></i>Template Settings
|
|
</h5>
|
|
</div>
|
|
|
|
<div class="template-settings">
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" name="requires_signature" id="requiresSignature" {% if template.requires_signature %}checked{% endif %}>
|
|
<label class="form-check-label" for="requiresSignature">
|
|
Requires Digital Signature
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" name="requires_witness" id="requiresWitness" {% if template.requires_witness %}checked{% endif %}>
|
|
<label class="form-check-label" for="requiresWitness">
|
|
Requires Witness Signature
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" name="is_mandatory" id="isMandatory" {% if template.is_mandatory %}checked{% endif %}>
|
|
<label class="form-check-label" for="isMandatory">
|
|
Mandatory Template
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" name="allow_modifications" id="allowModifications" {% if template.allow_modifications %}checked{% endif %}>
|
|
<label class="form-check-label" for="allowModifications">
|
|
Allow Content Modifications
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Expiry Period (Days)</label>
|
|
<input type="number" class="form-control" name="expiry_days" value="{{ template.expiry_days|default:'' }}" min="1" max="365">
|
|
<div class="form-text">Leave blank for no expiry</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Reminder Days</label>
|
|
<input type="number" class="form-control" name="reminder_days" value="{{ template.reminder_days|default:'' }}" min="1" max="30">
|
|
<div class="form-text">Days before expiry to send reminder</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label">Legal Disclaimer</label>
|
|
<textarea class="form-control" name="legal_disclaimer" rows="3" placeholder="Enter any legal disclaimer or additional terms">{{ template.legal_disclaimer|default:'' }}</textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Preview Tab -->
|
|
<div class="tab-pane fade" id="preview" role="tabpanel">
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-eye me-2"></i>Template Preview
|
|
</h5>
|
|
</div>
|
|
|
|
<div class="preview-toggle mb-3">
|
|
<div class="btn-group" role="group">
|
|
<input type="radio" class="btn-check" name="previewMode" id="previewFormatted" checked>
|
|
<label class="btn btn-outline-primary" for="previewFormatted">
|
|
<i class="fas fa-file-alt me-1"></i>Formatted
|
|
</label>
|
|
<input type="radio" class="btn-check" name="previewMode" id="previewPrint">
|
|
<label class="btn btn-outline-secondary" for="previewPrint">
|
|
<i class="fas fa-print me-1"></i>Print View
|
|
</label>
|
|
<input type="radio" class="btn-check" name="previewMode" id="previewMobile">
|
|
<label class="btn btn-outline-info" for="previewMobile">
|
|
<i class="fas fa-mobile-alt me-1"></i>Mobile
|
|
</label>
|
|
</div>
|
|
<button type="button" class="btn btn-success ms-2" onclick="updatePreview()">
|
|
<i class="fas fa-sync me-1"></i>Update Preview
|
|
</button>
|
|
</div>
|
|
|
|
<div id="templatePreview" class="template-preview">
|
|
<div class="text-center text-muted py-5">
|
|
<i class="fas fa-eye fa-3x mb-3"></i>
|
|
<h6>Template Preview</h6>
|
|
<p>Click "Update Preview" to see how your template will look</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="form-section">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="saveDraft()">
|
|
<i class="fas fa-save me-2"></i>Save as Draft
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="validateTemplate()">
|
|
<i class="fas fa-check-circle me-2"></i>Validate
|
|
</button>
|
|
</div>
|
|
<div>
|
|
<a href="{% url 'patients:consent_template_list' %}" class="btn btn-secondary me-2">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-save me-2"></i>{% if template %}Update{% else %}Create{% endif %} Template
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script src="{% static 'assets/plugins/summernote/summernote-lite.min.js' %}"></script>
|
|
<script src="{% static 'assets/plugins/bootstrap-tagsinput/bootstrap-tagsinput.min.js' %}"></script>
|
|
|
|
<script>
|
|
let autoSaveTimer;
|
|
let variableCounter = 0;
|
|
|
|
$(document).ready(function() {
|
|
// Initialize Summernote
|
|
$('#contentEditor').summernote({
|
|
height: 400,
|
|
toolbar: [
|
|
['style', ['style']],
|
|
['font', ['bold', 'underline', 'clear']],
|
|
['fontname', ['fontname']],
|
|
['color', ['color']],
|
|
['para', ['ul', 'ol', 'paragraph']],
|
|
['table', ['table']],
|
|
['insert', ['link', 'picture', 'video']],
|
|
['view', ['fullscreen', 'codeview', 'help']]
|
|
],
|
|
callbacks: {
|
|
onChange: function(contents, $editable) {
|
|
scheduleAutoSave();
|
|
}
|
|
}
|
|
});
|
|
|
|
// Initialize tags input
|
|
$('[data-role="tagsinput"]').tagsinput({
|
|
trimValue: true,
|
|
confirmKeys: [13, 44], // Enter and comma
|
|
focusClass: 'focus'
|
|
});
|
|
|
|
// Auto-save functionality
|
|
$('#templateForm input, #templateForm select, #templateForm textarea').on('input change', function() {
|
|
scheduleAutoSave();
|
|
});
|
|
|
|
// Load existing variables if editing
|
|
{% if template.variables %}
|
|
{% for variable in template.variables %}
|
|
addVariable('{{ variable.name }}', '{{ variable.description }}', '{{ variable.type }}', '{{ variable.default_value }}');
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
// Preview mode toggle
|
|
$('input[name="previewMode"]').change(function() {
|
|
updatePreview();
|
|
});
|
|
});
|
|
|
|
function scheduleAutoSave() {
|
|
clearTimeout(autoSaveTimer);
|
|
autoSaveTimer = setTimeout(function() {
|
|
saveDraft(true);
|
|
}, 5000); // Auto-save after 5 seconds of inactivity
|
|
}
|
|
|
|
function saveDraft(isAutoSave = false) {
|
|
const formData = new FormData($('#templateForm')[0]);
|
|
formData.append('save_as_draft', 'true');
|
|
|
|
$.ajax({
|
|
url: window.location.href,
|
|
method: 'POST',
|
|
data: formData,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(response) {
|
|
if (response.success) {
|
|
showAutoSaveIndicator(isAutoSave ? 'Auto-saved' : 'Draft saved');
|
|
}
|
|
},
|
|
error: function() {
|
|
if (!isAutoSave) {
|
|
alert('Error saving draft.');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function showAutoSaveIndicator(message) {
|
|
const indicator = $('#autoSaveIndicator');
|
|
indicator.html('<i class="fas fa-check me-2"></i>' + message);
|
|
indicator.removeClass('d-none');
|
|
setTimeout(function() {
|
|
indicator.addClass('d-none');
|
|
}, 3000);
|
|
}
|
|
|
|
function insertText(text) {
|
|
$('#contentEditor').summernote('editor.insertText', text);
|
|
}
|
|
|
|
function insertVariable(variableName) {
|
|
const variableText = '{{' + variableName + '}}';
|
|
$('#contentEditor').summernote('editor.insertText', variableText);
|
|
}
|
|
|
|
function addVariable(name = '', description = '', type = 'text', defaultValue = '') {
|
|
variableCounter++;
|
|
const variableHtml = `
|
|
<div class="variable-item" id="variable-${variableCounter}">
|
|
<div class="row g-3">
|
|
<div class="col-md-3">
|
|
<label class="form-label">Variable Name</label>
|
|
<input type="text" class="form-control" name="variables[${variableCounter}][name]" value="${name}" placeholder="e.g., patient_age">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Type</label>
|
|
<select class="form-select" name="variables[${variableCounter}][type]">
|
|
<option value="text" ${type === 'text' ? 'selected' : ''}>Text</option>
|
|
<option value="number" ${type === 'number' ? 'selected' : ''}>Number</option>
|
|
<option value="date" ${type === 'date' ? 'selected' : ''}>Date</option>
|
|
<option value="boolean" ${type === 'boolean' ? 'selected' : ''}>Yes/No</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Description</label>
|
|
<input type="text" class="form-control" name="variables[${variableCounter}][description]" value="${description}" placeholder="Variable description">
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Actions</label>
|
|
<div>
|
|
<button type="button" class="btn btn-outline-danger btn-sm" onclick="removeVariable(${variableCounter})">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label">Default Value</label>
|
|
<input type="text" class="form-control" name="variables[${variableCounter}][default_value]" value="${defaultValue}" placeholder="Optional default value">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
$('#variablesList').append(variableHtml);
|
|
}
|
|
|
|
function removeVariable(id) {
|
|
$(`#variable-${id}`).remove();
|
|
}
|
|
|
|
function updatePreview() {
|
|
const formData = new FormData($('#templateForm')[0]);
|
|
const previewMode = $('input[name="previewMode"]:checked').attr('id');
|
|
|
|
formData.append('preview_mode', previewMode);
|
|
formData.append('action', 'preview');
|
|
|
|
$.ajax({
|
|
url: '{% url "patients:consent_template_preview" %}',
|
|
method: 'POST',
|
|
data: formData,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(response) {
|
|
$('#templatePreview').html(response);
|
|
},
|
|
error: function() {
|
|
$('#templatePreview').html('<div class="alert alert-danger">Error generating preview</div>');
|
|
}
|
|
});
|
|
}
|
|
|
|
function validateTemplate() {
|
|
const formData = new FormData($('#templateForm')[0]);
|
|
formData.append('action', 'validate');
|
|
|
|
$.ajax({
|
|
url: window.location.href,
|
|
method: 'POST',
|
|
data: formData,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(response) {
|
|
if (response.valid) {
|
|
alert('Template validation successful!');
|
|
} else {
|
|
alert('Validation errors:\n' + response.errors.join('\n'));
|
|
}
|
|
},
|
|
error: function() {
|
|
alert('Error validating template.');
|
|
}
|
|
});
|
|
}
|
|
|
|
function previewTemplate() {
|
|
updatePreview();
|
|
$('a[href="#preview"]').tab('show');
|
|
}
|
|
|
|
// Form submission
|
|
$('#templateForm').on('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
// Validate required fields
|
|
const requiredFields = ['name', 'category', 'language'];
|
|
let isValid = true;
|
|
|
|
requiredFields.forEach(function(field) {
|
|
const input = $(`[name="${field}"]`);
|
|
if (!input.val().trim()) {
|
|
input.addClass('is-invalid');
|
|
isValid = false;
|
|
} else {
|
|
input.removeClass('is-invalid');
|
|
}
|
|
});
|
|
|
|
if (!isValid) {
|
|
alert('Please fill in all required fields.');
|
|
return;
|
|
}
|
|
|
|
// Submit form
|
|
this.submit();
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|