Skip to content

Commit f1951b7

Browse files
Shuwen Qiananthonykoerber
authored andcommitted
bleh
1 parent 1a9d0a8 commit f1951b7

4 files changed

Lines changed: 109 additions & 22 deletions

File tree

src/mm-repeater/index.html

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<script language="javascript" src="../../bower_components/webcomponentsjs/webcomponents-lite.js"></script>
55
<link rel="import" href="mm-repeater.html" />
66
<link rel="import" href="../mm-group/mm-group.html" />
7+
<link rel="import" href="../mm-button/mm-button.html" />
78
<link rel="import" href="../mm-radio/mm-radio.html" />
89
<link rel="import" href="../mm-input/mm-input.html" />
910
<link rel="import" href="../mm-dropdown/mm-dropdown.html" />
@@ -114,9 +115,9 @@
114115
<hr>
115116

116117
<h3>Prepopulated</h3>
117-
<mm-repeater id="repeater" data='[{"name": "John","firstOption": "","secondOption": "Test 1"},{"name": "Paul","firstOption": "Test Item 1","secondOption": "Test 2"},{"name": "Ringo","firstOption": "Test Item 1","secondOption": "Test 3"}]'>
118+
<mm-repeater id="withData">
118119
<template preserve-content>
119-
<mm-input name="name"></mm-input>
120+
<mm-input name="name" validation="alpha"></mm-input>
120121
<mm-dropdown name="firstOption">
121122
<mm-list-item>Test Item 1</mm-list-item>
122123
<mm-list-item>Test Item 2</mm-list-item>
@@ -130,9 +131,36 @@ <h3>Prepopulated</h3>
130131
</mm-group>
131132
</template>
132133
</mm-repeater>
134+
<mm-button id="validateBtn"><label>Validate!</label></mm-button>
133135
</div>
134136

135137
<script>
138+
var data = [
139+
{
140+
name: "John",
141+
firstOption: "Test Item 2",
142+
secondOption: "Test 1"
143+
},
144+
{
145+
name: "Paul",
146+
firstOption: "Test Item 1",
147+
secondOption: "Test 2"
148+
},
149+
{
150+
name: "Ringo",
151+
firstOption: "Test Item 1",
152+
secondOption: "Test 3"
153+
}
154+
]
155+
var wd = document.querySelector('#withData');
156+
wd.async(function() {
157+
wd.data = null
158+
wd.value = data;
159+
});
160+
161+
document.querySelector('#validateBtn').addEventListener('click', function() {
162+
wd.validate();
163+
});
136164
</script>
137165
</body>
138166
</html>

src/mm-repeater/mm-repeater.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<link rel="import" type="css" href="mm-repeater.css"/>
1818
<template>
1919
<template is="dom-repeat" items="{{data}}" id="repeater">
20-
<mm-box ref="{{item._ref}}" align="stretch" justify="space-between" on-changed="_updateModel" on-input="_updateModel">
20+
<mm-box ref="{{item._ref}}" align="stretch" justify="space-between">
2121
<div inner-h-t-m-l="{{template}}"></div>
2222
<mm-box class="control" align="center">
2323
<mm-action on-tap="_addRow"><label>{{addRowLabel}}</label></mm-action>

src/mm-repeater/mm-repeater.js

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
type: Object,
1515
value: null
1616
},
17+
1718
data: {
1819
type: Array,
1920
notify: true,
20-
value: function() { return []; },
21-
observer: '_handleDataChanged'
21+
value: function() { return [{}]; }
2222
},
23+
2324
addRowLabel: {
2425
type: String,
2526
value: '+Add Item'
@@ -32,35 +33,87 @@
3233
StrandTraits.Validatable
3334
],
3435

35-
get value() { return this.data; },
36-
set value(newVal) { if (newVal instanceof Array) this.data = newVal; },
36+
get value() {
37+
return this.data;
38+
},
39+
40+
set value(newVal) {
41+
if (newVal instanceof Array) {
42+
this.set('data', newVal);
43+
}
44+
},
45+
46+
observers: [
47+
'_injectModelData(data.*)'
48+
],
49+
50+
_injectModelData: function(e) {
51+
var path = e.path.split('.'),
52+
record = path[path.length-1];
53+
54+
console.log(e);
55+
if(record === '_ref') {
56+
var index = parseInt(path[1].substring(1)),
57+
model = e.base[index],
58+
node = model._ref;
59+
60+
if(node) {
61+
var fields = node.querySelectorAll('[name]');
62+
for(var i=0; i<fields.length; i++) {
63+
var field = fields[i],
64+
name = field.getAttribute('name');
65+
if(model[name]) field.setAttribute('value', model[name]);
66+
}
67+
}
68+
}
69+
},
70+
71+
// Model -> DOM
72+
// DOM -> Model
73+
// Push onto DOM with empty state
74+
// Pop off DOM |> (DOM -> Model)
75+
// Model -> DOM |> Push multiple onto DOM
76+
// Modify DOM in place
77+
78+
// Add log
79+
// Remove log
80+
// Change log
3781

3882
ready: function() {
3983
var templateTag = this.queryEffectiveChildren('template');
4084
this.set('template', templateTag.innerHTML);
41-
if(!this.data || this.data.length === 0) this._addRow();
4285
},
4386

44-
_handleDataChanged: function(newData) {
45-
this.async(function() {
46-
newData.forEach(function(record) {
47-
var node = record._ref;
48-
if(node) {
49-
var fields = node.querySelectorAll('[name]');
50-
for(var i=0; i<fields.length; i++) {
51-
var field=fields[i];
52-
var name=field.getAttribute('name');
53-
field.setAttribute('value',record[name]);
54-
}
55-
}
56-
});
57-
}.bind(this));
87+
validate: function() {
88+
this.data.forEach(function(item, index) {
89+
90+
var valid = true;
91+
92+
if(typeof item.validation === 'function') {
93+
// Custom validation provided: call validation, passing name:value pairs as arguments
94+
var elems = item._ref.querySelectorAll('[name]'),
95+
rowData = Object.keys(elems).map(function(key) { return {name: elems[key].name, value: elems[key].value }; });
96+
valid = item.validation.apply(rowData);
97+
} else {
98+
// Default validation: call validate on each form element and fold them together
99+
var fields = item._ref.querySelectorAll('[validation]');
100+
valid = Object.keys(fields).reduce(function(sum, elt) {
101+
return sum && (!fields[elt].validate || fields[elt].validate(fields[elt].value));
102+
}, true);
103+
}
104+
105+
// Reflect validation to the model for error messaging
106+
this.set('data.'+index+'.error', !valid);
107+
108+
}, this);
58109
},
59110

60111
_updateModel: function(e) {
61112
var target = Polymer.dom(e).localTarget,
62113
name = target.name || target.getAttribute('name'),
63114
value = target.value || target.getAttribute('value');
115+
116+
console.log('_updateModel triggered');
64117
if(name && value) {
65118
var index = this.$.repeater.indexForElement(target);
66119
this.set('data.'+(index)+'.'+name, value);

src/mm-repeater/mm-repeater.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,9 @@ mm-action {
3232
mm-icon[type="delete"] {
3333
cursor: pointer;
3434
}
35+
36+
mm-inline-box[type="error"] {
37+
display: block;
38+
margin-bottom: 8px;
39+
width: 100%;
40+
}

0 commit comments

Comments
 (0)