i am building a form that saves as draft . i use the rest Api to insert form data and all works well . The only issue now is how to upload file.
My code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Offline Form with Draft Saving</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input, textarea, select {
width: 100%;
padding: 8px;
box-sizing: border-box;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
margin-right: 10px;
}
button:hover {
background-color: #45a049;
}
#status {
margin-top: 15px;
padding: 10px;
border-radius: 4px;
}
.online { background-color: #dff0d8; color: #3c763d; }
.offline { background-color: #f2dede; color: #a94442; }
.syncing { background-color: #d9edf7; color: #31708f; }
</style>
</head>
<body>
<h1>Offline-Capable Form</h1>
<div id="status" class="offline">Status: Checking connection...</div>
<form id="myForm">
<div class="form-group">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="message">Message:</label>
<textarea id="message" name="message" rows="5" required></textarea>
</div>
<div class="form-group">
<label for="priority">Priority:</label>
<select id="priority" name="priority">
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
</select>
</div>
<div class="form-group">
<label for="image">Upload Image:</label>
<input type="file" id="image" name="image" accept="image/*">
<img id="imagePreview" alt="Image Preview">
</div>
<button type="submit">Submit</button>
<button type="button" id="saveDraft">Save Draft</button>
<button type="button" id="loadDraft">Load Draft</button>
</form>
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('myForm');
const saveDraftBtn = document.getElementById('saveDraft');
const loadDraftBtn = document.getElementById('loadDraft');
const statusDiv = document.getElementById('status');
// Check online status
function updateOnlineStatus() {
if (navigator.onLine) {
statusDiv.textContent = 'Status: Online';
statusDiv.className = 'online';
// Try to sync any pending submissions
syncPendingSubmissions();
} else {
statusDiv.textContent = 'Status: Offline - Drafts will be saved locally';
statusDiv.className = 'offline';
}
}
// Initial check
updateOnlineStatus();
// Listen for online/offline events
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
// Save draft to localStorage
saveDraftBtn.addEventListener('click', function() {
const formData = {
name: form.name.value,
email: form.email.value,
message: form.message.value,
priority: form.priority.value,
image: form.image.value,
timestamp: new Date().toISOString()
};
localStorage.setItem('formDraft', JSON.stringify(formData));
statusDiv.textContent = 'Draft saved locally at ' + new Date().toLocaleTimeString();
statusDiv.className = 'online';
// Hide the message after 3 seconds
setTimeout(() => {
updateOnlineStatus();
}, 3000);
});
// Load draft from localStorage
loadDraftBtn.addEventListener('click', function() {
const draft = localStorage.getItem('formDraft');
if (draft) {
const formData = JSON.parse(draft);
form.name.value = formData.name || '';
form.email.value = formData.email || '';
form.message.value = formData.message || '';
form.image.value = formData.image || '';
form.priority.value = formData.priority || 'low';
statusDiv.textContent = 'Draft loaded from ' + new Date(formData.timestamp).toLocaleString();
statusDiv.className = 'online';
// Hide the message after 3 seconds
setTimeout(() => {
updateOnlineStatus();
}, 3000);
} else {
statusDiv.textContent = 'No draft found in local storage';
statusDiv.className = 'offline';
setTimeout(() => {
updateOnlineStatus();
}, 3000);
}
});
// Save pending submissions to localStorage when offline
function savePendingSubmission(formData) {
let pendingSubmissions = JSON.parse(localStorage.getItem('pendingSubmissions')) || [];
pendingSubmissions.push(formData);
localStorage.setItem('pendingSubmissions', JSON.stringify(pendingSubmissions));
}
// Sync pending submissions when coming online
function syncPendingSubmissions() {
const pendingSubmissions = JSON.parse(localStorage.getItem('pendingSubmissions')) || [];
if (pendingSubmissions.length > 0) {
statusDiv.textContent = 'Syncing ' + pendingSubmissions.length + ' pending submission(s)...';
statusDiv.className = 'syncing';
// Process each pending submission
pendingSubmissions.forEach((submission, index) => {
submitFormData(submission)
.then(() => {
// Remove successfully submitted item
const updatedPending = JSON.parse(localStorage.getItem('pendingSubmissions')) || [];
updatedPending.splice(index, 1);
localStorage.setItem('pendingSubmissions', JSON.stringify(updatedPending));
if (index === pendingSubmissions.length - 1) {
statusDiv.textContent = 'All pending submissions synced successfully!';
statusDiv.className = 'online';
setTimeout(updateOnlineStatus, 3000);
}
})
.catch(error => {
console.error('Failed to sync submission:', error);
statusDiv.textContent = 'Some submissions failed to sync. Will retry later.';
statusDiv.className = 'offline';
setTimeout(updateOnlineStatus, 3000);
});
});
}
}
// Submit form data to server
function submitFormData(formData) {
return new Promise((resolve, reject) => {
fetch('http://localhost/app/api/add/frmdata', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Success:', data);
resolve(data);
})
.catch(error => {
console.error('Error:', error);
reject(error);
});
});
}
// Form submission handler
form.addEventListener('submit', function(e) {
e.preventDefault();
const formData = {
name: form.name.value,
email: form.email.value,
message: form.message.value,
priority: form.priority.value,
image: form.image.value,
timestamp: new Date().toISOString()
};
if (navigator.onLine) {
// Submit directly if online
statusDiv.textContent = 'Submitting form...';
statusDiv.className = 'syncing';
submitFormData(formData)
.then(data => {
statusDiv.textContent = 'Form submitted successfully!';
statusDiv.className = 'online';
form.reset();
setTimeout(updateOnlineStatus, 3000);
})
.catch(error => {
statusDiv.textContent = 'Submission failed. Saved as draft.';
statusDiv.className = 'offline';
savePendingSubmission(formData);
setTimeout(updateOnlineStatus, 3000);
});
} else {
// Save as pending submission if offline
savePendingSubmission(formData);
statusDiv.textContent = 'Offline: Submission saved locally. Will sync when online.';
statusDiv.className = 'offline';
form.reset();
setTimeout(updateOnlineStatus, 3000);
}
});
// Check for drafts on page load
const draft = localStorage.getItem('formDraft');
if (draft) {
if (confirm('You have a saved draft. Would you like to load it?')) {
loadDraftBtn.click();
}
}
});
</script>
</body>
</html>