@cocreate/render 1.9.1 → 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,30 @@
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
+
14
+ # [1.10.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.2...v1.10.0) (2022-07-14)
15
+
16
+
17
+ ### Features
18
+
19
+ * renderMap function to apply map containing placeholder to node object in order to render new values ([7afffa0](https://github.com/CoCreate-app/CoCreate-render/commit/7afffa07b2cc1dd562e96d1ee558433d3f6d043a))
20
+
21
+ ## [1.9.2](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.1...v1.9.2) (2022-07-10)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * use dataOriginal if path includes collection ([e6b9288](https://github.com/CoCreate-app/CoCreate-render/commit/e6b92886bad560fa64e487609c69f37268d87587))
27
+
1
28
  ## [1.9.1](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.0...v1.9.1) (2022-07-08)
2
29
 
3
30
 
@@ -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.9.1",
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
- if (path.indexOf('.') == -1)
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++) {
@@ -52,7 +61,7 @@ const CoCreateRender = {
52
61
  }
53
62
  },
54
63
 
55
- __replaceValue: function(data, inputValue, renderKey) {
64
+ __replaceValue: function(data, inputValue, renderKey, valueType) {
56
65
  let isPass = false;
57
66
  let self = this;
58
67
  let resultValue = null;
@@ -64,18 +73,8 @@ const CoCreateRender = {
64
73
  data[renderKey]['collection'] = this.dataOriginal[renderKey]['collection']
65
74
 
66
75
  let value = self.__getValue(data, attr);
67
- // if (value) {
68
- // if (value && typeof(value) !== "object") {
69
- // if (value && !Array.isArray(value)) {
70
76
  if (value) {
71
- // converts object to string
72
- // if (!Array.isArray(value) && typeof(value) == "object") {
73
77
  if (typeof(value) == "object") {
74
- // let str = '';
75
- // for (const [key, val] of Object.entries(value)) {
76
- // str += `${key}: ${val}\n`;
77
- // }
78
-
79
78
  value = this.generateString(value)
80
79
  }
81
80
  isPass = true;
@@ -113,33 +112,33 @@ const CoCreateRender = {
113
112
  },
114
113
 
115
114
  render: function(template, data) {
116
- let type = template.getAttribute('render-array') || "data";
117
- const renderKey = template.getAttribute('render-key') || type;
118
115
  const self = this;
119
-
120
- // const arrayData = this.__getValueFromObject(data, type);
116
+ let type = '';
121
117
  let arrayData = data;
122
118
 
123
119
  const isRenderObject = template.hasAttribute('render-object');
124
120
  if (isRenderObject){
125
- const renderObject = template.getAttribute('render-object');
126
- type = renderObject || 'data'
121
+ const renderObject = template.getAttribute('render-object');
122
+ type = renderObject || ''
127
123
  }
128
124
 
129
125
  const isRenderArray = template.hasAttribute('render-array');
130
126
  if (isRenderArray){
131
- const renderArray = template.getAttribute('render-array');
127
+ var renderArray = template.getAttribute('render-array');
132
128
  if (renderArray)
133
129
  arrayData = data[renderArray];
134
- type = renderArray || 'data';
130
+ type = renderArray || '';
135
131
  }
132
+
133
+ let renderKey = template.getAttribute('render-key') || type;
134
+
136
135
  if (isRenderObject && type) {
137
- let r_data = self.isRenderObject(arrayData[type], renderKey)
138
- 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) {
139
139
  let cloneEl = this.cloneEl(template);
140
- cloneEl.classList.add('clone_' + type);
141
- self.setValue([cloneEl], sdata, renderKey);
142
- template.insertAdjacentHTML('beforebegin', cloneEl.outerHTML);
140
+ self.setValue([cloneEl], item, renderArray, renderKey);
141
+ template.insertAdjacentElement('beforebegin', cloneEl);
143
142
  }
144
143
  } else {
145
144
 
@@ -148,18 +147,16 @@ const CoCreateRender = {
148
147
 
149
148
  if (!arrayData) {
150
149
  let cloneEl = this.cloneEl(template);
151
- cloneEl.classList.add('cloned');
152
- self.setValue([cloneEl], data, renderKey);
153
- template.insertAdjacentHTML('beforebegin', cloneEl.outerHTML);
150
+ self.setValue([cloneEl], data, renderArray, renderKey);
151
+ template.insertAdjacentElement('beforebegin', cloneEl);
154
152
  }
155
153
 
156
154
  if(type && Array.isArray(arrayData)) {
157
155
  arrayData.forEach((item) => {
158
156
  let cloneEl = this.cloneEl(template);
159
- cloneEl.classList.add('clone_' + type);
160
- let r_data = self.__createObject(item, renderKey);
161
- self.setValue([cloneEl], r_data, renderKey);
162
- template.insertAdjacentHTML('beforebegin', cloneEl.outerHTML);
157
+ let object = self.__createObject(item, renderKey);
158
+ self.setValue([cloneEl], object, renderArray, renderKey);
159
+ template.insertAdjacentElement('beforebegin', cloneEl);
163
160
  });
164
161
  }
165
162
  }
@@ -167,6 +164,8 @@ const CoCreateRender = {
167
164
 
168
165
  isRenderObject: function(data, renderKey) {
169
166
  let array = []
167
+ if (!data)
168
+ return array
170
169
  for (const [key, value] of Object.entries(data)) {
171
170
  let type = 'string';
172
171
  if (typeof(value) == "object")
@@ -181,76 +180,161 @@ const CoCreateRender = {
181
180
 
182
181
  cloneEl: function(template) {
183
182
  let cloneEl = template.cloneNode(true);
184
- cloneEl.classList.remove('template');
183
+
185
184
  let templateId = cloneEl.getAttribute('template_id');
185
+ if (templateId)
186
+ cloneEl.setAttribute('templateId', templateId);
187
+
186
188
  cloneEl.removeAttribute('template_id');
187
- 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
+
188
195
  return cloneEl;
189
196
  },
190
197
 
191
- setValue: function(els, data, renderKey){
198
+ setValue: function(els, data, renderArray, renderKey){
192
199
  if (!data) return;
193
200
  const that = this;
194
201
  Array.from(els).forEach(el => {
202
+ let updateData;
203
+
195
204
  if (el.nodeType == 1) {
205
+ if (el.hasAttribute('render-clone')) {
206
+ el.renderData = {...data}
207
+ }
208
+ if (el.renderMap) {
209
+ let placeholder = el.renderMap.get(el)
210
+ if (placeholder){
211
+ renderKey = placeholder.renderKey
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
221
+ }
222
+ }
223
+
196
224
  Array.from(el.attributes).forEach(attr=>{
197
225
  let attr_name = attr.name.toLowerCase();
198
226
  let attrValue = attr.value;
199
- attrValue = that.__replaceValue(data, attrValue, renderKey);
227
+
228
+ let placeholder
229
+ if (attr.renderMap)
230
+ placeholder = attr.renderMap.get(attr)
231
+ else
232
+ that.renderMap(attr, attr.value, renderArray, renderKey)
233
+
234
+ if(placeholder){
235
+ let updateData = data;
236
+ attrValue = placeholder.placeholder;
237
+ renderKey = placeholder.renderKey
238
+ renderArray = placeholder.renderArray
239
+ if (renderArray)
240
+ updateData = data[renderArray][0]
241
+ if (renderKey)
242
+ updateData = {[renderKey]: updateData}
243
+
244
+ attrValue = that.__replaceValue(updateData, attrValue, renderKey);
245
+ }
246
+ else
247
+ attrValue = that.__replaceValue(data, attrValue, renderKey);
200
248
 
249
+ // ToDo support attibute name replace if has {{}}
250
+ // attr_name = that.__replaceValue(data, attr_name, renderKey);
251
+
201
252
  if (attrValue || attrValue == "") {
202
253
  el.setAttribute(attr_name, attrValue);
203
254
  }
204
255
  });
205
256
 
206
- if(el.childNodes.length > 0) {
207
- that.setValue(el.childNodes, data, renderKey);
257
+ if(el.childNodes.length > 0) {
258
+ that.setValue(el.childNodes, updateData || data, renderArray, renderKey);
208
259
  }
209
260
  if (el.classList.contains('template') && !el.hasAttribute('template_id')) {
210
261
  that.render(el, data);
211
262
  }
212
263
  }
213
-
264
+
214
265
  if (el.nodeType == 3) {
215
266
  let valueType = el.parentElement.getAttribute('value-type')
216
- let textContent = el.textContent;
217
- let text = that.__replaceValue(data, textContent, renderKey);
267
+
268
+ let textContent, placeholder, text;
269
+ if (el.renderMap)
270
+ placeholder = el.renderMap.get(el)
271
+ if (placeholder) {
272
+ let updateData = data;
273
+ textContent = placeholder.placeholder
274
+ renderKey = placeholder.renderKey
275
+ renderArray = placeholder.renderArray
276
+ if (renderArray)
277
+ updateData = data[renderArray][0]
278
+ if (renderKey)
279
+ updateData = {[renderKey]: updateData}
280
+ text = that.__replaceValue(updateData, textContent, renderKey, valueType);
281
+ }
282
+ if (!text) {
283
+ textContent = el.textContent;
284
+ that.renderMap(el, textContent, renderArray, renderKey)
285
+ text = that.__replaceValue(data, textContent, renderKey, valueType);
286
+ }
287
+
218
288
  if (text || text == "") {
219
289
  if (valueType == 'text' || valueType == 'string'){
220
290
  el.textContent = text;
221
291
  } else {
222
292
  const newNode = document.createElement('div');
223
293
  newNode.innerHTML = text;
294
+ let parentElement = el.parentElement
295
+ if (!parentElement.renderMap) {
296
+ that.renderMap(parentElement, textContent, renderArray, renderKey)
297
+ } else if (!parentElement['renderMap'].has(parentElement))
298
+ that.renderMap(parentElement, textContent, renderArray, renderKey)
224
299
  el.replaceWith(...newNode.childNodes)
225
300
  }
226
301
  }
227
302
  }
228
-
229
303
  });
230
304
  },
305
+
306
+ renderMap: function(node, placeholder, renderArray, renderKey) {
307
+ if (!node.renderMap) {
308
+ node['renderMap'] = new Map();
309
+ }
310
+ if (placeholder && renderKey)
311
+ node['renderMap'].set(node, {placeholder, renderArray, renderKey})
312
+ },
231
313
 
232
314
  dataOriginal: {},
233
315
  data: function({selector, data, elements}) {
234
- 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
+
235
323
  if (selector) {
236
324
  let template = queryDocumentSelector(selector);
237
325
  if (!template) return;
326
+ template.dataOriginal = {...data}
238
327
  if (template.classList.contains('template')) {
239
328
  this.render(template, data);
240
329
  }
241
330
  else
242
331
  this.setValue([template], data);
243
332
  } else if (elements) {
244
- if (elements.length == 1 && elements[0].classList.contains('template'))
333
+ if (elements.length == 1 && elements[0].classList.contains('template')){
245
334
  this.render(elements[0], data);
335
+ }
246
336
  else
247
337
  this.setValue(elements, data);
248
- // for (let element of elements) {
249
- // if (element.classList.contains('template'))
250
- // this.render(element, data);
251
- // else
252
- // this.setValue([element], data);
253
- // }
254
338
  }
255
339
 
256
340
  }
@@ -279,4 +363,79 @@ action.init({
279
363
  }
280
364
  });
281
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
+
282
441
  export default CoCreateRender;