Skip to content

Commit d4471a6

Browse files
committed
monkey punching array to re-render repeaters
1 parent 4687478 commit d4471a6

File tree

4 files changed

+290
-4
lines changed

4 files changed

+290
-4
lines changed

Slim.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
console.log('SlimJS v2.2.5')
1+
console.log('SlimJS v2.2.6')
22

33
class Slim extends HTMLElement {
44

@@ -478,7 +478,7 @@ window.Slim = Slim
478478
Array.prototype.registerSlimRepeater = function(repeater) {
479479
this.registeredSlimRepeaters = this.registeredSlimRepeaters || []
480480

481-
if (this.registeredSlimRepeaters.indexOf(repeater < 0)) {
481+
if (this.registeredSlimRepeaters.indexOf(repeater) < 0) {
482482
this.registeredSlimRepeaters.push(repeater)
483483
}
484484
}

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "slimjs",
33
"main": "Slim.js",
4-
"version": "2.2.5",
4+
"version": "2.2.6",
55
"ignore": [
66
"example",
77
"components",

example/Contacts/Contacts.html

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Title</title>
6+
<script>
7+
if (!(function() {return ('registerElement' in document
8+
&& 'import' in document.createElement('link')
9+
&& 'content' in document.createElement('template'))})()) {
10+
let s = "<script type=\"text\/javascript\" " +
11+
"src=\"https ://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/0.7.23/webcomponents.min.js\"" +
12+
" > <\/script> "
13+
document.write(s)
14+
}
15+
</script>
16+
<script src="../../Slim.js"></script>
17+
</head>
18+
<body>
19+
20+
21+
<script>
22+
class ContactsModel {
23+
24+
constructor() {
25+
let contactsFromLocal = localStorage.getItem('slim-contacts')
26+
if (contactsFromLocal) contactsFromLocal = JSON.parse(contactsFromLocal)
27+
this.contacts = contactsFromLocal || []
28+
}
29+
30+
create(first, last) {
31+
let newContact = new Contact(first, last)
32+
this.contacts.push( newContact )
33+
this.sort()
34+
this.save()
35+
return newContact
36+
}
37+
38+
save() {
39+
localStorage.setItem('slim-contacts', JSON.stringify(this.contacts))
40+
}
41+
42+
sort() {
43+
this.contacts = this.contacts.sort( (a,b) => {
44+
if (a.last > b.last) return 1
45+
if (b.last > a.last) return -1
46+
if (a.first > b.first) return 1
47+
if (b.first > a.first) return -1
48+
return 0
49+
})
50+
}
51+
52+
remove(contact) {
53+
let i = this.contacts.indexOf(contact)
54+
this.contacts.splice(i, 1)
55+
this.save()
56+
}
57+
58+
}
59+
60+
class Contact {
61+
constructor (first = "Moshe", last = "Vilner") {
62+
this.first = first
63+
this.last = last
64+
this.email = 'moshe@vilner.com'
65+
this.phones = []
66+
}
67+
68+
addPhone(phone) {
69+
this.phones.push(number)
70+
}
71+
72+
removePhone(phone) {
73+
let i = this.phones.indexOf(phone)
74+
this.phones.splice(i)
75+
}
76+
}
77+
78+
class Phone {
79+
constructor(type = 'Mobile', number = '555-1234-567') {
80+
this.type = type
81+
this.number = number
82+
}
83+
}
84+
85+
window.Phone = Phone
86+
window.Contact = Contact
87+
window.ContactsModel = new ContactsModel()
88+
89+
90+
91+
/**
92+
* Classic web component implementation
93+
*/
94+
var SlimHeaderProto = Object.create(HTMLElement.prototype);
95+
96+
SlimHeaderProto.createdCallback = function() {
97+
this.innerHTML = '<h1>Slim is awesome</h1>'
98+
this.style.width = '100%'
99+
this.style.display = 'block'
100+
this.style.textAlign = 'center'
101+
}
102+
103+
document.registerElement('slim-header', {
104+
prototype: SlimHeaderProto
105+
})
106+
107+
108+
109+
110+
111+
112+
113+
114+
115+
/**
116+
* Slim web component example
117+
*/
118+
Slim.tag('slim-app', class extends Slim {
119+
120+
121+
get template() {
122+
return `<div class="container"><slim-header></slim-header><slim-contacts /></div>`
123+
}
124+
125+
})
126+
127+
128+
/**
129+
* This is the wrapper for the slim-contacts application.
130+
*/
131+
Slim.tag('slim-contacts', class SlimContacts extends Slim {
132+
133+
get template() {
134+
return `
135+
<!-- header of the application, main menu -->
136+
<div class="navbar navbar-default">
137+
<div class="navbar-header">
138+
<div class="navbar-brand">Slim Contacts</div>
139+
<ul class="nav navbar-nav">
140+
<li><a #btn_add_contact>Add Contact</a></li>
141+
</ul>
142+
</div>
143+
</div>
144+
145+
<!-- pay attention how repeater works in slim -->
146+
<div class="row">
147+
<slim-contact-view slim-repeat="model.contacts"></slim-contact-view>
148+
</div>
149+
`
150+
}
151+
152+
onCreated() {
153+
this.model = window.ContactsModel
154+
this.btn_add_contact.onclick = () => {
155+
this.model.create()
156+
this.update()
157+
}
158+
159+
this.addEventListener('removeContact', contact => {
160+
this.model.remove(contact)
161+
// this.update()
162+
})
163+
}
164+
165+
select(contact) {
166+
this.selected = contact
167+
}
168+
169+
onAfterRender() {
170+
this.find('slim-repeat').onchange = () => {
171+
setTimeout( () => {
172+
this.model.sort()
173+
// this.update()
174+
}, 0)
175+
}
176+
}
177+
178+
})
179+
180+
181+
182+
Slim.tag('slim-contact-view', class SlimContactView extends Slim {
183+
184+
get template() {
185+
return `
186+
<div class="row contact-entry">
187+
<div class="col-xs-1"><input type="button" slim-id="btnRemove" class="btn btn-xs btn-danger" value="X" /> </div>
188+
<div class="col-xs-4"><slim-editable-input text="[[data.first]]" slim-id="inpFirst"></slim-editable-input> <slim-editable-input text="[[data.last]]" slim-id="inpLast"></slim-editable-input></div>
189+
<div class="col-xs-3"><slim-editable-input slim-id="inpEmail"></slim-editable-input></div>
190+
<div class="col-xs-4"><slim-phones slim-id="phones"></slim-phones></div>
191+
</div>`
192+
}
193+
194+
onCreated() {
195+
this.inpEmail.text = this.data.email
196+
this.inpEmail.onchange = () => {
197+
this.data.email = this.inpEmail.text
198+
}
199+
this.inpFirst.onchange = () => {
200+
this.data.first = this.inpFirst.text
201+
}
202+
203+
this.inpLast.onchange = () => {
204+
this.data.last = this.inpLast.text
205+
}
206+
207+
this.btnRemove.onclick = () => {
208+
let e = new Event('removeContact', {bubbles:true})
209+
e.value = this.data
210+
this.dispatchEvent(e)
211+
}
212+
213+
this.phones.data = this.data.phones
214+
}
215+
216+
217+
})
218+
219+
Slim.tag('slim-phones', class extends Slim {
220+
get template() {
221+
return `
222+
<div class="row"><input slim-id="btnAddPhone" type="button" class="btn btn-xs btn-primary" value="+ Phone" /></div>
223+
<div class="row"><slim-phone slim-repeat="data"></slim-phone></div>
224+
`
225+
}
226+
227+
onCreated() {
228+
this.btnAddPhone.onclick = () => {
229+
this.data.push( new window.Phone() )
230+
this.update()
231+
window.ContactsModel.save()
232+
}
233+
}
234+
})
235+
236+
Slim.tag('slim-phone', class extends Slim {
237+
get template() {
238+
return `<div class="col-xs-6"><slim-editable-input slim-id="type"></slim-editable-input></div>
239+
<div class="col-xs-6"><slim-editable-input slim-id="number"></slim-editable-input></div>`
240+
}
241+
242+
onCreated() {
243+
this.type.text = this.data.type
244+
this.number.text = this.data.number
245+
246+
this.number.onchange = () => {
247+
this.data.number = this.number.text
248+
}
249+
250+
this.type.onchange = () => {
251+
this.data.type = this.type.text
252+
}
253+
}
254+
})
255+
256+
257+
Slim.tag('slim-editable-input', class extends Slim {
258+
259+
get template() {
260+
return `<span slim-id="label" bind>[[text]]</span><input slim-id="inp" type="text" value=[[text]] />`
261+
}
262+
263+
onCreated() {
264+
this.inp.style.display = 'none'
265+
this.inp.style.position = 'absolute'
266+
this.inp.style.left = '0'
267+
this.inp.style.top = '0'
268+
this.inp.onblur = this.inp.onchange = () => {
269+
this.text = this.inp.value
270+
this.setAttribute('text', this.inp.value)
271+
this.inp.style.display = 'none'
272+
this.onchange()
273+
}
274+
this.label.ondblclick = () => {
275+
this.inp.style.display = 'initial'
276+
this.inp.focus()
277+
}
278+
}
279+
280+
})
281+
282+
</script>
283+
284+
<slim-app></slim-app>
285+
</body>
286+
</html>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "slim-js",
3-
"version": "2.2.5",
3+
"version": "2.2.6",
44
"description": "Slim web components infrastructure",
55
"main": "Slim.js",
66
"scripts": {

0 commit comments

Comments
 (0)