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.
- data/CHANGELOG.md +5 -0
- data/Gemfile +11 -0
- data/README.md +208 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/demos/html5-form-demo.html +79 -0
- data/html5forms-rails.gemspec +142 -0
- data/lib/html5forms.rb +6 -0
- data/vendor/assets/images/colorpicker/blank.gif +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_background.png +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_hex.png +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_hsb_b.png +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_hsb_h.png +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_hsb_s.png +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_indic.gif +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_overlay.png +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_rgb_b.png +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_rgb_g.png +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_rgb_r.png +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_select.gif +0 -0
- data/vendor/assets/images/colorpicker/colorpicker_submit.png +0 -0
- data/vendor/assets/images/colorpicker/custom_background.png +0 -0
- data/vendor/assets/images/colorpicker/custom_hex.png +0 -0
- data/vendor/assets/images/colorpicker/custom_hsb_b.png +0 -0
- data/vendor/assets/images/colorpicker/custom_hsb_h.png +0 -0
- data/vendor/assets/images/colorpicker/custom_hsb_s.png +0 -0
- data/vendor/assets/images/colorpicker/custom_indic.gif +0 -0
- data/vendor/assets/images/colorpicker/custom_rgb_b.png +0 -0
- data/vendor/assets/images/colorpicker/custom_rgb_g.png +0 -0
- data/vendor/assets/images/colorpicker/custom_rgb_r.png +0 -0
- data/vendor/assets/images/colorpicker/custom_submit.png +0 -0
- data/vendor/assets/images/colorpicker/select.png +0 -0
- data/vendor/assets/images/colorpicker/select2.png +0 -0
- data/vendor/assets/images/colorpicker/slider.png +0 -0
- data/vendor/assets/images/h5f/form_validation.png +0 -0
- data/vendor/assets/images/html5form-shim/asterisk.png +0 -0
- data/vendor/assets/images/html5form-shim/down.png +0 -0
- data/vendor/assets/images/html5form-shim/fail.png +0 -0
- data/vendor/assets/images/html5form-shim/ok.png +0 -0
- data/vendor/assets/images/html5forms/jscolor/arrow.gif +0 -0
- data/vendor/assets/images/html5forms/jscolor/cross.gif +0 -0
- data/vendor/assets/images/html5forms/jscolor/hs.png +0 -0
- data/vendor/assets/images/html5forms/jscolor/hv.png +0 -0
- data/vendor/assets/images/html5forms/slider/slider-1.png +0 -0
- data/vendor/assets/images/html5forms/slider/slider-disabled-1.png +0 -0
- data/vendor/assets/images/html5forms/slider/slider-disabled.png +0 -0
- data/vendor/assets/images/html5forms/slider/slider.png +0 -0
- data/vendor/assets/javascripts/colorpicker.js +484 -0
- data/vendor/assets/javascripts/colorpicker.min.js +9 -0
- data/vendor/assets/javascripts/h5f.js +328 -0
- data/vendor/assets/javascripts/h5f.min.js +4 -0
- data/vendor/assets/javascripts/html5forms/EventHelpers.min.js +15 -0
- data/vendor/assets/javascripts/html5forms/autocomplete.min.js +1 -0
- data/vendor/assets/javascripts/html5forms/cssQuery-p.min.js +6 -0
- data/vendor/assets/javascripts/html5forms/dev/EventHelpers.js +486 -0
- data/vendor/assets/javascripts/html5forms/dev/autocomplete.js +387 -0
- data/vendor/assets/javascripts/html5forms/dev/cssQuery-p.js +6 -0
- data/vendor/assets/javascripts/html5forms/dev/html5.js +121 -0
- data/vendor/assets/javascripts/html5forms/dev/html5Forms.js +892 -0
- data/vendor/assets/javascripts/html5forms/dev/html5Widgets.js +1417 -0
- data/vendor/assets/javascripts/html5forms/dev/jscolor.js +840 -0
- data/vendor/assets/javascripts/html5forms/dev/slider.js +797 -0
- data/vendor/assets/javascripts/html5forms/dev/timer.js +137 -0
- data/vendor/assets/javascripts/html5forms/dev/visibleIf.js +1100 -0
- data/vendor/assets/javascripts/html5forms/html5.min.js +2 -0
- data/vendor/assets/javascripts/html5forms/html5Forms.min.js +1 -0
- data/vendor/assets/javascripts/html5forms/html5Widgets.min.js +20 -0
- data/vendor/assets/javascripts/html5forms/jscolor.min.js +10 -0
- data/vendor/assets/javascripts/html5forms/slider.min.js +25 -0
- data/vendor/assets/javascripts/html5forms/timer.min.js +1 -0
- data/vendor/assets/javascripts/html5forms/visibleIf.min.js +19 -0
- data/vendor/assets/javascripts/html5forms.fallback.js +115 -0
- data/vendor/assets/javascripts/html5forms.fallback.min.js +11 -0
- data/vendor/assets/javascripts/jquery.html5form-shim.js +402 -0
- data/vendor/assets/javascripts/jquery.html5form.min.js +4 -0
- data/vendor/assets/javascripts/jquery.placehold.min.js +7 -0
- data/vendor/assets/javascripts/ui.spinner.js +649 -0
- data/vendor/assets/javascripts/ui.spinner.min.js +7 -0
- data/vendor/assets/javascripts/webforms2/webforms2-msie.js +1 -0
- data/vendor/assets/javascripts/webforms2/webforms2-p.js +14 -0
- data/vendor/assets/javascripts/webforms2/webforms2.js +14 -0
- data/vendor/assets/javascripts/webforms2/webforms2_src.js +3195 -0
- data/vendor/assets/stylesheets/colorpicker.css +161 -0
- data/vendor/assets/stylesheets/h5f.css +86 -0
- data/vendor/assets/stylesheets/html5form-shim.css +109 -0
- data/vendor/assets/stylesheets/html5forms/number.css +35 -0
- data/vendor/assets/stylesheets/html5forms/slider.css +169 -0
- data/vendor/assets/stylesheets/html5forms/slider_ie.css +41 -0
- data/vendor/assets/stylesheets/html5forms/visibleIf.css +23 -0
- data/vendor/assets/stylesheets/html5forms.layout.css +116 -0
- data/vendor/assets/stylesheets/ui.spinner.css +3 -0
- data/vendor/assets/stylesheets/webforms2.css +42 -0
- metadata +221 -0
|
@@ -0,0 +1,1417 @@
|
|
|
1
|
+
/*******************************************************************************
|
|
2
|
+
* This notice must be untouched at all times.
|
|
3
|
+
*
|
|
4
|
+
* This javascript library contains helper routines to assist with event
|
|
5
|
+
* handling consinstently among browsers
|
|
6
|
+
*
|
|
7
|
+
* html5Widgets.js v.1.1 by Zoltan Hawryluk
|
|
8
|
+
* latest version and documentation available at http://www.useragentman.com/
|
|
9
|
+
*
|
|
10
|
+
* Changelog:
|
|
11
|
+
* version 1.0: initial release
|
|
12
|
+
* version 1.1: implemented oninput method for form elements for unsupported browsers
|
|
13
|
+
* fix IE9 to ensure backspace and delete keys fire an oninput event.
|
|
14
|
+
* version 1.2: Added Number Element Widget
|
|
15
|
+
*
|
|
16
|
+
* released under the MIT License:
|
|
17
|
+
* http://www.opensource.org/licenses/mit-license.php
|
|
18
|
+
*
|
|
19
|
+
*******************************************************************************/
|
|
20
|
+
|
|
21
|
+
var html5Widgets = new function(){
|
|
22
|
+
var me = this;
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
var delayEventTimeout = null;
|
|
26
|
+
|
|
27
|
+
me.inputNodes = new Array();
|
|
28
|
+
me.outputNodes = new Array();
|
|
29
|
+
me.formElements = null;
|
|
30
|
+
me.placeholderNodes = new Array();
|
|
31
|
+
me.dummyLink = document.createElement('input');
|
|
32
|
+
var quoteRe = /\"/g;
|
|
33
|
+
|
|
34
|
+
var dummyIDCount = 0;
|
|
35
|
+
var supportsNatively = new Object();
|
|
36
|
+
|
|
37
|
+
var isBadChrome = navigator.userAgent.indexOf('Chrome');
|
|
38
|
+
var valueRe = /this\.value/g;
|
|
39
|
+
var varRe = /([a-zA-Z][a-zA-Z0-9]*\.value)/g;
|
|
40
|
+
var isDebug;
|
|
41
|
+
|
|
42
|
+
var isIE9 = false;
|
|
43
|
+
|
|
44
|
+
/*@cc_on
|
|
45
|
+
@if (@_jscript_version == 9)
|
|
46
|
+
isIE9 = true;
|
|
47
|
+
@end
|
|
48
|
+
@*/
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
me.init = function(){
|
|
53
|
+
|
|
54
|
+
if (EventHelpers.hasPageLoadHappened(arguments)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
supportsNatively['oninput'] = EventHelpers.isSupported('input', 'form');
|
|
59
|
+
|
|
60
|
+
isDebug = CSSHelpers.isMemberOfClass(document.body, 'html5Widgets-debug')
|
|
61
|
+
|
|
62
|
+
// dummy link setup
|
|
63
|
+
me.type = 'text'
|
|
64
|
+
me.dummyLink.style.position = 'absolute';
|
|
65
|
+
me.dummyLink.style.top = '-200px';
|
|
66
|
+
document.body.appendChild(me.dummyLink)
|
|
67
|
+
|
|
68
|
+
var inputSupport = Modernizr.input
|
|
69
|
+
|
|
70
|
+
if (!inputSupport['placeholder']) {
|
|
71
|
+
setPlaceholders();
|
|
72
|
+
}
|
|
73
|
+
indexOutputNodes();
|
|
74
|
+
insertElements();
|
|
75
|
+
|
|
76
|
+
me.resolveOutputs();
|
|
77
|
+
|
|
78
|
+
/* document.getElementById('supports').innerHTML =
|
|
79
|
+
DebugHelpers.getProperties(Modernizr.inputtypes, 'inputtypes') + " " +
|
|
80
|
+
DebugHelpers.getProperties(Modernizr.input, 'input') + " " +
|
|
81
|
+
DebugHelpers.getProperties(Modernizr, 'Modernizr'); */
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
function supports_input_placeholder() {
|
|
88
|
+
var i = document.createElement('input');
|
|
89
|
+
return 'placeholder' in i;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function setPlaceholders() {
|
|
93
|
+
|
|
94
|
+
var nodes = [document.getElementsByTagName('input'), document.getElementsByTagName('textarea')];
|
|
95
|
+
|
|
96
|
+
for (var i=0; i<nodes.length; i++) {
|
|
97
|
+
for (var j=0; j<nodes[i].length; j++) {
|
|
98
|
+
var node = nodes[i][j];
|
|
99
|
+
|
|
100
|
+
if (DOMHelpers.getAttributeValue(node, 'placeholder')) {
|
|
101
|
+
me.placeholderNodes.push(new PlaceholderInput(node));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
function getNextDummyID () {
|
|
112
|
+
dummyIDCount ++;
|
|
113
|
+
return "id" + dummyIDCount;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function indexOutputNodes () {
|
|
117
|
+
var outputElements = document.getElementsByTagName('output');
|
|
118
|
+
for (var i=0; i<outputElements.length; i++) {
|
|
119
|
+
var outputEl = outputElements[i];
|
|
120
|
+
if (outputEl.value != undefined && outputEl.onforminput != undefined) {
|
|
121
|
+
|
|
122
|
+
// this browser supports the output tag .. bail
|
|
123
|
+
supportsNatively["output"] = true;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
me.outputNodes.push(new OutputElement(outputEl))
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
me.formElements = document.getElementsByTagName('form');
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function setOutputEvents(nodeName) {
|
|
134
|
+
var formElements = document.getElementsByTagName(nodeName);
|
|
135
|
+
|
|
136
|
+
for (var i=0; i<formElements.length; i++) {
|
|
137
|
+
var formElement = formElements[i];
|
|
138
|
+
// first - set event to resolve output tags
|
|
139
|
+
EventHelpers.addEvent(formElement, 'change', me.resolveOutputs);
|
|
140
|
+
EventHelpers.addEvent(formElement, 'keyup', me.resolveOutputs);
|
|
141
|
+
EventHelpers.addEvent(formElement, 'cut', me.resolveOutputs);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
function insertElements(){
|
|
147
|
+
var inputSupport = Modernizr.inputtypes;
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
// Remove the onload event as we are creating the sliders with a JS call
|
|
151
|
+
if (window.fdSliderController) {
|
|
152
|
+
fdSliderController.removeOnLoadEvent();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
var formElementTypes = ["input", "select", "textarea"];
|
|
156
|
+
for (var i=0; i<formElementTypes.length; i++) {
|
|
157
|
+
setOutputEvents(formElementTypes[i]);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
var formElements = document.getElementsByTagName('input');
|
|
161
|
+
|
|
162
|
+
// leave if this browser supports the range type.
|
|
163
|
+
if (formElements.length <= 0) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
for (var i = 0; i < formElements.length; i++) {
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
var formElement = formElements[i];
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
//var elType = getAttributeValue(formElement, 'type');
|
|
174
|
+
var elType = DOMHelpers.getAttributeValue(formElement, 'type');
|
|
175
|
+
//jslog.debug(elType)
|
|
176
|
+
if (!formElement.name) {
|
|
177
|
+
formElement.name = getNextDummyID();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
switch (elType) {
|
|
181
|
+
|
|
182
|
+
case "range":
|
|
183
|
+
|
|
184
|
+
if (!inputSupport.range) {
|
|
185
|
+
|
|
186
|
+
me.inputNodes.push(new RangeElement(formElement));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
break;
|
|
190
|
+
|
|
191
|
+
case "date":
|
|
192
|
+
case "week":
|
|
193
|
+
case "month":
|
|
194
|
+
case "datetime":
|
|
195
|
+
case "datetime-local":
|
|
196
|
+
|
|
197
|
+
// check to see if the browser supports the type.
|
|
198
|
+
if (!inputSupport[elType] || (window.html5Forms && html5Forms.forceJSDatePicker)) {
|
|
199
|
+
me.inputNodes.push(new CalendarElement(formElement, elType));
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
case "color":
|
|
203
|
+
if (!inputSupport.color || isBadChrome) {
|
|
204
|
+
me.inputNodes.push(new ColorElement(formElement, elType));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
break;
|
|
208
|
+
case "number":
|
|
209
|
+
|
|
210
|
+
if (!inputSupport.number) {
|
|
211
|
+
me.inputNodes.push(new NumberElement(formElement, elType));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
if (window.fdSliderController) {
|
|
222
|
+
fdSliderController.redrawAll();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (window.jscolor) {
|
|
226
|
+
jscolor.init();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
function delayedFireEvent(el, ev, callback){
|
|
234
|
+
|
|
235
|
+
if (!document.createEventObject ) {
|
|
236
|
+
me.fireEvent(el, ev);
|
|
237
|
+
if (callback) {
|
|
238
|
+
callback();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
if (delayEventTimeout != null) {
|
|
245
|
+
clearTimeout(delayEventTimeout)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
delayEventTimeout = setTimeout(
|
|
249
|
+
function(){
|
|
250
|
+
EventHelpers.fireEvent(el, ev);
|
|
251
|
+
|
|
252
|
+
if (callback) {
|
|
253
|
+
callback();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
, 1);
|
|
257
|
+
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
me.fireEvent = function(el, ev){
|
|
262
|
+
EventHelpers.fireEvent(el, ev);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
me.resolveOutputs = function (e) {
|
|
266
|
+
|
|
267
|
+
// This resolves the onforminput events on the output nodes
|
|
268
|
+
for (var i=0; i<me.outputNodes.length; i++) {
|
|
269
|
+
var outputNode = me.outputNodes[i];
|
|
270
|
+
outputNode.resolve();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// This resolves the oninput events on the form nodes
|
|
274
|
+
if (!supportsNatively['oninput']) {
|
|
275
|
+
for (var i=0; i<me.formElements.length; i++) {
|
|
276
|
+
var formNode = me.formElements[i];
|
|
277
|
+
var oninput = DOMHelpers.getAttributeValue(formNode, 'oninput');
|
|
278
|
+
if (oninput) {
|
|
279
|
+
eval(me.getValueFormula(oninput, formNode));
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
} else if (isIE9 && e) {
|
|
283
|
+
// must deal with buggy implementation - delete and backspace don't fire
|
|
284
|
+
// the oninput event
|
|
285
|
+
var input = EventHelpers.getEventTarget(e);
|
|
286
|
+
switch (e.type) {
|
|
287
|
+
|
|
288
|
+
case "keyup":
|
|
289
|
+
var key = EventHelpers.getKey(e);
|
|
290
|
+
|
|
291
|
+
switch (key) {
|
|
292
|
+
case 8:
|
|
293
|
+
case 46:
|
|
294
|
+
case 88:
|
|
295
|
+
EventHelpers.fireEvent(input.form, 'input');
|
|
296
|
+
}
|
|
297
|
+
break;
|
|
298
|
+
case "cut":
|
|
299
|
+
delayedFireEvent(input.form, 'input');
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
me.hideInput = function (node) {
|
|
307
|
+
|
|
308
|
+
node.style.position = 'absolute';
|
|
309
|
+
node.style.top = '-1000px';
|
|
310
|
+
node.style.left = '-1000px';
|
|
311
|
+
node.style.visibility = 'hidden'
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
me.getValueFormula = function(expr, parentForm) {
|
|
315
|
+
var formula = expr
|
|
316
|
+
if (formula == null) {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
formula = formula
|
|
320
|
+
.replace(valueRe, 'value')
|
|
321
|
+
.replace(varRe, 'document.forms["' + parentForm.id + '"].$1');
|
|
322
|
+
return formula;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
function showError(err) {
|
|
327
|
+
if (isDebug) {
|
|
328
|
+
alert(err);
|
|
329
|
+
}
|
|
330
|
+
throw(err);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
/*
|
|
336
|
+
* Range Element
|
|
337
|
+
*/
|
|
338
|
+
|
|
339
|
+
function RangeElement(node){
|
|
340
|
+
var me = this,
|
|
341
|
+
parentForm,
|
|
342
|
+
hasFiredChangeEvent = false;
|
|
343
|
+
|
|
344
|
+
me.node = node;
|
|
345
|
+
me.sliderNode = null;
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
function init (){
|
|
349
|
+
parentForm = DOMHelpers.getAncestorByTagName(node, 'form');
|
|
350
|
+
var min = parseFloat(DOMHelpers.getAttributeValue(me.node, 'min'));
|
|
351
|
+
var max = parseFloat(DOMHelpers.getAttributeValue(me.node, 'max'));
|
|
352
|
+
|
|
353
|
+
if (!window.fdSliderController) {
|
|
354
|
+
showError("slider.js must be included in order for the range element to work in this browser. See documentation for more details.");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (isNaN(min)) {
|
|
358
|
+
min = 0;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (isNaN(max)) {
|
|
362
|
+
max = 100;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
var step = DOMHelpers.getAttributeValue(me.node, 'step');
|
|
367
|
+
|
|
368
|
+
if (step == null) {
|
|
369
|
+
step = "1"
|
|
370
|
+
} else if (typeof(step) == 'number') {
|
|
371
|
+
step = step + "";
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Must add id if not there (Requirement of the script)
|
|
375
|
+
if (!me.node.id) {
|
|
376
|
+
me.node.id = "HTML5Form-slider" + getNextDummyID();
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
// Create an Object to hold the slider's initialisation data
|
|
382
|
+
var options = {
|
|
383
|
+
// A reference to the input
|
|
384
|
+
inp: me.node,
|
|
385
|
+
// A String containing the increment value (and the return precision, in this case 2 decimal places "x.20")
|
|
386
|
+
inc: step,
|
|
387
|
+
// Maximum keyboard increment (automatically uses double the normal increment if not given)
|
|
388
|
+
maxInc: step,
|
|
389
|
+
// Numeric range
|
|
390
|
+
range: [min, max],
|
|
391
|
+
// Callback functions
|
|
392
|
+
callbacks: {
|
|
393
|
+
"update": [me.changeEvent]
|
|
394
|
+
},
|
|
395
|
+
// String representing the classNames to give the created slider
|
|
396
|
+
classNames: "html5Widgets-slider fd_jump",
|
|
397
|
+
// Tween the handle onclick?
|
|
398
|
+
tween: false,
|
|
399
|
+
// Is this a vertical slider
|
|
400
|
+
vertical: false,
|
|
401
|
+
// Do we hide the associated input on slider creation
|
|
402
|
+
hideInput: false,
|
|
403
|
+
// Does the handle jump to the nearest click value point when the bar is clicked (tween cannot then be true)
|
|
404
|
+
clickJump: true,
|
|
405
|
+
// Full ARIA required
|
|
406
|
+
fullARIA: false,
|
|
407
|
+
// Do we disable the mouseWheel for this slider
|
|
408
|
+
noMouseWheel: false
|
|
409
|
+
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
// Create the slider
|
|
413
|
+
fdSliderController.createSlider(options);
|
|
414
|
+
|
|
415
|
+
//tweak styles
|
|
416
|
+
me.sliderNode = document.getElementById('fd-slider-' + me.node.id);
|
|
417
|
+
me.sliderNode.style.width = me.node.offsetWidth + "px";
|
|
418
|
+
|
|
419
|
+
elDisplay = me.node.style.display
|
|
420
|
+
if (elDisplay != 'block') {
|
|
421
|
+
me.sliderNode.style.display = 'inline-block';
|
|
422
|
+
//me.sliderNode.style.paddingTop = "0.9em";
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
html5Widgets.hideInput(me.node);
|
|
426
|
+
|
|
427
|
+
document.getElementById('fd-slider-' + me.node.id).style.zIndex = '0';
|
|
428
|
+
|
|
429
|
+
me.node.tabIndex = "-1";
|
|
430
|
+
me.node.type = "text";
|
|
431
|
+
|
|
432
|
+
// Event Handling
|
|
433
|
+
EventHelpers.addEvent(me.node, 'change', changeOriginalNodeEvent);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
me.changeEvent = function (e){
|
|
437
|
+
var oninput = DOMHelpers.getAttributeValue(parentForm, 'oninput');
|
|
438
|
+
|
|
439
|
+
if (oninput) {
|
|
440
|
+
eval(html5Widgets.getValueFormula(oninput, parentForm));
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/* The if statement is to prevent this to continuously fire in an endless loop */
|
|
444
|
+
if (!hasFiredChangeEvent) {
|
|
445
|
+
hasFiredChangeEvent = true;
|
|
446
|
+
delayedFireEvent(me.node, 'change', function () {
|
|
447
|
+
hasFiredChangeEvent = false;
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function changeOriginalNodeEvent(e) {
|
|
453
|
+
|
|
454
|
+
fdSliderController.updateSlider(me.node.id);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
init();
|
|
458
|
+
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function CalendarElement (node, type) {
|
|
462
|
+
var me = this;
|
|
463
|
+
|
|
464
|
+
me.node = node;
|
|
465
|
+
me.type = type;
|
|
466
|
+
|
|
467
|
+
var badDateTimeValueRe =
|
|
468
|
+
/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}Z{0,1}$/;
|
|
469
|
+
var displayDateTimeValueRe =
|
|
470
|
+
/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$/;
|
|
471
|
+
var originalVisibilityState;
|
|
472
|
+
|
|
473
|
+
function init() {
|
|
474
|
+
|
|
475
|
+
if (!window.Calendar && isDebug) {
|
|
476
|
+
showError("jscalendar scripts and CSS must be included for date and time form elements to work. See documentation for more details. ")
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Must add id if not there (Requirement of the script)
|
|
480
|
+
if (!me.node.id) {
|
|
481
|
+
me.node.id = "HTML5Form-calendar" + getNextDummyID();
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/*
|
|
485
|
+
* If this is the result of coming back to the page from history,
|
|
486
|
+
* then it may have an old reformatted version in it from a previous
|
|
487
|
+
* submit. Let's re-format it back.
|
|
488
|
+
*/
|
|
489
|
+
|
|
490
|
+
prepareForDisplay();
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
var formatString = "";
|
|
494
|
+
switch (me.type) {
|
|
495
|
+
case 'date':
|
|
496
|
+
formatString = "%Y-%m-%d";
|
|
497
|
+
break;
|
|
498
|
+
case 'month':
|
|
499
|
+
formatString = "%Y-%m";
|
|
500
|
+
break;
|
|
501
|
+
case 'week':
|
|
502
|
+
formatString = "%Y-W%W";
|
|
503
|
+
break;
|
|
504
|
+
case 'datetime':
|
|
505
|
+
placeUTCInfo();
|
|
506
|
+
case 'datetime-local':
|
|
507
|
+
case 'datetime':
|
|
508
|
+
formatString = "%Y-%m-%d %H:%M"
|
|
509
|
+
break;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/*
|
|
513
|
+
* Chrome, unfortunately, only implements type="date", and it's
|
|
514
|
+
* implementation displays the data in DD/MM/YYYY format. Even
|
|
515
|
+
* though it submits the data in YYYY-MM-DD format, this can
|
|
516
|
+
* be confusing to users if there is a, say, datetime widget
|
|
517
|
+
* with a date widget and they show different formats. In order
|
|
518
|
+
* to fix this, I change the type to "text" so that it uses the
|
|
519
|
+
* polyfill instead of the native one. Note that type="date"
|
|
520
|
+
* widgets in Chrome are only changed to type="text" when
|
|
521
|
+
* html5Forms.js's script tag has its
|
|
522
|
+
* data-webforms2-force-js-date-picker attribute set to "true".
|
|
523
|
+
*/
|
|
524
|
+
me.node.type = 'text';
|
|
525
|
+
|
|
526
|
+
//me.node.readOnly = true;
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
Calendar.setup(
|
|
531
|
+
{
|
|
532
|
+
eventName :"click",
|
|
533
|
+
showsTime : type.indexOf('time') >= 0,
|
|
534
|
+
cache : true,
|
|
535
|
+
inputField : me.node.id, // ID of the input field
|
|
536
|
+
ifFormat : formatString, // the date format
|
|
537
|
+
button : me.node.id // ID of the button
|
|
538
|
+
}
|
|
539
|
+
);
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
EventHelpers.addEvent(me.node, 'click', forceCalToTop);
|
|
546
|
+
EventHelpers.addEvent(me.node, 'focus', focusEvent)
|
|
547
|
+
EventHelpers.addEvent(me.node, 'keypress', openCalendar);
|
|
548
|
+
EventHelpers.addEvent(me.node, 'blur', closeCalendar);
|
|
549
|
+
|
|
550
|
+
EventHelpers.addEvent(me.node, 'keypress', keydownEvent)
|
|
551
|
+
//me.node.type = "text";
|
|
552
|
+
|
|
553
|
+
// this will call submitEvent() after the form has been validated by
|
|
554
|
+
// webforms2.js
|
|
555
|
+
if (window.$wf2) {
|
|
556
|
+
$wf2.callBeforeValidation.push(prepareForSubmission);
|
|
557
|
+
$wf2.callAfterValidation.push(validationEvent);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function placeUTCInfo() {
|
|
563
|
+
|
|
564
|
+
var label = document.createElement('span');
|
|
565
|
+
label.innerHTML = "UTC";
|
|
566
|
+
label.style.paddingLeft = "5px";
|
|
567
|
+
|
|
568
|
+
DOMHelpers.insertAfter(me.node, label);
|
|
569
|
+
|
|
570
|
+
var width = label.offsetWidth;
|
|
571
|
+
|
|
572
|
+
me.node.style.width = (me.node.offsetWidth - 5 - width) + 'px';
|
|
573
|
+
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
function prepareForSubmission() {
|
|
577
|
+
var splitVals;
|
|
578
|
+
|
|
579
|
+
switch (me.type) {
|
|
580
|
+
case "datetime":
|
|
581
|
+
case "datetime-local":
|
|
582
|
+
|
|
583
|
+
originalVisibilityState = me.node.style.visibility;
|
|
584
|
+
me.node.style.visibility = 'hidden';
|
|
585
|
+
if (me.node.value.match(displayDateTimeValueRe)) {
|
|
586
|
+
splitVals = me.node.value.split(' ');
|
|
587
|
+
me.node.value = splitVals[0] + "T" + splitVals[1];
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
switch (me.type) {
|
|
591
|
+
case "datetime-local":
|
|
592
|
+
break;
|
|
593
|
+
case "datetime":
|
|
594
|
+
if (me.node.value != "") {
|
|
595
|
+
me.node.value += "Z";
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
function prepareForDisplay() {
|
|
603
|
+
switch(me.type) {
|
|
604
|
+
case "datetime":
|
|
605
|
+
case "datetime-local":
|
|
606
|
+
if ( me.node.value.match(badDateTimeValueRe)) {
|
|
607
|
+
me.node.value = me.node.value.replace(/T/, ' ').replace(/Z/, '');
|
|
608
|
+
}
|
|
609
|
+
if (originalVisibilityState != null) {
|
|
610
|
+
me.node.style.visibility = originalVisibilityState;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function validationEvent(e, hasValidated) {
|
|
619
|
+
if (!hasValidated) {
|
|
620
|
+
prepareForDisplay();
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
function forceCalToTop(e) {
|
|
625
|
+
var cal = window.calendar;
|
|
626
|
+
|
|
627
|
+
cal.element.style.zIndex = 100;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
function focusEvent(e) {
|
|
631
|
+
var el = EventHelpers.getEventTarget(e);
|
|
632
|
+
EventHelpers.fireEvent(el, 'click')
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
function openCalendar(e) {
|
|
636
|
+
|
|
637
|
+
var cal = window.calendar;
|
|
638
|
+
|
|
639
|
+
cal.element.style.zIndex = 100;
|
|
640
|
+
if (cal.open != undefined) {
|
|
641
|
+
cal.open();
|
|
642
|
+
}
|
|
643
|
+
//EventHelpers.fireEvent(this, 'blur');
|
|
644
|
+
//EventHelpers.fireEvent(this, 'focus');
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
function closeCalendar(e){
|
|
648
|
+
|
|
649
|
+
var cal = window.calendar;
|
|
650
|
+
if (cal) {
|
|
651
|
+
cal.hide();
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
function keydownEvent(e) {
|
|
656
|
+
|
|
657
|
+
var c = EventHelpers.getKey(e);
|
|
658
|
+
|
|
659
|
+
switch(c){
|
|
660
|
+
case 13:
|
|
661
|
+
html5Widgets.dummyLink.focus();
|
|
662
|
+
this.focus();
|
|
663
|
+
EventHelpers.preventDefault(e);
|
|
664
|
+
openCalendar(e);
|
|
665
|
+
break;
|
|
666
|
+
case 9:
|
|
667
|
+
closeCalendar(e);
|
|
668
|
+
break;
|
|
669
|
+
default:
|
|
670
|
+
EventHelpers.preventDefault(e);
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
function submitEvent(e) {
|
|
678
|
+
prepareForSubmission();
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
init();
|
|
682
|
+
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
/*
|
|
692
|
+
* Output Element
|
|
693
|
+
*/
|
|
694
|
+
function OutputElement (node) {
|
|
695
|
+
var me = this;
|
|
696
|
+
me.node = node;
|
|
697
|
+
|
|
698
|
+
var value;
|
|
699
|
+
var valueFormula;
|
|
700
|
+
var parentForm;
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
function init () {
|
|
705
|
+
parentForm = DOMHelpers.getAncestorByTagName(node, 'form');
|
|
706
|
+
if (!parentForm.id) {
|
|
707
|
+
parentForm.id = getNextDummyID();
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
valueFormula = html5Widgets.getValueFormula(DOMHelpers.getAttributeValue(me.node, 'onforminput'), parentForm);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
me.resolve = function () {
|
|
716
|
+
if (valueFormula == null) {
|
|
717
|
+
return;
|
|
718
|
+
} else {
|
|
719
|
+
eval(valueFormula);
|
|
720
|
+
me.node.innerHTML = value;
|
|
721
|
+
me.node.value = value;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
init();
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
function ColorElement (node) {
|
|
731
|
+
var me = this;
|
|
732
|
+
|
|
733
|
+
/* note: color picker setPad() is what you are looking for */
|
|
734
|
+
me.node = node;
|
|
735
|
+
|
|
736
|
+
function init () {
|
|
737
|
+
if (!window.jscolor) {
|
|
738
|
+
showError('jscolor script must be included in order for the color input type to work in this browser. See documentation for more details.')
|
|
739
|
+
}
|
|
740
|
+
CSSHelpers.addClass(me.node, 'color');
|
|
741
|
+
CSSHelpers.addClass(me.node, '{hash:true,caps:false}');
|
|
742
|
+
me.node.type = "text";
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
init();
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/*
|
|
750
|
+
* NumberElement: refactored from http://www.kethinov.com/jsstepper.php.
|
|
751
|
+
*/
|
|
752
|
+
|
|
753
|
+
function NumberElement (node) {
|
|
754
|
+
var me = this,
|
|
755
|
+
min = parseFloat(DOMHelpers.getAttributeValue(node, 'min')),
|
|
756
|
+
max = parseFloat(DOMHelpers.getAttributeValue(node, 'max')),
|
|
757
|
+
step = parseFloat(DOMHelpers.getAttributeValue(node, 'step'));
|
|
758
|
+
|
|
759
|
+
me.node = node;
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
if (isNaN(step)) {
|
|
764
|
+
// we don't have to create the up and down arraw widgets
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
EventHelpers.addEvent(node, 'keyup', keyUpEvent);
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
function keyUpEvent() {
|
|
772
|
+
|
|
773
|
+
if (isNumeric(this.value)) {
|
|
774
|
+
|
|
775
|
+
/* if (this.value > max) this.value = max;
|
|
776
|
+
else if (this.value < min) this.value = this.min; */
|
|
777
|
+
|
|
778
|
+
} else if (this.value != '') {
|
|
779
|
+
var val = parseFloat(this.value);
|
|
780
|
+
if (isNaN(val)) {
|
|
781
|
+
this.value = '';
|
|
782
|
+
} else {
|
|
783
|
+
this.value = val;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
function nearestValid(value, direction) {
|
|
792
|
+
|
|
793
|
+
var n = (value - min)/step,
|
|
794
|
+
r;
|
|
795
|
+
//alert(StringHelpers.sprintf("n: %s, value: %s, min: %s, step: %s", n, value, min, step))
|
|
796
|
+
if (n == parseInt(n)) {
|
|
797
|
+
r = value;
|
|
798
|
+
} else {
|
|
799
|
+
|
|
800
|
+
if (direction < 0) {
|
|
801
|
+
n = Math.floor(n + 1);
|
|
802
|
+
} else {
|
|
803
|
+
n = Math.ceil(n -1);
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
r = min + step * n;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
if (r > max) {
|
|
810
|
+
r -= step;
|
|
811
|
+
} else if (r < min) {
|
|
812
|
+
r+= step
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
return r;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
function buttonMouseDownEvent(e) {
|
|
819
|
+
|
|
820
|
+
var buttonType = this.className;
|
|
821
|
+
var stepMult = step;
|
|
822
|
+
if (buttonType == 'dnbutton') {
|
|
823
|
+
stepMult = -step;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
var min = this.min;
|
|
828
|
+
var max = this.max;
|
|
829
|
+
if (
|
|
830
|
+
(stepMult < 0 && (node.value > min || isNaN(min))) ||
|
|
831
|
+
(stepMult > 0 && (node.value < max || isNaN(max)))
|
|
832
|
+
) {
|
|
833
|
+
setValue(me.node, nearestValid(parseFloat(node.value) + stepMult, stepMult));
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
var delayedOnce = false;
|
|
837
|
+
var date = new Date();
|
|
838
|
+
var curDate = null;
|
|
839
|
+
|
|
840
|
+
this.interval = setInterval(function() {
|
|
841
|
+
if (!delayedOnce) {
|
|
842
|
+
curDate = new Date();
|
|
843
|
+
if (curDate - date > 500) delayedOnce = true;
|
|
844
|
+
}
|
|
845
|
+
else if (
|
|
846
|
+
(stepMult < 0 && (node.value > min || isNaN(min))) ||
|
|
847
|
+
(stepMult > 0 && (node.value < max || isNaN(max)))
|
|
848
|
+
) {
|
|
849
|
+
setValue(me.node, nearestValid(parseFloat(node.value) + stepMult, stepMult));
|
|
850
|
+
}
|
|
851
|
+
}, 50);
|
|
852
|
+
EventHelpers.preventDefault(e);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
function setValue(node, value) {
|
|
856
|
+
if (isNaN(value)) {
|
|
857
|
+
node.value = '';
|
|
858
|
+
} else {
|
|
859
|
+
node.value = value;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
function buttonClickEvent(e) {
|
|
864
|
+
clearInterval(this.interval);
|
|
865
|
+
EventHelpers.preventDefault(e);
|
|
866
|
+
}
|
|
867
|
+
function buttonMouseUpEvent(e) {
|
|
868
|
+
clearInterval(this.interval);
|
|
869
|
+
EventHelpers.preventDefault(e);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
function isNumeric(n) {
|
|
873
|
+
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
function hasNativeSpinner() {
|
|
878
|
+
try {
|
|
879
|
+
return window.getComputedStyle(me.node, '-webkit-inner-spin-button').WebkitAppearance != undefined;
|
|
880
|
+
} catch (ex) {
|
|
881
|
+
return false;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
function init () {
|
|
886
|
+
var upbutton = document.createElement('a');
|
|
887
|
+
upbutton.className = 'upbutton';
|
|
888
|
+
upbutton.appendChild(document.createTextNode("\u25B2"));
|
|
889
|
+
upbutton.targInput = node;
|
|
890
|
+
upbutton.max = max;
|
|
891
|
+
|
|
892
|
+
var dnbutton = document.createElement('a');
|
|
893
|
+
dnbutton.className = 'dnbutton';
|
|
894
|
+
dnbutton.appendChild(document.createTextNode("\u25BC"));
|
|
895
|
+
dnbutton.targInput = node;
|
|
896
|
+
dnbutton.min = min;
|
|
897
|
+
dnbutton.max = max;
|
|
898
|
+
|
|
899
|
+
EventHelpers.addEvent(upbutton, 'mousedown', buttonMouseDownEvent);
|
|
900
|
+
EventHelpers.addEvent(dnbutton, 'mousedown', buttonMouseDownEvent);
|
|
901
|
+
|
|
902
|
+
EventHelpers.addEvent(upbutton, 'click', buttonClickEvent);
|
|
903
|
+
EventHelpers.addEvent(upbutton, 'mouseup', buttonMouseUpEvent);
|
|
904
|
+
EventHelpers.addEvent(dnbutton, 'click', buttonClickEvent);
|
|
905
|
+
EventHelpers.addEvent(dnbutton, 'mouseup', buttonMouseUpEvent);
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
if (!hasNativeSpinner()) {
|
|
909
|
+
var controlsNode = document.createElement('div');
|
|
910
|
+
controlsNode.className = 'html5-numberControls';
|
|
911
|
+
controlsNode.appendChild(upbutton);
|
|
912
|
+
controlsNode.appendChild(dnbutton);
|
|
913
|
+
|
|
914
|
+
var wrapperNode = document.createElement('div')
|
|
915
|
+
wrapperNode.className = 'html5-numberWrapper';
|
|
916
|
+
wrapperNode.appendChild(controlsNode);
|
|
917
|
+
var parentNode = node.parentNode;
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
parentNode.insertBefore(wrapperNode, node);
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
var nodeWidth = node.offsetWidth;
|
|
926
|
+
var nodeStyle = CSSHelpers.getCurrentStyle(node);
|
|
927
|
+
|
|
928
|
+
node.style.width = (nodeWidth - upbutton.offsetWidth -9) + 'px';
|
|
929
|
+
wrapperNode.style.width = nodeWidth + 'px';
|
|
930
|
+
wrapperNode.style.marginTop = nodeStyle.marginTop;
|
|
931
|
+
wrapperNode.style.height = (node.offsetHeight) + 'px';
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
}
|
|
937
|
+
/* Finally: if the form field has a value onload that is not a number, remove it
|
|
938
|
+
if (!isNumeric(node.value)) {
|
|
939
|
+
node.value = '';
|
|
940
|
+
EventHelpers.fireEvent(node, 'change');
|
|
941
|
+
}*/
|
|
942
|
+
init();
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
function PlaceholderInput (node) {
|
|
946
|
+
var me = this;
|
|
947
|
+
|
|
948
|
+
me.node = node;
|
|
949
|
+
|
|
950
|
+
var form, defaultText;
|
|
951
|
+
|
|
952
|
+
function init () {
|
|
953
|
+
defaultText = DOMHelpers.getAttributeValue(node, 'placeholder');
|
|
954
|
+
form = DOMHelpers.getAncestorByTagName(node, 'form');
|
|
955
|
+
|
|
956
|
+
me.setPlaceholderText(true);
|
|
957
|
+
EventHelpers.addEvent(me.node, 'blur', blurEvent);
|
|
958
|
+
EventHelpers.addEvent(me.node, 'focus', focusEvent);
|
|
959
|
+
|
|
960
|
+
if (me.node.form) {
|
|
961
|
+
EventHelpers.addEvent(me.node.form, 'submit', removePlaceholderText);
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
if (window.$wf2) {
|
|
965
|
+
if ($wf2.callBeforeValidation != undefined) {
|
|
966
|
+
$wf2.callBeforeValidation.push(removePlaceholderText);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
if ($wf2.callAfterValidation != undefined) {
|
|
970
|
+
$wf2.callAfterValidation.push(postValidationEvent);
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
me.setPlaceholderText = function (isLoadEvent) {
|
|
976
|
+
//jslog.debug(StringHelpers.sprintf('initiator: %s', this));
|
|
977
|
+
var isAutofocus = DOMHelpers.getAttributeValue(me.node, 'autofocus') != null;
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
if (me.node.value == "" || (isLoadEvent && me.node.value == defaultText)) {
|
|
981
|
+
CSSHelpers.addClass(me.node, 'html5-hasPlaceholderText');
|
|
982
|
+
me.node.value = defaultText;
|
|
983
|
+
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
if (isLoadEvent && isAutofocus && me.node.value == defaultText ) {
|
|
987
|
+
CSSHelpers.removeClass(me.node, 'html5-hasPlaceholderText');
|
|
988
|
+
me.node.value = '';
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
function focusEvent(e) {
|
|
996
|
+
|
|
997
|
+
CSSHelpers.addClass(me.node, 'html5-hasFocus');
|
|
998
|
+
removePlaceholderText();
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
function blurEvent(e) {
|
|
1002
|
+
//jslog.debug('removed focus on ' + me.node.name)
|
|
1003
|
+
CSSHelpers.removeClass(me.node, 'html5-hasFocus');
|
|
1004
|
+
me.setPlaceholderText();
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
function removePlaceholderText() {
|
|
1008
|
+
//jslog.debug('removePlaceholderText() for ' + me.node.name)
|
|
1009
|
+
if (CSSHelpers.isMemberOfClass(me.node, 'html5-hasPlaceholderText')) {
|
|
1010
|
+
me.node.value = "";
|
|
1011
|
+
CSSHelpers.removeClass(me.node, 'html5-hasPlaceholderText');
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
function postValidationEvent(e, didValidate) {
|
|
1016
|
+
////jslog.debug(StringHelpers.sprintf('post Validation: %s, didValidate = %s, has focus = %s', me.node.name, didValidate, CSSHelpers.isMemberOfClass(me.node, 'html5-hasFocus') ) )
|
|
1017
|
+
if (!didValidate && !CSSHelpers.isMemberOfClass(me.node, 'html5-hasFocus')) {
|
|
1018
|
+
me.setPlaceholderText();
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
init();
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
var CSSHelpers = new function () {
|
|
1026
|
+
var me = this;
|
|
1027
|
+
|
|
1028
|
+
var blankRe = new RegExp('\\s');
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* Generates a regular expression string that can be used to detect a class name
|
|
1032
|
+
* in a tag's class attribute. It is used by a few methods, so I
|
|
1033
|
+
* centralized it.
|
|
1034
|
+
*
|
|
1035
|
+
* @param {String} className - a name of a CSS class.
|
|
1036
|
+
*/
|
|
1037
|
+
|
|
1038
|
+
function getClassReString(className) {
|
|
1039
|
+
return '\\s'+className+'\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className +'$';
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
function getClassPrefixReString(className) {
|
|
1043
|
+
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_]+$';
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
|
|
1047
|
+
/**
|
|
1048
|
+
* Make an HTML object be a member of a certain class.
|
|
1049
|
+
*
|
|
1050
|
+
* @param {Object} obj - an HTML object
|
|
1051
|
+
* @param {String} className - a CSS class name.
|
|
1052
|
+
*/
|
|
1053
|
+
me.addClass = function (obj, className) {
|
|
1054
|
+
|
|
1055
|
+
if (blankRe.test(className)) {
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// only add class if the object is not a member of it yet.
|
|
1060
|
+
if (!me.isMemberOfClass(obj, className)) {
|
|
1061
|
+
obj.className += " " + className;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* Make an HTML object *not* be a member of a certain class.
|
|
1068
|
+
*
|
|
1069
|
+
* @param {Object} obj - an HTML object
|
|
1070
|
+
* @param {Object} className - a CSS class name.
|
|
1071
|
+
*/
|
|
1072
|
+
me.removeClass = function (obj, className) {
|
|
1073
|
+
|
|
1074
|
+
if (blankRe.test(className)) {
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
var re = new RegExp(getClassReString(className) , "g");
|
|
1080
|
+
|
|
1081
|
+
var oldClassName = obj.className;
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
if (obj.className) {
|
|
1085
|
+
obj.className = oldClassName.replace(re, ' ');
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* Determines if an HTML object is a member of a specific class.
|
|
1092
|
+
* @param {Object} obj - an HTML object.
|
|
1093
|
+
* @param {Object} className - the CSS class name.
|
|
1094
|
+
*/
|
|
1095
|
+
me.isMemberOfClass = function (obj, className) {
|
|
1096
|
+
|
|
1097
|
+
if (blankRe.test(className))
|
|
1098
|
+
return false;
|
|
1099
|
+
|
|
1100
|
+
var re = new RegExp(getClassReString(className) , "g");
|
|
1101
|
+
|
|
1102
|
+
return (re.test(obj.className));
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/* from http://blog.stchur.com/2006/06/21/css-computed-style/ */
|
|
1108
|
+
me.getCurrentStyle = function(obj)
|
|
1109
|
+
{
|
|
1110
|
+
var computedStyle;
|
|
1111
|
+
if (typeof obj.currentStyle != 'undefined')
|
|
1112
|
+
{ computedStyle = obj.currentStyle; }
|
|
1113
|
+
else
|
|
1114
|
+
{ computedStyle = document.defaultView.getComputedStyle(obj, null); }
|
|
1115
|
+
|
|
1116
|
+
return computedStyle;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
var DOMHelpers = new function () {
|
|
1123
|
+
var me = this;
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Given an HTML or XML object, find the an attribute by name.
|
|
1127
|
+
*
|
|
1128
|
+
* @param {Object} obj - a DOM object.
|
|
1129
|
+
* @param {String} attrName - the name of an attribute inside the DOM object.
|
|
1130
|
+
* @return {Object} - the attribute object or null if there isn't one.
|
|
1131
|
+
*/
|
|
1132
|
+
me.getAttributeByName = function (obj, attrName) {
|
|
1133
|
+
var i;
|
|
1134
|
+
|
|
1135
|
+
var attributes = obj.attributes;
|
|
1136
|
+
for (i=0; i<attributes.length; i++) {
|
|
1137
|
+
var attr = attributes[i]
|
|
1138
|
+
if (attr.nodeName == attrName && attr.specified) {
|
|
1139
|
+
return attr;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
return null;
|
|
1143
|
+
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Given an HTML or XML object, find the value of an attribute.
|
|
1146
|
+
*
|
|
1147
|
+
* @param {Object} obj - a DOM object.
|
|
1148
|
+
* @param {String} attrName - the name of an attribute inside the DOM object.
|
|
1149
|
+
* @return {String} - the value of the attribute.
|
|
1150
|
+
*/
|
|
1151
|
+
me.getAttributeValue = function (obj, attrName) {
|
|
1152
|
+
var attr = me.getAttributeByName(obj, attrName);
|
|
1153
|
+
|
|
1154
|
+
if (attr != null) {
|
|
1155
|
+
return attr.nodeValue;
|
|
1156
|
+
} else {
|
|
1157
|
+
var typeRe = new RegExp(attrName + '=(\\"([a-zA-Z\-]*)\\"|[a-zA-Z\-]*)');
|
|
1158
|
+
//jslog.debug(XMLHelpers.getOuterXML(obj))
|
|
1159
|
+
var typeVal = XMLHelpers.getOuterXML(obj).split('>')[0].match(typeRe);
|
|
1160
|
+
//jslog.debug(typeVal)
|
|
1161
|
+
if (typeVal && typeVal.length >= 1) {
|
|
1162
|
+
return typeVal[1].replace(quoteRe, '');
|
|
1163
|
+
} else {
|
|
1164
|
+
return null;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
me.insertAfter = function (refNode, nodeToInsert) {
|
|
1171
|
+
var parent = refNode.parentNode;
|
|
1172
|
+
|
|
1173
|
+
var nextSibling = refNode.nextSibling;
|
|
1174
|
+
if (nextSibling) {
|
|
1175
|
+
parent.insertBefore(nodeToInsert, nextSibling);
|
|
1176
|
+
} else {
|
|
1177
|
+
parent.appendChild(nodeToInsert);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/**
|
|
1182
|
+
* Given an tag, find the first ancestor tag of a given tag name.
|
|
1183
|
+
*
|
|
1184
|
+
* @param {Object} obj - a HTML or XML tag.
|
|
1185
|
+
* @param {String} tagName - the name of the ancestor tag to find.
|
|
1186
|
+
* @return {Object} - the ancestor tag, or null if not found.
|
|
1187
|
+
*/
|
|
1188
|
+
me.getAncestorByTagName = function(obj, tagName) {
|
|
1189
|
+
|
|
1190
|
+
for (var node = obj.parentNode;
|
|
1191
|
+
node.nodeName.toLowerCase() != 'body';
|
|
1192
|
+
node = node.parentNode) {
|
|
1193
|
+
|
|
1194
|
+
if (tagName.toLowerCase() == node.nodeName.toLowerCase()) {
|
|
1195
|
+
return node;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
}
|
|
1199
|
+
return null;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
me.removeNode = function (node) {
|
|
1203
|
+
var parentNode = node.parentNode;
|
|
1204
|
+
if (parentNode) {
|
|
1205
|
+
parentNode.removeChild(node);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
var StringHelpers = new function () {
|
|
1212
|
+
var me = this;
|
|
1213
|
+
|
|
1214
|
+
/*******************************************************************************
|
|
1215
|
+
* Function sprintf(format_string,arguments...) Javascript emulation of the C
|
|
1216
|
+
* printf function (modifiers and argument types "p" and "n" are not supported
|
|
1217
|
+
* due to language restrictions)
|
|
1218
|
+
*
|
|
1219
|
+
* Copyright 2003 K&L Productions. All rights reserved
|
|
1220
|
+
* http://www.klproductions.com
|
|
1221
|
+
*
|
|
1222
|
+
* Terms of use: This function can be used free of charge IF this header is not
|
|
1223
|
+
* modified and remains with the function code.
|
|
1224
|
+
*
|
|
1225
|
+
* Legal: Use this code at your own risk. K&L Productions assumes NO
|
|
1226
|
+
* resposibility for anything.
|
|
1227
|
+
******************************************************************************/
|
|
1228
|
+
me.sprintf = function (fstring)
|
|
1229
|
+
{ var pad = function(str,ch,len)
|
|
1230
|
+
{ var ps='';
|
|
1231
|
+
for(var i=0; i<Math.abs(len); i++) ps+=ch;
|
|
1232
|
+
return len>0?str+ps:ps+str;
|
|
1233
|
+
}
|
|
1234
|
+
var processFlags = function(flags,width,rs,arg)
|
|
1235
|
+
{ var pn = function(flags,arg,rs)
|
|
1236
|
+
{ if(arg>=0)
|
|
1237
|
+
{ if(flags.indexOf(' ')>=0) rs = ' ' + rs;
|
|
1238
|
+
else if(flags.indexOf('+')>=0) rs = '+' + rs;
|
|
1239
|
+
}
|
|
1240
|
+
else
|
|
1241
|
+
rs = '-' + rs;
|
|
1242
|
+
return rs;
|
|
1243
|
+
}
|
|
1244
|
+
var iWidth = parseInt(width,10);
|
|
1245
|
+
if(width.charAt(0) == '0')
|
|
1246
|
+
{ var ec=0;
|
|
1247
|
+
if(flags.indexOf(' ')>=0 || flags.indexOf('+')>=0) ec++;
|
|
1248
|
+
if(rs.length<(iWidth-ec)) rs = pad(rs,'0',rs.length-(iWidth-ec));
|
|
1249
|
+
return pn(flags,arg,rs);
|
|
1250
|
+
}
|
|
1251
|
+
rs = pn(flags,arg,rs);
|
|
1252
|
+
if(rs.length<iWidth)
|
|
1253
|
+
{ if(flags.indexOf('-')<0) rs = pad(rs,' ',rs.length-iWidth);
|
|
1254
|
+
else rs = pad(rs,' ',iWidth - rs.length);
|
|
1255
|
+
}
|
|
1256
|
+
return rs;
|
|
1257
|
+
}
|
|
1258
|
+
var converters = new Array();
|
|
1259
|
+
converters['c'] = function(flags,width,precision,arg)
|
|
1260
|
+
{ if(typeof(arg) == 'number') return String.fromCharCode(arg);
|
|
1261
|
+
if(typeof(arg) == 'string') return arg.charAt(0);
|
|
1262
|
+
return '';
|
|
1263
|
+
}
|
|
1264
|
+
converters['d'] = function(flags,width,precision,arg)
|
|
1265
|
+
{ return converters['i'](flags,width,precision,arg);
|
|
1266
|
+
}
|
|
1267
|
+
converters['u'] = function(flags,width,precision,arg)
|
|
1268
|
+
{ return converters['i'](flags,width,precision,Math.abs(arg));
|
|
1269
|
+
}
|
|
1270
|
+
converters['i'] = function(flags,width,precision,arg)
|
|
1271
|
+
{ var iPrecision=parseInt(precision);
|
|
1272
|
+
var rs = ((Math.abs(arg)).toString().split('.'))[0];
|
|
1273
|
+
if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
|
|
1274
|
+
return processFlags(flags,width,rs,arg);
|
|
1275
|
+
}
|
|
1276
|
+
converters['E'] = function(flags,width,precision,arg)
|
|
1277
|
+
{ return (converters['e'](flags,width,precision,arg)).toUpperCase();
|
|
1278
|
+
}
|
|
1279
|
+
converters['e'] = function(flags,width,precision,arg)
|
|
1280
|
+
{ iPrecision = parseInt(precision);
|
|
1281
|
+
if(isNaN(iPrecision)) iPrecision = 6;
|
|
1282
|
+
rs = (Math.abs(arg)).toExponential(iPrecision);
|
|
1283
|
+
if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) rs = rs.replace(/^(.*)(e.*)$/,'$1.$2');
|
|
1284
|
+
return processFlags(flags,width,rs,arg);
|
|
1285
|
+
}
|
|
1286
|
+
converters['f'] = function(flags,width,precision,arg)
|
|
1287
|
+
{ iPrecision = parseInt(precision);
|
|
1288
|
+
if(isNaN(iPrecision)) iPrecision = 6;
|
|
1289
|
+
rs = (Math.abs(arg)).toFixed(iPrecision);
|
|
1290
|
+
if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) rs = rs + '.';
|
|
1291
|
+
return processFlags(flags,width,rs,arg);
|
|
1292
|
+
}
|
|
1293
|
+
converters['G'] = function(flags,width,precision,arg)
|
|
1294
|
+
{ return (converters['g'](flags,width,precision,arg)).toUpperCase();
|
|
1295
|
+
}
|
|
1296
|
+
converters['g'] = function(flags,width,precision,arg)
|
|
1297
|
+
{ iPrecision = parseInt(precision);
|
|
1298
|
+
absArg = Math.abs(arg);
|
|
1299
|
+
rse = absArg.toExponential();
|
|
1300
|
+
rsf = absArg.toFixed(6);
|
|
1301
|
+
if(!isNaN(iPrecision))
|
|
1302
|
+
{ rsep = absArg.toExponential(iPrecision);
|
|
1303
|
+
rse = rsep.length < rse.length ? rsep : rse;
|
|
1304
|
+
rsfp = absArg.toFixed(iPrecision);
|
|
1305
|
+
rsf = rsfp.length < rsf.length ? rsfp : rsf;
|
|
1306
|
+
}
|
|
1307
|
+
if(rse.indexOf('.')<0 && flags.indexOf('#')>=0) rse = rse.replace(/^(.*)(e.*)$/,'$1.$2');
|
|
1308
|
+
if(rsf.indexOf('.')<0 && flags.indexOf('#')>=0) rsf = rsf + '.';
|
|
1309
|
+
rs = rse.length<rsf.length ? rse : rsf;
|
|
1310
|
+
return processFlags(flags,width,rs,arg);
|
|
1311
|
+
}
|
|
1312
|
+
converters['o'] = function(flags,width,precision,arg)
|
|
1313
|
+
{ var iPrecision=parseInt(precision);
|
|
1314
|
+
var rs = Math.round(Math.abs(arg)).toString(8);
|
|
1315
|
+
if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
|
|
1316
|
+
if(flags.indexOf('#')>=0) rs='0'+rs;
|
|
1317
|
+
return processFlags(flags,width,rs,arg);
|
|
1318
|
+
}
|
|
1319
|
+
converters['X'] = function(flags,width,precision,arg)
|
|
1320
|
+
{ return (converters['x'](flags,width,precision,arg)).toUpperCase();
|
|
1321
|
+
}
|
|
1322
|
+
converters['x'] = function(flags,width,precision,arg)
|
|
1323
|
+
{ var iPrecision=parseInt(precision);
|
|
1324
|
+
arg = Math.abs(arg);
|
|
1325
|
+
var rs = Math.round(arg).toString(16);
|
|
1326
|
+
if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
|
|
1327
|
+
if(flags.indexOf('#')>=0) rs='0x'+rs;
|
|
1328
|
+
return processFlags(flags,width,rs,arg);
|
|
1329
|
+
}
|
|
1330
|
+
converters['s'] = function(flags,width,precision,arg)
|
|
1331
|
+
{ var iPrecision=parseInt(precision);
|
|
1332
|
+
var rs = arg;
|
|
1333
|
+
if(rs.length > iPrecision) rs = rs.substring(0,iPrecision);
|
|
1334
|
+
return processFlags(flags,width,rs,0);
|
|
1335
|
+
}
|
|
1336
|
+
farr = fstring.split('%');
|
|
1337
|
+
retstr = farr[0];
|
|
1338
|
+
fpRE = /^([-+ #]*)(\d*)\.?(\d*)([cdieEfFgGosuxX])(.*)$/;
|
|
1339
|
+
for(var i=1; i<farr.length; i++)
|
|
1340
|
+
{ fps=fpRE.exec(farr[i]);
|
|
1341
|
+
if(!fps) continue;
|
|
1342
|
+
if(arguments[i]!=null) retstr+=converters[fps[4]](fps[1],fps[2],fps[3],arguments[i]);
|
|
1343
|
+
retstr += fps[5];
|
|
1344
|
+
}
|
|
1345
|
+
return retstr;
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
var XMLHelpers = new function () {
|
|
1350
|
+
var me = this;
|
|
1351
|
+
|
|
1352
|
+
/**
|
|
1353
|
+
* Given an XML node, return the XML inside as a string and the XML string of the node itself.
|
|
1354
|
+
* Similar to Internet Explorer's outerHTML property, except it is for XML, not HTML.
|
|
1355
|
+
* Created with information from http://www.codingforums.com/showthread.php?t=31489
|
|
1356
|
+
* and http://www.mercurytide.co.uk/whitepapers/issues-working-with-ajax/
|
|
1357
|
+
*
|
|
1358
|
+
* @param {Object} node - a DOM object.
|
|
1359
|
+
* @param {Object} options - a JS object containing options. To date,
|
|
1360
|
+
* the only one supported is "insertClosingTags", when set to
|
|
1361
|
+
* true, converts self closing tags, like <td />, to <td></td>.
|
|
1362
|
+
* @return {String} - the XML String inside the object.
|
|
1363
|
+
*/
|
|
1364
|
+
me.getOuterXML = function (node, options) {
|
|
1365
|
+
var r;
|
|
1366
|
+
// Internet Explorer
|
|
1367
|
+
if (node.xml) {
|
|
1368
|
+
r = node.xml;
|
|
1369
|
+
|
|
1370
|
+
// Everyone else
|
|
1371
|
+
} else if (node.outerHTML) {
|
|
1372
|
+
r = node.outerHTML;
|
|
1373
|
+
} else if (window.XMLSerializer) {
|
|
1374
|
+
|
|
1375
|
+
var serializer = new XMLSerializer();
|
|
1376
|
+
var text = serializer.serializeToString(node);
|
|
1377
|
+
r = text;
|
|
1378
|
+
} else {
|
|
1379
|
+
return null;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
/*
|
|
1383
|
+
* If the XML is actually HTML and you are inserting it into an HTML
|
|
1384
|
+
* document, you must use the "insertClosingTags" option, otherwise
|
|
1385
|
+
* Opera will not like you, especially if you have empty <td> tags.
|
|
1386
|
+
*/
|
|
1387
|
+
if (options) {
|
|
1388
|
+
if (options.insertClosingTags) {
|
|
1389
|
+
r = r.replace(selfClosingTagRe, "<$1></$1>");
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
return r;
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
|
|
1397
|
+
// default styles
|
|
1398
|
+
var placeholderCSS = 'color: #999999; font-style: italic';
|
|
1399
|
+
var placeholderRequiredCSS = 'color: #ffcccc !important;'
|
|
1400
|
+
|
|
1401
|
+
var sb = "";
|
|
1402
|
+
|
|
1403
|
+
// has to be two seperate rules, or some browsers, like firefox, will not use the rule.
|
|
1404
|
+
if (document.getElementsByTagName('body').length == 0) {
|
|
1405
|
+
sb = '<style type="text/css" id="testCSS">' +
|
|
1406
|
+
StringHelpers.sprintf('.html5-hasPlaceholderText{%s} input::-webkit-input-placeholder {%s}', placeholderCSS, placeholderCSS) +
|
|
1407
|
+
'</style>';
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
document.write(sb);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
EventHelpers.addPageLoadEvent('html5Widgets.init');
|
|
1417
|
+
|