polymer-rails-forms 0.2.01 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/assets/rails-forms/rails-form-helpers.html +295 -422
- data/assets/rails-forms/rails-form-validators.html +24 -18
- data/assets/rails-forms/rails-form.html +533 -186
- metadata +4 -3
@@ -2,16 +2,12 @@
|
|
2
2
|
/* TODO clean this up */
|
3
3
|
var FormHelpers = {
|
4
4
|
/* Utility things */
|
5
|
-
log: function(o){
|
6
|
-
console.log("Data", o)
|
7
|
-
},
|
8
|
-
|
9
5
|
capitalize: function(str){
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
if (str && str.length > 1){
|
7
|
+
return str.split(" ").map( function(s){ return s[0].toUpperCase() + s.substr(1) } ).join(" ");
|
8
|
+
} else {
|
9
|
+
return "";
|
10
|
+
}
|
15
11
|
},
|
16
12
|
|
17
13
|
findParent: function(el, selector){
|
@@ -52,132 +48,6 @@
|
|
52
48
|
}
|
53
49
|
},
|
54
50
|
|
55
|
-
indexStore: {},
|
56
|
-
genIndexStoreKey: function(){
|
57
|
-
var key = "_" + ((Math.random() * 1000000) | 0);
|
58
|
-
while(this.indexStore[key] !== void(0)){
|
59
|
-
key = "_" + ((Math.random() * 1000000) | 0);
|
60
|
-
}
|
61
|
-
|
62
|
-
return key;
|
63
|
-
},
|
64
|
-
|
65
|
-
getIndex: function(obj){
|
66
|
-
for (var x in this.indexStore){
|
67
|
-
if (this.indexStore[x].obj === obj) return this.indexStore[x].index;
|
68
|
-
}
|
69
|
-
},
|
70
|
-
|
71
|
-
addToIndexStore: function(obj, index){
|
72
|
-
var key = this.genIndexStoreKey();
|
73
|
-
this.indexStore[key] = {obj: obj, index: index}
|
74
|
-
},
|
75
|
-
|
76
|
-
removeFromIndexStore: function(obj){
|
77
|
-
for (var x in this.indexStore){
|
78
|
-
if (this.indexStore[x].obj === obj) delete this.indexStore[x];
|
79
|
-
}
|
80
|
-
},
|
81
|
-
|
82
|
-
updateIndex: function(obj, index){
|
83
|
-
for (var x in this.indexStore){
|
84
|
-
if (this.indexStore[x].obj === obj) this.indexStore[x].index = index;
|
85
|
-
}
|
86
|
-
},
|
87
|
-
|
88
|
-
enumerate: function(obj){
|
89
|
-
//TODO: keygen should check for uniquness
|
90
|
-
var used = [];
|
91
|
-
for (var i=0; i<obj.length; i++){
|
92
|
-
var current_index = this.getIndex(obj[i]);
|
93
|
-
if (current_index) used.push();
|
94
|
-
}
|
95
|
-
|
96
|
-
for (var i=0; i<obj.length; i++){
|
97
|
-
var index = i;
|
98
|
-
while (used.indexOf(index) !== -1){ index++ }
|
99
|
-
this.addToIndexStore(obj[i], index);
|
100
|
-
}
|
101
|
-
|
102
|
-
return obj
|
103
|
-
},
|
104
|
-
|
105
|
-
/* Type Checks */
|
106
|
-
|
107
|
-
getKeys: function(o){
|
108
|
-
return Object.keys(o);
|
109
|
-
},
|
110
|
-
|
111
|
-
isArray: function(v){
|
112
|
-
return Array.isArray(v);
|
113
|
-
},
|
114
|
-
|
115
|
-
isNotArray: function(v){
|
116
|
-
return !Array.isArray(v);
|
117
|
-
},
|
118
|
-
|
119
|
-
isNest: function(v){
|
120
|
-
return v.type === "nest";
|
121
|
-
},
|
122
|
-
|
123
|
-
isField: function(v){
|
124
|
-
return v.type !== "nest";
|
125
|
-
},
|
126
|
-
|
127
|
-
isMultiple: function(s){
|
128
|
-
return s.multiple;
|
129
|
-
},
|
130
|
-
|
131
|
-
isNotMultiple: function(s){
|
132
|
-
return !s.multiple
|
133
|
-
},
|
134
|
-
|
135
|
-
isHidden: function(o){
|
136
|
-
return o.type === 'hidden' ? "hidden" : "";
|
137
|
-
},
|
138
|
-
|
139
|
-
isEmpty: function(o){
|
140
|
-
var blank = true;
|
141
|
-
for (var x in this.structure[this.key].structure){
|
142
|
-
if (!blank) break;
|
143
|
-
if (this.structure[this.key].structure[x].type !== 'nest'){
|
144
|
-
if (this.structure[this.key].structure[x].type === 'json'){
|
145
|
-
for (var y in o[x]){
|
146
|
-
if (typeof o[x][y] !== 'object'){
|
147
|
-
if (!(o[x][y] === null || o[x][y].length === 0)){
|
148
|
-
blank = false;
|
149
|
-
break;
|
150
|
-
}
|
151
|
-
}
|
152
|
-
}
|
153
|
-
} else {
|
154
|
-
if (!(o[x] === null || o[x].length === 0)){
|
155
|
-
blank = false;
|
156
|
-
break;
|
157
|
-
}
|
158
|
-
}
|
159
|
-
}
|
160
|
-
}
|
161
|
-
|
162
|
-
if (!blank){
|
163
|
-
return "";
|
164
|
-
} else {
|
165
|
-
return "is-blank";
|
166
|
-
}
|
167
|
-
},
|
168
|
-
|
169
|
-
exists: function(o, key){
|
170
|
-
return o[key] !== void(0)
|
171
|
-
},
|
172
|
-
|
173
|
-
notExists: function(o, key){
|
174
|
-
return o[key] === void (0)
|
175
|
-
},
|
176
|
-
|
177
|
-
displayableField: function(field){
|
178
|
-
return ["string"].indexOf(field.type) !== -1;
|
179
|
-
},
|
180
|
-
|
181
51
|
/* Scope things */
|
182
52
|
wrapperClass: function(structure){
|
183
53
|
if (structure.type === "nest"){
|
@@ -191,96 +61,54 @@
|
|
191
61
|
}
|
192
62
|
},
|
193
63
|
|
194
|
-
addIndex: function(scope,
|
195
|
-
|
196
|
-
|
197
|
-
this.scope = this.structure[this.key].multiple ? scope + "[" + index + "]" : scope;
|
198
|
-
return this.scope;
|
64
|
+
addIndex: function(scope, index){
|
65
|
+
return scope + "[" + index + "]";
|
199
66
|
},
|
200
67
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
invalid = parent.querySelectorAll(".input-wrapper.is-invalid input")[0];
|
205
|
-
|
206
|
-
for (var i=0; i<items.length; i++){
|
207
|
-
var inputs = items[i].querySelectorAll("input"),
|
208
|
-
blank = true;
|
209
|
-
|
210
|
-
for (var j=0; j<inputs.length; j++){
|
211
|
-
if (inputs[j].value.replace(/\s/g, "").length !== 0){ blank = false; break; }
|
212
|
-
}
|
213
|
-
|
214
|
-
if (blank){
|
215
|
-
invalid = inputs[0];
|
216
|
-
break;
|
217
|
-
}
|
218
|
-
}
|
219
|
-
|
220
|
-
if (!invalid){
|
221
|
-
var data = this.classToData(t.className),
|
222
|
-
newData = {};
|
223
|
-
|
224
|
-
var index = data.length,
|
225
|
-
used = [];
|
226
|
-
for (var i=0; i<data.length; i++){ used.push(this.getIndex(data[i])) }
|
227
|
-
while (used.indexOf(index) !== -1){ index++ }
|
228
|
-
|
229
|
-
this.addToIndexStore(newData, index);
|
230
|
-
data.push(newData)
|
231
|
-
} else {
|
232
|
-
invalid.focus();
|
233
|
-
}
|
68
|
+
updateFieldScope: function(structure, key, scope){
|
69
|
+
if (scope === null) return null;
|
70
|
+
return structure.options.unscoped ? key : scope + "[" + key + "]"
|
234
71
|
},
|
235
72
|
|
236
|
-
updateScope: function(key){
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
return
|
73
|
+
updateScope: function(structure, key, scope){
|
74
|
+
if (scope === null) return null;
|
75
|
+
|
76
|
+
scope = structure.unscoped ? key : scope + "[" + key + "_attributes]";
|
77
|
+
return scope;
|
241
78
|
},
|
242
79
|
|
243
|
-
scopeFieldData: function(data, key){
|
244
|
-
data = this.structure[this.key].unscoped ? this.unscopedData : data;
|
245
|
-
|
246
|
-
|
247
|
-
if (data[key] === void(0)) data[key] = this.structure[this.key].value || null;
|
80
|
+
scopeFieldData: function(data, structure, key){
|
81
|
+
//data = this.structure[this.key].unscoped ? this.unscopedData : data;
|
82
|
+
if (structure.type !== 'html'){
|
83
|
+
if (data[key] === void(0)) data[key] = structure.value || null;
|
248
84
|
return data;
|
249
85
|
}
|
250
86
|
},
|
251
87
|
|
252
|
-
scopeNestData: function(
|
253
|
-
|
88
|
+
scopeNestData: function(structure, key, data){
|
89
|
+
data = structure.unscoped ? this.unscopedData : data;
|
254
90
|
//console.log("nest", key, data[key]);
|
255
|
-
if (
|
256
|
-
|
257
|
-
if (
|
91
|
+
if (structure.multiple){
|
92
|
+
if (data[key] === void(0)){
|
93
|
+
if (structure.allowAdd) {
|
258
94
|
data[key] = [];
|
259
95
|
} else {
|
260
96
|
data[key] = [{}];
|
261
97
|
}
|
262
98
|
}
|
263
99
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
this.data = data[key];
|
268
|
-
}
|
269
|
-
|
270
|
-
return this.data;
|
271
|
-
},
|
100
|
+
} else {
|
101
|
+
if (data[key] === void(0)) data[key] = {};
|
102
|
+
}
|
272
103
|
|
273
|
-
|
274
|
-
this.parentContext = key;
|
275
|
-
this.parentStructure = this.structure;
|
276
|
-
this.parentData = this.data;
|
104
|
+
return data[key];
|
277
105
|
},
|
278
106
|
|
279
107
|
scopeDataToIndex: function(data, obj){
|
280
108
|
var index = this.getIndex(obj);
|
281
109
|
|
282
110
|
this.data = this.data[index];
|
283
|
-
|
111
|
+
return this.data
|
284
112
|
},
|
285
113
|
|
286
114
|
listItemClassName: function(obj){
|
@@ -349,25 +177,25 @@
|
|
349
177
|
},
|
350
178
|
|
351
179
|
/* Creating Element */
|
352
|
-
|
180
|
+
//TODO: Wow, this seems like it could be way simpler.
|
181
|
+
createListItem: function(obj, structure, data){
|
353
182
|
var className = this.listItemClassName(obj),
|
354
|
-
isEmpty = Object.keys(obj).length === 0,
|
355
183
|
container = this.createWithAttributes("div", {'class': "list-item-display"});
|
356
|
-
|
357
|
-
if (
|
358
|
-
for (var i=0; i<
|
359
|
-
var field =
|
184
|
+
|
185
|
+
if (structure.display_fields){
|
186
|
+
for (var i=0; i<structure.display_fields.length; i++){
|
187
|
+
var field = structure.display_fields[i],
|
360
188
|
baseField = field.split(".")[0],
|
361
189
|
nameField = field.split(".")[field.split(".").length - 1]
|
362
190
|
|
363
191
|
var el = document.createElement("div"),
|
364
192
|
label = this.createWithAttributes("span", { text: this.capitalize(nameField.replace(/_/g, " ")) + ": " });
|
365
|
-
|
366
|
-
|
193
|
+
|
367
194
|
var value = document.createElement("span"),
|
368
|
-
val = document.createTextNode("")
|
195
|
+
val = document.createTextNode(""),
|
196
|
+
row = structure.structure.filter(function(item){ return item.key === baseField })[0];
|
369
197
|
|
370
|
-
if (
|
198
|
+
if (row.type === "json"){
|
371
199
|
var struct = field.split("."),
|
372
200
|
o = obj;
|
373
201
|
|
@@ -392,38 +220,23 @@
|
|
392
220
|
container.appendChild(el);
|
393
221
|
}
|
394
222
|
} else {
|
395
|
-
container.appendChild(this.createWithAttributes("div", {text: "item " + (
|
223
|
+
container.appendChild(this.createWithAttributes("div", {text: "item " + (data.indexOf(obj) + 1) }))
|
396
224
|
}
|
397
225
|
|
398
226
|
var remove_button = this.createWithAttributes("core-icon", {icon: 'clear'});
|
399
227
|
remove_button.addEventListener("click", function(e){
|
400
228
|
e.stopPropagation();
|
401
|
-
|
402
|
-
clone.splice(clone.indexOf(obj), 1);
|
403
|
-
|
404
|
-
while (this.parentData.length){
|
405
|
-
this.removeFromIndexStore(this.parentData[0]);
|
406
|
-
this.parentData.shift();
|
407
|
-
}
|
408
|
-
|
409
|
-
this.async(function(){
|
410
|
-
for (var i=0; i<clone.length; i++){
|
411
|
-
this.addToIndexStore(clone[i], i);
|
412
|
-
this.parentData.push(clone[i]);
|
413
|
-
}
|
414
|
-
});
|
415
|
-
|
229
|
+
data.splice(data.indexOf(obj), 1);
|
416
230
|
}.bind(this), false)
|
417
231
|
|
418
232
|
container.appendChild(remove_button);
|
419
233
|
|
420
234
|
var self = this;
|
421
|
-
|
422
|
-
|
235
|
+
|
423
236
|
container.addEventListener("click", function(e){
|
424
237
|
var stop = function(e){ e.stopPropagation(); }
|
425
238
|
group = self.findParent(container, ".list-group"),
|
426
|
-
first_input = group.querySelector(".input
|
239
|
+
first_input = group.querySelector(".input gc-input-decorator");
|
427
240
|
|
428
241
|
stop(e);
|
429
242
|
var alreadyFocued = self.shadowRoot.querySelectorAll(".list-group.focused");
|
@@ -432,9 +245,9 @@
|
|
432
245
|
}
|
433
246
|
|
434
247
|
first_input.focused = true;
|
435
|
-
|
248
|
+
self.async(function(){
|
436
249
|
first_input.querySelector("input").focus();
|
437
|
-
}
|
250
|
+
});
|
438
251
|
|
439
252
|
self.addClass(group, "focused");
|
440
253
|
group.addEventListener("click", stop, false);
|
@@ -444,10 +257,14 @@
|
|
444
257
|
self.removeClass(group, "focused");
|
445
258
|
}, false)
|
446
259
|
}, false)
|
260
|
+
|
261
|
+
return container;
|
447
262
|
},
|
448
263
|
|
449
|
-
createInput: function(structure){
|
450
|
-
|
264
|
+
createInput: function(structure, data, key, scope){
|
265
|
+
data = data || this.data;
|
266
|
+
|
267
|
+
var default_structure = {
|
451
268
|
type: "string",
|
452
269
|
label: "",
|
453
270
|
options: {
|
@@ -474,62 +291,26 @@
|
|
474
291
|
}
|
475
292
|
|
476
293
|
setOptions(structure, default_structure);
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
this.inputList.push(obj)
|
294
|
+
|
295
|
+
return this.getElement(structure, data, key, scope);
|
296
|
+
//this.inputList.push(obj)
|
481
297
|
},
|
482
298
|
|
483
|
-
scopeToClass: function(key){
|
484
|
-
if (
|
299
|
+
scopeToClass: function(structure, key, scope){
|
300
|
+
if (scope === null) return key;
|
301
|
+
|
302
|
+
if (structure.unscoped){
|
485
303
|
var className = key
|
486
304
|
} else {
|
487
|
-
|
488
|
-
}
|
489
|
-
return className;
|
490
|
-
},
|
491
|
-
|
492
|
-
classToData: function(cn){
|
493
|
-
var self = this,
|
494
|
-
data = this.unscopedData;
|
495
|
-
|
496
|
-
for (var x in self.unscopedData){
|
497
|
-
if (cn.substr(0, x.length) === x){
|
498
|
-
cn = cn.replace(new RegExp(x + "_?"), "");
|
499
|
-
data = data[x];
|
500
|
-
break;
|
501
|
-
}
|
502
|
-
}
|
503
|
-
|
504
|
-
function nest(str){
|
505
|
-
var p = str.split("_attributes_");
|
506
|
-
if (p.length > 1){
|
507
|
-
data = data[p[0]]
|
508
|
-
cn = p.slice(1).join("_attributes_");
|
509
|
-
return true;
|
510
|
-
} else {
|
511
|
-
return false
|
512
|
-
}
|
305
|
+
var className = scope.replace(/\[/g, "_").replace(/\]/g, "") + "_" + key;
|
513
306
|
}
|
514
|
-
|
515
|
-
function arr(str){
|
516
|
-
var p = str.split("_");
|
517
|
-
if (p.length > 1 && !isNaN(p[0])){
|
518
|
-
data = data[p[0]];
|
519
|
-
cn = p.slice(1).join("_");
|
520
|
-
return true;
|
521
|
-
} else {
|
522
|
-
return false
|
523
|
-
}
|
524
|
-
}
|
525
|
-
|
526
|
-
while (nest(cn) || arr(cn)){ }
|
527
|
-
return cn.length > 0 ? data[cn] : data;
|
307
|
+
return className;
|
528
308
|
},
|
529
309
|
|
530
310
|
checkForBlank: function(group){
|
531
|
-
var inputs = group.querySelectorAll("input"),
|
532
|
-
blank = true
|
311
|
+
var inputs = group.querySelectorAll("input[type=text], textarea, select"),
|
312
|
+
blank = true,
|
313
|
+
single = true;
|
533
314
|
|
534
315
|
for (var i=0; i<inputs.length; i++){
|
535
316
|
if (inputs[i].value.replace(/\s/g, "").length !== 0){
|
@@ -539,59 +320,59 @@
|
|
539
320
|
}
|
540
321
|
|
541
322
|
if (blank){
|
542
|
-
this.addClass(group, 'is-blank');
|
323
|
+
this.addClass(this.findParent(group, ".input"), 'is-blank');
|
324
|
+
return true;
|
543
325
|
} else {
|
544
|
-
this.removeClass(group, 'is-blank');
|
326
|
+
this.removeClass(this.findParent(group, ".input"), 'is-blank');
|
327
|
+
return false;
|
545
328
|
}
|
546
329
|
},
|
547
330
|
|
548
|
-
|
549
|
-
|
550
|
-
},
|
331
|
+
getElement: function(structure, data, key, scope){
|
332
|
+
data = data || this.data;
|
551
333
|
|
552
|
-
getElement: function(structure){
|
553
334
|
var inputs = {
|
554
335
|
string: function(){
|
555
|
-
return this.createBasicInput("text");
|
336
|
+
return this.createBasicInput("text", data, structure, key, scope);
|
556
337
|
}.bind(this),
|
557
338
|
|
558
339
|
email: function(){
|
559
|
-
return this.createBasicInput("text");
|
340
|
+
return this.createBasicInput("text", data, structure, key, scope);
|
560
341
|
},
|
561
342
|
|
562
343
|
hidden: function(){
|
563
|
-
return this.createBasicInput("hidden");
|
344
|
+
return this.createBasicInput("hidden", data, structure, key, scope);
|
564
345
|
}.bind(this),
|
565
346
|
|
566
347
|
json: function(){
|
567
|
-
return this.createJSONField(structure.fields);
|
348
|
+
return this.createJSONField(structure.fields, data, structure, key, scope);
|
568
349
|
}.bind(this),
|
569
350
|
|
570
351
|
password: function(){
|
571
|
-
return this.createBasicInput("password");
|
352
|
+
return this.createBasicInput("password", data, structure, key, scope);
|
572
353
|
}.bind(this),
|
573
354
|
|
574
355
|
integer: function(){
|
575
|
-
return this.createBasicInput("text");
|
356
|
+
return this.createBasicInput("text", data, structure, key, scope);
|
576
357
|
}.bind(this),
|
577
358
|
|
578
359
|
url: function(){
|
579
|
-
return this.createBasicInput("text");
|
360
|
+
return this.createBasicInput("text", data, structure, key, scope);
|
580
361
|
}.bind(this),
|
581
362
|
|
582
363
|
textarea: function(){
|
583
|
-
return this.createBasicInput("textarea")
|
364
|
+
return this.createBasicInput("textarea", data, structure, key, scope)
|
584
365
|
}.bind(this),
|
585
366
|
|
586
367
|
checkbox: function(){
|
587
368
|
var box = document.createElement("paper-checkbox"),
|
588
|
-
input = this.createWithAttributes('input', {type: "checkbox", name: this.updateFieldScope()});
|
369
|
+
input = this.createWithAttributes('input', {type: "checkbox", name: this.updateFieldScope(structure, key, scope)});
|
589
370
|
|
590
|
-
box.label = this.capitalize(
|
371
|
+
box.label = this.capitalize(structure.label || key);
|
591
372
|
box.appendChild(input);
|
592
373
|
|
593
374
|
box.addEventListener("change", function(e){
|
594
|
-
|
375
|
+
data[key] = e.target.checked ? 1 : 0;
|
595
376
|
input.checked = e.target.checked;
|
596
377
|
}.bind(this), false)
|
597
378
|
|
@@ -600,98 +381,162 @@
|
|
600
381
|
}.bind(this),
|
601
382
|
|
602
383
|
date: function(){
|
603
|
-
var wrapper = this.
|
604
|
-
|
384
|
+
var wrapper = this.createWithAttributes("div", {"class": "date-wrapper"}),
|
385
|
+
decorator = this.createWithAttributes("gc-input-decorator", { label: this.capitalize(structure.label || key.replace(/_/g, " ")), floatingLabel: structure.options.floatingLabel}),
|
386
|
+
visibleInput = document.createElement("input"),
|
387
|
+
input = this.createWithAttributes("input", {type: "hidden", name: this.updateFieldScope(structure, key, scope) })
|
388
|
+
|
389
|
+
decorator.appendChild(visibleInput);
|
390
|
+
wrapper.appendChild(decorator);
|
391
|
+
wrapper.appendChild(input);
|
605
392
|
|
606
|
-
var picker = new Pikaday({ field:
|
393
|
+
var picker = new Pikaday({ field: visibleInput, bound: false, onSelect: function(){
|
394
|
+
data[key] = picker._d.getFullYear() + "-" + (picker._d.getMonth() + 1) + "-" + picker._d.getDate();
|
395
|
+
}.bind(this) });
|
607
396
|
|
608
|
-
|
609
|
-
|
610
|
-
});
|
397
|
+
visibleInput.addEventListener("focus", function(){ picker.show(); });
|
398
|
+
new PathObserver(data, key).open(function(){ input.value = data[key]; });
|
611
399
|
|
612
400
|
return wrapper;
|
613
401
|
}.bind(this),
|
614
402
|
|
615
403
|
select: function(){
|
616
|
-
var
|
617
|
-
values = structure.values;
|
404
|
+
var values = structure.values;
|
618
405
|
|
619
406
|
var wrapper = this.createWithAttributes("div", {"class": "select-wrapper"}),
|
620
|
-
decorator = this.createWithAttributes("gc-input-decorator", { label: this.capitalize(structure.label ||
|
621
|
-
secretInput = this.createWithAttributes('input', {type: 'hidden', name: this.updateFieldScope()}),
|
407
|
+
decorator = this.createWithAttributes("gc-input-decorator", { label: this.capitalize(structure.label || key), floatingLabel: structure.options.floatingLabel}),
|
408
|
+
secretInput = this.createWithAttributes('input', {type: 'hidden', name: this.updateFieldScope(structure, key, scope)}),
|
622
409
|
input = this.createWithAttributes("input", { type: "text", name: "", "class": "pseudo-select-input", disabled: true }),
|
623
410
|
select = this.createWithAttributes("core-selector", {valueattr: "val", "class": "pseudo-select", multi: (!!structure.multi) });
|
624
411
|
|
625
|
-
secretInput.bind('value', new PathObserver(
|
626
|
-
select.bind('selected', new PathObserver(
|
412
|
+
//secretInput.bind('value', new PathObserver(data, key));
|
413
|
+
//select.bind('selected', new PathObserver(data, key));
|
414
|
+
new PathObserver(data, key).open(function(){
|
415
|
+
secretInput.value = !!structure.multi ? JSON.stringify(data[key]) : data[key];
|
416
|
+
select.selected = data[key];
|
417
|
+
})
|
627
418
|
|
628
419
|
if (!structure.blank){
|
629
|
-
|
420
|
+
data[key] = values.length > 0 ? values[0][0] : (!!structure.multi ? [] : "");
|
630
421
|
input.value = values.length > 0 ? values[0][1] : "";
|
631
422
|
}
|
632
423
|
var self = this;
|
633
424
|
|
634
|
-
|
635
|
-
|
636
|
-
|
425
|
+
if (!structure.opened){
|
426
|
+
|
427
|
+
select.addEventListener("click", function(e){
|
428
|
+
if (!!structure.multi) e.stopPropagation();
|
429
|
+
}, false);
|
637
430
|
|
638
|
-
|
639
|
-
|
431
|
+
decorator.addEventListener('click', function(e){
|
432
|
+
if (self.hasClass(wrapper, 'opened')) return;
|
640
433
|
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
434
|
+
e.stopPropagation();
|
435
|
+
decorator.updateLabelVisibility("down");
|
436
|
+
|
437
|
+
if (!structure.scrollTarget){
|
438
|
+
self.addClass(wrapper, 'opened');
|
439
|
+
} else {
|
440
|
+
var scrollTarget = document.querySelector(structure.scrollTarget);
|
441
|
+
|
442
|
+
if (scrollTarget === document.body){
|
443
|
+
var coords = wrapper.getBoundingClientRect();
|
444
|
+
coords.top = coords.top + window.pageYOffset + wrapper.offsetHeight;
|
445
|
+
coords.left = coords.left + window.pageXOffset;
|
446
|
+
} else {
|
447
|
+
var parentCoords = scrollTarget.tagName.indexOf("-") !== -1 ? scrollTarget.scroller.getBoundingClientRect() : scrollTarget.getBoundingClientRect(),
|
448
|
+
wrapperCoords = wrapper.getBoundingClientRect(),
|
449
|
+
scrollTop = scrollTarget.tagName.indexOf("-") !== -1 ? scrollTarget.scroller.scrollTop : scrollTarget.scrollTop;
|
450
|
+
|
451
|
+
var coords = {
|
452
|
+
width: wrapperCoords.width,
|
453
|
+
height: wrapperCoords.height,
|
454
|
+
top: wrapperCoords.top - parentCoords.top + scrollTop + wrapperCoords.height,
|
455
|
+
left: wrapperCoords.left - parentCoords.left + scrollTarget.scrollLeft
|
456
|
+
}
|
457
|
+
}
|
458
|
+
|
459
|
+
select.style.width = coords.width + "px";
|
460
|
+
select.style.top = (coords.top ) + "px";
|
461
|
+
select.style.left = (coords.left) + "px";
|
462
|
+
|
463
|
+
scrollTarget.appendChild(select);
|
464
|
+
}
|
465
|
+
|
466
|
+
window.addEventListener('click', function(){
|
467
|
+
if (!structure.scrollTarget){
|
468
|
+
self.removeClass(wrapper, 'opened');
|
469
|
+
} else {
|
470
|
+
wrapper.appendChild(select);
|
471
|
+
}
|
472
|
+
|
473
|
+
window.removeEventListener('click', arguments.callee);
|
474
|
+
}, false);
|
648
475
|
}, false);
|
649
|
-
}
|
476
|
+
} else {
|
477
|
+
self.addClass(wrapper, 'opened');
|
478
|
+
decorator.updateLabelVisibility("down");
|
479
|
+
}
|
650
480
|
|
651
481
|
select.addEventListener('core-select', function(){
|
652
|
-
if (!
|
482
|
+
if (!structure.multi) self.removeClass(wrapper, 'opened');
|
653
483
|
decorator.updateLabelVisibility(select.selected ? select.selected : "");
|
654
484
|
|
655
485
|
self.async(function(){
|
656
486
|
if (!!structure.multi){
|
657
487
|
input.value = select === null ? "" : select.selectedItem.map(function(s){ return s.textContent }).join(', ');
|
658
|
-
|
488
|
+
data[key] = select.selectedItem.map(function(s){ return s.getAttribute('val') });
|
659
489
|
} else {
|
660
490
|
input.value = select === null ? "" : select.selectedItem.textContent;
|
661
|
-
|
491
|
+
data[key] = select.selectedItem.getAttribute('val');
|
662
492
|
}
|
663
493
|
});
|
664
494
|
}, false);
|
665
495
|
|
666
496
|
var build_options = function(){
|
497
|
+
var keys = {};
|
498
|
+
|
667
499
|
while (select.firstChild) { select.removeChild(select.firstChild) };
|
668
|
-
if (structure.blank) select.appendChild(this.createWithAttributes("div", {val: "", text: "" }))
|
500
|
+
if (!!structure.blank) select.appendChild(this.createWithAttributes("div", {val: "huh", text: (typeof structure.blank === "string" ? structure.blank : "") }))
|
669
501
|
for (var i=0; i<structure.values.length; i++){
|
670
502
|
var div = self.createWithAttributes("div", {val: structure.values[i][0], text: structure.values[i][1] });
|
671
503
|
|
672
504
|
if (!!structure.multi){
|
673
505
|
var checkbox = this.createWithAttributes("paper-checkbox", {"class": "select-check"});
|
674
506
|
div.appendChild(checkbox);
|
675
|
-
div.addEventListener("click", function(el, box){
|
676
|
-
this.async(function(){
|
677
|
-
box.checked = this.hasClass(el, 'core-selected');
|
678
|
-
}.bind(this));
|
679
|
-
}.bind(this, div, checkbox), false)
|
680
507
|
}
|
681
508
|
select.appendChild(div);
|
682
509
|
}
|
683
510
|
|
684
511
|
var nil = structure.values.length === 0 ? self.addClass(wrapper, 'is-blank') : self.removeClass(wrapper, 'is-blank');
|
685
512
|
nil = structure.values.length === 1 ? self.addClass(wrapper, 'is-single') : self.removeClass(wrapper, 'is-single');
|
513
|
+
|
514
|
+
//if (!structure.blank && values.length > 0) select.selected = values[0][0];
|
686
515
|
}.bind(this);
|
687
516
|
|
688
517
|
build_options();
|
689
|
-
new
|
518
|
+
new ArrayObserver(structure.values).open(function(){
|
690
519
|
build_options();
|
691
520
|
})
|
692
521
|
|
522
|
+
//Binding the checkboxes state to whether or not they're selected
|
523
|
+
if (!!structure.multi){
|
524
|
+
new ArrayObserver(select.selection).open(function(changed){
|
525
|
+
for (var j=0; j<changed.length; j++){
|
526
|
+
var changes = changed[j];
|
527
|
+
for (var i=0; i<changes.addedCount; i++){
|
528
|
+
select.selectedItem[changes.index + i].querySelector("paper-checkbox").checked = true;
|
529
|
+
}
|
530
|
+
|
531
|
+
for (var i=0; i<changes.removed.length; i++){
|
532
|
+
changes.removed[i].querySelector("paper-checkbox").checked = false;
|
533
|
+
}
|
534
|
+
}
|
535
|
+
})
|
536
|
+
}
|
537
|
+
|
693
538
|
new PathObserver(structure, 'label').open(function(){
|
694
|
-
decorator.label = this.capitalize(
|
539
|
+
decorator.label = this.capitalize(structure.label || key)
|
695
540
|
}.bind(this));
|
696
541
|
|
697
542
|
wrapper.appendChild(decorator);
|
@@ -706,14 +551,16 @@
|
|
706
551
|
var wrapper = document.createElement("gc-input-decorator"),
|
707
552
|
input = document.createElement( "input" );
|
708
553
|
//google-location-input
|
709
|
-
if (!
|
554
|
+
if (!data[key]) data[key] = { value: null, lat: null, lng: null }
|
710
555
|
|
711
|
-
wrapper.label = this.capitalize(
|
712
|
-
wrapper.floatingLabel =
|
556
|
+
wrapper.label = this.capitalize(structure.label || key);
|
557
|
+
wrapper.floatingLabel = structure.options.floatingLabel;
|
713
558
|
|
714
559
|
input.type = "text";
|
715
|
-
input.name = this.updateFieldScope();
|
716
|
-
input.bind('value', new PathObserver(
|
560
|
+
input.name = this.updateFieldScope(structure, key, scope);
|
561
|
+
input.bind('value', new PathObserver(data[key], "value"))
|
562
|
+
|
563
|
+
this.addValidation('location', input, structure, key, data);
|
717
564
|
|
718
565
|
var autocomplete = new google.maps.places.Autocomplete(
|
719
566
|
input, { types: ['(cities)'] }
|
@@ -723,12 +570,12 @@
|
|
723
570
|
google.maps.event.addListener(autocomplete, 'place_changed', function () {
|
724
571
|
var place = autocomplete.getPlace();
|
725
572
|
|
726
|
-
|
727
|
-
|
728
|
-
|
573
|
+
data[key].value = input.value;
|
574
|
+
data[key].lat = place.geometry.location.lat();
|
575
|
+
data[key].lng = place.geometry.location.lng();
|
729
576
|
|
730
|
-
if (!!
|
731
|
-
|
577
|
+
if (!!structure.options.events.select){
|
578
|
+
structure.options.events.select(data[key])
|
732
579
|
}
|
733
580
|
})
|
734
581
|
|
@@ -738,7 +585,7 @@
|
|
738
585
|
|
739
586
|
image: function(){
|
740
587
|
var wrapper = this.createWithAttributes("span", { "class": "btn-image-upload" }),
|
741
|
-
input = this.createWithAttributes("input", { type: "file", name: this.updateFieldScope() }),
|
588
|
+
input = this.createWithAttributes("input", { type: "file", name: this.updateFieldScope(structure, key, scope), required: structure.required || false }),
|
742
589
|
icon_wrapper = this.createWithAttributes("div", {"class": "image-icon-wrapper"}),
|
743
590
|
explanation = this.createWithAttributes("p", {text: "Click here to upload an image"}),
|
744
591
|
icon = this.createWithAttributes("core-icon", {icon: "image:photo"});
|
@@ -748,7 +595,7 @@
|
|
748
595
|
wrapper.appendChild(icon_wrapper);
|
749
596
|
wrapper.appendChild(explanation);
|
750
597
|
|
751
|
-
this.addValidation('image', input)
|
598
|
+
this.addValidation('image', input, structure, key);
|
752
599
|
input.addEventListener("click", function(e){ e.stopPropagation(); }, true)
|
753
600
|
|
754
601
|
var self = this;
|
@@ -774,105 +621,131 @@
|
|
774
621
|
return wrapper;
|
775
622
|
}.bind(this),
|
776
623
|
|
624
|
+
file: function(){
|
625
|
+
var wrapper = this.createWithAttributes("span", { "class": "btn-file-upload" }),
|
626
|
+
decorator = this.createWithAttributes("gc-input-decorator", { "class": "file-decorator", label: this.capitalize(structure.label || key.replace(/_/g, " ")), floatingLabel: structure.options.floatingLabel }),
|
627
|
+
textInput = this.createWithAttributes("input", { type: "text", "class": "file-dummy" }),
|
628
|
+
input = this.createWithAttributes("input", { type: "file", name: this.updateFieldScope(structure, key, scope), required: structure.required || false });
|
629
|
+
|
630
|
+
decorator.appendChild(textInput);
|
631
|
+
wrapper.appendChild(input);
|
632
|
+
wrapper.appendChild(decorator);
|
633
|
+
|
634
|
+
this.addValidation('file', input, structure, key);
|
635
|
+
input.addEventListener("click", function(e){ e.stopPropagation(); }, true)
|
636
|
+
|
637
|
+
var self = this;
|
638
|
+
input.addEventListener("change", function(){
|
639
|
+
if (this.files.length){
|
640
|
+
textInput.value = Array.apply(null, this.files).map(function(item){ return item.name }).join(",");
|
641
|
+
self.addClass(wrapper.parentNode, "has-file");
|
642
|
+
self.data[self.key] = this.files;
|
643
|
+
decorator.updateLabelVisibility(this.files[0].name);
|
644
|
+
|
645
|
+
} else {
|
646
|
+
textInput.value = "";
|
647
|
+
self.removeClass(wrapper.parentNode, "has-file");
|
648
|
+
self.data[self.key] = null;
|
649
|
+
decorator.updateLabelVisibility("");
|
650
|
+
}
|
651
|
+
}, true)
|
652
|
+
|
653
|
+
return wrapper;
|
654
|
+
}.bind(this),
|
655
|
+
|
777
656
|
html: function(){
|
778
657
|
var content = document.createElement('div');
|
779
|
-
content.innerHTML =
|
658
|
+
content.innerHTML = structure.content;
|
780
659
|
return content;
|
781
660
|
}.bind(this)
|
782
661
|
|
783
662
|
}
|
784
663
|
|
785
|
-
try {
|
664
|
+
//try {
|
786
665
|
return inputs[structure.type]()
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
},
|
791
|
-
|
792
|
-
appendInputs: function(){
|
793
|
-
while (this.inputList.length){
|
794
|
-
var obj = this.inputList.shift(),
|
795
|
-
container = this.shadowRoot.querySelector(obj.container);
|
796
|
-
|
797
|
-
//TODO: insert points
|
798
|
-
if (!obj.position || obj.position === 'append'){
|
799
|
-
if (this.findParent(obj.element, obj.container) === null){
|
800
|
-
container.appendChild(obj.element)
|
801
|
-
}
|
802
|
-
} else if (!!obj.position && obj.position === 'before') {
|
803
|
-
if ([].indexOf.call(container.parentNode.childNodes, obj.element) === -1){
|
804
|
-
container.parentNode.insertBefore(obj.element, container)
|
805
|
-
}
|
806
|
-
}
|
807
|
-
|
808
|
-
if (!!obj.events.onFocus) container.addEventListener("focus", obj.events.onFocus, false);
|
809
|
-
if (!!obj.events.onBlur) container.addEventListener("blur", obj.events.onBlur, false);
|
810
|
-
}
|
666
|
+
//} catch(e){
|
667
|
+
// throw "Unknown field type: " + structure.type
|
668
|
+
//}
|
811
669
|
},
|
812
670
|
|
813
|
-
createBasicInput: function(type,
|
671
|
+
createBasicInput: function(type, data, structure, key, scope){
|
814
672
|
var wrapper = document.createElement("gc-input-decorator"),
|
815
|
-
|
673
|
+
input = document.createElement( type === "textarea" ? "textarea" : "input" );
|
816
674
|
|
817
|
-
wrapper.label = this.capitalize(
|
818
|
-
wrapper.floatingLabel =
|
675
|
+
wrapper.label = this.capitalize(structure.label || key);
|
676
|
+
wrapper.floatingLabel = structure.options.floatingLabel;
|
819
677
|
|
820
678
|
input.type = type;
|
821
|
-
|
822
|
-
input.value =
|
823
|
-
input.id = this.scopeToClass(
|
824
|
-
|
825
|
-
input.bind('value', new PathObserver(
|
826
|
-
|
827
|
-
this.addValidation(type, input)
|
679
|
+
input.name = this.updateFieldScope(structure, key, scope);
|
680
|
+
input.value = structure.value || '';
|
681
|
+
input.id = this.scopeToClass(structure, key, scope)
|
682
|
+
if (structure.required) input.required = true;
|
683
|
+
input.bind('value', new PathObserver(data, key))
|
684
|
+
|
685
|
+
this.addValidation(type, input, structure, key);
|
828
686
|
|
687
|
+
if (!!structure.autocomplete && typeof structure.autocomplete === "string"){
|
688
|
+
this.autocomplete(input, structure.autocomplete, structure.autocompleteOptions || {});
|
689
|
+
}
|
690
|
+
|
829
691
|
if (type === 'textarea') input.rows = 3;
|
830
|
-
if (type !== "hidden"){
|
692
|
+
if (type !== "hidden"){
|
831
693
|
wrapper.appendChild(input);
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
694
|
+
return wrapper;
|
695
|
+
} else {
|
696
|
+
return input;
|
697
|
+
}
|
836
698
|
|
837
699
|
},
|
838
700
|
|
839
|
-
createJSONField: function(fields){
|
840
|
-
|
701
|
+
createJSONField: function(fields, data, structure, key, scope){
|
702
|
+
|
703
|
+
// //TODO: only basic JSON support, if you want crazy complicated stuff, just use a textarea or custom input
|
841
704
|
var wrapper = this.createWithAttributes('div', { "class": "json-wrapper" }),
|
842
|
-
input = this.createWithAttributes("textarea", { name: this.updateFieldScope(), "class": "hidden", text: JSON.stringify(
|
843
|
-
isList =
|
844
|
-
|
845
|
-
if (!this.data[this.key]) this.data[this.key] = {};
|
705
|
+
input = this.createWithAttributes("textarea", { name: this.updateFieldScope(structure, key, scope), "class": "hidden", text: JSON.stringify(data[key]) }),
|
706
|
+
isList = structure.allowAdd;
|
846
707
|
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
708
|
+
if (structure.multiple){
|
709
|
+
this.jsonData[key] = [{}]
|
710
|
+
this.buildStructure(structure.structure, this.jsonData[key][0], wrapper, null);
|
711
|
+
} else {
|
712
|
+
this.jsonData[key] = {}
|
713
|
+
this.buildStructure(structure.structure, this.jsonData[key], wrapper, null);
|
714
|
+
}
|
715
|
+
wrapper.appendChild(input)
|
716
|
+
|
717
|
+
var self = this;
|
718
|
+
|
719
|
+
function recurse(obj){
|
720
|
+
if (Array.isArray(obj)){
|
721
|
+
new ArrayObserver(obj).open(function(changed){
|
722
|
+
for (var j=0; j<changed.length; j++){
|
723
|
+
var changes = changed[j];
|
724
|
+
for (var i=0; i<changes.addedCount; i++){
|
725
|
+
recurse(obj[changes.index + i]);
|
726
|
+
}
|
727
|
+
}
|
728
|
+
|
729
|
+
input.value = JSON.stringify(self.jsonData[key]);
|
730
|
+
data[key] = JSON.parse(input.value);
|
731
|
+
})
|
732
|
+
|
733
|
+
for (var i=0; i<obj.length; i++) recurse(obj[i]);
|
870
734
|
} else {
|
871
|
-
|
872
|
-
|
735
|
+
new ObjectObserver(obj).open(function(){
|
736
|
+
input.value = JSON.stringify(self.jsonData[key]);
|
737
|
+
data[key] = JSON.parse(input.value);
|
738
|
+
});
|
873
739
|
|
874
|
-
|
740
|
+
for (var x in obj){
|
741
|
+
if (typeof obj[x] === 'object' && obj[x] !== null) recurse(obj[x]);
|
742
|
+
}
|
743
|
+
}
|
875
744
|
}
|
745
|
+
recurse(this.jsonData[key]);
|
746
|
+
|
747
|
+
input.value = JSON.stringify(this.jsonData[key]);
|
748
|
+
data[key] = JSON.parse(input.value);
|
876
749
|
|
877
750
|
return wrapper;
|
878
751
|
},
|