html5forms-rails 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +11 -0
  3. data/README.md +208 -0
  4. data/Rakefile +49 -0
  5. data/VERSION +1 -0
  6. data/demos/html5-form-demo.html +79 -0
  7. data/html5forms-rails.gemspec +142 -0
  8. data/lib/html5forms.rb +6 -0
  9. data/vendor/assets/images/colorpicker/blank.gif +0 -0
  10. data/vendor/assets/images/colorpicker/colorpicker_background.png +0 -0
  11. data/vendor/assets/images/colorpicker/colorpicker_hex.png +0 -0
  12. data/vendor/assets/images/colorpicker/colorpicker_hsb_b.png +0 -0
  13. data/vendor/assets/images/colorpicker/colorpicker_hsb_h.png +0 -0
  14. data/vendor/assets/images/colorpicker/colorpicker_hsb_s.png +0 -0
  15. data/vendor/assets/images/colorpicker/colorpicker_indic.gif +0 -0
  16. data/vendor/assets/images/colorpicker/colorpicker_overlay.png +0 -0
  17. data/vendor/assets/images/colorpicker/colorpicker_rgb_b.png +0 -0
  18. data/vendor/assets/images/colorpicker/colorpicker_rgb_g.png +0 -0
  19. data/vendor/assets/images/colorpicker/colorpicker_rgb_r.png +0 -0
  20. data/vendor/assets/images/colorpicker/colorpicker_select.gif +0 -0
  21. data/vendor/assets/images/colorpicker/colorpicker_submit.png +0 -0
  22. data/vendor/assets/images/colorpicker/custom_background.png +0 -0
  23. data/vendor/assets/images/colorpicker/custom_hex.png +0 -0
  24. data/vendor/assets/images/colorpicker/custom_hsb_b.png +0 -0
  25. data/vendor/assets/images/colorpicker/custom_hsb_h.png +0 -0
  26. data/vendor/assets/images/colorpicker/custom_hsb_s.png +0 -0
  27. data/vendor/assets/images/colorpicker/custom_indic.gif +0 -0
  28. data/vendor/assets/images/colorpicker/custom_rgb_b.png +0 -0
  29. data/vendor/assets/images/colorpicker/custom_rgb_g.png +0 -0
  30. data/vendor/assets/images/colorpicker/custom_rgb_r.png +0 -0
  31. data/vendor/assets/images/colorpicker/custom_submit.png +0 -0
  32. data/vendor/assets/images/colorpicker/select.png +0 -0
  33. data/vendor/assets/images/colorpicker/select2.png +0 -0
  34. data/vendor/assets/images/colorpicker/slider.png +0 -0
  35. data/vendor/assets/images/h5f/form_validation.png +0 -0
  36. data/vendor/assets/images/html5form-shim/asterisk.png +0 -0
  37. data/vendor/assets/images/html5form-shim/down.png +0 -0
  38. data/vendor/assets/images/html5form-shim/fail.png +0 -0
  39. data/vendor/assets/images/html5form-shim/ok.png +0 -0
  40. data/vendor/assets/images/html5forms/jscolor/arrow.gif +0 -0
  41. data/vendor/assets/images/html5forms/jscolor/cross.gif +0 -0
  42. data/vendor/assets/images/html5forms/jscolor/hs.png +0 -0
  43. data/vendor/assets/images/html5forms/jscolor/hv.png +0 -0
  44. data/vendor/assets/images/html5forms/slider/slider-1.png +0 -0
  45. data/vendor/assets/images/html5forms/slider/slider-disabled-1.png +0 -0
  46. data/vendor/assets/images/html5forms/slider/slider-disabled.png +0 -0
  47. data/vendor/assets/images/html5forms/slider/slider.png +0 -0
  48. data/vendor/assets/javascripts/colorpicker.js +484 -0
  49. data/vendor/assets/javascripts/colorpicker.min.js +9 -0
  50. data/vendor/assets/javascripts/h5f.js +328 -0
  51. data/vendor/assets/javascripts/h5f.min.js +4 -0
  52. data/vendor/assets/javascripts/html5forms/EventHelpers.min.js +15 -0
  53. data/vendor/assets/javascripts/html5forms/autocomplete.min.js +1 -0
  54. data/vendor/assets/javascripts/html5forms/cssQuery-p.min.js +6 -0
  55. data/vendor/assets/javascripts/html5forms/dev/EventHelpers.js +486 -0
  56. data/vendor/assets/javascripts/html5forms/dev/autocomplete.js +387 -0
  57. data/vendor/assets/javascripts/html5forms/dev/cssQuery-p.js +6 -0
  58. data/vendor/assets/javascripts/html5forms/dev/html5.js +121 -0
  59. data/vendor/assets/javascripts/html5forms/dev/html5Forms.js +892 -0
  60. data/vendor/assets/javascripts/html5forms/dev/html5Widgets.js +1417 -0
  61. data/vendor/assets/javascripts/html5forms/dev/jscolor.js +840 -0
  62. data/vendor/assets/javascripts/html5forms/dev/slider.js +797 -0
  63. data/vendor/assets/javascripts/html5forms/dev/timer.js +137 -0
  64. data/vendor/assets/javascripts/html5forms/dev/visibleIf.js +1100 -0
  65. data/vendor/assets/javascripts/html5forms/html5.min.js +2 -0
  66. data/vendor/assets/javascripts/html5forms/html5Forms.min.js +1 -0
  67. data/vendor/assets/javascripts/html5forms/html5Widgets.min.js +20 -0
  68. data/vendor/assets/javascripts/html5forms/jscolor.min.js +10 -0
  69. data/vendor/assets/javascripts/html5forms/slider.min.js +25 -0
  70. data/vendor/assets/javascripts/html5forms/timer.min.js +1 -0
  71. data/vendor/assets/javascripts/html5forms/visibleIf.min.js +19 -0
  72. data/vendor/assets/javascripts/html5forms.fallback.js +115 -0
  73. data/vendor/assets/javascripts/html5forms.fallback.min.js +11 -0
  74. data/vendor/assets/javascripts/jquery.html5form-shim.js +402 -0
  75. data/vendor/assets/javascripts/jquery.html5form.min.js +4 -0
  76. data/vendor/assets/javascripts/jquery.placehold.min.js +7 -0
  77. data/vendor/assets/javascripts/ui.spinner.js +649 -0
  78. data/vendor/assets/javascripts/ui.spinner.min.js +7 -0
  79. data/vendor/assets/javascripts/webforms2/webforms2-msie.js +1 -0
  80. data/vendor/assets/javascripts/webforms2/webforms2-p.js +14 -0
  81. data/vendor/assets/javascripts/webforms2/webforms2.js +14 -0
  82. data/vendor/assets/javascripts/webforms2/webforms2_src.js +3195 -0
  83. data/vendor/assets/stylesheets/colorpicker.css +161 -0
  84. data/vendor/assets/stylesheets/h5f.css +86 -0
  85. data/vendor/assets/stylesheets/html5form-shim.css +109 -0
  86. data/vendor/assets/stylesheets/html5forms/number.css +35 -0
  87. data/vendor/assets/stylesheets/html5forms/slider.css +169 -0
  88. data/vendor/assets/stylesheets/html5forms/slider_ie.css +41 -0
  89. data/vendor/assets/stylesheets/html5forms/visibleIf.css +23 -0
  90. data/vendor/assets/stylesheets/html5forms.layout.css +116 -0
  91. data/vendor/assets/stylesheets/ui.spinner.css +3 -0
  92. data/vendor/assets/stylesheets/webforms2.css +42 -0
  93. metadata +221 -0
