PageSourceSearch

https://www.flikvlooi.co.za/js/beforeUnload.r40242.js

js flikvlooi.co.za collected 2026-10-04 03:37:31 UTC 6,596 bytes, 224 lines download raw bytes

1// $Id: beforeUnload.js 27849 2017-11-13 14:21:10Z warren $
2// Functions to handle prompting when user navigates away from an unsaved form
3
4// Declare global variables
5var beforeUnloadFired = false;
6var keepaliveCount = 0;
7var isSubmit = false;  // should be set to "true" in form's "onSubmit" handler (prevent prompts when submitting a form)
8var keepAliveTimer = 0; // Records time from the second last keepAliveLimit is started
9var warningAlertTimer = 2400; // 40 minutes = 2400 seconds
10
11// Get a form object for the form we wish to check
12function getFormToCheck () {
13	if (typeof window.formToCheck == 'string' && document.forms[window.formToCheck]) {
14		return document.forms[window.formToCheck];
15	}
16	
17	return document.forms[0];
18}
19
20// Cycle through all form fields, and return as soon as a changed field has been detected
21function hasFormChanged (form) {
22	var changed = false;
23	var ignoreFormField = "ignoreFieldDefaultValueChanged";
24
25	if (form) {
26		var fields = form.elements;
27		
28		for (var i = 0; !changed && i < fields.length; i++) {
29			if (fields[i].nodeName == "FIELDSET" || fields[i].nodeName == "LABEL" || multipleClasses("check", fields[i], ignoreFormField)) {
30				// filter fieldset and label elements (label elements are part of elements array in BlackBerry OS 5.x, and undesired), and fields with attached className 'ignoreFieldDefaultValueChanged'
31				continue;
32			}
33			changed = hasFieldChanged(fields[i]);
34			if ((debug = 0) && changed) {
35				alert(fields[i].name + " has changed.");
36			}
37		}
38	}
39	
40	return changed;
41}
42
43// Detect if a particular form field value or selection has changed from a load-time default
44function hasFieldChanged (formElement) {
45	switch (formElement.type.toLowerCase()) {
46		case 'text':
47		case 'textarea':
48		case 'password':
49		case 'number':
50		case 'date':
51		case 'color':
52		case 'range':
53		case 'month':
54		case 'week':
55		case 'time':
56		case 'datetime':
57		case 'datetime-local':
58		case 'email':
59		case 'search':
60		case 'tel':
61		case 'url':
62			if (formElement.value != formElement.defaultValue) {
63				return true;
64			}
65			break;
66		case 'radio':
67		case 'checkbox':
68			if (formElement.checked != formElement.defaultChecked) {
69				return true;
70			}
71			break;
72		
73		case 'select-one':
74		case 'select-multiple':
75			var i;
76			var hasDefaultValue = false;
77			for (i = 0; i < formElement.options.length; i++) {
78				if (formElement.options[i].defaultSelected) {
79					hasDefaultValue = true;
80					i = formElement.options.length;
81				}
82			}
83			
84			for (i = 0; i < formElement.options.length; i++) {
85				if (hasDefaultValue) {
86					if (formElement.options[i].selected != formElement.options[i].defaultSelected) {
87						return true;
88					}
89				} else if (formElement.options[i].selected && i != 0) {
90					return true;
91				}
92			}
93			break;
94	}
95	
96	return false;
97}
98
99// Keep a session alive by making an Ajax call at regular intervals
100function keepAlive (options) {
101	var nowDate = Math.round(new Date().getTime() / 1000).toString();
102	var formToCheck = getFormToCheck();
103
104	if (typeof links != 'undefined' && typeof links["help_keepAlive"] != 'undefined') {
105		var defaults = {
106			keepaliveLimit: 3,
107			url: links["help_keepAlive"],
108			method: 'get',
109			async: true,
110			data: { date: nowDate },
111			headers: { Accept: 'application/json' }
112		};
113
114		// override default options
115		if (typeof options != 'undefined') {
116			for (var key in defaults) {
117				if (!options.hasOwnProperty(key)) {
118					options[key] = defaults[key];
119				}
120			}
121		} else {
122			options = defaults;
123		}
124		
125		if (!hasFormChanged(formToCheck)) {
126			// reset counter if nothing has changed in the form
127			keepaliveCount = 0;
128			return false;
129		}
130
131		var keepaliveLimitReached = false;
132		if (typeof jQuery != 'undefined') {
133			// if jQuery is available
134			$.ajax(options)
135			.done(function(data, textStatus, transport) {
136				var contentType = transport.getResponseHeader('Content-Type') || '';
137				if (contentType.indexOf('application/json') !== -1) {
138					json = {};
139					$.extend(json, jQuery.parseJSON(transport.responseText) || {});
140				}
141			});
142			if (options.keepaliveLimit != 0 && keepaliveCount == options.keepaliveLimit - 1) {
143				keepaliveLimitReached = true;
144			}
145		} else if ((options.keepaliveLimit == 0 && keepaliveCount == 0) || (options.keepaliveLimit != 0 && keepaliveCount == options.keepaliveLimit - 1)) {
146			// if jQuery is not available
147			keepaliveLimitReached = true;
148		}
149		keepaliveCount++;
150
151		// This timer is required so that we can alert users when their session is about to end.
152		if (options.keepaliveLimit != 0 && keepaliveCount == (options.keepaliveLimit - 1)) {
153			var keepaliveAlert = setInterval(function () {
154				keepAliveTimer++;
155				
156				if (keepAliveTimer >= warningAlertTimer) {
157					alert(valStrings["keepaliveAlert"]);
158					clearInterval(keepaliveAlert);
159				}
160			}, 1000);
161		}
162
163		if (keepaliveLimitReached && typeof keepaliveID != 'undefined') {
164			// clears the current interval after keepaliveLimit has been reached
165			clearInterval(keepaliveID);
166			return false;
167		}
168	} else {
169		keepaliveCount = 0;
170		return false;
171	}
172}
173
174// Event handler function for "onBeforeUnload" & "onUnload" events
175function interceptUnload (e) {
176	if (!isSubmit) {
177		var formToCheck = getFormToCheck();
178		
179		if (hasFormChanged(formToCheck)) {
180			if (typeof e == 'undefined') {
181				e = window.event;
182			}
183			
184			if (typeof buttonToFocus == 'string' && formToCheck.elements[buttonToFocus]) {
185				formToCheck.elements[buttonToFocus].focus();
186			} else if (typeof buttonToFocus == 'string' && document.getElementById(buttonToFocus)) {
187				document.getElementById(buttonToFocus).focus();
188			} else {
189				// guess by iterating over the form's elements, in reverse, for efficiency
190				for (var i = formToCheck.elements.length - 1; i >= 0; i--) {
191					if (formToCheck.elements[i].type.toLowerCase() == 'submit') {
192						formToCheck.elements[i].focus();
193						break;
194					}
195				}
196			}
197			
198			if (e.type == 'beforeunload') {
199				// where possible prompt user, attempting to show custom text where supported
200				beforeUnloadFired = true;
201				e.returnValue = valStrings["unloadPrompt"];  // Firefox (< 4.0 see ), IE
202				return valStrings["unloadPrompt"];  // Webkit, Safari, Chrome etc.
203			} else if (!beforeUnloadFired) {
204				// just notify user as a fallback
205				alert(valStrings["unloadPrompt"]);
206				return true;
207			}
208		}
209	}
210}
211
212if (typeof jQuery != 'undefined') {
213	$(window).unload(function(e) {
214		return interceptUnload(e);
215	});
216	$(window).on('beforeunload', function(e){ 
217		return interceptUnload(e);
218	});
219} else {
220	// fallback
221	window.onunload = interceptUnload;
222	window.onbeforeunload = interceptUnload;
223}
224

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.