@cocreate/render 1.10.0 → 1.11.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # [1.11.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.10.0...v1.11.0) (2022-07-25)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * if templateId setAttribute ([41e30b3](https://github.com/CoCreate-app/CoCreate-render/commit/41e30b3a748aa8900d9f9397584f14052d637197))
7
+
8
+
9
+ ### Features
10
+
11
+ * getValueFromObject supports deeply nested array and objects ([db7fefd](https://github.com/CoCreate-app/CoCreate-render/commit/db7fefd81a908ba6f68dbf4c43d62639aa73e3f8))
12
+ * observe new elements with atrribute render, if elements detected replace placholders with values ([90d7d98](https://github.com/CoCreate-app/CoCreate-render/commit/90d7d982eedf83b194cfae0704d06e110914ca52))
13
+
1
14
  # [1.10.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.2...v1.10.0) (2022-07-14)
2
15
 
3
16
 
@@ -0,0 +1,42 @@
1
+ <html>
2
+ <head>
3
+ <title>Render | CoCreateJS</title>
4
+
5
+ <!-- CoCreate Favicon -->
6
+ <link rel="icon" href="https://cdn.cocreate.app/favicon.ico" type="image/ico" sizes="16x16">
7
+ </head>
8
+ <style>
9
+ .template{display:none}
10
+ </style>
11
+ <body>
12
+
13
+ <body>
14
+
15
+ <div class="template" template_id="abc1">
16
+ <h3>{{collection}}</h3>
17
+ <h3>{{data._id}}</h3>
18
+ </div>
19
+
20
+ <pre>
21
+ <h1>Paste in your browser console</h1>
22
+
23
+ /** Example **/
24
+ CoCreate.render.data({
25
+ selector: '[template_id=abc1]',
26
+ data: {
27
+ collection: 'dededede',
28
+ data: {
29
+ _id : '123kijfhgfkel45',
30
+ current_org: ['test1', 'test2', 'test31', 'test3'],
31
+ current: [{name: 'test1w'}, {name: 'test2'}, {name: 'test31'}, {name: 'test3'}]
32
+ }
33
+ }
34
+
35
+ })
36
+
37
+ </pre>
38
+
39
+ <!-- CoCreate JS CDN -->
40
+ <script src="../../../CoCreateJS/dist/CoCreate.js" ></script>
41
+ </body>
42
+ </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/render",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "A simple render component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "render",
package/src/index.js CHANGED
@@ -1,17 +1,26 @@
1
1
  /*globals CustomEvent*/
2
2
  import action from '@cocreate/actions';
3
+ import observer from '@cocreate/observer';
4
+ import uuid from '@cocreate/uuid';
3
5
  import { queryDocumentSelector } from '@cocreate/utils';
4
6
  // import { getValue } from '../../CoCreate-elements/src/getValue';
5
7
  // import api from '@cocreate/api';
6
8
 
7
9
  const CoCreateRender = {
8
-
10
+ // Can be called from crud getObjectValueByPath
9
11
  __getValueFromObject : function(json, path) {
10
12
  try {
11
13
  if(typeof json == 'undefined' || !path)
12
14
  return false;
13
15
  if (path.indexOf('.') == -1 && path.includes('collection'))
14
16
  json = this.dataOriginal
17
+ if (/\[([0-9]*)\]/g.test(path)) {
18
+ path = path.replace(/\[/g, '.');
19
+ if (path.endsWith(']'))
20
+ path = path.slice(0, -1)
21
+ path = path.replace(/\]./g, '.');
22
+ path = path.replace(/\]/g, '.');
23
+ }
15
24
  let jsonData = json, subpath = path.split('.');
16
25
 
17
26
  for (let i = 0; i < subpath.length; i++) {
@@ -103,31 +112,32 @@ const CoCreateRender = {
103
112
  },
104
113
 
105
114
  render: function(template, data) {
106
- let type = template.getAttribute('render-array') || "data";
107
- const renderKey = template.getAttribute('render-key') || type;
108
115
  const self = this;
109
-
116
+ let type = '';
110
117
  let arrayData = data;
111
118
 
112
119
  const isRenderObject = template.hasAttribute('render-object');
113
120
  if (isRenderObject){
114
- const renderObject = template.getAttribute('render-object');
115
- type = renderObject || 'data'
121
+ const renderObject = template.getAttribute('render-object');
122
+ type = renderObject || ''
116
123
  }
117
124
 
118
125
  const isRenderArray = template.hasAttribute('render-array');
119
126
  if (isRenderArray){
120
- const renderArray = template.getAttribute('render-array');
127
+ var renderArray = template.getAttribute('render-array');
121
128
  if (renderArray)
122
129
  arrayData = data[renderArray];
123
- type = renderArray || 'data';
130
+ type = renderArray || '';
124
131
  }
132
+
133
+ let renderKey = template.getAttribute('render-key') || type;
134
+
125
135
  if (isRenderObject && type) {
126
- let r_data = self.isRenderObject(arrayData[type], renderKey)
127
- for (let sdata of r_data) {
136
+ let Data = self.__getValueFromObject(arrayData, type);
137
+ let array = self.isRenderObject(Data, renderKey)
138
+ for (let item of array) {
128
139
  let cloneEl = this.cloneEl(template);
129
- cloneEl.classList.add('clone_' + type);
130
- self.setValue([cloneEl], sdata, renderKey);
140
+ self.setValue([cloneEl], item, renderArray, renderKey);
131
141
  template.insertAdjacentElement('beforebegin', cloneEl);
132
142
  }
133
143
  } else {
@@ -137,17 +147,15 @@ const CoCreateRender = {
137
147
 
138
148
  if (!arrayData) {
139
149
  let cloneEl = this.cloneEl(template);
140
- cloneEl.classList.add('cloned');
141
- self.setValue([cloneEl], data, renderKey);
150
+ self.setValue([cloneEl], data, renderArray, renderKey);
142
151
  template.insertAdjacentElement('beforebegin', cloneEl);
143
152
  }
144
153
 
145
154
  if(type && Array.isArray(arrayData)) {
146
155
  arrayData.forEach((item) => {
147
156
  let cloneEl = this.cloneEl(template);
148
- cloneEl.classList.add('clone_' + type);
149
- let r_data = self.__createObject(item, renderKey);
150
- self.setValue([cloneEl], r_data, renderKey);
157
+ let object = self.__createObject(item, renderKey);
158
+ self.setValue([cloneEl], object, renderArray, renderKey);
151
159
  template.insertAdjacentElement('beforebegin', cloneEl);
152
160
  });
153
161
  }
@@ -156,6 +164,8 @@ const CoCreateRender = {
156
164
 
157
165
  isRenderObject: function(data, renderKey) {
158
166
  let array = []
167
+ if (!data)
168
+ return array
159
169
  for (const [key, value] of Object.entries(data)) {
160
170
  let type = 'string';
161
171
  if (typeof(value) == "object")
@@ -170,26 +180,44 @@ const CoCreateRender = {
170
180
 
171
181
  cloneEl: function(template) {
172
182
  let cloneEl = template.cloneNode(true);
173
- cloneEl.classList.remove('template');
183
+
174
184
  let templateId = cloneEl.getAttribute('template_id');
185
+ if (templateId)
186
+ cloneEl.setAttribute('templateId', templateId);
187
+
175
188
  cloneEl.removeAttribute('template_id');
176
- cloneEl.setAttribute('templateId', templateId);
189
+ cloneEl.setAttribute('render-clone', '');
190
+ cloneEl.classList.remove('template');
191
+
192
+ if (template.dataOriginal)
193
+ cloneEl.dataOriginal = template.dataOriginal
194
+
177
195
  return cloneEl;
178
196
  },
179
197
 
180
- setValue: function(els, data, renderKey){
198
+ setValue: function(els, data, renderArray, renderKey){
181
199
  if (!data) return;
182
200
  const that = this;
183
201
  Array.from(els).forEach(el => {
202
+ let updateData;
184
203
 
185
204
  if (el.nodeType == 1) {
205
+ if (el.hasAttribute('render-clone')) {
206
+ el.renderData = {...data}
207
+ }
186
208
  if (el.renderMap) {
187
209
  let placeholder = el.renderMap.get(el)
188
210
  if (placeholder){
189
- el.innerHTML = placeholder.placeholder
190
211
  renderKey = placeholder.renderKey
191
- if (data[renderKey][0])
192
- data = {[renderKey]: data[renderKey][0]}
212
+ renderArray = placeholder.renderArray
213
+ if (renderArray)
214
+ updateData = data[renderArray][0]
215
+ if (renderKey)
216
+ updateData = {[renderKey]: updateData}
217
+ let textContent = placeholder.placeholder
218
+ let text = that.__replaceValue(updateData, textContent, renderKey, valueType);
219
+ if (text)
220
+ el.innerHTML = placeholder.placeholder
193
221
  }
194
222
  }
195
223
 
@@ -197,31 +225,37 @@ const CoCreateRender = {
197
225
  let attr_name = attr.name.toLowerCase();
198
226
  let attrValue = attr.value;
199
227
 
200
- // get placeholder
201
228
  let placeholder
202
229
  if (attr.renderMap)
203
230
  placeholder = attr.renderMap.get(attr)
204
231
  else
205
- that.renderMap(attr, attr.value, renderKey)
232
+ that.renderMap(attr, attr.value, renderArray, renderKey)
206
233
 
207
234
  if(placeholder){
235
+ let updateData = data;
208
236
  attrValue = placeholder.placeholder;
209
237
  renderKey = placeholder.renderKey
210
- let updateData = data;
211
- if (data[renderKey][0])
212
- updateData = {[renderKey]: data[renderKey][0]}
238
+ renderArray = placeholder.renderArray
239
+ if (renderArray)
240
+ updateData = data[renderArray][0]
241
+ if (renderKey)
242
+ updateData = {[renderKey]: updateData}
243
+
213
244
  attrValue = that.__replaceValue(updateData, attrValue, renderKey);
214
245
  }
215
246
  else
216
247
  attrValue = that.__replaceValue(data, attrValue, renderKey);
217
248
 
249
+ // ToDo support attibute name replace if has {{}}
250
+ // attr_name = that.__replaceValue(data, attr_name, renderKey);
251
+
218
252
  if (attrValue || attrValue == "") {
219
253
  el.setAttribute(attr_name, attrValue);
220
254
  }
221
255
  });
222
256
 
223
257
  if(el.childNodes.length > 0) {
224
- that.setValue(el.childNodes, data, renderKey);
258
+ that.setValue(el.childNodes, updateData || data, renderArray, renderKey);
225
259
  }
226
260
  if (el.classList.contains('template') && !el.hasAttribute('template_id')) {
227
261
  that.render(el, data);
@@ -231,26 +265,26 @@ const CoCreateRender = {
231
265
  if (el.nodeType == 3) {
232
266
  let valueType = el.parentElement.getAttribute('value-type')
233
267
 
234
- // get placeholder
235
268
  let textContent, placeholder, text;
236
269
  if (el.renderMap)
237
270
  placeholder = el.renderMap.get(el)
238
271
  if (placeholder) {
272
+ let updateData = data;
239
273
  textContent = placeholder.placeholder
240
274
  renderKey = placeholder.renderKey
241
- let updateData = data;
242
- if (data[renderKey][0])
243
- updateData = {[renderKey]: data[renderKey][0]}
275
+ renderArray = placeholder.renderArray
276
+ if (renderArray)
277
+ updateData = data[renderArray][0]
278
+ if (renderKey)
279
+ updateData = {[renderKey]: updateData}
244
280
  text = that.__replaceValue(updateData, textContent, renderKey, valueType);
245
281
  }
246
282
  if (!text) {
247
283
  textContent = el.textContent;
248
- that.renderMap(el, textContent, renderKey)
284
+ that.renderMap(el, textContent, renderArray, renderKey)
249
285
  text = that.__replaceValue(data, textContent, renderKey, valueType);
250
286
  }
251
287
 
252
- // let textContent = el.textContent;
253
- // let text = that.__replaceValue(data, textContent, renderKey, valueType);
254
288
  if (text || text == "") {
255
289
  if (valueType == 'text' || valueType == 'string'){
256
290
  el.textContent = text;
@@ -259,9 +293,9 @@ const CoCreateRender = {
259
293
  newNode.innerHTML = text;
260
294
  let parentElement = el.parentElement
261
295
  if (!parentElement.renderMap) {
262
- that.renderMap(parentElement, textContent, renderKey)
296
+ that.renderMap(parentElement, textContent, renderArray, renderKey)
263
297
  } else if (!parentElement['renderMap'].has(parentElement))
264
- that.renderMap(parentElement, textContent, renderKey)
298
+ that.renderMap(parentElement, textContent, renderArray, renderKey)
265
299
  el.replaceWith(...newNode.childNodes)
266
300
  }
267
301
  }
@@ -269,28 +303,36 @@ const CoCreateRender = {
269
303
  });
270
304
  },
271
305
 
272
- renderMap: function(node, placeholder, renderKey) {
306
+ renderMap: function(node, placeholder, renderArray, renderKey) {
273
307
  if (!node.renderMap) {
274
308
  node['renderMap'] = new Map();
275
309
  }
276
310
  if (placeholder && renderKey)
277
- node['renderMap'].set(node, {placeholder, renderKey})
311
+ node['renderMap'].set(node, {placeholder, renderArray, renderKey})
278
312
  },
279
313
 
280
314
  dataOriginal: {},
281
315
  data: function({selector, data, elements}) {
282
- this.dataOriginal = data;
316
+ this.dataOriginal = {...data};
317
+ this.dataString = {...data};
318
+ delete this.dataOriginal.data
319
+
320
+ for (let element of elements)
321
+ element.dataOriginal = {...this.dataOriginal};
322
+
283
323
  if (selector) {
284
324
  let template = queryDocumentSelector(selector);
285
325
  if (!template) return;
326
+ template.dataOriginal = {...data}
286
327
  if (template.classList.contains('template')) {
287
328
  this.render(template, data);
288
329
  }
289
330
  else
290
331
  this.setValue([template], data);
291
332
  } else if (elements) {
292
- if (elements.length == 1 && elements[0].classList.contains('template'))
333
+ if (elements.length == 1 && elements[0].classList.contains('template')){
293
334
  this.render(elements[0], data);
335
+ }
294
336
  else
295
337
  this.setValue(elements, data);
296
338
  }
@@ -321,4 +363,79 @@ action.init({
321
363
  }
322
364
  });
323
365
 
366
+ observer.init({
367
+ name: 'render',
368
+ observe: ['addedNodes'],
369
+ target: '[render]',
370
+ callback: function(mutation) {
371
+ let element = mutation.target
372
+ element.removeAttribute('render')
373
+
374
+ let parentElement = element.parentElement
375
+ if (parentElement) {
376
+ let el = element
377
+ let parentKeys = [];
378
+ let renderData = new Map();
379
+ do {
380
+ let data;
381
+ el = el.parentElement
382
+ if (el) {
383
+ if (el.dataOriginal)
384
+ renderData.set(el.dataOriginal, '')
385
+ if (el.hasAttribute('render-clone'))
386
+ data = el.renderData
387
+ if (data)
388
+ renderData.set(data, '')
389
+
390
+ let parentKey = el.getAttribute('parentKey')
391
+ if(parentKey && parentKey != null) {
392
+ if (/^\d+$/.test(parentKey))
393
+ parentKey = `[${parentKey}]`
394
+ parentKeys.push(parentKey)
395
+ }
396
+ }
397
+ } while (el)
398
+
399
+ let renderKey = element.getAttribute('render-key')
400
+
401
+ let parentKey;
402
+ parentKey = parentElement.getAttribute('parentKey')
403
+ if(renderKey == '$auto' || parentKey || parentKeys) {
404
+ let template = element.outerHTML
405
+ if (renderKey) {
406
+ template = template.replace(/\$auto/g, uuid.generate(6));
407
+ }
408
+ if (parentKeys.length > 0) {
409
+ let string = ''
410
+ if (parentKeys.length == 1){
411
+ string = parentKeys[0]
412
+ }
413
+ else
414
+ string = parentKeys.reverse().join('.')
415
+ string = string.replace(/.\[/g, '[');
416
+ template = template.replace(/\$parents/g, string);
417
+ }
418
+ if (parentKey) {
419
+ template = template.replace(/\$parent/g, parentKey);
420
+ }
421
+
422
+ parentElement.innerHTML = template
423
+
424
+ }
425
+
426
+ element = parentElement.firstElementChild
427
+ let obj = {}
428
+ let array = Array.from(renderData.keys())
429
+ for (let data of array.reverse()){
430
+ obj = {...obj, ...data}
431
+ }
432
+
433
+ CoCreateRender.data({
434
+ elements: [element],
435
+ data: obj
436
+ });
437
+ }
438
+ }
439
+ });
440
+
324
441
  export default CoCreateRender;