@@ -0,0 +1,1100 @@
1
+ /*
2
+ * This notice must be untouched at all times.
3
+ *
4
+ * visibleIf.js - a cross browser form field manager that hides and shows
5
+ * form fields depending on the values of other form fields.
6
+ *
7
+ * Version 1.0 released Feb 21, 2009
8
+ * Version 2.0 (this release) released June 20, 2010. Features new
9
+ * rules engine originally developed for HTML5Widgets.js and HTML5 custom
10
+ * data- attribute support.
11
+ *
12
+ * Written by: Zoltan Hawryluk.
13
+ *
14
+ * Latest release available at http://www.useragentman.com/
15
+ *
16
+ * released under the MIT License:
17
+ * http://www.opensource.org/licenses/mit-license.php
18
+ */
19
+
20
+ var visibleIf = new function(){
21
+ var me = this;
22
+
23
+ var formInputCache = new Array();
24
+ var changedInput = null;
25
+
26
+ var visibleIfNodes;
27
+ var mandatoryNodes;
28
+ var varRe = /\s([a-zA-Z][a-zA-Z0-9\.]*)\s/g;
29
+ var operatorRe = /\s*(~|!=|==|>={0,1}|<={0,1})\s*/g;
30
+ var leftBkRe = /\(/g;
31
+ var rightBkRe = /\)/g;
32
+ var reRe = /~ \"([^\"]*)\"/g;
33
+ var equalsRe = / == /g;
34
+ var quotedStringRe = /"[^"]*"/g;
35
+ var quotedStringOneOnlyRe = /"[^"]*"/;
36
+ var placeHolderString = '_pLaCeHoLdEr_';
37
+ var placeHolderRe = new RegExp(placeHolderString);
38
+
39
+ var nodesWithEventsAttached = new Array();
40
+
41
+ var inputsToClear;
42
+
43
+ var req = null;
44
+
45
+ var nameCounter = 0;
46
+ var CSSHelpers, StringHelpers, XMLHelpers, DOMHelpers;
47
+ /*
48
+ * Things to look into:
49
+ *
50
+ * I don't think you need the options.isPageLoad checks inside
51
+ * setFormElementsInside() since we are setting doClear accordingly.
52
+ */
53
+ me.init = function(reset){
54
+ if (EventHelpers.hasPageLoadHappened(arguments) && !reset) {
55
+ return;
56
+ }
57
+
58
+ visibleIfNodes = CSSHelpers.getElementsByClassName(document, 'visibleIf');
59
+ mandatoryNodes = CSSHelpers.getElementsByClassName(document, 'mandatoryIf');
60
+
61
+ removeDisabledNodes();
62
+ me.refreshPage({
63
+ isPageLoad: true
64
+ });
65
+ setMandatoryStates();
66
+ setEvents();
67
+ //strutsHelpers.populateDynamicFormElements();
68
+ }
69
+
70
+ function removeDisabledNodes(){
71
+
72
+ for (var i = 0; i < visibleIfNodes.length; i++) {
73
+ var node = visibleIfNodes[i];
74
+
75
+ var els = getAllFormElementsIn(node)
76
+
77
+ for (var j = 0; j < els.length; j++) {
78
+ var el = els[j];
79
+ el.disabled = false;
80
+
81
+ }
82
+ }
83
+ }
84
+
85
+ function refreshPageEvent(e){
86
+ me.refreshPage();
87
+ }
88
+
89
+ me.refreshPage = function(options){
90
+
91
+ changedInput = this;
92
+
93
+ inputsToClear = new Array();
94
+ qsSb = new StringBuffer();
95
+ for (var i = 0; i < visibleIfNodes.length; i++) {
96
+ setVisibility(visibleIfNodes[i], options);
97
+
98
+ }
99
+
100
+
101
+ if (!(options && !options.isPageLoaded)) {
102
+ for (i in inputsToClear) {
103
+ var el = inputsToClear[i];
104
+ if (i != 0) {
105
+ qsSb.append('&');
106
+ }
107
+ qsSb.append(i).append('=');
108
+ }
109
+
110
+ var qs = qsSb.toString();
111
+
112
+
113
+ if (qsSb.getLength() > 0) {
114
+
115
+ var url = DOMHelpers.getDatasetItem(document.body, 'visibleif-deletedataurl');
116
+
117
+ if (url) {
118
+ req = XMLHelpers.getXMLHttpRequest(url, deleteRequestHandler, 'GET', qs);
119
+ }
120
+
121
+ }
122
+
123
+
124
+
125
+ for (var i = 0; i < mandatoryNodes.length; i++) {
126
+ setMandatoryStates(mandatoryNodes[i], options);
127
+
128
+ }
129
+ }
130
+
131
+ var formNodes = document.getElementsByTagName('form');
132
+
133
+ for (var i=0; i<formNodes.length; i++) {
134
+ updateVisibilityProperties(formNodes[i]);
135
+ }
136
+ }
137
+
138
+ function setMandatoryStates(e){
139
+ changedInput = this;
140
+ for (var i = 0; i < mandatoryNodes.length; i++) {
141
+ setMandatoryState(mandatoryNodes[i]);
142
+
143
+ }
144
+
145
+ }
146
+
147
+ function getRule(node, type){
148
+ var r = DOMHelpers.getDatasetItem(node, type);
149
+
150
+ if (!r) {
151
+ r = CSSHelpers.getElementsByClassName(node, type);
152
+
153
+ if (r.length == 0) {
154
+ r = null;
155
+ } else {
156
+ r = r[0].innerHTML.trim()
157
+ }
158
+ }
159
+
160
+ if (r) {
161
+ r = StringHelpers.unentify(" " + r.replace(operatorRe, ' $1 ') + " ");
162
+ }
163
+
164
+ return r;
165
+ }
166
+
167
+ function setEvents(){
168
+
169
+ visibleIfNodes = CSSHelpers.getElementsByClassName(document, 'visibleIf');
170
+ mandatoryNodes = CSSHelpers.getElementsByClassName(document, 'mandatoryIf');
171
+ var nodesToIndex = [visibleIfNodes, mandatoryNodes];
172
+ var nameCounter = 0;
173
+ var forms = document.getElementsByTagName('form');
174
+
175
+ for (var i = 0; i < forms.length; i++) {
176
+ EventHelpers.addEvent(forms[i], 'submit', formSubmitEvent);
177
+ }
178
+
179
+
180
+
181
+ for (var n = 0; n < nodesToIndex.length; n++) {
182
+ var nodes = nodesToIndex[n];
183
+ for (var i = 0; i < nodes.length; i++) {
184
+ var node = nodes[i];
185
+ var parentForm = DOMHelpers.getAncestorByTagName(node, 'form');
186
+
187
+
188
+
189
+ var rule;
190
+ var ruleType;
191
+ if (n == 0) {
192
+ ruleType = "visibleIf-rule";
193
+ } else {
194
+ ruleType = "mandatoryIf-rule";
195
+ }
196
+
197
+ rule = getRule(node, ruleType);
198
+
199
+ if (!rule) {
200
+ throw "There is no rule for with the node with the following HTML:" + XMLHelpers.getOuterXML(node);
201
+ }
202
+
203
+
204
+
205
+ var inputVars = getInputVars(rule);
206
+
207
+ if (inputVars) {
208
+ for (var j = 0; j < inputVars.length; j++) {
209
+ var inputVar = inputVars[j];
210
+ if (!nodesWithEventsAttached[parentForm.id]|| !nodesWithEventsAttached[parentForm.id][inputVar]) {
211
+
212
+ if (!nodesWithEventsAttached[parentForm.id]) {
213
+ nodesWithEventsAttached[parentForm.id] = new Array();
214
+ }
215
+
216
+ nodesWithEventsAttached[parentForm.id][inputVar] = true;
217
+
218
+ if (inputVars.length > 0) {
219
+
220
+ var fieldNode = parentForm[inputVars[j]];
221
+ //var fieldNode = document.getElementById(inputVars[j]);
222
+
223
+ if (fieldNode != null) {
224
+ if (fieldNode.nodeName != "SELECT" && fieldNode.length) {
225
+ for (var k = 0; k < fieldNode.length; k++) {
226
+
227
+ EventHelpers.addEvent(fieldNode[k], 'click', refreshPageEvent);
228
+
229
+ }
230
+ } else {
231
+
232
+ EventHelpers.addEvent(fieldNode, 'change', refreshPageEvent);
233
+ }
234
+
235
+ if (fieldNode.type == 'text') {
236
+
237
+ EventHelpers.addEvent(fieldNode, 'change', refreshPageEvent);
238
+ }
239
+
240
+ if (fieldNode.type == 'checkbox') {
241
+ EventHelpers.addEvent(fieldNode, 'click', refreshPageEvent);
242
+ }
243
+ }
244
+
245
+ }
246
+ }
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ }
253
+
254
+ function updateVisibilityProperties(formNode){
255
+ var fields = formNode.elements;
256
+
257
+ for (var i = 0; i < fields.length; i++) {
258
+ var field = fields[i]
259
+ if (!isVisible(field) && !CSSHelpers.isMemberOfClass(field, 'visibleIf-submitIfInvisible')) {
260
+ CSSHelpers.addClass(field, 'visibleIf-notSubmitted');
261
+ field.disabled = true;
262
+ } else {
263
+ CSSHelpers.removeClass(field, 'visibleIf-notSubmitted');
264
+ field.disabled = false;
265
+ }
266
+ }
267
+ }
268
+
269
+ function formSubmitEvent(e){
270
+
271
+ if (CSSHelpers.isMemberOfClass(this, 'visibleIf-submitInvisibleData')) {
272
+ return;
273
+ }
274
+
275
+ updateVisibilityProperties(this);
276
+ }
277
+
278
+ function isVisible(node){
279
+ return node.offsetWidth != 0;
280
+ }
281
+
282
+
283
+
284
+ function setVisibility(node, options){
285
+ var rule = getRule(node, 'visibleIf-rule')
286
+
287
+ if (rule == null) {
288
+ throw "There is no rule for with the node with the following HTML:" + XMLHelpers.getOuterXML(node);
289
+ }
290
+
291
+ var isRuleTrue = evaluateRule(DOMHelpers.getAncestorByTagName(node, 'form'), rule);
292
+
293
+
294
+ if (isRuleTrue) {
295
+ CSSHelpers.addClass(node, 'visibleIf-visible');
296
+ setFormElementsInside(node, false, options);
297
+ } else {
298
+ CSSHelpers.removeClass(node, 'visibleIf-visible');
299
+
300
+ if (options && options.isPageLoad) {
301
+ setFormElementsInside(node, false, options);
302
+ } else {
303
+ setFormElementsInside(node, true, options);
304
+ }
305
+ }
306
+ }
307
+
308
+ function setMandatoryState(node){
309
+ var rule = getRule(node, 'mandatoryIf-rule')
310
+
311
+ if (rule == null) {
312
+ throw "There is no rule for with the node with the following HTML:" + XMLHelpers.getOuterXML(node);
313
+ }
314
+
315
+
316
+ var isRuleTrue = evaluateRule(DOMHelpers.getAncestorByTagName(node, 'form'), getRule(node, rule));
317
+
318
+
319
+ if (isRuleTrue) {
320
+ CSSHelpers.addClass(node, 'mandatoryIf-mandatory');
321
+ //setFormElementsInside(node, false);
322
+ } else {
323
+ CSSHelpers.removeClass(node, 'mandatoryIf-mandatory');
324
+ //setFormElementsInside(node, true);
325
+ }
326
+
327
+ }
328
+
329
+
330
+ function evaluateRule(parentForm, rule){ //node, ruleNode) {
331
+ //var rule = getRuleString(ruleNode);
332
+
333
+ if (rule == "") {
334
+ return true;
335
+ } else {
336
+
337
+
338
+ if (rule != null) {
339
+
340
+ //var parentForm = DOMHelpers.getAncestorByTagName(node, 'form');
341
+ if (!parentForm) {
342
+ throw "Error: the rule " + rule + " is not attached to a form."
343
+ }
344
+
345
+ var stringToEval;
346
+
347
+ var formElem = parentForm[rule.name];
348
+
349
+ // first, replace all quoted strings with placeholders:
350
+ var diddledRule = rule.replace(quotedStringRe, placeHolderString);
351
+
352
+ // next, grab all those quoted strings
353
+ var quotedVals = rule.match(quotedStringRe);
354
+
355
+
356
+ var formId = parentForm.id;
357
+
358
+ if (!formId) {
359
+ formId = 'visibleIf-form' + nameCounter;
360
+ parentForm.id = formId;
361
+
362
+ nameCounter++;
363
+ }
364
+
365
+
366
+ // now replace all variables with javascript form element values
367
+ stringToEval = diddledRule.replace(leftBkRe, '( ').replace(rightBkRe, ' )').replace(varRe, 'getFieldValue(document.getElementById("' +
368
+ formId +
369
+ '")["$1"]) ').replace(reRe, '.match(/$1/)');
370
+
371
+ // now, replace placeholders back to the original strings.
372
+ if (quotedVals) {
373
+ for (var i = 0; i < quotedVals.length; i++) {
374
+ stringToEval = stringToEval.replace(placeHolderRe, quotedVals[i]);
375
+ }
376
+ }
377
+
378
+
379
+ try {
380
+ if (eval(stringToEval)) {
381
+ return true;
382
+ } else {
383
+ return false;
384
+ }
385
+ }
386
+ catch (ex) {
387
+ //alert('Bad equation: ' + stringToEval)
388
+ return false;
389
+ }
390
+ }
391
+ }
392
+ }
393
+
394
+
395
+ function setFormElementsInside(node, doClear, options){
396
+
397
+
398
+
399
+ if (!options) {
400
+ options = {};
401
+ }
402
+
403
+ var formElements = getAllFormElementsIn(node);
404
+
405
+ for (var i = 0; i < formElements.length; i++) {
406
+
407
+
408
+ var el = formElements[i];
409
+
410
+
411
+ /* Let's disable them so they aren't submitted
412
+ if (!CSSHelpers.isMemberOfClass(node, 'visibleIf-ignoreDisableAttr')) {
413
+
414
+ el.disabled = doClear ? "disabled" : "";
415
+
416
+ if (CSSHelpers.isMemberOfClass(el, 'streetName')) {
417
+ jslog.debug(el.disabled);
418
+ }
419
+ }*/
420
+ if (el != changedInput) {
421
+
422
+ switch (el.nodeName) {
423
+ case "INPUT":
424
+ switch (el.type) {
425
+
426
+ case "checkbox":
427
+ if (el.checked) {
428
+ if (doClear) {
429
+
430
+ if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) {
431
+ // cache the value
432
+ formCache.setValue(el.name, el.value);
433
+ el.checked = false;
434
+ addToInputToClear(el);
435
+ }
436
+
437
+ } else if (formCache.getValue(el.name) == el.value) {
438
+ //el.checked = true;
439
+
440
+ }
441
+ }
442
+ break;
443
+ case "radio":
444
+
445
+ if (doClear) {
446
+
447
+ if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) {
448
+
449
+ // cache the value
450
+ if (el.checked) {
451
+ formCache.setValue(el.name, el.value);
452
+ el.checked = false;
453
+ }
454
+ addToInputToClear(el);
455
+
456
+ }
457
+
458
+ } else if (formCache.getValue(el.name) == el.value) {
459
+ //el.checked = true;
460
+
461
+ }
462
+
463
+ break;
464
+
465
+ case "file":
466
+
467
+ // do nothing to avoid a security error.
468
+ break;
469
+ case "hidden":
470
+ // don't do anything
471
+ break;
472
+ default:
473
+ if (doClear) {
474
+
475
+ /*
476
+ * The following code is for use with a seperate
477
+ * JavaScript library, fileChanger.js. If
478
+ * it's a fileChanger widget, we need to do an Ajax call
479
+ */
480
+ if (CSSHelpers.isMemberOfClass(el, 'fileList_fileDisplay')) {
481
+ CSSHelpers.removeClass(el, 'fileList_fileDisplay');
482
+ el.disabled = false;
483
+ el.name = el.name.replace("_ignore", "")
484
+ var html = XMLHelpers.getOuterXML(el).replace(/text/, 'file');
485
+ el.parentNode.innerHTML = html;
486
+
487
+ // insert ajax call to delete file here.
488
+ url = config.getScriptedValue('visibleIf.urls.deleteFiles', {
489
+ files: StringHelpers.urlencode(el.value),
490
+ formProperty: el.name
491
+ })
492
+ req = XMLHelpers.getXMLHttpRequest(url, deleteRequestHandler);
493
+ }
494
+
495
+
496
+ // cache the value
497
+ formCache.setValue(el.name, el.value);
498
+ if (options.isPageLoad) {
499
+ el.value = DOMHelpers.getAttributeValue(el, 'value');
500
+ if (el.value == "null") {
501
+ el.value = "";
502
+ }
503
+ } else if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) {
504
+ el.value = "";
505
+ addToInputToClear(el);
506
+ }
507
+
508
+ } else {
509
+ //el.value = formCache.getValue(el.name);
510
+ }
511
+ break;
512
+ }
513
+ break;
514
+ case "TEXTAREA":
515
+ if (doClear) {
516
+ // cache the value
517
+ formCache.setValue(el.name, el.value);
518
+ if (options.isPageLoad) {
519
+ //el.value = DOMHelpers.getAttributeValue(el, 'value');
520
+ } else if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) {
521
+ el.value = "";
522
+ addToInputToClear(el);
523
+ }
524
+ } else {
525
+ //el.value = formCache.getValue(el.name);
526
+ }
527
+
528
+ break;
529
+ case "SELECT":
530
+ if (doClear) {
531
+
532
+ if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) {
533
+ // cache the value
534
+ formCache.setValue(el.name, el.selectedIndex);
535
+
536
+ // TODO: should this be 0 or -1?
537
+ el.selectedIndex = 0;
538
+ addToInputToClear(el);
539
+ }
540
+
541
+ el.disabled = true;
542
+
543
+ } else {
544
+ //el.selectedValue = formCache.getValue(el.name);
545
+ el.disabled = false;
546
+ }
547
+ break;
548
+
549
+
550
+ }
551
+ }
552
+
553
+ }
554
+
555
+
556
+
557
+
558
+
559
+
560
+
561
+ }
562
+
563
+ function addToInputToClear(el){
564
+ if (!inputsToClear[el.name]) {
565
+ inputsToClear[el.name] = el;
566
+ }
567
+ }
568
+
569
+ function deleteRequestHandler(){
570
+
571
+ if (!req) {
572
+ return;
573
+ }
574
+
575
+ // only if req shows "complete"
576
+ if (req.readyState == ReadyState.COMPLETED) {
577
+ // only if "OK"
578
+ //DebugHelpers.log(req.getAllResponseHeaders());
579
+
580
+ if (req.status == HttpCode.OK || req.status == HttpCode.LOCAL_OK) {
581
+ // whatever
582
+ //jslog.debug('Deleted Successfully')
583
+ } else {
584
+ throw "Something bad happened. HTTP Status: " + req.status;
585
+
586
+ }
587
+ }
588
+ }
589
+
590
+
591
+ function getInputVars(rule){
592
+ rule = rule.replace(leftBkRe, '( ').replace(rightBkRe, ' )');
593
+ var vars = rule.match(varRe);
594
+
595
+ if (vars == null) {
596
+ return new Array();
597
+ }
598
+
599
+ for (var i = 0; i < vars.length; i++) {
600
+ vars[i] = vars[i].trim();
601
+ }
602
+
603
+
604
+ return vars;
605
+
606
+ }
607
+
608
+
609
+ function getFieldValue(formElementNode){
610
+ var r = "";
611
+ var type;
612
+
613
+ type = formElementNode.type
614
+
615
+ if (!type) {
616
+ if (formElementNode.length)
617
+ type = formElementNode[0].type;
618
+ }
619
+
620
+
621
+ switch (type) {
622
+
623
+ case 'text':
624
+ case 'hidden':
625
+ case 'password':
626
+ case 'textarea':
627
+ case 'select-one':
628
+ r = formElementNode.value;
629
+ case 'checkbox':
630
+ if (formElementNode.checked) {
631
+ r = formElementNode.value;
632
+ }
633
+ break;
634
+ case 'radio':
635
+ for (var i = 0; i < formElementNode.length; i++) {
636
+ if (formElementNode[i].checked) {
637
+ r = formElementNode[i].value;
638
+ break;
639
+ }
640
+ }
641
+
642
+
643
+ }
644
+
645
+ if (formElementNode.length) {
646
+ for (var i = 0; i < formElementNode.length; i++) {
647
+ if (formElementNode[i].checked) {
648
+ r = formElementNode[i].value;
649
+ }
650
+ }
651
+
652
+ }
653
+
654
+ return r.replace('\n', '').replace(' ', '');
655
+ }
656
+
657
+ function getAllFormElementsIn(node){
658
+ if (!node) {
659
+ node = document;
660
+ }
661
+
662
+ var r = new Array();
663
+
664
+ var elems = {
665
+ inputs: node.getElementsByTagName('input'),
666
+ selects: node.getElementsByTagName('select'),
667
+ textareas: node.getElementsByTagName('textarea')
668
+ };
669
+
670
+ for (var i in elems) {
671
+ var elem = elems[i];
672
+ for (j = 0; j < elem.length; j++) {
673
+ r.push(elem[j]);
674
+ }
675
+ }
676
+
677
+ return r;
678
+ }
679
+
680
+
681
+ /* Helper routines */
682
+ if (window.CSSHelpers) {
683
+ CSSHelpers = window.CSSHelpers;
684
+ } else {
685
+ CSSHelpers = new function(){
686
+ var me = this;
687
+ var blankRe = new RegExp('\\s');
688
+
689
+ /**
690
+ * Generates a regular expression string that can be used to detect a class name
691
+ * in a tag's class attribute. It is used by a few methods, so I
692
+ * centralized it.
693
+ *
694
+ * @param {String} className - a name of a CSS class.
695
+ */
696
+ function getClassReString(className){
697
+ return '\\s' + className + '\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className + '$';
698
+ }
699
+
700
+ function getClassPrefixReString(className){
701
+ return '\\s' + className + '-[0-9a-zA-Z_]+\\s|^' + className + '[0-9a-zA-Z_]+\\s|\\s' + className + '[0-9a-zA-Z_]+$|' + '^' + className + '[0-9a-zA-Z_]+$';
702
+ }
703
+
704
+
705
+
706
+ /**
707
+ * Make an HTML object be a member of a certain class.
708
+ *
709
+ * @param {Object} obj - an HTML object
710
+ * @param {String} className - a CSS class name.
711
+ */
712
+ me.addClass = function(obj, className){
713
+ if (blankRe.test(className)) {
714
+ return;
715
+ }
716
+
717
+ // only add class if the object is not a member of it yet.
718
+ if (!me.isMemberOfClass(obj, className)) {
719
+ obj.className += " " + className;
720
+ }
721
+ }
722
+
723
+ /**
724
+ * Make an HTML object *not* be a member of a certain class.
725
+ *
726
+ * @param {Object} obj - an HTML object
727
+ * @param {Object} className - a CSS class name.
728
+ */
729
+ me.removeClass = function(obj, className){
730
+
731
+ if (blankRe.test(className)) {
732
+ return;
733
+ }
734
+
735
+
736
+ var re = new RegExp(getClassReString(className), "g");
737
+
738
+ var oldClassName = obj.className;
739
+
740
+
741
+ if (obj.className) {
742
+ obj.className = oldClassName.replace(re, '');
743
+ }
744
+
745
+
746
+ }
747
+
748
+ /**
749
+ * Given an HTML element, find all child nodes of a specific class.
750
+ *
751
+ * With ideas from Jonathan Snook
752
+ * (http://snook.ca/archives/javascript/your_favourite_1/)
753
+ * Since this was presented within a post on this site, it is for the
754
+ * public domain according to the site's copyright statement.
755
+ *
756
+ * @param {Object} obj - an HTML element. If you want to search a whole document, set
757
+ * this to the document object.
758
+ * @param {String} className - the class name of the objects to return
759
+ * @return {Array} - the list of objects of class cls.
760
+ */
761
+ me.getElementsByClassName = function(obj, className){
762
+ if (obj.getElementsByClassName) {
763
+ return DOMHelpers.nodeListToArray(obj.getElementsByClassName(className))
764
+ } else {
765
+ var a = [];
766
+ var re = new RegExp(getClassReString(className));
767
+ var els = DOMHelpers.getAllDescendants(obj);
768
+
769
+ for (var i = 0, j = els.length; i < j; i++) {
770
+ if (re.test(els[i].className)) {
771
+ a.push(els[i]);
772
+
773
+ }
774
+ }
775
+ return a;
776
+ }
777
+ }
778
+
779
+ /**
780
+ * Determines if an HTML object is a member of a specific class.
781
+ * @param {Object} obj - an HTML object.
782
+ * @param {Object} className - the CSS class name.
783
+ */
784
+ me.isMemberOfClass = function(obj, className){
785
+
786
+ if (blankRe.test(className))
787
+ return false;
788
+
789
+ var re = new RegExp(getClassReString(className), "g");
790
+
791
+ return (re.test(obj.className));
792
+ }
793
+ }
794
+ }
795
+
796
+ if (window.DOMHelpers) {
797
+ DOMHelpers = window.DOMHelpers;
798
+ } else {
799
+ DOMHelpers = new function(){
800
+
801
+ var me = this;
802
+ /**
803
+ * Given an tag, find the first ancestor tag of a given tag name.
804
+ *
805
+ * @param {Object} obj - a HTML or XML tag.
806
+ * @param {String} tagName - the name of the ancestor tag to find.
807
+ * @return {Object} - the ancestor tag, or null if not found.
808
+ */
809
+ /**
810
+ * Returns all children of an element. Needed if it is necessary to do
811
+ * the equivalent of getElementsByTagName('*') for IE5 for Windows.
812
+ *
813
+ * @param {Object} e - an HTML object.
814
+ */
815
+ me.getAllDescendants = function(obj){
816
+ return obj.all ? obj.all : obj.getElementsByTagName('*');
817
+ }
818
+
819
+ me.getAncestorByTagName = function(obj, tagName){
820
+
821
+ for (var node = obj.parentNode; node.nodeName.toLowerCase() != 'body'; node = node.parentNode) {
822
+
823
+ if (tagName.toLowerCase() == node.nodeName.toLowerCase()) {
824
+ return node;
825
+ }
826
+
827
+ }
828
+ return null;
829
+ }
830
+
831
+ /**
832
+ * Given an HTML or XML object, find the an attribute by name.
833
+ *
834
+ * @param {Object} obj - a DOM object.
835
+ * @param {String} attrName - the name of an attribute inside the DOM object.
836
+ * @return {Object} - the attribute object or null if there isn't one.
837
+ */
838
+ me.getAttributeByName = function(obj, attrName){
839
+ var i;
840
+
841
+ var attributes = obj.attributes;
842
+ for (i = 0; i < attributes.length; i++) {
843
+ var attr = attributes[i]
844
+ if (attr.nodeName == attrName && attr.specified) {
845
+ return attr;
846
+ }
847
+ }
848
+ return null;
849
+ }
850
+
851
+ /**
852
+ * Given an HTML or XML object, find the value of an attribute.
853
+ *
854
+ * @param {Object} obj - a DOM object.
855
+ * @param {String} attrName - the name of an attribute inside the DOM object.
856
+ * @return {String} - the value of the attribute.
857
+ */
858
+ me.getAttributeValue = function(obj, attrName){
859
+ var attr = me.getAttributeByName(obj, attrName);
860
+
861
+ if (attr != null) {
862
+ return attr.nodeValue;
863
+ } else {
864
+ return null;
865
+ }
866
+ }
867
+
868
+ me.getDatasetItem = function(obj, name){
869
+ var r = DOMHelpers.getAttributeValue(obj, 'data-' + name);
870
+
871
+ if (!r) {
872
+ r = DOMHelpers.getAttributeValue(obj, 'data-' + name.toLowerCase())
873
+ }
874
+ return r;
875
+ }
876
+
877
+ /******
878
+ * Converts a DOM live node list to a static/dead array. Good when you don't
879
+ * want the thing you are iterating in a for loop changing as the DOM changes.
880
+ *
881
+ * @param {Object} nodeList - a node list (like one returned by document.getElementsByTagName)
882
+ * @return {Array} - an array of nodes.
883
+ *
884
+ *******/
885
+ me.nodeListToArray = function(nodeList){
886
+ var ary = [];
887
+ for (var i = 0, len = nodeList.length; i < len; i++) {
888
+ ary.push(nodeList[i]);
889
+ }
890
+ return ary;
891
+ }
892
+
893
+ }
894
+ }
895
+
896
+ if (window.StringHelpers) {
897
+ StringHelpers = window.StringHelpers;
898
+ } else {
899
+ StringHelpers = new function(){
900
+ var me = this;
901
+ me.initWhitespaceRe = /^\s\s*/;
902
+ me.endWhitespaceRe = /\s\s*$/;
903
+ me.whitespaceRe = /\s/;
904
+
905
+ me.unentify = function(s){
906
+
907
+ return s.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
908
+ }
909
+
910
+ me.urlencode = function(str){
911
+ return escape(str).replace('+', '%2B').replace('%20', '+').replace('*', '%2A').replace('/', '%2F').replace('@', '%40');
912
+ }
913
+
914
+ }
915
+ }
916
+
917
+ if (window.XMLHelpers) {
918
+ XMLHelpers = window.XMLHelpers;
919
+ } else {
920
+ XMLHelpers = new function(){
921
+ var me = this;
922
+
923
+ /**
924
+ * Given an XML node, return the XML inside as a string and the XML string of the node itself.
925
+ * Similar to Internet Explorer's outerHTML property, except it is for XML, not HTML.
926
+ * Created with information from http://www.codingforums.com/showthread.php?t=31489
927
+ * and http://www.mercurytide.co.uk/whitepapers/issues-working-with-ajax/
928
+ *
929
+ * @param {Object} node - a DOM object.
930
+ * @param {Object} options - a JS object containing options. To date,
931
+ * the only one supported is "insertClosingTags", when set to
932
+ * true, converts self closing tags, like <td />, to <td></td>.
933
+ * @return {String} - the XML String inside the object.
934
+ */
935
+ me.getOuterXML = function(node, options){
936
+ var r;
937
+ // Internet Explorer
938
+ if (node.xml) {
939
+ r = node.xml;
940
+
941
+ // Everyone else
942
+ } else if (node.outerHTML) {
943
+ r = node.outerHTML;
944
+ } else if (window.XMLSerializer) {
945
+
946
+ var serializer = new XMLSerializer();
947
+ var text = serializer.serializeToString(node);
948
+ r = text;
949
+ } else {
950
+ return null;
951
+ }
952
+
953
+ /*
954
+ * If the XML is actually HTML and you are inserting it into an HTML
955
+ * document, you must use the "insertClosingTags" option, otherwise
956
+ * Opera will not like you, especially if you have empty <td> tags.
957
+ */
958
+ if (options) {
959
+ if (options.insertClosingTags) {
960
+ r = r.replace(selfClosingTagRe, "<$1></$1>");
961
+ }
962
+ }
963
+ return r;
964
+ }
965
+
966
+ /**
967
+ * Wrapper for XMLHttpRequest Object. Grabbing data (XML and/or text) from a URL.
968
+ * Grabbing data from a URL. Input is one parameter, url. It returns a request
969
+ * object. Based on code from
970
+ * http://www.xml.com/pub/a/2005/02/09/xml-http-request.html. IE caching problem
971
+ * fix from Wikipedia article http://en.wikipedia.org/wiki/XMLHttpRequest
972
+ *
973
+ * @param {String} url - the URL to retrieve
974
+ * @param {Function} processReqChange - the function/method to call at key events of the URL retrieval.
975
+ * @param {String} method - (optional) "GET" or "POST" (default "GET")
976
+ * @param {String} data - (optional) the CGI data to pass. Default null.
977
+ * @param {boolean} isAsync - (optional) is this call asyncronous. Default true.
978
+ *
979
+ * @return {Object} a XML request object.
980
+ */
981
+ me.getXMLHttpRequest = function(url, processReqChange) //, method, data, isAsync)
982
+ {
983
+ var argv = me.getXMLHttpRequest.arguments;
984
+ var argc = me.getXMLHttpRequest.arguments.length;
985
+ var httpMethod = (argc > 2) ? argv[2] : 'GET';
986
+ var data = (argc > 3) ? argv[3] : "";
987
+ var isAsync = (argc > 4) ? argv[4] : true;
988
+
989
+ var req;
990
+ // branch for native XMLHttpRequest object
991
+ if (window.XMLHttpRequest) {
992
+ req = new XMLHttpRequest();
993
+ // branch for IE/Windows ActiveX version
994
+ } else if (window.ActiveXObject) {
995
+ try {
996
+ req = new ActiveXObject('Msxml2.XMLHTTP');
997
+ }
998
+ catch (ex) {
999
+ req = new ActiveXObject("Microsoft.XMLHTTP");
1000
+ }
1001
+ // the browser doesn't support XML HttpRequest. Return null;
1002
+ } else {
1003
+ return null;
1004
+ }
1005
+
1006
+ if (isAsync) {
1007
+ req.onreadystatechange = processReqChange;
1008
+ }
1009
+
1010
+ if (httpMethod == "GET" && data != "") {
1011
+ url += "?" + data;
1012
+ }
1013
+
1014
+ req.open(httpMethod, url, isAsync);
1015
+
1016
+ //Fixes IE Caching problem
1017
+ req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
1018
+ req.send(data);
1019
+
1020
+ return req;
1021
+ }
1022
+
1023
+ }
1024
+ }
1025
+
1026
+ /*
1027
+ * stringBuffer - ideas from
1028
+ * http://www.multitask.com.au/people/dion/archives/000354.html
1029
+ */
1030
+ function StringBuffer(){
1031
+ var me = this;
1032
+
1033
+ var buffer = [];
1034
+
1035
+
1036
+ me.append = function(string){
1037
+ buffer.push(string);
1038
+ return me;
1039
+ }
1040
+
1041
+ me.appendBuffer = function(bufferToAppend){
1042
+ buffer = buffer.concat(bufferToAppend);
1043
+ }
1044
+
1045
+ me.toString = function(){
1046
+ return buffer.join("");
1047
+ }
1048
+
1049
+ me.getLength = function(){
1050
+ return buffer.length;
1051
+ }
1052
+
1053
+ me.flush = function(){
1054
+ buffer.length = 0;
1055
+ }
1056
+
1057
+ }
1058
+
1059
+ /*
1060
+ * Adding trim method to String Object. Ideas from
1061
+ * http://www.faqts.com/knowledge_base/view.phtml/aid/1678/fid/1 and
1062
+ * http://blog.stevenlevithan.com/archives/faster-trim-javascript
1063
+ */
1064
+ String.prototype.trim = function(){
1065
+ var str = this;
1066
+
1067
+ // The first method is faster on long strings than the second and
1068
+ // vice-versa.
1069
+ if (this.length > 6000) {
1070
+ str = this.replace(StringHelpers.initWhitespaceRe, '');
1071
+ var i = str.length;
1072
+ while (StringHelpers.whitespaceRe.test(str.charAt(--i)))
1073
+ ;
1074
+ return str.slice(0, i + 1);
1075
+ } else {
1076
+ return this.replace(StringHelpers.initWhitespaceRe, '').replace(StringHelpers.endWhitespaceRe, '');
1077
+ }
1078
+ };
1079
+
1080
+ }
1081
+
1082
+ var formCache = new function(){
1083
+ var me = this;
1084
+ var values = new Array();
1085
+
1086
+ me.setValue = function(name, value){
1087
+ values[name] = value;
1088
+ }
1089
+
1090
+ me.getValue = function(name){
1091
+ if (values[name] == undefined) {
1092
+ return "";
1093
+ } else {
1094
+ return values[name];
1095
+ }
1096
+ }
1097
+ }
1098
+
1099
+ EventHelpers.addPageLoadEvent('visibleIf.init');
1100
+