PageSourceSearch

https://jewishgen.org/JG/Scripts/FormUtils.js

js jewishgen.org collected 2026-09-24 09:02:44 UTC 11,352 bytes, 400 lines download raw bytes

1// FormUtils.js
2// ~~~~~~~~~~~~
3// Warren Blatt
4// May 2012, Dec 2012
5// ValidateMT() added by Michael Tobias 6 May 2015
6// Path: /JG/Scripts/FormUtils.js
7//
8// Includes functions:
9//   * DisableForm (fo)
10//   * EnableForm (fo)
11//   * doSubmit (fo)
12//   * OneClick_EnableForm (fo)
13//   * OneClick_DisableForm (fo)
14//   * GetSubmitButton (fo)
15//   * OneClick_doSubmit (fo)
16//   * CreateOverlay (fo)
17//   * EnableForms()
18//   * OneClick_Init (fo)
19//   * addEvent (eventTarget, eventType, eventHandler)
20//   * removeEvent (eventTarget, eventType, eventHandler)
21//   * validateMT()
22//
23// **************************************************************************
24
25// Disables all form controls.
26function DisableForm (fo)
27{
28  var count = fo.elements.length;
29  for (i=0; i<count; i++) 
30    {
31      fo.elements[i].disabled = true; 
32    } 
33}
34
35// Enables all form controls.
36function EnableForm (fo)
37{
38  var count = fo.elements.length;
39  for (i=0; i<count; i++) 
40    {
41      fo.elements[i].disabled = false; 
42    } 
43}
44
45
46// Submits form, then disables (to prevent repeat clicks).
47function doSubmit(fo)
48  {
49    fo.submit();
50    DisableForm(fo);
51    document.getElementById("SearchButton").value = "Request has been submitted";
52  }
53
54
55// **************************************************************************
56// "OneClick" multi-click disabling.  When a <FORM>'s class is "OneClick".
57
58
59// Re-enables form submission:
60function OneClick_EnableForm (fo)
61{
62  // Re-enable FORM submission clicks:
63  fo.setAttribute('ClickedOnce', 'No');
64
65  // Enable the FORM's "Submit" button:
66  submit_button = GetSubmitButton (fo)
67  if (submit_button) 
68    { submit_button.disabled = false; } 
69}
70
71
72// Disables form submission:
73function OneClick_DisableForm (fo)
74{
75  // Disable the FORM's "Submit" button:
76  submit_button = GetSubmitButton (fo)
77
78  if (submit_button) 
79    { 
80      submit_button.disabled = true;
81
82      // Re-label the button, if it has a certain ID: 
83      if ( submit_button.id == "SearchButton" )
84        { submit_button.value = "Request has been submitted"; }
85    } 
86}
87
88
89// Utility: Gets the FORM's "Submit" button:
90function GetSubmitButton (fo)
91{
92  // Find the FORM's "Submit" button:
93  var foElems = fo.elements;
94  for (i=0; i<foElems.length; i++) 
95    {
96      if (foElems[i].type.toLowerCase() == 'submit') 
97        { return foElems[i]; }
98    } 
99
100  // Here if not found:
101  return undefined;
102}
103
104
105// OnSubmit event handler for a <FORM>.
106// Submits form, then disables (to prevent repeat clicks).
107function OneClick_doSubmit(fo)
108{
109  // Find the <FORM> object.  This can be complicated...
110  // In IE, the event handler function's parameter is the Event object.
111  if ( fo.srcElement )
112    { fo = fo.srcElement; }
113
114  if ( this.tagName == "FORM" )
115    { fo = this; }
116  
117  
118  // Should do any field content validation HERE, before submitting.
119  //   var valid = validateForm(fo);
120  //   if ( ! valid ) return false;
121  // Also, don't neglect the possibility of HTML5 form validation.
122  // see Form.checkValidity() method:  
123  // * http://www.w3.org/TR/html5/constraints.html#constraint-validation
124  // * "JavaScript: The Definitive Guide" (6th ed.), pp. 929-932, 454-455.
125  // . . .
126
127
128  // Check if form has already been submitted, and return if so.
129  clicked = fo.getAttribute('ClickedOnce'); 
130  if ( clicked == 'Yes' ) 
131    { return false; }
132    
133  // Disable subsequent clicks:
134  fo.setAttribute('ClickedOnce', 'Yes');
135  
136  
137  // Submit the form to the server.
138  fo.submit();
139  
140
141  // Disable the FORM's "Submit" button:
142  OneClick_DisableForm(fo);
143
144
145  // Put an "overlay" <DIV> over the <FORM>:
146  var div = CreateOverlay (fo);
147
148  // Now that the overlay <DIV> has been created, with an initial style,
149  //   define a 'target' style for the overlay, using CSS3 transitions.
150  //   The transition timings are defined in CreateOverlay().
151  //   Make the overlay <DIV> grow, from the center outwards.
152
153  // Get the FORM's coordinate position:
154  // *** Put this into a small subroutine?? *** 
155  //    (Can a subr return TWO values?  Or maybe an array/set?)
156  var offsetTrail = fo;
157  var offsetLeft = 0;
158  var offsetTop = 0;
159  while (offsetTrail)
160    {
161      offsetLeft += offsetTrail.offsetLeft;
162      offsetTop  += offsetTrail.offsetTop;
163      offsetTrail = offsetTrail.offsetParent;
164    }
165
166  // Get the FORM's height and width:
167  hei = fo.offsetHeight;
168  wid = fo.offsetWidth;
169
170  // Set the <DIV>'s NEW target position and size:
171  div.style.top    = offsetTop.toString() + "px";
172  div.style.left   = offsetLeft.toString() + "px";
173  div.style.width  = wid.toString() + "px";
174  div.style.height = hei.toString() + "px";
175
176  div.style.opacity = "0.9";  /* transparency */
177  div.style.filter  = "alpha(opacity=60)"; /* transparency for IE */
178
179  div.style.background = "#646C24";     /* dark green */
180  div.style.borderRadius = "50px";      /* CSS3 rounded corners */
181  div.style.transform    = "scale(2)";
182  div.style.WebkitTransform = "scale(2)";
183
184  
185  // Return a boolean value of "true", indicating success.
186  return true;
187}
188
189
190// Creates an overlay <DIV> over a <FORM>.
191function CreateOverlay (fo)
192{
193  // Get the FORM's coordinate position:
194  var offsetTrail = fo;
195  var offsetLeft  = 0;
196  var offsetTop   = 0;
197  while (offsetTrail)
198    {
199      offsetLeft += offsetTrail.offsetLeft;
200      offsetTop  += offsetTrail.offsetTop;
201      offsetTrail = offsetTrail.offsetParent;
202    }
203
204  // Get the FORM's height and width:
205  hei = fo.offsetHeight;
206  wid = fo.offsetWidth;
207
208  // Create a <DIV> element:
209  var newdiv = document.createElement('div');
210  newdiv.id = 'overlayDiv';
211
212  newdiv.style.position = "absolute";
213  newdiv.style.zIndex = "100";
214
215  // Set the <DIV>'s position and size.
216  //   The initial size is the size of the "waiting" GIF image. 
217  //   The coordinates should be centered on the FORM.
218  newdiv.style.width  = "32px";
219  newdiv.style.height = "32px";
220
221  var init_top  = offsetTop  + (hei / 2) - 16;
222  var init_left = offsetLeft + (wid / 2) - 16;
223  newdiv.style.top  = init_top.toString() + "px";
224  newdiv.style.left = init_left.toString() + "px";
225    
226  // Add some CSS styling:
227  newdiv.style.borderRadius = "10px";  /* CSS3 rounded corners */
228  newdiv.style.cursor = "wait";
229  newdiv.style.textAlign = "center";
230
231  //newdiv.style.color = "white";
232  newdiv.style.background = "#134B7D";  /* dark blue */
233  newdiv.style.boxShadow = "4px 4px 4px 4px gray";
234
235  newdiv.style.opacity = "0.15";  /* transparency */
236  newdiv.style.filter  = "alpha(opacity=15)"; /* IE transparency */
237   
238  trans_style = "top 2s, left 2s, height 2s, width 2s, opacity 20s, background 2s 10s";
239  newdiv.style.transition       = trans_style + ", border-radius 5s 20s, transform 20s 30s";
240  newdiv.style.MsTransition     = trans_style + ", border-radius 5s 20s, -ms-transform 20s 30s";
241  newdiv.style.WebkitTransition = trans_style + ", border-radius 5s 20s, -webkit-transform 20s 30s";
242
243
244  // Set the DIV's visible contents:
245  //   (We use a <TABLE> only so that the image can be fully centered).
246  newdiv.innerHTML = '<TABLE WIDTH="100%" height="100%">'+
247    '<tr><td align="center">'+
248    '<IMG SRC="/JG/HomePage/images/waiting.gif"'+
249    ' WIDTH="32" HEIGHT="32" BORDER="0">'+
250    '</td></tr></TABLE>';
251
252  // Attach the DIV to the page:
253  document.body.appendChild(newdiv);
254  
255  // Return the overlay <DIV> object:
256  return newdiv;
257}
258
259
260// Enables form controls for all "OneClick" FORMs:
261//   A window.OnLoad event.
262function EnableForms()
263{
264  var forms = document.forms;
265  for (var i = 0; i < forms.length; i++)
266    { 
267      if ( forms[i].className == "OneClick" )
268        { OneClick_EnableForm (forms[i]); }
269    }
270}
271
272
273// Initializes the "Allow only one click" for a form.
274function OneClick_Init (fo)
275{
276  // Set the OnSubmit event handler of the FORM to be "OneClick_doSubmit()":
277  addEvent (fo, 'submit', OneClick_doSubmit);
278
279  // Initialize the FORM's custom "ClickedOnce" attribute:
280  fo.setAttribute('ClickedOnce', 'No');
281}
282
283
284// **************************************************************************
285//
286// Utilities: Generic "Add/Reomve Event Handler" Functions.
287//   [From "JavaScript Cookbook" (2010), p. 122.]
288function addEvent (eventTarget, eventType, eventHandler)
289{
290  if (eventTarget.addEventListener)
291    { 
292      eventTarget.addEventListener(eventType, eventHandler, false); 
293    }
294  else if (eventTarget.attachEvent)
295    {
296      eventType = "on" + eventType;
297      eventTarget.attachEvent(eventType, eventHandler);
298    }
299  else
300    {
301      eventTarget["on" + eventType] = eventHandler;
302    }
303}
304  
305function removeEvent (eventTarget, eventType, eventHandler) 
306{
307   if (eventTarget.removeEventListener) 
308     {
309      eventTarget.removeEventListener(eventType, eventHandler, false);
310     } 
311   else if (eventTarget.detachEvent) 
312     {
313      eventType = "on" + eventType;
314      eventTarget.detachEvent(eventType, eventHandler);
315     } 
316   else 
317     {
318      eventTarget["on" + eventType] = null;
319     }
320}
321
322
323// **************************************************************************
324// Here is the initialization which needs to be run to 
325//   set the event handlers for all <FORM>s of class "OneClick".
326
327var OneClickUsed = false;
328var forms = document.forms;
329for (var i = 0; i < forms.length; i++)
330  { 
331    if ( forms[i].className == "OneClick" )
332      { 
333        OneClick_Init (forms[i]); 
334        OneClickUsed = true;
335      }
336  }
337
338if ( OneClickUsed ) 
339  {
340    // Add EnableForms() to the Window BODY's OnLoad event:
341    addEvent (window, 'load', EnableForms);
342
343    // Pre-load the animated gif "waiting" image:  (THIS DOESN'T HELP IN FIREFOX)
344    var wait_img = new Image(32,32);
345    // wait_img.src = "https://www.jewishgen.org/JG/HomePage/images/waiting.gif";
346    wait_img.src = "/JG/HomePage/images/waiting.gif";
347  }
348  
349// **************************************************************************
350// Here is a basic validation script to ensure at least 'proper' 3 characters are entered
351// in our standard 4 variable allcountry search forms
352function validateMT() {
353
354	var xtotal="";
355
356	for (y = 1; y <= 4; y++)
357	{
358    		var x = document.forms["f"]["srch"+y].value;
359    		var letters = /^[A-Za-zacelnószzACELNÓSZZ*?]+$/;
360
361
362   		x= x.replace(/\*/g, "");
363   		x= x.replace(/\?/g, "");
364   		x= x.replace(/\%/g, "");
365   		x= x.replace(/\#/g, "");
366   		x= x.replace(/\ /g, "");
367
368   		if (x.length <3 && x.length >0)
369		{
370   		  	alert("At least 3 letters required");
371    		 	return false;
372		}
373		xtotal=xtotal+x;
374	}
375
376	if ("!"+xtotal+"!" == "!!")
377	{
378   		alert("Input Required");
379   		return false;
380	}
381
382	if(!xtotal.match(letters))
383	{
384     		alert("Invalid Characters Entered");
385	     	return false;
386	}
387
388    document.forms["f"].submit();
389    var count = document.forms["f"].elements.length;
390    for (i=0; i<count; i++)
391    {
392      document.forms["f"].elements[i].disabled = true;
393    }
394    document.getElementById("SearchButton").value = "Request has been submitted";
395
396    return true;
397
398}
399
400// **************************************************************************

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.