@livinglogic/livingapi 0.12.0 → 0.13.2
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 +66 -0
- package/README.md +3 -3
- package/dist/esm-node/livingapi.js +1 -1
- package/dist/esm-node/livingapi.js.map +1 -1
- package/dist/esm-static/livingapi.js +1 -1
- package/dist/esm-static/livingapi.js.map +1 -1
- package/dist/umd/livingapi.js +1 -1
- package/dist/umd/livingapi.js.map +1 -1
- package/package.json +9 -9
- package/src/livingapi.js +1610 -194
package/src/livingapi.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* LivingAPI JavaScript Library
|
|
3
3
|
* https://my.living-apps.de/docs/LivingAPI.html
|
|
4
4
|
*
|
|
5
|
-
* Copyright 2017-
|
|
6
|
-
* Copyright 2017-
|
|
5
|
+
* Copyright 2017-2022 by LivingLogic AG, Bayreuth/Germany
|
|
6
|
+
* Copyright 2017-2022 by Walter Dörwald
|
|
7
7
|
*
|
|
8
8
|
* All Rights Reserved
|
|
9
9
|
*
|
|
@@ -33,11 +33,18 @@ export { version };
|
|
|
33
33
|
|
|
34
34
|
import * as ul4 from '@livinglogic/ul4';
|
|
35
35
|
|
|
36
|
+
|
|
36
37
|
export class Base extends ul4.Proto
|
|
37
38
|
{
|
|
38
|
-
constructor()
|
|
39
|
+
constructor(id)
|
|
39
40
|
{
|
|
40
41
|
super();
|
|
42
|
+
this.id = id;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get ul4onid()
|
|
46
|
+
{
|
|
47
|
+
return this.id;
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
ul4ondump(encoder)
|
|
@@ -76,7 +83,7 @@ export class Base extends ul4.Proto
|
|
|
76
83
|
this[name] = null;
|
|
77
84
|
}
|
|
78
85
|
|
|
79
|
-
|
|
86
|
+
[ul4.symbols.getattr](name)
|
|
80
87
|
{
|
|
81
88
|
if (this._ul4attrs.has(name))
|
|
82
89
|
{
|
|
@@ -95,12 +102,18 @@ export class Base extends ul4.Proto
|
|
|
95
102
|
throw new ul4.AttributeError(this, name);
|
|
96
103
|
}
|
|
97
104
|
|
|
98
|
-
|
|
105
|
+
[ul4.symbols.repr]()
|
|
99
106
|
{
|
|
100
107
|
return "<" + this.constructor.name + ">";
|
|
101
108
|
}
|
|
109
|
+
|
|
110
|
+
toString()
|
|
111
|
+
{
|
|
112
|
+
return this[ul4.symbols.repr]();
|
|
113
|
+
}
|
|
102
114
|
};
|
|
103
115
|
|
|
116
|
+
|
|
104
117
|
export class Handler
|
|
105
118
|
{
|
|
106
119
|
save(record)
|
|
@@ -112,11 +125,14 @@ export class Handler
|
|
|
112
125
|
}
|
|
113
126
|
};
|
|
114
127
|
|
|
128
|
+
|
|
115
129
|
export class Globals extends Base
|
|
116
130
|
{
|
|
117
|
-
|
|
131
|
+
static classdoc = "Global information";
|
|
132
|
+
|
|
133
|
+
constructor(id)
|
|
118
134
|
{
|
|
119
|
-
super();
|
|
135
|
+
super(id);
|
|
120
136
|
this.version = null;
|
|
121
137
|
this.hostname = null;
|
|
122
138
|
this.platform = null;
|
|
@@ -157,67 +173,137 @@ export class Globals extends Base
|
|
|
157
173
|
return s;
|
|
158
174
|
}
|
|
159
175
|
|
|
160
|
-
|
|
176
|
+
scaledURL(url, width, height, type="fill", enlarge=true, gravity="sm", quality=null, rotate=null, blur=null, sharpen=null, format=null, cache=true)
|
|
177
|
+
{
|
|
178
|
+
let filename = null;
|
|
179
|
+
|
|
180
|
+
if (url instanceof File)
|
|
181
|
+
{
|
|
182
|
+
url = "https://" + this.hostname + url.url;
|
|
183
|
+
filename = encodeURIComponent(url.filename);
|
|
184
|
+
if (filename != url.filename)
|
|
185
|
+
filename = null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
let result = "";
|
|
189
|
+
|
|
190
|
+
if (cache)
|
|
191
|
+
result += "/imgproxycache/insecure";
|
|
192
|
+
else
|
|
193
|
+
result += "/imgproxy/insecure";
|
|
194
|
+
|
|
195
|
+
if (type !== "fit")
|
|
196
|
+
result += "/rt:" + type;
|
|
197
|
+
|
|
198
|
+
if (width !== null && width !== undefined)
|
|
199
|
+
result += "/w:" + width;
|
|
200
|
+
|
|
201
|
+
if (height !== null && height !== undefined)
|
|
202
|
+
result += "/h:" + height;
|
|
203
|
+
|
|
204
|
+
if (enlarge)
|
|
205
|
+
result += "/el:1";
|
|
206
|
+
|
|
207
|
+
if (gravity !== null && gravity !== undefined)
|
|
208
|
+
result += "/g:" + gravity;
|
|
209
|
+
|
|
210
|
+
if (quality !== null && quality !== undefined)
|
|
211
|
+
result += "/q:" + quality;
|
|
212
|
+
|
|
213
|
+
if (rotate !== null && rotate % 360 != 0)
|
|
214
|
+
result += "/rot:" + rotatet;
|
|
215
|
+
|
|
216
|
+
if (blur !== null && blur !== undefined)
|
|
217
|
+
result += "/bl:" + blur;
|
|
218
|
+
|
|
219
|
+
if (sharpen !== null && sharpen !== undefined)
|
|
220
|
+
result += "/sh:" + sharpen;
|
|
221
|
+
|
|
222
|
+
if (format !== null && format !== undefined)
|
|
223
|
+
result += "/f:" + format;
|
|
224
|
+
|
|
225
|
+
if (filename !== null && filename !== undefined)
|
|
226
|
+
result += "/fn:" + filename;
|
|
227
|
+
|
|
228
|
+
result += "/plain/" + encodeURIComponent(url);
|
|
229
|
+
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
[ul4.symbols.repr]()
|
|
161
234
|
{
|
|
162
235
|
return "<Globals version=" + ul4._repr(this.version) + ">";
|
|
163
236
|
}
|
|
164
237
|
};
|
|
165
238
|
|
|
166
|
-
Globals.prototype._ul4onattrs = ["version", "platform", "user", "maxdbactions", "maxtemplateruntime", "flashmessages", "lang", "datasources", "hostname", "app", "record"];
|
|
167
|
-
Globals.prototype._ul4attrs =
|
|
239
|
+
Globals.prototype._ul4onattrs = ["version", "platform", "user", "maxdbactions", "maxtemplateruntime", "flashmessages", "lang", "datasources", "hostname", "app", "record", "google_api_key", "mode", "view_template_id", "email_template_id", "view_id"];
|
|
240
|
+
Globals.prototype._ul4attrs = new Set(["version", "hostname", "platform", "user", "lang", "app", "record", "maxdbactions", "maxtemplateruntime", "flashmessages", "mode"]);
|
|
241
|
+
|
|
168
242
|
|
|
169
243
|
export class FlashMessage extends Base
|
|
170
244
|
{
|
|
171
|
-
|
|
245
|
+
static classdoc = "A flash message in a web page";
|
|
246
|
+
|
|
247
|
+
[ul4.symbols.repr]()
|
|
172
248
|
{
|
|
173
249
|
return "<FlashMessage type=" + ul4._repr(this.type) + " title=" + ul4._repr(this.title) + ">";
|
|
174
250
|
}
|
|
175
251
|
};
|
|
176
252
|
|
|
177
253
|
FlashMessage.prototype._ul4onattrs = ["timestamp", "type", "title", "message"];
|
|
178
|
-
FlashMessage.prototype._ul4attrs =
|
|
254
|
+
FlashMessage.prototype._ul4attrs = new Set(["timestamp", "type", "title", "message"]);
|
|
255
|
+
|
|
179
256
|
|
|
180
257
|
export class App extends Base
|
|
181
258
|
{
|
|
182
|
-
|
|
259
|
+
static classdoc = "A LivingApps application";
|
|
260
|
+
|
|
261
|
+
[ul4.symbols.repr]()
|
|
183
262
|
{
|
|
184
263
|
return "<App id=" + ul4._repr(this.id) + " name=" + ul4._repr(this.name) + ">";
|
|
185
264
|
}
|
|
186
265
|
|
|
187
266
|
insert(values={})
|
|
188
267
|
{
|
|
189
|
-
let record = this.
|
|
268
|
+
let record = this[ul4.symbols.call](values);
|
|
190
269
|
this.globals.handler.save(this);
|
|
191
270
|
return record;
|
|
192
271
|
}
|
|
193
272
|
|
|
194
|
-
|
|
273
|
+
get layout_controls()
|
|
274
|
+
{
|
|
275
|
+
if (this.active_view === null)
|
|
276
|
+
return new Map();
|
|
277
|
+
return this.active_view.layout_controls;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
[ul4.symbols.call](values={})
|
|
195
281
|
{
|
|
196
|
-
let record = new Record(this);
|
|
282
|
+
let record = new Record(null, this);
|
|
197
283
|
if (ul4._ismap(values))
|
|
198
284
|
{
|
|
199
|
-
for (let
|
|
285
|
+
for (let identifier of values.keys())
|
|
200
286
|
{
|
|
201
|
-
if (!record.fields.has(
|
|
202
|
-
throw new ul4.ArgumentError("
|
|
203
|
-
record.fields.get(key).value = value;
|
|
287
|
+
if (!record.fields.has(identifier))
|
|
288
|
+
throw new ul4.ArgumentError(ul4._repr(this) + "() get an unexpected keyword argument " + ul4._repr(identifier));
|
|
204
289
|
}
|
|
290
|
+
record._make_fields(true, values, null, null);
|
|
205
291
|
}
|
|
206
292
|
else if (ul4._isobject(values))
|
|
207
293
|
{
|
|
208
|
-
for (let
|
|
294
|
+
for (let identifier in values)
|
|
209
295
|
{
|
|
210
|
-
if (!record.fields.has(
|
|
211
|
-
throw new ul4.ArgumentError("
|
|
212
|
-
record.fields.get(key).value = values[key];
|
|
296
|
+
if (!record.fields.has(identifier))
|
|
297
|
+
throw new ul4.ArgumentError(ul4._repr(this) + "() get an unexpected keyword argument " + ul4._repr(identifier));
|
|
213
298
|
}
|
|
299
|
+
record._make_fields(true, new Map(ul4._list(ul4.dicttype.items(values))), null, null);
|
|
214
300
|
}
|
|
215
301
|
else
|
|
216
302
|
throw new ul4.TypeError("values must be an object or a Map");
|
|
217
303
|
return record;
|
|
218
304
|
}
|
|
219
305
|
|
|
220
|
-
|
|
306
|
+
[ul4.symbols.getattr](name)
|
|
221
307
|
{
|
|
222
308
|
if (name.startsWith("c_"))
|
|
223
309
|
{
|
|
@@ -226,43 +312,83 @@ export class App extends Base
|
|
|
226
312
|
return this.controls.get(name.substr(2));
|
|
227
313
|
}
|
|
228
314
|
else
|
|
229
|
-
return super.
|
|
315
|
+
return super[ul4.symbols.getattr](name);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
get active_view()
|
|
319
|
+
{
|
|
320
|
+
return this._active_view;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
set active_view(view)
|
|
324
|
+
{
|
|
325
|
+
if (view === null)
|
|
326
|
+
;
|
|
327
|
+
else if (typeof(view) === "string")
|
|
328
|
+
{
|
|
329
|
+
if (this.views !== null && this.views.has(view))
|
|
330
|
+
view = this.views.get(view);
|
|
331
|
+
else
|
|
332
|
+
throw new ul4.ValueError("View " + ul4._repr(view) + " not found!");
|
|
333
|
+
}
|
|
334
|
+
else if (view instanceof View)
|
|
335
|
+
{
|
|
336
|
+
if (view.app === this)
|
|
337
|
+
;
|
|
338
|
+
else
|
|
339
|
+
throw new ul4.ValueError("View " + ul4._repr(view) + " belongs to the wrong app!");
|
|
340
|
+
}
|
|
341
|
+
else
|
|
342
|
+
{
|
|
343
|
+
throw new ul4.TypeError(ul4._repr(view) + " is not a view!");
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
this._active_view = view;
|
|
230
347
|
}
|
|
231
348
|
};
|
|
232
349
|
|
|
233
|
-
|
|
234
|
-
App.prototype.
|
|
235
|
-
|
|
350
|
+
|
|
351
|
+
App.prototype._ul4onattrs = ["globals", "name", "description", "lang", "startlink", "iconlarge", "iconsmall", "createdby", "controls", "records", "recordcount", "installation", "categories", "params", "views", "datamanagement_identifier", "basetable", "primarykey", "insertprocedure", "updateprocedure", "deleteprocedure", "templates", "createdat", "updatedat", "updatedby", "superid", "favorite", "_active_view"];
|
|
352
|
+
App.prototype._ul4attrs = new Set(["id", "globals", "name", "description", "lang", "startlink", "iconlarge", "iconsmall", "createdat", "createdby", "updatedat", "updatedby", "controls", "records", "recordcount", "installation", "categories", "params", "views", "datamanagement_identifier", "insert", "favorite", "_active_view"]);
|
|
353
|
+
ul4.expose(App.prototype[ul4.symbols.call], ["**values"], {"needsobject": true});
|
|
236
354
|
ul4.expose(App.prototype.insert, ["**values"], {"needsobject": true});
|
|
237
355
|
|
|
356
|
+
|
|
238
357
|
export class View extends Base
|
|
239
358
|
{
|
|
240
|
-
|
|
359
|
+
static classdoc = "An input form for a LivingApps application";
|
|
360
|
+
|
|
361
|
+
[ul4.symbols.repr]()
|
|
241
362
|
{
|
|
242
363
|
return "<View id=" + ul4._repr(this.id) + " name=" + ul4._repr(this.name) + ">";
|
|
243
364
|
}
|
|
244
365
|
};
|
|
245
366
|
|
|
246
|
-
View.prototype._ul4onattrs = ["
|
|
247
|
-
View.prototype._ul4attrs =
|
|
367
|
+
View.prototype._ul4onattrs = ["name", "combined_type", "app", "order", "width", "height", "start", "end", "controls", "layout_controls", "lang"];
|
|
368
|
+
View.prototype._ul4attrs = new Set(["id", "name", "combined_type", "app", "order", "width", "height", "start", "end", "controls", "layout_controls", "lang"]);
|
|
369
|
+
|
|
248
370
|
|
|
249
371
|
export class DataSourceData extends Base
|
|
250
372
|
{
|
|
251
|
-
|
|
373
|
+
static classdoc = "The data resulting from a data source configuration";
|
|
374
|
+
|
|
375
|
+
[ul4.symbols.repr]()
|
|
252
376
|
{
|
|
253
|
-
return "<
|
|
377
|
+
return "<DataSourceData id=" + ul4._repr(this.id) + " identifier=" + ul4._repr(this.identifier) + ">";
|
|
254
378
|
}
|
|
255
379
|
};
|
|
256
380
|
|
|
257
|
-
DataSourceData.prototype._ul4onattrs = ["
|
|
258
|
-
DataSourceData.prototype._ul4attrs =
|
|
381
|
+
DataSourceData.prototype._ul4onattrs = ["identifier", "app", "apps"];
|
|
382
|
+
DataSourceData.prototype._ul4attrs = new Set(["id", "identifier", "app", "apps"]);
|
|
383
|
+
|
|
259
384
|
|
|
260
385
|
export class Record extends Base
|
|
261
386
|
{
|
|
262
|
-
|
|
387
|
+
static classdoc = "A record of a LivingApp application";
|
|
388
|
+
|
|
389
|
+
constructor(id, app)
|
|
263
390
|
{
|
|
264
|
-
super();
|
|
265
|
-
this.id = null;
|
|
391
|
+
super(id);
|
|
266
392
|
this.app = app;
|
|
267
393
|
this.createdat = null;
|
|
268
394
|
this.createdby = null;
|
|
@@ -275,15 +401,47 @@ export class Record extends Base
|
|
|
275
401
|
this.children = new Map();
|
|
276
402
|
this.attachments = null;
|
|
277
403
|
this.errors = [];
|
|
404
|
+
this._sparsefielderrors = null;
|
|
405
|
+
this._sparsefieldlookupdata = null;
|
|
278
406
|
this._is_deleted = false;
|
|
407
|
+
this._is_new = true;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
_make_fields(defaults, values, errors, lookupdata)
|
|
411
|
+
{
|
|
412
|
+
let fields = new Map();
|
|
413
|
+
|
|
414
|
+
for (let control of this.app.controls.values())
|
|
415
|
+
{
|
|
416
|
+
let identifier = control.identifier;
|
|
417
|
+
let value = null;
|
|
418
|
+
if (values !== null)
|
|
419
|
+
{
|
|
420
|
+
if (defaults && !values.has(identifier))
|
|
421
|
+
value = control.default;
|
|
422
|
+
else if (values.has(identifier))
|
|
423
|
+
value = values.get(identifier);
|
|
424
|
+
}
|
|
425
|
+
let field = new control.fieldtype(control, this, value);
|
|
426
|
+
fields.set(identifier, field);
|
|
427
|
+
if (errors !== null && errors.has(identifier))
|
|
428
|
+
field.errors = errors.get(identifier);
|
|
429
|
+
if (lookupdata !== null && lookupdata.has(identifier))
|
|
430
|
+
field.lookupdata = lookupdata.get(identifier);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
this._fields = fields;
|
|
434
|
+
this._sparsevalues = null;
|
|
435
|
+
this._sparsefielderrors = null;
|
|
436
|
+
this._sparselookupdata = null;
|
|
279
437
|
}
|
|
280
438
|
|
|
281
|
-
|
|
439
|
+
[ul4.symbols.repr]()
|
|
282
440
|
{
|
|
283
441
|
let v = ["<Record id=", ul4._repr(this.id)];
|
|
284
442
|
for (let field of this.fields.values())
|
|
285
443
|
{
|
|
286
|
-
if (field.control.priority)
|
|
444
|
+
if (field.control.priority && !field.is_empty())
|
|
287
445
|
{
|
|
288
446
|
v.push(" v_");
|
|
289
447
|
v.push(field.control.identifier);
|
|
@@ -291,21 +449,32 @@ export class Record extends Base
|
|
|
291
449
|
v.push(ul4._repr(field.value)); // FIXME: This might lead to infinite recursions
|
|
292
450
|
}
|
|
293
451
|
}
|
|
294
|
-
v.push("
|
|
452
|
+
v.push(" state=");
|
|
453
|
+
v.push(ul4._repr(this.state));
|
|
454
|
+
v.push(">");
|
|
295
455
|
return v.join("");
|
|
296
456
|
}
|
|
297
457
|
|
|
458
|
+
get state()
|
|
459
|
+
{
|
|
460
|
+
if (this._is_deleted)
|
|
461
|
+
return "deleted";
|
|
462
|
+
else if (this._is_new)
|
|
463
|
+
return "new";
|
|
464
|
+
else if (this.is_dirty())
|
|
465
|
+
return "dirty";
|
|
466
|
+
else
|
|
467
|
+
return "saved";
|
|
468
|
+
}
|
|
469
|
+
|
|
298
470
|
get values()
|
|
299
471
|
{
|
|
300
472
|
if (this._values === null)
|
|
301
473
|
{
|
|
302
|
-
this._values =
|
|
303
|
-
for (let
|
|
474
|
+
this._values = new Map();
|
|
475
|
+
for (let field of this.fields.values())
|
|
304
476
|
{
|
|
305
|
-
|
|
306
|
-
if (typeof(fieldvalue) === "undefined")
|
|
307
|
-
fieldvalue = null;
|
|
308
|
-
this._values.set(identifier, fieldvalue);
|
|
477
|
+
this._values.set(field.control.identifier, field.value);
|
|
309
478
|
}
|
|
310
479
|
}
|
|
311
480
|
return this._values;
|
|
@@ -314,14 +483,7 @@ export class Record extends Base
|
|
|
314
483
|
get fields()
|
|
315
484
|
{
|
|
316
485
|
if (this._fields === null)
|
|
317
|
-
|
|
318
|
-
this._fields = ul4._havemap ? new Map() : {};
|
|
319
|
-
for (let [identifier, value] of this.values.entries())
|
|
320
|
-
{
|
|
321
|
-
let field = new Field(this.app.controls.get(identifier), this, value);
|
|
322
|
-
this._fields.set(identifier, field);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
486
|
+
this._make_fields(false, this._sparsevalues, this._sparsefielderrors, this._sparsefieldlookupdata)
|
|
325
487
|
return this._fields;
|
|
326
488
|
}
|
|
327
489
|
|
|
@@ -351,7 +513,9 @@ export class Record extends Base
|
|
|
351
513
|
|
|
352
514
|
delete()
|
|
353
515
|
{
|
|
354
|
-
|
|
516
|
+
let result = this.app.globals.handler.delete(this);
|
|
517
|
+
this._is_deleted = true;
|
|
518
|
+
return result;
|
|
355
519
|
}
|
|
356
520
|
|
|
357
521
|
save()
|
|
@@ -399,62 +563,898 @@ export class Record extends Base
|
|
|
399
563
|
return true;
|
|
400
564
|
}
|
|
401
565
|
|
|
402
|
-
|
|
566
|
+
ul4onload(decoder)
|
|
567
|
+
{
|
|
568
|
+
super.ul4onload(decoder);
|
|
569
|
+
this._is_new = false;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
_dumpUL4ONAttr(name)
|
|
573
|
+
{
|
|
574
|
+
if (name === "values")
|
|
575
|
+
return this._sparsevalues;
|
|
576
|
+
else
|
|
577
|
+
return this[name];
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
_loadUL4ONAttr(name, value)
|
|
581
|
+
{
|
|
582
|
+
if (name === "values")
|
|
583
|
+
{
|
|
584
|
+
this._sparsevalues = value;
|
|
585
|
+
this._values = null;
|
|
586
|
+
this._fields = null;
|
|
587
|
+
}
|
|
588
|
+
else
|
|
589
|
+
this[name] = value;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
[ul4.symbols.getattr](name)
|
|
593
|
+
{
|
|
594
|
+
if (name.startsWith("c_"))
|
|
595
|
+
return this.children.get(name.substr(2))
|
|
596
|
+
else if (name.startsWith("f_"))
|
|
597
|
+
return this.fields.get(name.substr(2))
|
|
598
|
+
else if (name.startsWith("v_"))
|
|
599
|
+
return this.values.get(name.substr(2))
|
|
600
|
+
else
|
|
601
|
+
return this[name];
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
[ul4.symbols.setattr](name, value)
|
|
605
|
+
{
|
|
606
|
+
if (name.startsWith("c_"))
|
|
607
|
+
this.children[name.substr(2)] = value;
|
|
608
|
+
else if (name.startsWith("v_"))
|
|
609
|
+
this.fields.get(name.substr(2)).value = value;
|
|
610
|
+
else
|
|
611
|
+
throw new ul4.AttributeError(this, name);
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
Record.prototype._ul4onattrs = ["app", "createdat", "createdby", "updatedat", "updatedby", "updatecount", "_sparsevalues", "attachments", "children", "errors", "_sparsefielderrors", "_sparsefieldlookupdata"];
|
|
616
|
+
Record.prototype._ul4attrs = new Set(["id", "app", "createdat", "createdby", "updatedat", "updatedby", "updatecount", "values", "attachments", "children", "errors"]);
|
|
617
|
+
ul4.expose(Record.prototype.is_dirty, []);
|
|
618
|
+
ul4.expose(Record.prototype.has_errors, []);
|
|
619
|
+
ul4.expose(Record.prototype.delete, []);
|
|
620
|
+
ul4.expose(Record.prototype.save, []);
|
|
621
|
+
ul4.expose(Record.prototype.update, ["**values"], {"needsobject": true});
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
export class Field extends Base
|
|
625
|
+
{
|
|
626
|
+
static classdoc = "Holds the value of a field of a record (and related information)";
|
|
627
|
+
|
|
628
|
+
constructor(control, record, value)
|
|
629
|
+
{
|
|
630
|
+
super(null);
|
|
631
|
+
this.control = control;
|
|
632
|
+
this.record = record;
|
|
633
|
+
this._label = null;
|
|
634
|
+
this._lookupdate = null;
|
|
635
|
+
this.errors = [];
|
|
636
|
+
this._value = null;
|
|
637
|
+
this.value = value;
|
|
638
|
+
this._dirty = false;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
get value()
|
|
642
|
+
{
|
|
643
|
+
return this._value;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
set value(value)
|
|
647
|
+
{
|
|
648
|
+
let oldvalue = this._value;
|
|
649
|
+
|
|
650
|
+
let change = {value: value, errors: []};
|
|
651
|
+
this._validate(change);
|
|
652
|
+
|
|
653
|
+
if (ul4._ne(oldvalue, change.value))
|
|
654
|
+
{
|
|
655
|
+
this.record.values.set(this.control.identifier, change.value);
|
|
656
|
+
this._value = change.value;
|
|
657
|
+
this._dirty = true;
|
|
658
|
+
}
|
|
659
|
+
this.errors = change.errors;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
_validate(change)
|
|
663
|
+
{
|
|
664
|
+
// Do nothing, i.e. accept the value unchanged and without errors
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
get label()
|
|
668
|
+
{
|
|
669
|
+
if (this._label !== null)
|
|
670
|
+
return this._label;
|
|
671
|
+
return this.control.label;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
set label(value)
|
|
675
|
+
{
|
|
676
|
+
this._label = value;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
get globals()
|
|
680
|
+
{
|
|
681
|
+
return this.control.globals;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
is_empty()
|
|
685
|
+
{
|
|
686
|
+
return this._value === null || (ul4._islist(this._value) && this._value.length === 0);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
is_dirty()
|
|
690
|
+
{
|
|
691
|
+
return this._dirty;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
has_errors()
|
|
695
|
+
{
|
|
696
|
+
return this.errors.length !== 0;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
search(searchvalue)
|
|
700
|
+
{
|
|
701
|
+
return this.control.search(this.value, searchvalue);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
msg_field_required(value)
|
|
705
|
+
{
|
|
706
|
+
switch (this.globals.lang)
|
|
707
|
+
{
|
|
708
|
+
case "de":
|
|
709
|
+
return `"${this.label}" wird benötigt!`;
|
|
710
|
+
default:
|
|
711
|
+
return `"${this.label}" is required!`;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
msg_field_wrong_type(value)
|
|
716
|
+
{
|
|
717
|
+
return `"${this.label}" doesn't support the type ${ul4._type(value).name}!`;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
msg_bool_truerequired(value)
|
|
721
|
+
{
|
|
722
|
+
return `"${this.label}" only accepts "Yes"!`;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
msg_string_tooshort(value)
|
|
726
|
+
{
|
|
727
|
+
return `"${this.label}" is too short. Tou must use at least ${this.control.minlength} characters!`;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
msg_string_toolong(value)
|
|
731
|
+
{
|
|
732
|
+
return `"${this.label}" is too long. You may use at most ${this.control.maxlength} characters!`;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
msg_email_format(value)
|
|
736
|
+
{
|
|
737
|
+
return `"${this.label}" must be a valid email address!`;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
msg_url_format(value)
|
|
741
|
+
{
|
|
742
|
+
return `"${this.label}" must be a valid URL!`;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
msg_tel_format(value)
|
|
746
|
+
{
|
|
747
|
+
return `"${this.label}" must be a valid phone number!`;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
msg_date_format(value)
|
|
751
|
+
{
|
|
752
|
+
return `"${this.label}" doesn't support this date format!`;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
msg_lookup_wrongitem(value)
|
|
756
|
+
{
|
|
757
|
+
return `The option ${ul4._repr(value)} for "${this.label}" doesn't belong to this lookup!`;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
msg_lookup_unknownkey(value)
|
|
761
|
+
{
|
|
762
|
+
return `The option ${ul4._repr(value)} for "${this.label}" is unknown!`;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
msg_applookup_wrongrecord(value)
|
|
766
|
+
{
|
|
767
|
+
return `The record ${ul4._repr(value)} for "${this.label}" doesn't belong to the correct app!`;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
msg_applookup_unknownkey(value)
|
|
771
|
+
{
|
|
772
|
+
return `The record ${ul4._repr(value)} for "${this.label}" can't be found!`;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
[ul4.symbols.repr]()
|
|
776
|
+
{
|
|
777
|
+
let s = "<Field identifier=";
|
|
778
|
+
s += ul4._repr(this.control.identifier)
|
|
779
|
+
if (this._dirty)
|
|
780
|
+
s += " is_dirty()=True";
|
|
781
|
+
if (this.errors.length > 0)
|
|
782
|
+
s += " has_errors()=True";
|
|
783
|
+
s += ">"
|
|
784
|
+
return s;
|
|
785
|
+
}
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
Field.prototype._ul4onattrs = ["control", "record", "label", "value", "errors", "enabled", "writable", "visible"];
|
|
789
|
+
Field.prototype._ul4attrs = new Set(["control", "record", "label", "value", "errors", "enabled", "writable", "visible"]);
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
export class BoolField extends Field
|
|
793
|
+
{
|
|
794
|
+
static classdoc = "Holds the value of a bool field of a record (and related information)";
|
|
795
|
+
|
|
796
|
+
_validate(change)
|
|
797
|
+
{
|
|
798
|
+
if (change.value === null)
|
|
799
|
+
{
|
|
800
|
+
if (this.control.required)
|
|
801
|
+
change.errors.push(this.msg_field_required(change.value));
|
|
802
|
+
}
|
|
803
|
+
else if (typeof(change.value) === "boolean")
|
|
804
|
+
{
|
|
805
|
+
if (this.control.required && !change.value)
|
|
806
|
+
change.errors.push(this.msg_bool_truerequired(change.value));
|
|
807
|
+
}
|
|
808
|
+
else
|
|
809
|
+
{
|
|
810
|
+
change.errors.push(this.msg_field_wrong_type(change.value));
|
|
811
|
+
change.value = null;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
export class IntField extends Field
|
|
818
|
+
{
|
|
819
|
+
static classdoc = "Holds the value of an int field of a record (and related information)";
|
|
820
|
+
|
|
821
|
+
_validate(change)
|
|
822
|
+
{
|
|
823
|
+
if (change.value === null)
|
|
824
|
+
{
|
|
825
|
+
if (this.control.required)
|
|
826
|
+
change.errors.push(this.msg_field_required(change.value));
|
|
827
|
+
}
|
|
828
|
+
else if (typeof(change.value) !== "number" || Math.round(change.value) !== change.value)
|
|
829
|
+
{
|
|
830
|
+
change.errors.push(this.msg_field_wrong_type(change.value));
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
export class NumberField extends Field
|
|
837
|
+
{
|
|
838
|
+
static classdoc = "Holds the value of a number field of a record (and related information)";
|
|
839
|
+
|
|
840
|
+
_validate(change)
|
|
841
|
+
{
|
|
842
|
+
if (change.value === null || change.value === "")
|
|
843
|
+
{
|
|
844
|
+
if (this.control.required)
|
|
845
|
+
change.errors.push(this.msg_field_required(change.value));
|
|
846
|
+
change.value = null;
|
|
847
|
+
}
|
|
848
|
+
else if (typeof(change.value) !== "number")
|
|
849
|
+
{
|
|
850
|
+
change.errors.push(this.msg_field_wrong_type(change.value));
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
export class StringField extends Field
|
|
857
|
+
{
|
|
858
|
+
static classdoc = "Holds the value of a string field of a record (and related information)";
|
|
859
|
+
|
|
860
|
+
_validate(change)
|
|
861
|
+
{
|
|
862
|
+
if (change.value === null || change.value === "")
|
|
863
|
+
{
|
|
864
|
+
if (this.control.required)
|
|
865
|
+
change.errors.push(this.msg_field_required(change.value));
|
|
866
|
+
change.value = null;
|
|
867
|
+
}
|
|
868
|
+
else if (typeof(change.value) === "string")
|
|
869
|
+
{
|
|
870
|
+
let minlength = this.control.minlength;
|
|
871
|
+
let maxlength = this.control.maxlength;
|
|
872
|
+
if (minlength !== null && change.value.length < minlength)
|
|
873
|
+
change.errors.push(this.msg_string_tooshort(change.value))
|
|
874
|
+
if (maxlength !== null && change.value.length > maxlength)
|
|
875
|
+
change.errors.push(this.msg_string_toolong(change.value))
|
|
876
|
+
}
|
|
877
|
+
else
|
|
878
|
+
{
|
|
879
|
+
change.errors.push(this.msg_field_wrong_type(change.value));
|
|
880
|
+
change.value = null;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
export class EmailField extends StringField
|
|
887
|
+
{
|
|
888
|
+
static classdoc = "Holds the value of a string/email field of a record (and related information)";
|
|
889
|
+
|
|
890
|
+
_validate(change)
|
|
891
|
+
{
|
|
892
|
+
if (typeof(change.value) === "string" && change.value.length > 0)
|
|
893
|
+
{
|
|
894
|
+
const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i;
|
|
895
|
+
if (!re.test(change.value))
|
|
896
|
+
change.errors.push(this.msg_email_format(change.value));
|
|
897
|
+
}
|
|
898
|
+
super._validate(change);
|
|
899
|
+
}
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
export class URLField extends StringField
|
|
904
|
+
{
|
|
905
|
+
static classdoc = "Holds the value of a string/url field of a record (and related information)";
|
|
906
|
+
|
|
907
|
+
_validate(change)
|
|
908
|
+
{
|
|
909
|
+
if (typeof(change.value) === "string" && change.value.length > 0)
|
|
910
|
+
{
|
|
911
|
+
let url = null;
|
|
912
|
+
try
|
|
913
|
+
{
|
|
914
|
+
url = new URL(change.value);
|
|
915
|
+
}
|
|
916
|
+
catch (exc)
|
|
917
|
+
{
|
|
918
|
+
change.errors.push(this.msg_url_format(change.value));
|
|
919
|
+
}
|
|
920
|
+
if (url !== null && url.protocol !== "http:" && url.protocol !== "https:")
|
|
921
|
+
{
|
|
922
|
+
change.errors.push(this.msg_url_format(change.value));
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
super._validate(change);
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
export class TelField extends StringField
|
|
931
|
+
{
|
|
932
|
+
static classdoc = "Holds the value of a string/tel field of a record (and related information)";
|
|
933
|
+
|
|
934
|
+
_validate(change)
|
|
935
|
+
{
|
|
936
|
+
if (typeof(change.value) === "string" && change.value.length > 0)
|
|
937
|
+
{
|
|
938
|
+
const re = /^\\+?[0-9 /()-]+$/;
|
|
939
|
+
if (!re.test(change.value))
|
|
940
|
+
change.errors.push(this.msg_tel_format(change.value));
|
|
941
|
+
}
|
|
942
|
+
super._validate(change);
|
|
943
|
+
}
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
export class TextAreaField extends StringField
|
|
948
|
+
{
|
|
949
|
+
static classdoc = "Holds the value of a string/textarea field of a record (and related information)";
|
|
950
|
+
};
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
export class HTMLField extends StringField
|
|
954
|
+
{
|
|
955
|
+
static classdoc = "Holds the value of a string/html field of a record (and related information)";
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
export class GeoField extends Field
|
|
960
|
+
{
|
|
961
|
+
static classdoc = "Holds the value of a geo field of a record (and related information)";
|
|
962
|
+
|
|
963
|
+
_validate(change)
|
|
964
|
+
{
|
|
965
|
+
if (change.value === null || change.value === "")
|
|
966
|
+
{
|
|
967
|
+
if (this.control.required)
|
|
968
|
+
change.errors.push(this.msg_field_required(change.value));
|
|
969
|
+
change.value = null;
|
|
970
|
+
}
|
|
971
|
+
else if (!(change.value instanceof Geo))
|
|
972
|
+
{
|
|
973
|
+
change.errors.push(this.msg_field_wrong_type(change.value));
|
|
974
|
+
change.value = null;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
};
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
export class FileField extends Field
|
|
981
|
+
{
|
|
982
|
+
static classdoc = "Holds the value of a file field of a record (and related information)";
|
|
983
|
+
|
|
984
|
+
_validate(change)
|
|
985
|
+
{
|
|
986
|
+
if (change.value === null || change.value === "")
|
|
987
|
+
{
|
|
988
|
+
if (this.control.required)
|
|
989
|
+
change.errors.push(this.msg_field_required(change.value));
|
|
990
|
+
change.value = null;
|
|
991
|
+
}
|
|
992
|
+
else if (!(change.value instanceof File))
|
|
993
|
+
{
|
|
994
|
+
change.errors.push(this.msg_field_wrong_type(change.value));
|
|
995
|
+
change.value = null;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
export class FileSignatureField extends FileField
|
|
1002
|
+
{
|
|
1003
|
+
static classdoc = "Holds the value of a file/signature field of a record (and related information)";
|
|
1004
|
+
|
|
1005
|
+
_validate(change)
|
|
1006
|
+
{
|
|
1007
|
+
// FIXME: Implement handling of data URLs.
|
|
1008
|
+
super._validate(change);
|
|
1009
|
+
}
|
|
1010
|
+
};
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
export class DateFieldBase extends Field
|
|
1014
|
+
{
|
|
1015
|
+
static classdoc = "Holds the value of a date field of a record (and related information)";
|
|
1016
|
+
|
|
1017
|
+
_validate(change)
|
|
1018
|
+
{
|
|
1019
|
+
if (change.value === null || change.value === "")
|
|
1020
|
+
{
|
|
1021
|
+
if (this.control.required)
|
|
1022
|
+
change.errors.push(this.msg_field_required(change.value));
|
|
1023
|
+
change.value = null;
|
|
1024
|
+
}
|
|
1025
|
+
else if (change.value instanceof Date)
|
|
1026
|
+
{
|
|
1027
|
+
change.value = this._convert(change.value);
|
|
1028
|
+
}
|
|
1029
|
+
else if (change.value instanceof ul4.Date_)
|
|
1030
|
+
{
|
|
1031
|
+
change.value = this._convert(change.value._date);
|
|
1032
|
+
}
|
|
1033
|
+
else if (typeof(change.value) === "string")
|
|
1034
|
+
{
|
|
1035
|
+
let value = null;
|
|
1036
|
+
if (change.value.length === 10)
|
|
1037
|
+
value = new Date(change.value + "T00:00:00");
|
|
1038
|
+
else if (change.value.length === 16)
|
|
1039
|
+
value = new Date(change.value + ":00");
|
|
1040
|
+
else if (change.value.length === 19)
|
|
1041
|
+
value = new Date(change.value);
|
|
1042
|
+
|
|
1043
|
+
if (value === null || Number.isNaN(value.getYear()))
|
|
1044
|
+
{
|
|
1045
|
+
change.errors.push(this.msg_date_format(change.value));
|
|
1046
|
+
// Keep original invalid string
|
|
1047
|
+
}
|
|
1048
|
+
else
|
|
1049
|
+
{
|
|
1050
|
+
change.value = this._convert(value);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
else
|
|
1054
|
+
{
|
|
1055
|
+
change.errors.push(this.msg_field_wrong_type(change.value));
|
|
1056
|
+
change.value = null;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
export class DateField extends DateFieldBase
|
|
1063
|
+
{
|
|
1064
|
+
static classdoc = "Holds the value of a date/date field of a record (and related information)";
|
|
1065
|
+
|
|
1066
|
+
_convert(date)
|
|
1067
|
+
{
|
|
1068
|
+
return new ul4.Date_(date.getFullYear(), date.getMonth()+1, date.getDate());
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
export class DatetimeMinuteField extends DateFieldBase
|
|
1074
|
+
{
|
|
1075
|
+
static classdoc = "Holds the value of a date/datetimeminute field of a record (and related information)";
|
|
1076
|
+
|
|
1077
|
+
_convert(date)
|
|
1078
|
+
{
|
|
1079
|
+
// Get rid of seconds and milliseconds
|
|
1080
|
+
date.setSeconds(0);
|
|
1081
|
+
date.setMilliseconds(0);
|
|
1082
|
+
return date;
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
export class DatetimeSecondField extends DateFieldBase
|
|
1088
|
+
{
|
|
1089
|
+
static classdoc = "Holds the value of a date/datetimesecond field of a record (and related information)";
|
|
1090
|
+
|
|
1091
|
+
_convert(date)
|
|
1092
|
+
{
|
|
1093
|
+
// Get rid of milliseconds
|
|
1094
|
+
date.setMilliseconds(0);
|
|
1095
|
+
return date;
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
export class LookupFieldBase extends Field
|
|
1101
|
+
{
|
|
1102
|
+
static classdoc = "Base type of LookupField and MultipleLookupField";
|
|
1103
|
+
|
|
1104
|
+
get lookupdata()
|
|
1105
|
+
{
|
|
1106
|
+
if (this._lookupdate !== null)
|
|
1107
|
+
return this._lookupdate;
|
|
1108
|
+
else
|
|
1109
|
+
return this.control.lookupdata;
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
set lookupdata(value)
|
|
1113
|
+
{
|
|
1114
|
+
this._lookupdate = value;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
_find_lookupitem(change)
|
|
1118
|
+
{
|
|
1119
|
+
let v = change.value;
|
|
1120
|
+
if (typeof(v) === "string")
|
|
1121
|
+
{
|
|
1122
|
+
// If `lookupdata`} is `null`, this is probably an interface,
|
|
1123
|
+
// so we can't validate anything (note that interfaces will however go
|
|
1124
|
+
// away in the future)
|
|
1125
|
+
if (this.lookupdata === null)
|
|
1126
|
+
return;
|
|
1127
|
+
let lookupitem = this.lookupdata.get(v);
|
|
1128
|
+
if (lookupitem === undefined)
|
|
1129
|
+
{
|
|
1130
|
+
// If the lookup control is auto expandable,
|
|
1131
|
+
// the user may have given us a label
|
|
1132
|
+
if (this.control.autoexpandable)
|
|
1133
|
+
{
|
|
1134
|
+
// Search for the LookupItem with that label
|
|
1135
|
+
for (let search_lookupitem of this.lookupdata.values())
|
|
1136
|
+
{
|
|
1137
|
+
if (v === search_lookupitem.label)
|
|
1138
|
+
{
|
|
1139
|
+
change.value = search_lookupitem;
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
// If we couldn't find the label, keep the label as it is.
|
|
1144
|
+
}
|
|
1145
|
+
else
|
|
1146
|
+
{
|
|
1147
|
+
change.errors.push(this.msg_lookup_unknownkey(v))
|
|
1148
|
+
change.value = null;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
else
|
|
1152
|
+
{
|
|
1153
|
+
change.value = lookupitem;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
else if (v instanceof LookupItem)
|
|
1157
|
+
{
|
|
1158
|
+
let value = this.control.lookupdata.get(v.key);
|
|
1159
|
+
if (value !== v)
|
|
1160
|
+
{
|
|
1161
|
+
change.errors.push(this.msg_lookup_wrongitem(v));
|
|
1162
|
+
change.value = null;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
else
|
|
1166
|
+
{
|
|
1167
|
+
change.errors.push(this.msg_field_wrong_type(v));
|
|
1168
|
+
change.value = null;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
export class LookupField extends LookupFieldBase
|
|
1175
|
+
{
|
|
1176
|
+
static classdoc = "Holds the value of a lookup field of a record (and related information)";
|
|
1177
|
+
|
|
1178
|
+
_validate(change)
|
|
1179
|
+
{
|
|
1180
|
+
let v = change.value;
|
|
1181
|
+
if (v === null || v === "" || this.control.nonekey === v)
|
|
1182
|
+
{
|
|
1183
|
+
if (this.control.required)
|
|
1184
|
+
change.errors.push(this.msg_field_required(v));
|
|
1185
|
+
change.value = null;
|
|
1186
|
+
}
|
|
1187
|
+
else
|
|
1188
|
+
{
|
|
1189
|
+
this._find_lookupitem(change);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
};
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
export class MultipleLookupField extends LookupFieldBase
|
|
1196
|
+
{
|
|
1197
|
+
static classdoc = "Holds the value of a multiple lookup field of a record (and related information)";
|
|
1198
|
+
|
|
1199
|
+
_validate(change)
|
|
1200
|
+
{
|
|
1201
|
+
let v = change.value;
|
|
1202
|
+
let islist = (Object.prototype.toString.call(v) === "[object Array]");
|
|
1203
|
+
|
|
1204
|
+
if (v === null || v === "" || this.control.nonekey === v || (islist && v.length === 0))
|
|
1205
|
+
{
|
|
1206
|
+
if (this.control.required)
|
|
1207
|
+
change.errors.push(this.msg_field_required(v));
|
|
1208
|
+
change.value = [];
|
|
1209
|
+
}
|
|
1210
|
+
else if (islist)
|
|
1211
|
+
{
|
|
1212
|
+
let newvalue = [];
|
|
1213
|
+
for (let item of v)
|
|
1214
|
+
{
|
|
1215
|
+
let singlechange = {value: item, errors: []};
|
|
1216
|
+
this._find_lookupitem(singlechange);
|
|
1217
|
+
if (singlechange.errors.length > 0)
|
|
1218
|
+
change.errors = [...change.errors, ...singlechange.errors];
|
|
1219
|
+
else
|
|
1220
|
+
newvalue.push(singlechange.value);
|
|
1221
|
+
}
|
|
1222
|
+
change.value = newvalue;
|
|
1223
|
+
}
|
|
1224
|
+
else
|
|
1225
|
+
{
|
|
1226
|
+
this._find_lookupitem(change);
|
|
1227
|
+
if (change.errors.length > 0)
|
|
1228
|
+
change.value = [];
|
|
1229
|
+
else
|
|
1230
|
+
change.value = [change.value];
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
export class AppLookupFieldBase extends Field
|
|
1237
|
+
{
|
|
1238
|
+
static classdoc = "Base type of AppLookupField and MultipleAppLookupField";
|
|
1239
|
+
|
|
1240
|
+
get lookupdata()
|
|
1241
|
+
{
|
|
1242
|
+
if (this._lookupdata !== null)
|
|
1243
|
+
return this._lookupdata;
|
|
1244
|
+
else
|
|
1245
|
+
{
|
|
1246
|
+
if (this.control.lookup_app.records !== null)
|
|
1247
|
+
return this.control.lookup_app.records;
|
|
1248
|
+
}
|
|
1249
|
+
return new Map();
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
set lookupdata(value)
|
|
1253
|
+
{
|
|
1254
|
+
this._lookupdata = value;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
_find_record(change)
|
|
1258
|
+
{
|
|
1259
|
+
let v = change.value;
|
|
1260
|
+
if (typeof(v) === "string")
|
|
1261
|
+
{
|
|
1262
|
+
let record = this.lookupdata.get(v);
|
|
1263
|
+
if (record === undefined)
|
|
1264
|
+
{
|
|
1265
|
+
change.errors.push(this.msg_applookup_unknownkey(v))
|
|
1266
|
+
change.value = null;
|
|
1267
|
+
}
|
|
1268
|
+
else
|
|
1269
|
+
{
|
|
1270
|
+
change.value = record;
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
else if (v instanceof Record)
|
|
1274
|
+
{
|
|
1275
|
+
if (v.app !== this.control.lookup_app)
|
|
1276
|
+
{
|
|
1277
|
+
change.errors.push(this.msg_applookup_wrongrecord(v));
|
|
1278
|
+
change.value = null;
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
else
|
|
1282
|
+
{
|
|
1283
|
+
change.errors.push(this.msg_field_wrong_type(v));
|
|
1284
|
+
change.value = null;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
};
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
export class AppLookupField extends AppLookupFieldBase
|
|
1291
|
+
{
|
|
1292
|
+
static classdoc = "Holds the value of a applookup field of a record (and related information)";
|
|
1293
|
+
|
|
1294
|
+
_validate(change)
|
|
1295
|
+
{
|
|
1296
|
+
this._find_record(change);
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
export class MultipleAppLookupField extends AppLookupFieldBase
|
|
1302
|
+
{
|
|
1303
|
+
static classdoc = "Holds the value of a multiple applookup field of a record (and related information)";
|
|
1304
|
+
|
|
1305
|
+
_validate(change)
|
|
1306
|
+
{
|
|
1307
|
+
let v = change.value;
|
|
1308
|
+
let islist = (Object.prototype.toString.call(v) === "[object Array]");
|
|
1309
|
+
|
|
1310
|
+
if (v === null || v === "" || this.control.nonekey === v || (islist && v.length === 0))
|
|
1311
|
+
{
|
|
1312
|
+
if (this.control.required)
|
|
1313
|
+
change.errors.push(this.msg_field_required(v));
|
|
1314
|
+
change.value = [];
|
|
1315
|
+
}
|
|
1316
|
+
else if (islist)
|
|
1317
|
+
{
|
|
1318
|
+
let newvalue = [];
|
|
1319
|
+
for (let item of v)
|
|
1320
|
+
{
|
|
1321
|
+
let singlechange = {value: item, errors: []};
|
|
1322
|
+
this._find_record(singlechange);
|
|
1323
|
+
if (singlechange.errors.length > 0)
|
|
1324
|
+
change.errors = [...change.errors, ...singlechange.errors];
|
|
1325
|
+
else
|
|
1326
|
+
newvalue.push(singlechange.value);
|
|
1327
|
+
}
|
|
1328
|
+
change.value = newvalue;
|
|
1329
|
+
}
|
|
1330
|
+
else
|
|
1331
|
+
{
|
|
1332
|
+
this._find_record(change);
|
|
1333
|
+
if (change.errors.length > 0)
|
|
1334
|
+
change.value = [];
|
|
1335
|
+
else
|
|
1336
|
+
change.value = [change.value];
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1340
|
+
|
|
1341
|
+
|
|
1342
|
+
export class Control extends Base
|
|
1343
|
+
{
|
|
1344
|
+
[ul4.symbols.repr]()
|
|
1345
|
+
{
|
|
1346
|
+
return "<" + this.constructor.name + " id=" + ul4._repr(this.id) + " identifier=" + ul4._repr(this.identifier) + ">";
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
get globals()
|
|
1350
|
+
{
|
|
1351
|
+
return this.app.globals;
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
get fulltype()
|
|
1355
|
+
{
|
|
1356
|
+
return this.subtype ? this.type + "/" + this.subtype : this.type;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
get label()
|
|
1360
|
+
{
|
|
1361
|
+
let view_control = this._view_control();
|
|
1362
|
+
if (view_control === null)
|
|
1363
|
+
return this._label;
|
|
1364
|
+
let label = view_control.label;
|
|
1365
|
+
if (label === null)
|
|
1366
|
+
return this._label;
|
|
1367
|
+
return label;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
set label(value)
|
|
1371
|
+
{
|
|
1372
|
+
this._label = value;
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
get default()
|
|
1376
|
+
{
|
|
1377
|
+
return null;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
get top()
|
|
1381
|
+
{
|
|
1382
|
+
let view_control = this._view_control();
|
|
1383
|
+
return view_control !== null ? view_control.top : null;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
get left()
|
|
1387
|
+
{
|
|
1388
|
+
let view_control = this._view_control();
|
|
1389
|
+
return view_control !== null ? view_control.left : null;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
get width()
|
|
1393
|
+
{
|
|
1394
|
+
let view_control = this._view_control();
|
|
1395
|
+
return view_control !== null ? view_control.width : null;
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
get height()
|
|
1399
|
+
{
|
|
1400
|
+
let view_control = this._view_control();
|
|
1401
|
+
return view_control !== null ? view_control.height : null;
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
get liveupdate()
|
|
1405
|
+
{
|
|
1406
|
+
let view_control = this._view_control();
|
|
1407
|
+
return view_control !== null ? view_control.liveupdate : false;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
get tabindex()
|
|
1411
|
+
{
|
|
1412
|
+
let view_control = this._view_control();
|
|
1413
|
+
return view_control !== null ? view_control.tabindex : null;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
get required()
|
|
403
1417
|
{
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
else
|
|
407
|
-
return this[name];
|
|
1418
|
+
let view_control = this._view_control();
|
|
1419
|
+
return view_control !== null ? view_control.required : false;
|
|
408
1420
|
}
|
|
409
1421
|
|
|
410
|
-
|
|
1422
|
+
get mode()
|
|
411
1423
|
{
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
this._sparsevalues = value;
|
|
415
|
-
this._values = null;
|
|
416
|
-
this._fields = null;
|
|
417
|
-
}
|
|
418
|
-
else
|
|
419
|
-
this[name] = value;
|
|
1424
|
+
let view_control = this._view_control();
|
|
1425
|
+
return view_control !== null ? view_control.mode : "edit";
|
|
420
1426
|
}
|
|
421
1427
|
|
|
422
|
-
|
|
1428
|
+
get labelpos()
|
|
423
1429
|
{
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
else if (name.startsWith("f_"))
|
|
427
|
-
return this.fields.get(name.substr(2))
|
|
428
|
-
else if (name.startsWith("v_"))
|
|
429
|
-
return this.values.get(name.substr(2))
|
|
430
|
-
else
|
|
431
|
-
return this[name];
|
|
1430
|
+
let view_control = this._view_control();
|
|
1431
|
+
return view_control !== null ? view_control.labelpos : "left";
|
|
432
1432
|
}
|
|
433
1433
|
|
|
434
|
-
|
|
1434
|
+
get labelwidth()
|
|
435
1435
|
{
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
else if (name.startsWith("v_"))
|
|
439
|
-
this.fields.get(name.substr(2)).value = value;
|
|
440
|
-
else
|
|
441
|
-
throw new ul4.AttributeError(this, name);
|
|
1436
|
+
let view_control = this._view_control();
|
|
1437
|
+
return view_control !== null ? view_control.labelwidth : null;
|
|
442
1438
|
}
|
|
443
|
-
};
|
|
444
1439
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
ul4.expose(Record.prototype.save, []);
|
|
451
|
-
ul4.expose(Record.prototype.update, ["**values"], {"needsobject": true});
|
|
1440
|
+
get autoalign()
|
|
1441
|
+
{
|
|
1442
|
+
let view_control = this._view_control();
|
|
1443
|
+
return view_control !== null ? view_control.autoalign : true;
|
|
1444
|
+
}
|
|
452
1445
|
|
|
453
|
-
|
|
454
|
-
{
|
|
455
|
-
__repr__()
|
|
1446
|
+
get in_active_view()
|
|
456
1447
|
{
|
|
457
|
-
|
|
1448
|
+
let view_control = this._view_control();
|
|
1449
|
+
return view_control !== null;
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
_view_control()
|
|
1453
|
+
{
|
|
1454
|
+
if (this.app._active_view === null)
|
|
1455
|
+
return null;
|
|
1456
|
+
let view_control = this.app._active_view.controls.get(this.identifier);
|
|
1457
|
+
return view_control ?? null;
|
|
458
1458
|
}
|
|
459
1459
|
|
|
460
1460
|
_logsearch(value, search)
|
|
@@ -474,11 +1474,14 @@ export class Control extends Base
|
|
|
474
1474
|
|
|
475
1475
|
Control.prototype.type = null;
|
|
476
1476
|
Control.prototype.subtype = null;
|
|
477
|
-
Control.prototype._ul4onattrs = ["
|
|
478
|
-
Control.prototype._ul4attrs =
|
|
1477
|
+
Control.prototype._ul4onattrs = ["identifier", "fieldname", "app", "_label", "priority", "order", "ininsertprocedure", "inupdateprocedure"];
|
|
1478
|
+
Control.prototype._ul4attrs = new Set(["id", "identifier", "fieldname", "app", "priority", "order", "ininsertprocedure", "inupdateprocedure", "fulltype", "label", "top", "left", "width", "height", "liveupdate", "tabindex", "required", "mode", "labelpos", "autoalign", "in_active_view"]);
|
|
1479
|
+
|
|
479
1480
|
|
|
480
1481
|
export class BoolControl extends Control
|
|
481
1482
|
{
|
|
1483
|
+
static classdoc = "A LivingApps boolean field (type 'bool')";
|
|
1484
|
+
|
|
482
1485
|
// ``search`` must by ``null``, ``false`` or ``true``
|
|
483
1486
|
search(value, search)
|
|
484
1487
|
{
|
|
@@ -491,9 +1494,13 @@ export class BoolControl extends Control
|
|
|
491
1494
|
};
|
|
492
1495
|
|
|
493
1496
|
BoolControl.prototype.type = "bool";
|
|
1497
|
+
BoolControl.prototype.fieldtype = BoolField;
|
|
1498
|
+
|
|
494
1499
|
|
|
495
1500
|
export class IntControl extends Control
|
|
496
1501
|
{
|
|
1502
|
+
static classdoc = "A LivingApps integer field (type 'int')";
|
|
1503
|
+
|
|
497
1504
|
// ``search.value`` must by ``null`` or an integer
|
|
498
1505
|
search(value, search)
|
|
499
1506
|
{
|
|
@@ -506,9 +1513,29 @@ export class IntControl extends Control
|
|
|
506
1513
|
};
|
|
507
1514
|
|
|
508
1515
|
IntControl.prototype.type = "int";
|
|
1516
|
+
IntControl.prototype.fieldtype = IntField;
|
|
1517
|
+
|
|
509
1518
|
|
|
510
|
-
|
|
1519
|
+
class PlaceholderControl extends Control
|
|
511
1520
|
{
|
|
1521
|
+
static classdoc = "A LivingApps multiplelookup field (type 'multiplelookup/select')";
|
|
1522
|
+
|
|
1523
|
+
get placeholder()
|
|
1524
|
+
{
|
|
1525
|
+
let view_control = this._view_control();
|
|
1526
|
+
if (view_control === null)
|
|
1527
|
+
return null;
|
|
1528
|
+
return view_control.placeholder;
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
|
|
1532
|
+
PlaceholderControl.prototype._ul4attrs = new Set([...Control.prototype._ul4attrs, "placeholder"]);
|
|
1533
|
+
|
|
1534
|
+
|
|
1535
|
+
export class NumberControl extends PlaceholderControl
|
|
1536
|
+
{
|
|
1537
|
+
static classdoc = "A LivingApps number field (type 'number')";
|
|
1538
|
+
|
|
512
1539
|
// ``search.value`` must by ``null`` or an integer
|
|
513
1540
|
search(value, search)
|
|
514
1541
|
{
|
|
@@ -527,9 +1554,103 @@ export class NumberControl extends Control
|
|
|
527
1554
|
};
|
|
528
1555
|
|
|
529
1556
|
NumberControl.prototype.type = "number";
|
|
1557
|
+
NumberControl.prototype.fieldtype = NumberField;
|
|
1558
|
+
|
|
530
1559
|
|
|
531
|
-
export class StringControl extends
|
|
1560
|
+
export class StringControl extends PlaceholderControl
|
|
532
1561
|
{
|
|
1562
|
+
_user_placeholder(user, placeholder)
|
|
1563
|
+
{
|
|
1564
|
+
if (placeholder === null)
|
|
1565
|
+
return null;
|
|
1566
|
+
switch (placeholder)
|
|
1567
|
+
{
|
|
1568
|
+
case "{gender}":
|
|
1569
|
+
return user !== null ? user.gender : null;
|
|
1570
|
+
case "{title}":
|
|
1571
|
+
return user !== null ? user.title : null;
|
|
1572
|
+
case "{firstname}":
|
|
1573
|
+
return user !== null ? user.firstname : null;
|
|
1574
|
+
case "{surname}":
|
|
1575
|
+
return user !== null ? user.surname : null;
|
|
1576
|
+
case "{account}":
|
|
1577
|
+
return user !== null ? user.email : null;
|
|
1578
|
+
case "{streetname}":
|
|
1579
|
+
return user !== null ? user.streetname : null;
|
|
1580
|
+
case "{streetnumber}":
|
|
1581
|
+
return user !== null ? user.streetnumber : null;
|
|
1582
|
+
case "{street}":
|
|
1583
|
+
if (user === null)
|
|
1584
|
+
return null;
|
|
1585
|
+
else if (user.street === null)
|
|
1586
|
+
return user.streetnumber;
|
|
1587
|
+
else if (user.streetnumber === null)
|
|
1588
|
+
return user.street;
|
|
1589
|
+
else
|
|
1590
|
+
return user.street + " " + user.streetnumber;
|
|
1591
|
+
case "{zip}":
|
|
1592
|
+
return user !== null ? user.zip : null;
|
|
1593
|
+
case "{phone}":
|
|
1594
|
+
return user !== null ? user.phone : null;
|
|
1595
|
+
case "{fax}":
|
|
1596
|
+
return user !== null ? user.fax : null;
|
|
1597
|
+
case "{company}":
|
|
1598
|
+
return user !== null ? user.company : null;
|
|
1599
|
+
case "{city}":
|
|
1600
|
+
return user !== null ? user.city : null;
|
|
1601
|
+
case "{summary}":
|
|
1602
|
+
return user !== null ? user.summary : null;
|
|
1603
|
+
case "{interests}":
|
|
1604
|
+
return user !== null ? user.interests : null;
|
|
1605
|
+
case "{personal_website}":
|
|
1606
|
+
return user !== null ? user.personal_website : null;
|
|
1607
|
+
case "{company_website}":
|
|
1608
|
+
return user !== null ? user.company_website : null;
|
|
1609
|
+
case "{position}":
|
|
1610
|
+
return user !== null ? user.position : null;
|
|
1611
|
+
case "{department}":
|
|
1612
|
+
return user !== null ? user.department : null;
|
|
1613
|
+
case "{today}":
|
|
1614
|
+
return ul4.today();
|
|
1615
|
+
default:
|
|
1616
|
+
return placeholder;
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
get default()
|
|
1621
|
+
{
|
|
1622
|
+
let view_control = this._view_control();
|
|
1623
|
+
|
|
1624
|
+
if (view_control === null)
|
|
1625
|
+
return null;
|
|
1626
|
+
|
|
1627
|
+
return this._user_placeholder(this.app.globals.user, view_control.default);
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
get minlength()
|
|
1631
|
+
{
|
|
1632
|
+
let view_control = this._view_control();
|
|
1633
|
+
|
|
1634
|
+
if (view_control === null)
|
|
1635
|
+
return 0;
|
|
1636
|
+
let minlength = view_control.minlength;
|
|
1637
|
+
if (minlength === null || minlength < 0)
|
|
1638
|
+
return 0;
|
|
1639
|
+
return minlength;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
get maxlength()
|
|
1643
|
+
{
|
|
1644
|
+
let view_control = this._view_control();
|
|
1645
|
+
|
|
1646
|
+
if (view_control === null)
|
|
1647
|
+
return 4000;
|
|
1648
|
+
let maxlength = view_control.maxlength;
|
|
1649
|
+
if (maxlength === null || maxlength < 0 || maxlength > 4000)
|
|
1650
|
+
return 4000;
|
|
1651
|
+
return maxlength;
|
|
1652
|
+
}
|
|
1653
|
+
|
|
533
1654
|
search(value, search)
|
|
534
1655
|
{
|
|
535
1656
|
this._logsearch(value, search);
|
|
@@ -547,52 +1668,92 @@ export class StringControl extends Control
|
|
|
547
1668
|
|
|
548
1669
|
StringControl.prototype.type = "string";
|
|
549
1670
|
|
|
1671
|
+
|
|
550
1672
|
export class TextControl extends StringControl
|
|
551
1673
|
{
|
|
1674
|
+
static classdoc = "A LivingApps text field (type 'string/text')";
|
|
552
1675
|
};
|
|
553
1676
|
|
|
554
1677
|
TextControl.prototype.subtype = "text";
|
|
1678
|
+
TextControl.prototype.fieldtype = StringField;
|
|
1679
|
+
|
|
555
1680
|
|
|
556
1681
|
export class EmailControl extends StringControl
|
|
557
1682
|
{
|
|
1683
|
+
static classdoc = "A LivingApps email field (type 'string/email')";
|
|
558
1684
|
};
|
|
559
1685
|
|
|
560
1686
|
EmailControl.prototype.subtype = "email";
|
|
1687
|
+
EmailControl.prototype.fieldtype = EmailField;
|
|
1688
|
+
|
|
561
1689
|
|
|
562
1690
|
export class URLControl extends StringControl
|
|
563
1691
|
{
|
|
1692
|
+
static classdoc = "A LivingApps URL field (type 'string/url')";
|
|
564
1693
|
};
|
|
565
1694
|
|
|
566
1695
|
URLControl.prototype.subtype = "url";
|
|
1696
|
+
URLControl.prototype.fieldtype = URLField;
|
|
1697
|
+
|
|
567
1698
|
|
|
568
1699
|
export class TelControl extends StringControl
|
|
569
1700
|
{
|
|
1701
|
+
static classdoc = "A LivingApps phone number field (type 'string/tel')";
|
|
570
1702
|
};
|
|
571
1703
|
|
|
572
1704
|
TelControl.prototype.subtype = "tel";
|
|
1705
|
+
TelControl.prototype.fieldtype = TelField;
|
|
573
1706
|
|
|
574
|
-
export class PasswordControl extends StringControl
|
|
575
|
-
{
|
|
576
|
-
};
|
|
577
|
-
|
|
578
|
-
PasswordControl.prototype.subtype = "password";
|
|
579
1707
|
|
|
580
1708
|
export class TextAreaControl extends StringControl
|
|
581
1709
|
{
|
|
1710
|
+
static classdoc = "A LivingApps textarea field (type 'string/textarea')";
|
|
1711
|
+
|
|
1712
|
+
get maxlength()
|
|
1713
|
+
{
|
|
1714
|
+
let view_control = this._view_control();
|
|
1715
|
+
|
|
1716
|
+
if (view_control === null)
|
|
1717
|
+
return null;
|
|
1718
|
+
// We only get the encrypted text in encryption mode, so we can't check its length
|
|
1719
|
+
if (this.encrypted !== null)
|
|
1720
|
+
return null;
|
|
1721
|
+
let maxlength = view_control.maxlength;
|
|
1722
|
+
if (maxlength < 0)
|
|
1723
|
+
return null;
|
|
1724
|
+
return maxlength;
|
|
1725
|
+
}
|
|
582
1726
|
};
|
|
583
1727
|
|
|
584
1728
|
TextAreaControl.prototype.subtype = "textarea";
|
|
585
|
-
TextAreaControl.prototype.
|
|
586
|
-
TextAreaControl.prototype.
|
|
1729
|
+
TextAreaControl.prototype.fieldtype = TextAreaField;
|
|
1730
|
+
TextAreaControl.prototype._ul4onattrs = [...StringControl.prototype._ul4onattrs, "encrypted"];
|
|
1731
|
+
TextAreaControl.prototype._ul4attrs = new Set([...StringControl.prototype._ul4attrs, "encrypted"]);
|
|
1732
|
+
|
|
587
1733
|
|
|
588
1734
|
export class HTMLControl extends StringControl
|
|
589
1735
|
{
|
|
1736
|
+
static classdoc = "A LivingApps HTML field (type 'string/html')";
|
|
590
1737
|
};
|
|
591
1738
|
|
|
592
1739
|
HTMLControl.prototype.subtype = "html";
|
|
1740
|
+
HTMLControl.prototype.fieldtype = HTMLField;
|
|
593
1741
|
|
|
594
|
-
|
|
1742
|
+
|
|
1743
|
+
export class DateControl extends PlaceholderControl
|
|
595
1744
|
{
|
|
1745
|
+
static classdoc = "A LivingApps date field (type 'date/date')";
|
|
1746
|
+
|
|
1747
|
+
get default()
|
|
1748
|
+
{
|
|
1749
|
+
let view_control = this._view_control();
|
|
1750
|
+
|
|
1751
|
+
if (view_control === null)
|
|
1752
|
+
return null;
|
|
1753
|
+
|
|
1754
|
+
return view_control.default === "{today}" ? ul4.today() : null;
|
|
1755
|
+
}
|
|
1756
|
+
|
|
596
1757
|
formatstring(language)
|
|
597
1758
|
{
|
|
598
1759
|
language = language || this.app.language;
|
|
@@ -630,9 +1791,31 @@ export class DateControl extends Control
|
|
|
630
1791
|
|
|
631
1792
|
DateControl.prototype.type = "date";
|
|
632
1793
|
DateControl.prototype.subtype = "date";
|
|
1794
|
+
DateControl.prototype.fieldtype = DateField;
|
|
1795
|
+
|
|
633
1796
|
|
|
634
1797
|
export class DatetimeMinuteControl extends DateControl
|
|
635
1798
|
{
|
|
1799
|
+
static classdoc = "A LivingApps date field (type 'date/datetimeminute')";
|
|
1800
|
+
|
|
1801
|
+
get default()
|
|
1802
|
+
{
|
|
1803
|
+
let view_control = this._view_control();
|
|
1804
|
+
|
|
1805
|
+
if (view_control === null)
|
|
1806
|
+
return null;
|
|
1807
|
+
|
|
1808
|
+
if (view_control.default === "{today}")
|
|
1809
|
+
{
|
|
1810
|
+
let now = new Date();
|
|
1811
|
+
now.setSeconds(0);
|
|
1812
|
+
now.setMilliseconds(0);
|
|
1813
|
+
return now;
|
|
1814
|
+
}
|
|
1815
|
+
else
|
|
1816
|
+
return null;
|
|
1817
|
+
}
|
|
1818
|
+
|
|
636
1819
|
formatstring(language)
|
|
637
1820
|
{
|
|
638
1821
|
language = language || this.app.language;
|
|
@@ -645,9 +1828,30 @@ export class DatetimeMinuteControl extends DateControl
|
|
|
645
1828
|
};
|
|
646
1829
|
|
|
647
1830
|
DatetimeMinuteControl.prototype.subtype = "datetimeminute";
|
|
1831
|
+
DatetimeMinuteControl.prototype.fieldtype = DatetimeMinuteField;
|
|
1832
|
+
|
|
648
1833
|
|
|
649
1834
|
export class DatetimeSecondControl extends DateControl
|
|
650
1835
|
{
|
|
1836
|
+
static classdoc = "A LivingApps date field (type 'date/datetimesecond')";
|
|
1837
|
+
|
|
1838
|
+
get default()
|
|
1839
|
+
{
|
|
1840
|
+
let view_control = this._view_control();
|
|
1841
|
+
|
|
1842
|
+
if (view_control === null)
|
|
1843
|
+
return null;
|
|
1844
|
+
|
|
1845
|
+
if (view_control.default === "{today}")
|
|
1846
|
+
{
|
|
1847
|
+
let now = new Date();
|
|
1848
|
+
now.setMilliseconds(0);
|
|
1849
|
+
return now;
|
|
1850
|
+
}
|
|
1851
|
+
else
|
|
1852
|
+
return null;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
651
1855
|
formatstring(language)
|
|
652
1856
|
{
|
|
653
1857
|
language = language || this.app.language;
|
|
@@ -660,9 +1864,45 @@ export class DatetimeSecondControl extends DateControl
|
|
|
660
1864
|
};
|
|
661
1865
|
|
|
662
1866
|
DatetimeSecondControl.prototype.subtype = "datetimesecond";
|
|
1867
|
+
DatetimeSecondControl.prototype.fieldtype = DatetimeSecondField;
|
|
1868
|
+
|
|
663
1869
|
|
|
664
1870
|
export class LookupControl extends Control
|
|
665
1871
|
{
|
|
1872
|
+
get default()
|
|
1873
|
+
{
|
|
1874
|
+
let view_control = this._view_control();
|
|
1875
|
+
|
|
1876
|
+
if (view_control === null)
|
|
1877
|
+
return null;
|
|
1878
|
+
|
|
1879
|
+
return this.lookupdata.get(view_control) ?? null;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
get autoexpandable()
|
|
1883
|
+
{
|
|
1884
|
+
let view_control = this._view_control();
|
|
1885
|
+
if (view_control === null)
|
|
1886
|
+
return false;
|
|
1887
|
+
return view_control.autoexpandable;
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
get nonekey()
|
|
1891
|
+
{
|
|
1892
|
+
let view_control = this._view_control();
|
|
1893
|
+
if (view_control === null)
|
|
1894
|
+
return null;
|
|
1895
|
+
return view_control.lookupnonekey;
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
get nonelabel()
|
|
1899
|
+
{
|
|
1900
|
+
let view_control = this._view_control();
|
|
1901
|
+
if (view_control === null)
|
|
1902
|
+
return null;
|
|
1903
|
+
return view_control.lookupnonelabel;
|
|
1904
|
+
}
|
|
1905
|
+
|
|
666
1906
|
// ``search.value`` must be ``null`` or a ``LookupItem`` key
|
|
667
1907
|
search(value, search)
|
|
668
1908
|
{
|
|
@@ -679,27 +1919,38 @@ export class LookupControl extends Control
|
|
|
679
1919
|
};
|
|
680
1920
|
|
|
681
1921
|
LookupControl.prototype.type = "lookup";
|
|
682
|
-
LookupControl.prototype.
|
|
683
|
-
LookupControl.prototype.
|
|
1922
|
+
LookupControl.prototype.fieldtype = LookupField;
|
|
1923
|
+
LookupControl.prototype._ul4onattrs = [...Control.prototype._ul4onattrs, "lookupdata"];
|
|
1924
|
+
LookupControl.prototype._ul4attrs = new Set([...Control.prototype._ul4attrs, "lookupdata"]);
|
|
1925
|
+
|
|
684
1926
|
|
|
685
1927
|
export class LookupSelectControl extends LookupControl
|
|
686
1928
|
{
|
|
1929
|
+
static classdoc = "A LivingApps lookup field (type 'lookup/select')";
|
|
1930
|
+
|
|
687
1931
|
};
|
|
688
1932
|
|
|
689
1933
|
LookupSelectControl.prototype.subtype = "select";
|
|
690
1934
|
|
|
1935
|
+
|
|
691
1936
|
export class LookupRadioControl extends LookupControl
|
|
692
1937
|
{
|
|
1938
|
+
static classdoc = "A LivingApps lookup field (type 'lookup/radio')";
|
|
1939
|
+
|
|
693
1940
|
};
|
|
694
1941
|
|
|
695
1942
|
LookupRadioControl.prototype.subtype = "radio";
|
|
696
1943
|
|
|
1944
|
+
|
|
697
1945
|
export class LookupChoiceControl extends LookupControl
|
|
698
1946
|
{
|
|
1947
|
+
static classdoc = "A LivingApps lookup field (type 'lookup/choice')";
|
|
1948
|
+
|
|
699
1949
|
};
|
|
700
1950
|
|
|
701
1951
|
LookupChoiceControl.prototype.subtype = "choice";
|
|
702
1952
|
|
|
1953
|
+
|
|
703
1954
|
export class AppLookupControl extends Control
|
|
704
1955
|
{
|
|
705
1956
|
// ``search.value`` must be an object containing the search criteria for the referenced record
|
|
@@ -713,29 +1964,52 @@ export class AppLookupControl extends Control
|
|
|
713
1964
|
};
|
|
714
1965
|
|
|
715
1966
|
AppLookupControl.prototype.type = "applookup";
|
|
716
|
-
AppLookupControl.prototype.
|
|
717
|
-
AppLookupControl.prototype.
|
|
1967
|
+
AppLookupControl.prototype.fieldtype = AppLookupField;
|
|
1968
|
+
AppLookupControl.prototype._ul4onattrs = [...Control.prototype._ul4onattrs, "lookup_app", "lookup_controls", "local_master_control", "local_detail_controls", "remote_master_control"];
|
|
1969
|
+
AppLookupControl.prototype._ul4attrs = new Set([...Control.prototype._ul4attrs, "lookup_app", "lookup_controls", "local_master_control", "local_detail_controls", "remote_master_control"]);
|
|
1970
|
+
|
|
718
1971
|
|
|
719
1972
|
export class AppLookupSelectControl extends AppLookupControl
|
|
720
1973
|
{
|
|
1974
|
+
static classdoc = "A LivingApps applookup field (type 'applookup/select')";
|
|
1975
|
+
|
|
721
1976
|
};
|
|
722
1977
|
|
|
723
1978
|
AppLookupSelectControl.prototype.subtype = "select";
|
|
724
1979
|
|
|
1980
|
+
|
|
725
1981
|
export class AppLookupRadioControl extends AppLookupControl
|
|
726
1982
|
{
|
|
1983
|
+
static classdoc = "A LivingApps applookup field (type 'applookup/radio')";
|
|
1984
|
+
|
|
727
1985
|
};
|
|
728
1986
|
|
|
729
1987
|
AppLookupRadioControl.prototype.subtype = "radio";
|
|
730
1988
|
|
|
1989
|
+
|
|
731
1990
|
export class AppLookupChoiceControl extends AppLookupControl
|
|
732
1991
|
{
|
|
1992
|
+
static classdoc = "A LivingApps applookup field (type 'applookup/choice')";
|
|
1993
|
+
|
|
733
1994
|
};
|
|
734
1995
|
|
|
735
1996
|
AppLookupChoiceControl.prototype.subtype = "choice";
|
|
736
1997
|
|
|
1998
|
+
|
|
737
1999
|
export class MultipleLookupControl extends LookupControl
|
|
738
2000
|
{
|
|
2001
|
+
get default()
|
|
2002
|
+
{
|
|
2003
|
+
let view_control = this._view_control();
|
|
2004
|
+
|
|
2005
|
+
if (view_control === null)
|
|
2006
|
+
return null;
|
|
2007
|
+
|
|
2008
|
+
let defaultValue = this.lookupdata.get(view_control)
|
|
2009
|
+
|
|
2010
|
+
return (defaultValue !== undefined) ? [defaultValue] : [];
|
|
2011
|
+
}
|
|
2012
|
+
|
|
739
2013
|
// search.value must be ``null`` or a ``LookupItem`` key
|
|
740
2014
|
search(value, search)
|
|
741
2015
|
{
|
|
@@ -754,25 +2028,36 @@ export class MultipleLookupControl extends LookupControl
|
|
|
754
2028
|
};
|
|
755
2029
|
|
|
756
2030
|
MultipleLookupControl.prototype.subtype = "multiplelookup";
|
|
2031
|
+
MultipleLookupControl.prototype.fieldtype = MultipleLookupField;
|
|
2032
|
+
|
|
757
2033
|
|
|
758
2034
|
export class MultipleLookupSelectControl extends MultipleLookupControl
|
|
759
2035
|
{
|
|
2036
|
+
static classdoc = "A LivingApps multiplelookup field (type 'multiplelookup/select')";
|
|
2037
|
+
|
|
760
2038
|
};
|
|
761
2039
|
|
|
762
2040
|
MultipleLookupSelectControl.prototype.subtype = "select";
|
|
763
2041
|
|
|
2042
|
+
|
|
764
2043
|
export class MultipleLookupCheckboxControl extends MultipleLookupControl
|
|
765
2044
|
{
|
|
2045
|
+
static classdoc = "A LivingApps multiplelookup field (type 'multiplelookup/checkbox')";
|
|
2046
|
+
|
|
766
2047
|
};
|
|
767
2048
|
|
|
768
2049
|
MultipleLookupCheckboxControl.prototype.subtype = "checkbox";
|
|
769
2050
|
|
|
2051
|
+
|
|
770
2052
|
export class MultipleLookupChoiceControl extends MultipleLookupControl
|
|
771
2053
|
{
|
|
2054
|
+
static classdoc = "A LivingApps multiplelookup field (type 'multiplelookup/choice')";
|
|
2055
|
+
|
|
772
2056
|
};
|
|
773
2057
|
|
|
774
2058
|
MultipleLookupChoiceControl.prototype.subtype = "choice";
|
|
775
2059
|
|
|
2060
|
+
|
|
776
2061
|
export class MultipleAppLookupControl extends AppLookupControl
|
|
777
2062
|
{
|
|
778
2063
|
// ``search.value`` must be an object containing the search criteria for the referenced record
|
|
@@ -798,42 +2083,61 @@ export class MultipleAppLookupControl extends AppLookupControl
|
|
|
798
2083
|
};
|
|
799
2084
|
|
|
800
2085
|
MultipleAppLookupControl.prototype.type = "multipleapplookup";
|
|
2086
|
+
MultipleAppLookupControl.prototype.fieldtype = MultipleAppLookupField;
|
|
2087
|
+
|
|
801
2088
|
|
|
802
2089
|
export class MultipleAppLookupSelectControl extends MultipleAppLookupControl
|
|
803
2090
|
{
|
|
2091
|
+
static classdoc = "A LivingApps multiple applookup field (type 'multipleapplookup/select')";
|
|
2092
|
+
|
|
804
2093
|
};
|
|
805
2094
|
|
|
806
2095
|
MultipleAppLookupSelectControl.prototype.subtype = "select";
|
|
807
2096
|
|
|
2097
|
+
|
|
808
2098
|
export class MultipleAppLookupCheckboxControl extends MultipleAppLookupControl
|
|
809
2099
|
{
|
|
2100
|
+
static classdoc = "A LivingApps multiple applookup field (type 'multipleapplookup/checkbox')";
|
|
2101
|
+
|
|
810
2102
|
};
|
|
811
2103
|
|
|
812
2104
|
MultipleAppLookupCheckboxControl.prototype.subtype = "checkbox";
|
|
813
2105
|
|
|
2106
|
+
|
|
814
2107
|
export class MultipleAppLookupChoiceControl extends MultipleAppLookupControl
|
|
815
2108
|
{
|
|
2109
|
+
static classdoc = "A LivingApps multiple applookup field (type 'multipleapplookup/choice')";
|
|
816
2110
|
};
|
|
817
2111
|
|
|
818
2112
|
MultipleAppLookupChoiceControl.prototype.subtype = "choice";
|
|
819
2113
|
|
|
2114
|
+
|
|
820
2115
|
export class GeoControl extends Control
|
|
821
2116
|
{
|
|
2117
|
+
static classdoc = "A LivingApps geo field (type 'geo')";
|
|
822
2118
|
};
|
|
823
2119
|
|
|
824
2120
|
GeoControl.prototype.type = "geo";
|
|
2121
|
+
GeoControl.prototype.fieldtype = GeoField;
|
|
2122
|
+
|
|
825
2123
|
|
|
826
2124
|
export class FileControl extends Control
|
|
827
2125
|
{
|
|
2126
|
+
static classdoc = "A LivingApps upload field (type 'file')";
|
|
828
2127
|
};
|
|
829
2128
|
|
|
830
2129
|
FileControl.prototype.type = "file";
|
|
2130
|
+
FileControl.prototype.fieldtype = FileField;
|
|
2131
|
+
|
|
831
2132
|
|
|
832
2133
|
export class FileSignatureControl extends FileControl
|
|
833
2134
|
{
|
|
2135
|
+
static classdoc = "A LivingApps signature image field (type 'file/signature')";
|
|
834
2136
|
};
|
|
835
2137
|
|
|
836
2138
|
FileSignatureControl.prototype.subtype = "signature";
|
|
2139
|
+
FileSignatureControl.prototype.fieldtype = FileSignatureField;
|
|
2140
|
+
|
|
837
2141
|
|
|
838
2142
|
export class ButtonControl extends Control
|
|
839
2143
|
{
|
|
@@ -841,165 +2145,237 @@ export class ButtonControl extends Control
|
|
|
841
2145
|
|
|
842
2146
|
ButtonControl.prototype.type = "button";
|
|
843
2147
|
|
|
844
|
-
|
|
2148
|
+
|
|
2149
|
+
export class LookupItem extends Base
|
|
845
2150
|
{
|
|
846
|
-
|
|
2151
|
+
static classdoc = "An option in a lookup control/field";
|
|
2152
|
+
|
|
2153
|
+
get label()
|
|
847
2154
|
{
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
2155
|
+
if (this.control === null)
|
|
2156
|
+
return this._label;
|
|
2157
|
+
let view_lookupitem = this._view_lookupitem();
|
|
2158
|
+
if (view_lookupitem === null)
|
|
2159
|
+
return this._label;
|
|
2160
|
+
let label = view_lookupitem.label;
|
|
2161
|
+
if (label === null)
|
|
2162
|
+
return this._label;
|
|
2163
|
+
return label;
|
|
854
2164
|
}
|
|
855
2165
|
|
|
856
|
-
get
|
|
2166
|
+
get visible()
|
|
857
2167
|
{
|
|
858
|
-
|
|
2168
|
+
if (this.control === null)
|
|
2169
|
+
return true;
|
|
2170
|
+
let view_lookupitem = this._view_lookupitem();
|
|
2171
|
+
if (view_lookupitem === null)
|
|
2172
|
+
return true;
|
|
2173
|
+
return view_lookupitem.visible;
|
|
859
2174
|
}
|
|
860
2175
|
|
|
861
|
-
|
|
2176
|
+
_view_lookupitem()
|
|
862
2177
|
{
|
|
863
|
-
let
|
|
864
|
-
|
|
865
|
-
if (
|
|
2178
|
+
let identifier = this.control.identifier;
|
|
2179
|
+
let active_view = this.control.app.active_view;
|
|
2180
|
+
if (active_view !== null && active_view.controls !== null)
|
|
866
2181
|
{
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
2182
|
+
let view_control = active_view.controls.get(identifier);
|
|
2183
|
+
if (view_control !== undefined && view_control.lookupdata !== undefined && view_control.lookupdata !== null)
|
|
2184
|
+
{
|
|
2185
|
+
let view_lookupitem = view_control.lookupdata.get(this.key);
|
|
2186
|
+
if (view_lookupitem !== undefined)
|
|
2187
|
+
return view_lookupitem;
|
|
2188
|
+
}
|
|
870
2189
|
}
|
|
2190
|
+
return null;
|
|
871
2191
|
}
|
|
872
2192
|
|
|
873
|
-
|
|
2193
|
+
[ul4.symbols.repr]()
|
|
874
2194
|
{
|
|
875
|
-
|
|
2195
|
+
let repr = "<LookupItem key=" + ul4._repr(this.key) + " label=" + ul4._repr(this.label);
|
|
2196
|
+
if (!this.visible)
|
|
2197
|
+
repr += "visible=False"
|
|
2198
|
+
return repr + ">";
|
|
876
2199
|
}
|
|
2200
|
+
};
|
|
877
2201
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
return this._dirty;
|
|
881
|
-
}
|
|
2202
|
+
LookupItem.prototype._ul4onattrs = ["control", "key", "_label"];
|
|
2203
|
+
LookupItem.prototype._ul4attrs = new Set(["id", "control", "key", "label"]);
|
|
882
2204
|
|
|
883
|
-
has_errors()
|
|
884
|
-
{
|
|
885
|
-
return this.errors.length !== 0;
|
|
886
|
-
}
|
|
887
2205
|
|
|
888
|
-
|
|
2206
|
+
export class ViewLookupItem extends Base
|
|
2207
|
+
{
|
|
2208
|
+
static classdoc = "View specific information about a lookup item";
|
|
2209
|
+
|
|
2210
|
+
[ul4.symbols.repr]()
|
|
889
2211
|
{
|
|
890
|
-
|
|
2212
|
+
let repr = "<ViewLookupItem key=" + ul4._repr(this.key) + " label=" + ul4._repr(this.label);
|
|
2213
|
+
if (!this.visible)
|
|
2214
|
+
repr += " visible=False"
|
|
2215
|
+
return repr + ">";
|
|
891
2216
|
}
|
|
2217
|
+
};
|
|
2218
|
+
|
|
2219
|
+
ViewLookupItem.prototype._ul4onattrs = ["key", "label", "visible"];
|
|
2220
|
+
ViewLookupItem.prototype._ul4attrs = new Set(["key", "label", "visible"]);
|
|
892
2221
|
|
|
893
|
-
|
|
2222
|
+
|
|
2223
|
+
export class LayoutControl extends Base
|
|
2224
|
+
{
|
|
2225
|
+
static classdoc = "A decoration in an input form";
|
|
2226
|
+
|
|
2227
|
+
[ul4.symbols.repr]()
|
|
894
2228
|
{
|
|
895
|
-
|
|
896
|
-
s += ul4._repr(this.control.identifier)
|
|
897
|
-
if (this._dirty)
|
|
898
|
-
s += " is_dirty()=True";
|
|
899
|
-
if (this.errors.length !== 0)
|
|
900
|
-
s += " has_errors()=True";
|
|
901
|
-
s += ">"
|
|
902
|
-
return s;
|
|
2229
|
+
return "<" + this.constructor.name + " id=" + ul4._repr(this.id) + " identifier=" + ul4._repr(this.identifier) + ">";
|
|
903
2230
|
}
|
|
904
2231
|
};
|
|
905
2232
|
|
|
906
|
-
|
|
2233
|
+
LayoutControl.prototype._ul4onattrs = ["label", "identifier", "view", "top", "left", "width", "height"];
|
|
2234
|
+
LayoutControl.prototype._ul4attrs = new Set(["id", "label", "identifier", "view", "top", "left", "width", "height"]);
|
|
2235
|
+
|
|
2236
|
+
|
|
2237
|
+
export class HTMLLayoutControl extends LayoutControl
|
|
2238
|
+
{
|
|
2239
|
+
static classdoc = "An HTML decoration in an input form";
|
|
2240
|
+
};
|
|
2241
|
+
|
|
2242
|
+
HTMLLayoutControl.prototype._ul4onattrs = [...LayoutControl.prototype._ul4onattrs, "value"];
|
|
2243
|
+
HTMLLayoutControl.prototype._ul4attrs = new Set([LayoutControl.prototype._ul4attrs, "value"]);
|
|
2244
|
+
|
|
2245
|
+
|
|
2246
|
+
export class ImageLayoutControl extends LayoutControl
|
|
2247
|
+
{
|
|
2248
|
+
static classdoc = "An image decoration in an input form";
|
|
2249
|
+
};
|
|
2250
|
+
|
|
2251
|
+
ImageLayoutControl.prototype._ul4onattrs = [...LayoutControl.prototype._ul4onattrs, "original", "scaled"];
|
|
2252
|
+
ImageLayoutControl.prototype._ul4attrs = new Set([LayoutControl.prototype._ul4attrs, "original", "scaled"]);
|
|
2253
|
+
|
|
2254
|
+
|
|
2255
|
+
export class ViewControl extends Base
|
|
907
2256
|
{
|
|
908
|
-
|
|
2257
|
+
static classdoc = "Contains view specific information aboutn a control";
|
|
2258
|
+
|
|
2259
|
+
get mode()
|
|
909
2260
|
{
|
|
910
|
-
return
|
|
2261
|
+
return this._mode ? "display" : "edit";
|
|
911
2262
|
}
|
|
912
2263
|
};
|
|
913
2264
|
|
|
914
|
-
|
|
915
|
-
|
|
2265
|
+
ViewControl.prototype._ul4onattrs = ["view", "control", "top", "left", "width", "height", "liveupdate", "default", "tabindex", "minlength", "maxlength", "required", "placeholder", "_mode", "labelpos", "lookupnonekey", "lookupnonelabel", "label", "autoalign", "labelwidth", "lookupdata", "autoexpandable"];
|
|
2266
|
+
ViewControl.prototype._ul4attrs = new Set(["id", "view", "control", "top", "left", "width", "height", "liveupdate", "default", "tabindex", "minlength", "maxlength", "required", "placeholder", "mode", "labelpos", "lookupnonekey", "lookupnonelabel", "label", "autoalign", "labelwidth", "lookupdata", "autoexpandable"]);
|
|
2267
|
+
|
|
916
2268
|
|
|
917
2269
|
export class User extends Base
|
|
918
2270
|
{
|
|
919
|
-
|
|
2271
|
+
static classdoc = "A LivingApps user/account";
|
|
2272
|
+
|
|
2273
|
+
[ul4.symbols.repr]()
|
|
920
2274
|
{
|
|
921
2275
|
return "<User id=" + ul4._repr(this.id) + " firstname=" + ul4._repr(this.firstname) + " surname=" + ul4._repr(this.surname) + " email=" + ul4._repr(this.email) + ">";
|
|
922
2276
|
}
|
|
923
2277
|
};
|
|
924
2278
|
|
|
925
|
-
User.prototype._ul4onattrs = ["_id", "
|
|
926
|
-
User.prototype._ul4attrs =
|
|
2279
|
+
User.prototype._ul4onattrs = ["_id", "gender", "title", "firstname", "surname", "initials", "email", "streetname", "streetnumber", "zip", "city", "phone", "fax", "lang", "avatarsmall", "avatarlarge", "summary", "interests", "personalwebsite", "companywebsite", "company", "position", "department", "keyviews"];
|
|
2280
|
+
User.prototype._ul4attrs = new Set(["id", "_id", "gender", "title", "firstname", "surname", "initials", "email", "streetname", "streetnumber", "zip", "city", "phone", "fax", "lang", "avatarsmall", "avatarlarge", "summary", "interests", "personalwebsite", "companywebsite", "company", "position", "department", "keyviews"]);
|
|
2281
|
+
|
|
927
2282
|
|
|
928
2283
|
export class File extends Base
|
|
929
2284
|
{
|
|
930
|
-
|
|
2285
|
+
static classdoc = "An uploaded file";
|
|
2286
|
+
|
|
2287
|
+
[ul4.symbols.repr]()
|
|
931
2288
|
{
|
|
932
2289
|
return "<File id=" + ul4._repr(this.id) + " url=" + ul4._repr(this.url) + " filename=" + ul4._repr(this.filename) + ">";
|
|
933
2290
|
}
|
|
934
2291
|
};
|
|
935
2292
|
|
|
936
|
-
File.prototype._ul4onattrs = ["
|
|
937
|
-
File.prototype._ul4attrs =
|
|
2293
|
+
File.prototype._ul4onattrs = ["url", "filename", "mimetype", "width", "height", "internalid", "createdat", "size"];
|
|
2294
|
+
File.prototype._ul4attrs = new Set(["id", "url", "filename", "mimetype", "width", "height", "size", "createdat"]);
|
|
2295
|
+
|
|
938
2296
|
|
|
939
2297
|
export class Geo extends Base
|
|
940
2298
|
{
|
|
2299
|
+
static classdoc = "Geographical coordinates and location information";
|
|
2300
|
+
|
|
941
2301
|
constructor(lat, long, info)
|
|
942
2302
|
{
|
|
943
|
-
super();
|
|
2303
|
+
super(null);
|
|
944
2304
|
this.lat = lat;
|
|
945
2305
|
this.long = long;
|
|
946
2306
|
this.info = info;
|
|
947
2307
|
}
|
|
948
2308
|
|
|
949
|
-
|
|
2309
|
+
[ul4.symbols.repr]()
|
|
950
2310
|
{
|
|
951
2311
|
return "<Geo lat=" + ul4._repr(this.lat) + " long=" + ul4._repr(this.long) + " info=" + ul4._repr(this.info) + ">";
|
|
952
2312
|
}
|
|
953
2313
|
};
|
|
954
2314
|
|
|
955
2315
|
Geo.prototype._ul4onattrs = ["lat", "long", "info"];
|
|
956
|
-
Geo.prototype._ul4attrs =
|
|
2316
|
+
Geo.prototype._ul4attrs = new Set(["lat", "long", "info"]);
|
|
2317
|
+
|
|
957
2318
|
|
|
958
2319
|
export class Attachment extends Base
|
|
959
2320
|
{
|
|
960
|
-
|
|
2321
|
+
[ul4.symbols.repr]()
|
|
961
2322
|
{
|
|
962
|
-
return "<" + this.
|
|
2323
|
+
return "<" + this.constructor.name + " id=" + ul4._repr(this.id) + " label=" + ul4._repr(this.label) + ">";
|
|
963
2324
|
}
|
|
964
2325
|
};
|
|
965
2326
|
|
|
966
|
-
Attachment.prototype._ul4onattrs = ["
|
|
967
|
-
Attachment.prototype._ul4attrs =
|
|
2327
|
+
Attachment.prototype._ul4onattrs = ["record", "label", "active"];
|
|
2328
|
+
Attachment.prototype._ul4attrs = new Set(["id", "record", "label", "active"]);
|
|
2329
|
+
|
|
968
2330
|
|
|
969
2331
|
export class NoteAttachment extends Attachment
|
|
970
2332
|
{
|
|
2333
|
+
static classdoc = "A note attachment of a record";
|
|
2334
|
+
|
|
971
2335
|
};
|
|
972
2336
|
|
|
973
2337
|
NoteAttachment.prototype.type = "noteattachment";
|
|
974
|
-
NoteAttachment.prototype._ul4onattrs = Attachment.prototype._ul4onattrs
|
|
975
|
-
NoteAttachment.prototype._ul4attrs =
|
|
2338
|
+
NoteAttachment.prototype._ul4onattrs = [...Attachment.prototype._ul4onattrs, "value"];
|
|
2339
|
+
NoteAttachment.prototype._ul4attrs = new Set([...Attachment.prototype._ul4onattrs, "value"]);
|
|
2340
|
+
|
|
976
2341
|
|
|
977
2342
|
export class URLAttachment extends Attachment
|
|
978
2343
|
{
|
|
2344
|
+
static classdoc = "A URL attachment of a record";
|
|
2345
|
+
|
|
979
2346
|
};
|
|
980
2347
|
|
|
981
2348
|
URLAttachment.prototype.type = "urlattachment";
|
|
982
|
-
URLAttachment.prototype._ul4onattrs = Attachment.prototype._ul4onattrs
|
|
983
|
-
URLAttachment.prototype._ul4attrs =
|
|
2349
|
+
URLAttachment.prototype._ul4onattrs = [...Attachment.prototype._ul4onattrs, "value"];
|
|
2350
|
+
URLAttachment.prototype._ul4attrs = new Set([...Attachment.prototype._ul4onattrs, "value"]);
|
|
2351
|
+
|
|
984
2352
|
|
|
985
2353
|
export class FileAttachment extends Attachment
|
|
986
2354
|
{
|
|
2355
|
+
static classdoc = "A file attachment of a record";
|
|
2356
|
+
|
|
987
2357
|
};
|
|
988
2358
|
|
|
989
2359
|
FileAttachment.prototype.type = "fileattachment";
|
|
990
|
-
FileAttachment.prototype._ul4onattrs = Attachment.prototype._ul4onattrs
|
|
991
|
-
FileAttachment.prototype._ul4attrs =
|
|
2360
|
+
FileAttachment.prototype._ul4onattrs = [...Attachment.prototype._ul4onattrs, "value"];
|
|
2361
|
+
FileAttachment.prototype._ul4attrs = new Set([...Attachment.prototype._ul4onattrs, "value"]);
|
|
2362
|
+
|
|
992
2363
|
|
|
993
2364
|
export class ImageAttachment extends Attachment
|
|
994
2365
|
{
|
|
2366
|
+
static classdoc = "An image attachment of a record";
|
|
2367
|
+
|
|
995
2368
|
};
|
|
996
2369
|
|
|
997
2370
|
ImageAttachment.prototype.type = "imageattachment";
|
|
998
|
-
ImageAttachment.prototype._ul4onattrs = Attachment.prototype._ul4onattrs
|
|
999
|
-
ImageAttachment.prototype._ul4attrs =
|
|
2371
|
+
ImageAttachment.prototype._ul4onattrs = [...Attachment.prototype._ul4onattrs, "original", "thumb", "small", "medium","large"];
|
|
2372
|
+
ImageAttachment.prototype._ul4attrs = new Set([...Attachment.prototype._ul4onattrs, "original", "thumb", "small", "medium", "large"]);
|
|
2373
|
+
|
|
1000
2374
|
|
|
1001
2375
|
export class JSONAttachment extends Attachment
|
|
1002
2376
|
{
|
|
2377
|
+
static classdoc = "A JSON attachment of a record";
|
|
2378
|
+
|
|
1003
2379
|
_dumpUL4ONAttr(name)
|
|
1004
2380
|
{
|
|
1005
2381
|
if (name === "value")
|
|
@@ -1018,23 +2394,29 @@ export class JSONAttachment extends Attachment
|
|
|
1018
2394
|
};
|
|
1019
2395
|
|
|
1020
2396
|
JSONAttachment.prototype.type = "jsonattachment";
|
|
1021
|
-
JSONAttachment.prototype._ul4onattrs = Attachment.prototype._ul4onattrs
|
|
1022
|
-
JSONAttachment.prototype._ul4attrs =
|
|
2397
|
+
JSONAttachment.prototype._ul4onattrs = [...Attachment.prototype._ul4onattrs, "value"];
|
|
2398
|
+
JSONAttachment.prototype._ul4attrs = new Set([...Attachment.prototype._ul4onattrs, "value"]);
|
|
2399
|
+
|
|
1023
2400
|
|
|
1024
2401
|
export class Installation extends Base
|
|
1025
2402
|
{
|
|
1026
|
-
|
|
2403
|
+
static classdoc = "The installation that created an app";
|
|
2404
|
+
|
|
2405
|
+
[ul4.symbols.repr]()
|
|
1027
2406
|
{
|
|
1028
2407
|
return "<Installation id=" + ul4._repr(this.id) + " name=" + ul4._repr(this.name) + ">";
|
|
1029
2408
|
}
|
|
1030
2409
|
};
|
|
1031
2410
|
|
|
1032
|
-
Installation.prototype._ul4onattrs = ["
|
|
1033
|
-
Installation.prototype._ul4attrs =
|
|
2411
|
+
Installation.prototype._ul4onattrs = ["name"];
|
|
2412
|
+
Installation.prototype._ul4attrs = new Set(["id", "name"]);
|
|
2413
|
+
|
|
1034
2414
|
|
|
1035
2415
|
export class Category extends Base
|
|
1036
2416
|
{
|
|
1037
|
-
|
|
2417
|
+
static classdoc = "A navigation category";
|
|
2418
|
+
|
|
2419
|
+
[ul4.symbols.repr]()
|
|
1038
2420
|
{
|
|
1039
2421
|
let v = [];
|
|
1040
2422
|
let category = this;
|
|
@@ -1047,30 +2429,37 @@ export class Category extends Base
|
|
|
1047
2429
|
}
|
|
1048
2430
|
};
|
|
1049
2431
|
|
|
1050
|
-
Category.prototype._ul4onattrs = ["
|
|
1051
|
-
Category.prototype._ul4attrs =
|
|
2432
|
+
Category.prototype._ul4onattrs = ["identifier", "name", "order", "parent", "children", "apps"];
|
|
2433
|
+
Category.prototype._ul4attrs = new Set(["id", "identifier", "name", "order", "parent", "children", "apps"]);
|
|
2434
|
+
|
|
1052
2435
|
|
|
1053
2436
|
export class KeyView extends Base
|
|
1054
2437
|
{
|
|
1055
|
-
|
|
2438
|
+
static classdoc = "Object granting access to a view template";
|
|
2439
|
+
|
|
2440
|
+
[ul4.symbols.repr]()
|
|
1056
2441
|
{
|
|
1057
2442
|
return "<KeyView id=" + ul4._repr(this.id) + " identifier=" + ul4._repr(this.identifier) + ">";
|
|
1058
2443
|
}
|
|
1059
2444
|
};
|
|
1060
2445
|
|
|
1061
|
-
KeyView.prototype._ul4onattrs = ["
|
|
1062
|
-
KeyView.prototype._ul4attrs =
|
|
2446
|
+
KeyView.prototype._ul4onattrs = ["identifier", "name", "key", "user"];
|
|
2447
|
+
KeyView.prototype._ul4attrs = new Set(["id", "identifier", "name", "key", "user"]);
|
|
2448
|
+
|
|
1063
2449
|
|
|
1064
2450
|
export class AppParameter extends Base
|
|
1065
2451
|
{
|
|
1066
|
-
|
|
2452
|
+
static classdoc = "A parameter of a LivingApps application";
|
|
2453
|
+
|
|
2454
|
+
[ul4.symbols.repr]()
|
|
1067
2455
|
{
|
|
1068
2456
|
return "<AppParameter id=" + ul4._repr(this.id) + " identifier=" + ul4._repr(this.identifier) + ">";
|
|
1069
2457
|
}
|
|
1070
2458
|
};
|
|
1071
2459
|
|
|
1072
|
-
AppParameter.prototype._ul4onattrs = ["
|
|
1073
|
-
AppParameter.prototype._ul4attrs =
|
|
2460
|
+
AppParameter.prototype._ul4onattrs = ["app", "identifier", "description", "value"];
|
|
2461
|
+
AppParameter.prototype._ul4attrs = new Set(["id", "app", "identifier", "description", "value"]);
|
|
2462
|
+
|
|
1074
2463
|
|
|
1075
2464
|
let classes = [
|
|
1076
2465
|
Globals,
|
|
@@ -1086,7 +2475,6 @@ let classes = [
|
|
|
1086
2475
|
EmailControl,
|
|
1087
2476
|
URLControl,
|
|
1088
2477
|
TelControl,
|
|
1089
|
-
PasswordControl,
|
|
1090
2478
|
TextAreaControl,
|
|
1091
2479
|
DateControl,
|
|
1092
2480
|
DatetimeMinuteControl,
|
|
@@ -1109,9 +2497,37 @@ let classes = [
|
|
|
1109
2497
|
MultipleAppLookupChoiceControl,
|
|
1110
2498
|
GeoControl,
|
|
1111
2499
|
FileControl,
|
|
2500
|
+
FileSignatureControl,
|
|
1112
2501
|
ButtonControl,
|
|
1113
2502
|
Field,
|
|
2503
|
+
BoolField,
|
|
2504
|
+
StringField,
|
|
2505
|
+
EmailField,
|
|
2506
|
+
URLField,
|
|
2507
|
+
TelField,
|
|
2508
|
+
TextAreaField,
|
|
2509
|
+
HTMLField,
|
|
2510
|
+
IntField,
|
|
2511
|
+
NumberField,
|
|
2512
|
+
GeoField,
|
|
2513
|
+
FileField,
|
|
2514
|
+
FileSignatureField,
|
|
2515
|
+
DateFieldBase,
|
|
2516
|
+
DateField,
|
|
2517
|
+
DatetimeMinuteField,
|
|
2518
|
+
DatetimeSecondField,
|
|
2519
|
+
LookupFieldBase,
|
|
2520
|
+
LookupField,
|
|
2521
|
+
MultipleLookupField,
|
|
2522
|
+
AppLookupFieldBase,
|
|
2523
|
+
AppLookupField,
|
|
2524
|
+
MultipleAppLookupField,
|
|
1114
2525
|
LookupItem,
|
|
2526
|
+
ViewLookupItem,
|
|
2527
|
+
LayoutControl,
|
|
2528
|
+
HTMLLayoutControl,
|
|
2529
|
+
ImageLayoutControl,
|
|
2530
|
+
ViewControl,
|
|
1115
2531
|
User,
|
|
1116
2532
|
File,
|
|
1117
2533
|
Geo,
|