polymer-rails-forms 0.2.01 → 0.3.0
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.
- 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
|
},
|