Auto-save Draft Functionality
Periodically save form data automatically to prevent data loss if browser crashes or session expires.
onLoad Table: incident
#onLoad #auto-save #draft #localStorage #data-loss-prevention #user-experience
Script Code
JavaScript
1function onLoad() {
2 // Configuration
3 var autoSaveInterval = 120000; // Auto-save every 2 minutes (120000ms)
4 var storageKey = 'autosave_' + g_form.getTableName() + '_' + g_form.getUniqueValue();
5
6 // Skip auto-save for existing records that are already saved
7 // or if user is read-only
8 if (!g_form.isNewRecord() && !g_form.isModified()) {
9 return;
10 }
11
12 // Function to save form data to browser storage
13 function saveDraft() {
14 // Only save if form has been modified
15 if (!g_form.isModified()) {
16 return;
17 }
18
19 var draftData = {
20 timestamp: new Date().toISOString(),
21 table: g_form.getTableName(),
22 sys_id: g_form.getUniqueValue(),
23 fields: {}
24 };
25
26 // Get list of fields to save (exclude system fields)
27 var fieldsToSave = ['short_description', 'description', 'category',
28 'subcategory', 'priority', 'urgency', 'impact',
29 'assignment_group', 'assigned_to', 'work_notes'];
30
31 // Save each field value
32 fieldsToSave.forEach(function(fieldName) {
33 var value = g_form.getValue(fieldName);
34 if (value) {
35 draftData.fields[fieldName] = value;
36
37 // For reference fields, also save display value
38 if (g_form.getField(fieldName) &&
39 g_form.getField(fieldName).type === 'reference') {
40 draftData.fields[fieldName + '_display'] = g_form.getDisplayValue(fieldName);
41 }
42 }
43 });
44
45 // Save to localStorage
46 try {
47 localStorage.setItem(storageKey, JSON.stringify(draftData));
48 console.log('Draft auto-saved at ' + draftData.timestamp);
49
50 // Optional: Show subtle notification
51 g_form.addInfoMessage('Draft saved automatically');
52 setTimeout(function() {
53 g_form.clearMessages();
54 }, 2000);
55
56 } catch (e) {
57 console.error('Error saving draft:', e);
58 // localStorage might be full or disabled
59 }
60 }
61
62 // Function to restore draft
63 function restoreDraft() {
64 try {
65 var savedDraft = localStorage.getItem(storageKey);
66
67 if (savedDraft) {
68 var draftData = JSON.parse(savedDraft);
69
70 // Check if draft is recent (less than 24 hours old)
71 var draftAge = new Date() - new Date(draftData.timestamp);
72 var maxAge = 24 * 60 * 60 * 1000; // 24 hours
73
74 if (draftAge < maxAge) {
75 // Ask user if they want to restore
76 var draftDate = new Date(draftData.timestamp);
77 var message = 'A draft from ' + draftDate.toLocaleString() +
78 ' was found. Would you like to restore it?';
79
80 if (confirm(message)) {
81 // Restore each field
82 Object.keys(draftData.fields).forEach(function(fieldName) {
83 // Skip display value fields
84 if (fieldName.endsWith('_display')) {
85 return;
86 }
87
88 var value = draftData.fields[fieldName];
89 if (value && !g_form.getValue(fieldName)) {
90 g_form.setValue(fieldName, value);
91 }
92 });
93
94 g_form.addInfoMessage('Draft restored successfully');
95 }
96
97 // Clean up old draft
98 localStorage.removeItem(storageKey);
99 } else {
100 // Remove expired draft
101 localStorage.removeItem(storageKey);
102 }
103 }
104 } catch (e) {
105 console.error('Error restoring draft:', e);
106 }
107 }
108
109 // Function to clear draft
110 function clearDraft() {
111 try {
112 localStorage.removeItem(storageKey);
113 console.log('Draft cleared');
114 } catch (e) {
115 console.error('Error clearing draft:', e);
116 }
117 }
118
119 // Restore draft if exists (only for new records)
120 if (g_form.isNewRecord()) {
121 restoreDraft();
122 }
123
124 // Set up auto-save interval
125 var autoSaveTimer = setInterval(saveDraft, autoSaveInterval);
126
127 // Save before leaving page
128 window.addEventListener('beforeunload', function() {
129 saveDraft();
130 });
131
132 // Clear draft on successful submit
133 g_form.onSubmit(function() {
134 clearDraft();
135 });
136
137 // Add manual save button
138 // g_form.addInfoMessage('<a href="javascript:saveDraft()">Save draft now</a>');
139
140 console.log('Auto-save enabled. Interval: ' + (autoSaveInterval/1000) + ' seconds');
141}
How to Use
1. Create an onLoad Client Script on your table
2. Customize autoSaveInterval for your requirements
3. Update fieldsToSave array with fields you want to auto-save
4. Test with browser developer tools localStorage
5. Consider privacy/security implications of local storage
6. Add UI Page or banner to show draft status
7. Test restoration flow thoroughly
8. Clear old drafts periodically to avoid localStorage bloat
Related Scripts
Auto-populate Related Fields
Automatically populate fields when a reference field changes (e.g., populate caller's phone and email when caller is selected).
Conditional Mandatory Fields
Make fields mandatory based on the value of another field (e.g., require close notes only when state is Resolved).
Dynamic Field Visibility
Show or hide fields based on another field's value (e.g., show "Other reason" field only when user selects "Other" from dropdown).