Files
form-generator/templates/form.html
T

147 lines
4.8 KiB
HTML

{% extends "_layout.html" %}
{% block title %}{{ form_title }}{% endblock %}
{% block content %}
<div class="form-container">
<h1>{{ form_title }}</h1>
<form id="form-gen" action="submit" method="POST" autocomplete="off">
{% for f in fields %}
{% if let Some(html) = f.html_before %}{{ html | safe }}{% endif %}
<div class="field">
{% match f.widget() %}
{% when FieldWidget::Checkbox %}
<label for="{{ f.name }}" class="checkbox-label">
<input id="{{ f.name }}" name="{{ f.name }}" type="checkbox" value="true">
<div class="label-content">
<span class="label-title">{{ f.title }}</span>
<span class="desc checkbox-desc">{{ f.description }}</span>
</div>
</label>
{% when FieldWidget::Textarea %}
<label for="{{ f.name }}">
<span class="label-title">{{ f.title }}</span>
<span class="desc">{{ f.description }}</span>
</label>
<textarea id="{{ f.name }}" name="{{ f.name }}" rows="10" placeholder="{{ f.title|lower }}"></textarea>
{% when FieldWidget::Select with (options) %}
<label for="{{ f.name }}">
<span class="label-title">{{ f.title }}</span>
<span class="desc">{{ f.description }}</span>
</label>
<select id="{{ f.name }}" name="{{ f.name }}">
<option value="">Select an option</option>
{% for opt in options %}
<option value="{{ opt }}">{{ opt }}</option>
{% endfor %}
</select>
{% when FieldWidget::Input with (input_type) %}
<label for="{{ f.name }}">
<span class="label-title">{{ f.title }}</span>
<span class="desc">{{ f.description }}</span>
</label>
<input id="{{ f.name }}" name="{{ f.name }}" type="{{ input_type }}" placeholder="{{ f.title|lower }}">
{% endmatch %}
</div>
{% if let Some(html) = f.html_after %}{{ html | safe }}{% endif %}
{% endfor %}
<div class="submit-container">
<button type="submit">{{ submit_button }}</button>
</div>
</form>
</div>
<div id="status-modal" class="modal-overlay">
<div class="modal-content">
<h2 id="modal-title">Status</h2>
<p id="modal-text"></p>
<button class="modal-close-btn" onclick="closeModal()">OK</button>
</div>
</div>
<script>
const form = document.getElementById('form-gen');
const modal = document.getElementById('status-modal');
const modalTitle = document.getElementById('modal-title');
const modalText = document.getElementById('modal-text');
const STORAGE_KEY = 'form_generator_draft';
// Load Draft
function loadDraft() {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return;
try {
const data = JSON.parse(raw);
Object.keys(data).forEach(key => {
const input = form.elements[key];
if (!input) return;
if (input.type === 'checkbox') input.checked = data[key] === "true";
else input.value = data[key];
});
} catch (e) {}
}
// Save Draft
function saveDraft() {
const formData = new FormData(form);
const data = {};
formData.forEach((value, key) => data[key] = value);
form.querySelectorAll('input[type="checkbox"]').forEach(cb => {
data[cb.name] = cb.checked ? "true" : "false";
});
localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
}
function showModal(title, message, isError = false) {
modalTitle.innerText = title;
modalText.innerText = message;
modalTitle.className = isError ? 'error-title' : 'success-title';
modal.classList.add('active');
}
function closeModal() {
modal.classList.remove('active');
}
form.addEventListener('submit', async (e) => {
e.preventDefault();
const submitBtn = form.querySelector('button[type="submit"]');
const originalBtnText = submitBtn.innerText;
submitBtn.disabled = true;
submitBtn.innerText = "Submitting...";
try {
const response = await fetch(form.action, {
method: 'POST',
body: new URLSearchParams(new FormData(form)),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
});
if (response.ok) {
localStorage.removeItem(STORAGE_KEY);
form.reset();
showModal("{{ success_message }}", "", false);
} else {
showModal("{{ error_message }}", "", true);
}
} catch (err) {
showModal("{{ error_message }}", err, true);
} finally {
submitBtn.disabled = false;
submitBtn.innerText = originalBtnText;
}
});
form.addEventListener('input', saveDraft);
window.addEventListener('DOMContentLoaded', loadDraft);
</script>
{% endblock %}