@optionfactory/ful 4.0.15 → 5.0.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/dist/ful.css +1 -1
- package/dist/ful.css.map +1 -1
- package/dist/ful.iife.js +173 -111
- package/dist/ful.iife.js.map +1 -1
- package/dist/ful.iife.min.js +1 -1
- package/dist/ful.iife.min.js.map +1 -1
- package/dist/ful.min.mjs +1 -1
- package/dist/ful.min.mjs.map +1 -1
- package/dist/ful.mjs +174 -111
- package/dist/ful.mjs.map +1 -1
- package/package.json +3 -3
package/dist/ful.iife.js
CHANGED
|
@@ -461,7 +461,7 @@ var ful = (function (exports, ftl) {
|
|
|
461
461
|
*/
|
|
462
462
|
headers(hs) {
|
|
463
463
|
for (const [k, v] of new Headers(hs).entries()) {
|
|
464
|
-
if (v
|
|
464
|
+
if (v == null) {
|
|
465
465
|
this.#headers.delete(k);
|
|
466
466
|
} else {
|
|
467
467
|
this.#headers.set(k, v);
|
|
@@ -476,7 +476,7 @@ var ful = (function (exports, ftl) {
|
|
|
476
476
|
* @returns {HttpRequestBuilder} this builder
|
|
477
477
|
*/
|
|
478
478
|
header(k, v) {
|
|
479
|
-
if (v
|
|
479
|
+
if (v == null) {
|
|
480
480
|
this.#headers.delete(k);
|
|
481
481
|
} else {
|
|
482
482
|
this.#headers.set(k, v);
|
|
@@ -490,7 +490,7 @@ var ful = (function (exports, ftl) {
|
|
|
490
490
|
*/
|
|
491
491
|
params(ps) {
|
|
492
492
|
for (const [k, v] of new URLSearchParams(ps).entries()) {
|
|
493
|
-
if (v
|
|
493
|
+
if (v == null) {
|
|
494
494
|
this.#params.delete(k);
|
|
495
495
|
} else {
|
|
496
496
|
this.#params.set(k, v);
|
|
@@ -505,7 +505,7 @@ var ful = (function (exports, ftl) {
|
|
|
505
505
|
* @returns {HttpRequestBuilder} this builder
|
|
506
506
|
*/
|
|
507
507
|
param(k, ...vs) {
|
|
508
|
-
if (vs.length === 0 || vs[0]
|
|
508
|
+
if (vs.length === 0 || vs[0] == null) {
|
|
509
509
|
this.#params.delete(k);
|
|
510
510
|
return this;
|
|
511
511
|
}
|
|
@@ -1136,22 +1136,6 @@ var ful = (function (exports, ftl) {
|
|
|
1136
1136
|
}
|
|
1137
1137
|
}
|
|
1138
1138
|
|
|
1139
|
-
class Loaders {
|
|
1140
|
-
static fromAttributes(el, defaultLoader, options) {
|
|
1141
|
-
const http = ftl.registry.component("http-client");
|
|
1142
|
-
const requestMapper = el.hasAttribute("request-mapper") ? ftl.registry.component(el.getAttribute("request-mapper")) : v => v;
|
|
1143
|
-
const responseMapper = el.hasAttribute("response-mapper") ? ftl.registry.component(el.getAttribute("response-mapper")) : v => v;
|
|
1144
|
-
const loaderClass = ftl.registry.component(el.getAttribute("loader") ?? defaultLoader);
|
|
1145
|
-
return loaderClass.create({
|
|
1146
|
-
el,
|
|
1147
|
-
http,
|
|
1148
|
-
requestMapper,
|
|
1149
|
-
responseMapper,
|
|
1150
|
-
options: options ?? {}
|
|
1151
|
-
});
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
1139
|
class Bindings {
|
|
1156
1140
|
|
|
1157
1141
|
/**
|
|
@@ -1348,7 +1332,10 @@ var ful = (function (exports, ftl) {
|
|
|
1348
1332
|
}
|
|
1349
1333
|
|
|
1350
1334
|
class FormLoader {
|
|
1351
|
-
static create(
|
|
1335
|
+
static create(el, conf) {
|
|
1336
|
+
const http = ftl.registry.component("http-client");
|
|
1337
|
+
const requestMapper = el.hasAttribute("request-mapper") ? ftl.registry.component(el.getAttribute("request-mapper")) : v => v;
|
|
1338
|
+
const responseMapper = el.hasAttribute("response-mapper") ? ftl.registry.component(el.getAttribute("response-mapper")) : v => v;
|
|
1352
1339
|
const url = el.getAttribute("action");
|
|
1353
1340
|
if (!url) {
|
|
1354
1341
|
return new LocalFormLoader(requestMapper, responseMapper);
|
|
@@ -1380,7 +1367,7 @@ var ful = (function (exports, ftl) {
|
|
|
1380
1367
|
async submit() {
|
|
1381
1368
|
this.spinner(true);
|
|
1382
1369
|
try {
|
|
1383
|
-
const loader =
|
|
1370
|
+
const loader = ftl.registry.component(this.getAttribute("loader") ?? 'loaders:form').create(this);
|
|
1384
1371
|
const values = this.values;
|
|
1385
1372
|
let request = await loader.prepare(values, this);
|
|
1386
1373
|
try {
|
|
@@ -1431,7 +1418,7 @@ var ful = (function (exports, ftl) {
|
|
|
1431
1418
|
}
|
|
1432
1419
|
|
|
1433
1420
|
class Input extends ftl.ParsedElement {
|
|
1434
|
-
static observed = ['value', 'readonly:presence'];
|
|
1421
|
+
static observed = ['value', 'readonly:presence', 'required:presence'];
|
|
1435
1422
|
static slots = true;
|
|
1436
1423
|
static template = `
|
|
1437
1424
|
<div class="form-label">
|
|
@@ -1462,15 +1449,16 @@ var ful = (function (exports, ftl) {
|
|
|
1462
1449
|
_fragment(type, slots) {
|
|
1463
1450
|
return this.template().withOverlay({ type, slots }).render();
|
|
1464
1451
|
}
|
|
1465
|
-
render({ slots, observed, disabled,
|
|
1452
|
+
render({ slots, observed, disabled, skipObservedSetup }) {
|
|
1466
1453
|
const type = this._type();
|
|
1467
1454
|
const fragment = this._fragment(type, slots);
|
|
1468
1455
|
this._input = fragment.querySelector("input,textarea");
|
|
1469
1456
|
|
|
1470
1457
|
ftl.Attributes.forward('input-', this, this._input);
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1458
|
+
if (!skipObservedSetup) {
|
|
1459
|
+
this.disabled = disabled;
|
|
1460
|
+
this.readonly = observed.readonly;
|
|
1461
|
+
this.required = observed.required;
|
|
1474
1462
|
this.value = observed.value;
|
|
1475
1463
|
}
|
|
1476
1464
|
|
|
@@ -1513,6 +1501,15 @@ var ful = (function (exports, ftl) {
|
|
|
1513
1501
|
set disabled(d) {
|
|
1514
1502
|
ftl.Attributes.toggle(this._input, 'disabled', d);
|
|
1515
1503
|
}
|
|
1504
|
+
get required() {
|
|
1505
|
+
return this._input.getAttribute('aria-required') === 'true';
|
|
1506
|
+
}
|
|
1507
|
+
set required(d) {
|
|
1508
|
+
ftl.Attributes.set(this._input, "aria-required", d ? "true" : null);
|
|
1509
|
+
this.reflect(() => {
|
|
1510
|
+
ftl.Attributes.toggle(this, 'required', d);
|
|
1511
|
+
});
|
|
1512
|
+
}
|
|
1516
1513
|
focus(options) {
|
|
1517
1514
|
this._input.focus(options);
|
|
1518
1515
|
}
|
|
@@ -1526,7 +1523,7 @@ var ful = (function (exports, ftl) {
|
|
|
1526
1523
|
this._fieldError.innerText = error;
|
|
1527
1524
|
}
|
|
1528
1525
|
formResetCallback() {
|
|
1529
|
-
this.value = this.getAttribute("value");
|
|
1526
|
+
this.value = this.unmarshal('value', this.getAttribute("value"));
|
|
1530
1527
|
}
|
|
1531
1528
|
}
|
|
1532
1529
|
|
|
@@ -1570,22 +1567,22 @@ var ful = (function (exports, ftl) {
|
|
|
1570
1567
|
const date = `${d.getFullYear()}-${pad(2, d.getMonth() + 1)}-${pad(2, d.getDate())}`;
|
|
1571
1568
|
const time = `${pad(2, d.getHours())}:${pad(2, d.getMinutes())}:${pad(2, d.getSeconds())}.${pad(3, d.getMilliseconds())}`;
|
|
1572
1569
|
return `${date}T${time}`
|
|
1573
|
-
}
|
|
1570
|
+
}
|
|
1574
1571
|
}
|
|
1575
1572
|
|
|
1576
1573
|
|
|
1577
1574
|
class InputLocalDate extends Input {
|
|
1578
|
-
static observed = ['value', 'readonly:presence', 'min', 'max', 'step'];
|
|
1575
|
+
static observed = ['value', 'readonly:presence', 'required:presence', 'min', 'max', 'step'];
|
|
1579
1576
|
_type() {
|
|
1580
1577
|
return 'date';
|
|
1581
1578
|
}
|
|
1582
|
-
render(conf){
|
|
1583
|
-
const {observed} = conf;
|
|
1579
|
+
render(conf) {
|
|
1580
|
+
const { observed } = conf;
|
|
1584
1581
|
super.render(conf);
|
|
1585
1582
|
this.min = observed.min;
|
|
1586
1583
|
this.max = observed.max;
|
|
1587
1584
|
this.step = observed.step;
|
|
1588
|
-
}
|
|
1585
|
+
}
|
|
1589
1586
|
get min() {
|
|
1590
1587
|
const v = this._input.min;
|
|
1591
1588
|
return v === '' ? null : v;
|
|
@@ -1645,12 +1642,12 @@ var ful = (function (exports, ftl) {
|
|
|
1645
1642
|
|
|
1646
1643
|
|
|
1647
1644
|
class InputInstant extends Input {
|
|
1648
|
-
static observed = ['value', 'readonly:presence', 'min', 'max', 'step'];
|
|
1645
|
+
static observed = ['value', 'readonly:presence', 'required:presence', 'min', 'max', 'step'];
|
|
1649
1646
|
_type() {
|
|
1650
1647
|
return 'datetime-local';
|
|
1651
1648
|
}
|
|
1652
|
-
render(conf){
|
|
1653
|
-
const {observed} = conf;
|
|
1649
|
+
render(conf) {
|
|
1650
|
+
const { observed } = conf;
|
|
1654
1651
|
super.render(conf);
|
|
1655
1652
|
this.min = observed.min;
|
|
1656
1653
|
this.max = observed.min;
|
|
@@ -1701,7 +1698,7 @@ var ful = (function (exports, ftl) {
|
|
|
1701
1698
|
'maxtotalsizeexceeded': "La dimensione massima complessiva dei file è di {0}"
|
|
1702
1699
|
}
|
|
1703
1700
|
}
|
|
1704
|
-
static observed = ['value', 'readonly:presence', "accept:csv", 'multiple:presence', "itemlist:presence", "dropzone:presence", "maxfilesize:number", "maxtotalsize:number"];
|
|
1701
|
+
static observed = ['value', 'readonly:presence', 'required:presence', "accept:csv", 'multiple:presence', "itemlist:presence", "dropzone:presence", "maxfilesize:number", "maxtotalsize:number"];
|
|
1705
1702
|
#accept;
|
|
1706
1703
|
#items;
|
|
1707
1704
|
#dropzone;
|
|
@@ -1927,17 +1924,7 @@ var ful = (function (exports, ftl) {
|
|
|
1927
1924
|
#prefetch;
|
|
1928
1925
|
#revision;
|
|
1929
1926
|
#data;
|
|
1930
|
-
|
|
1931
|
-
return new RemoteLoader({
|
|
1932
|
-
http,
|
|
1933
|
-
url: el.getAttribute("src"),
|
|
1934
|
-
method: el.getAttribute("method") ?? 'POST',
|
|
1935
|
-
responseMapper,
|
|
1936
|
-
prefetch: el.hasAttribute("preload"),
|
|
1937
|
-
revision: el.getAttribute("revision")
|
|
1938
|
-
});
|
|
1939
|
-
}
|
|
1940
|
-
constructor({http, url, method, responseMapper, prefetch, revision}) {
|
|
1927
|
+
constructor({ http, url, method, responseMapper, prefetch, revision }) {
|
|
1941
1928
|
this.#http = http;
|
|
1942
1929
|
this.#url = url;
|
|
1943
1930
|
this.#method = method;
|
|
@@ -1960,7 +1947,7 @@ var ful = (function (exports, ftl) {
|
|
|
1960
1947
|
await this.#ensureFetched();
|
|
1961
1948
|
return this.#data.filter(([k, v]) => (v ?? '').toLowerCase().includes(needle?.toLowerCase()));
|
|
1962
1949
|
}
|
|
1963
|
-
async reconfigureUrl(url){
|
|
1950
|
+
async reconfigureUrl(url) {
|
|
1964
1951
|
this.#data = null;
|
|
1965
1952
|
this.#url = url;
|
|
1966
1953
|
}
|
|
@@ -1969,9 +1956,9 @@ var ful = (function (exports, ftl) {
|
|
|
1969
1956
|
return
|
|
1970
1957
|
}
|
|
1971
1958
|
const storageKey = `${this.#method}@${this.#url}`;
|
|
1972
|
-
if(this.#revision !== null){
|
|
1959
|
+
if (this.#revision !== null) {
|
|
1973
1960
|
const data = VersionedLocalStorage.load(storageKey, this.#revision);
|
|
1974
|
-
if(data !== undefined){
|
|
1961
|
+
if (data !== undefined) {
|
|
1975
1962
|
this.#data = data;
|
|
1976
1963
|
return;
|
|
1977
1964
|
}
|
|
@@ -1979,7 +1966,7 @@ var ful = (function (exports, ftl) {
|
|
|
1979
1966
|
const data = await this.#http.request(this.#method, this.#url)
|
|
1980
1967
|
.fetchJson();
|
|
1981
1968
|
this.#data = this.#responseMapper(data);
|
|
1982
|
-
if(this.#revision !== null){
|
|
1969
|
+
if (this.#revision !== null) {
|
|
1983
1970
|
VersionedLocalStorage.save(storageKey, this.#revision, this.#data);
|
|
1984
1971
|
}
|
|
1985
1972
|
}
|
|
@@ -1990,15 +1977,7 @@ var ful = (function (exports, ftl) {
|
|
|
1990
1977
|
#url;
|
|
1991
1978
|
#method;
|
|
1992
1979
|
#responseMapper;
|
|
1993
|
-
|
|
1994
|
-
return new PartialRemoteLoader({
|
|
1995
|
-
http,
|
|
1996
|
-
url: el.getAttribute("src"),
|
|
1997
|
-
method: el.getAttribute("method") ?? 'POST',
|
|
1998
|
-
responseMapper
|
|
1999
|
-
});
|
|
2000
|
-
}
|
|
2001
|
-
constructor({http, url, method, responseMapper}) {
|
|
1980
|
+
constructor({ http, url, method, responseMapper }) {
|
|
2002
1981
|
this.#http = http;
|
|
2003
1982
|
this.#url = url;
|
|
2004
1983
|
this.#method = method;
|
|
@@ -2036,16 +2015,49 @@ var ful = (function (exports, ftl) {
|
|
|
2036
2015
|
|
|
2037
2016
|
|
|
2038
2017
|
class SelectLoader {
|
|
2039
|
-
static create(conf) {
|
|
2040
|
-
if (!
|
|
2041
|
-
const els = Array.from(conf.options
|
|
2018
|
+
static create(el, conf) {
|
|
2019
|
+
if (!el.hasAttribute("src")) {
|
|
2020
|
+
const els = Array.from(conf.options?.querySelectorAll('option') ?? []);
|
|
2042
2021
|
const data = els.map(e => {
|
|
2043
2022
|
return [e.getAttribute("value") ?? e.innerText.trim(), e.innerText.trim()];
|
|
2044
2023
|
});
|
|
2045
2024
|
return new InMemoryLoader(data);
|
|
2046
2025
|
}
|
|
2047
|
-
const
|
|
2048
|
-
|
|
2026
|
+
const http = ftl.registry.component("http-client");
|
|
2027
|
+
const responseMapper = SelectLoader.#responseMapperFrom(el);
|
|
2028
|
+
|
|
2029
|
+
if ("chunked" == el.getAttribute("mode")) {
|
|
2030
|
+
return new PartialRemoteLoader({
|
|
2031
|
+
http,
|
|
2032
|
+
url: el.getAttribute("src"),
|
|
2033
|
+
method: el.getAttribute("method") ?? 'POST',
|
|
2034
|
+
responseMapper
|
|
2035
|
+
})
|
|
2036
|
+
}
|
|
2037
|
+
return new RemoteLoader({
|
|
2038
|
+
http,
|
|
2039
|
+
url: el.getAttribute("src"),
|
|
2040
|
+
method: el.getAttribute("method") ?? 'POST',
|
|
2041
|
+
responseMapper,
|
|
2042
|
+
prefetch: el.hasAttribute("preload"),
|
|
2043
|
+
revision: el.getAttribute("revision")
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
2046
|
+
static #responseMapperFrom(el) {
|
|
2047
|
+
if (el.hasAttribute("k-expr") && el.hasAttribute("l-expr")) {
|
|
2048
|
+
return v => {
|
|
2049
|
+
const evaluator = ftl.registry.evaluator().withOverlay(v);
|
|
2050
|
+
return [
|
|
2051
|
+
evaluator.evaluateExpression(el.getAttribute("k-expr")),
|
|
2052
|
+
evaluator.evaluateExpression(el.getAttribute("l-expr")),
|
|
2053
|
+
evaluator.evaluateExpression(el.getAttribute("m-expr") ?? 'self'),
|
|
2054
|
+
];
|
|
2055
|
+
};
|
|
2056
|
+
}
|
|
2057
|
+
if (el.hasAttribute("response-mapper")) {
|
|
2058
|
+
return ftl.registry.component(el.getAttribute("response-mapper"));
|
|
2059
|
+
}
|
|
2060
|
+
return v => v;
|
|
2049
2061
|
}
|
|
2050
2062
|
}
|
|
2051
2063
|
|
|
@@ -2080,7 +2092,7 @@ var ful = (function (exports, ftl) {
|
|
|
2080
2092
|
if (values === undefined) {
|
|
2081
2093
|
throw new Error("null data");
|
|
2082
2094
|
}
|
|
2083
|
-
this.#options = new Map(values.map((v,i) => [String(i), v]));
|
|
2095
|
+
this.#options = new Map(values.map((v, i) => [String(i), v]));
|
|
2084
2096
|
if (values.length === 0) {
|
|
2085
2097
|
const el = document.createElement('div');
|
|
2086
2098
|
el.classList.add('text-center', 'py-2', 'bi', 'bi-database-slash');
|
|
@@ -2132,7 +2144,7 @@ var ful = (function (exports, ftl) {
|
|
|
2132
2144
|
if (candidate) {
|
|
2133
2145
|
selected.removeAttribute('selected');
|
|
2134
2146
|
candidate.setAttribute("selected", "");
|
|
2135
|
-
candidate.scrollIntoView({block: "nearest", behavior: "smooth"});
|
|
2147
|
+
candidate.scrollIntoView({ block: "nearest", behavior: "smooth" });
|
|
2136
2148
|
}
|
|
2137
2149
|
return;
|
|
2138
2150
|
}
|
|
@@ -2141,7 +2153,7 @@ var ful = (function (exports, ftl) {
|
|
|
2141
2153
|
}
|
|
2142
2154
|
|
|
2143
2155
|
class Select extends ftl.ParsedElement {
|
|
2144
|
-
static observed = ['value:csvm', 'readonly:presence', 'itemlist:presence']
|
|
2156
|
+
static observed = ['value:csvm', 'readonly:presence', "required:presence", 'itemlist:presence']
|
|
2145
2157
|
static slots = true
|
|
2146
2158
|
static template = `
|
|
2147
2159
|
<div class="form-label">
|
|
@@ -2171,15 +2183,7 @@ var ful = (function (exports, ftl) {
|
|
|
2171
2183
|
<button type="button" class="btn btn-sm btn-outline-danger bi bi-x-lg"></button>
|
|
2172
2184
|
</ful-item>
|
|
2173
2185
|
`
|
|
2174
|
-
}
|
|
2175
|
-
static mappers = {
|
|
2176
|
-
"csvm": (v, name, el) => {
|
|
2177
|
-
if (el.hasAttribute("multiple")) {
|
|
2178
|
-
return v === null ? [] : v.split(",").map(e => e.trim()).filter(e => e)
|
|
2179
|
-
}
|
|
2180
|
-
return v === null || v === '' ? null : v
|
|
2181
|
-
}
|
|
2182
|
-
};
|
|
2186
|
+
}
|
|
2183
2187
|
static formAssociated = true
|
|
2184
2188
|
internals
|
|
2185
2189
|
#loader
|
|
@@ -2197,7 +2201,8 @@ var ful = (function (exports, ftl) {
|
|
|
2197
2201
|
}
|
|
2198
2202
|
async render({ slots, observed, disabled }) {
|
|
2199
2203
|
const name = this.getAttribute("name");
|
|
2200
|
-
this.#loader =
|
|
2204
|
+
this.#loader = ftl.registry.component(this.getAttribute("loader") ?? 'loaders:select').create(this, {options: slots.options});
|
|
2205
|
+
|
|
2201
2206
|
this.#multiple = this.hasAttribute("multiple");
|
|
2202
2207
|
await this.#loader.prefetch?.();
|
|
2203
2208
|
const fragment = this.template().withOverlay({ slots, name }).render();
|
|
@@ -2209,6 +2214,7 @@ var ful = (function (exports, ftl) {
|
|
|
2209
2214
|
this.value = observed.value;
|
|
2210
2215
|
this.disabled = disabled;
|
|
2211
2216
|
this.readonly = observed.readonly;
|
|
2217
|
+
this.required = observed.required;
|
|
2212
2218
|
this.itemlist = observed.itemlist;
|
|
2213
2219
|
|
|
2214
2220
|
this.#ddmenu = fragment.querySelector('ful-dropdown');
|
|
@@ -2224,7 +2230,7 @@ var ful = (function (exports, ftl) {
|
|
|
2224
2230
|
if (e.target.matches('input')) {
|
|
2225
2231
|
return;
|
|
2226
2232
|
}
|
|
2227
|
-
if(this.disabled || this.readonly){
|
|
2233
|
+
if (this.disabled || this.readonly) {
|
|
2228
2234
|
return;
|
|
2229
2235
|
}
|
|
2230
2236
|
if (this.#ddmenu.shown) {
|
|
@@ -2239,9 +2245,9 @@ var ful = (function (exports, ftl) {
|
|
|
2239
2245
|
if (!e.target.closest("button")) {
|
|
2240
2246
|
return;
|
|
2241
2247
|
}
|
|
2242
|
-
if(this.disabled || this.readonly){
|
|
2248
|
+
if (this.disabled || this.readonly) {
|
|
2243
2249
|
return;
|
|
2244
|
-
}
|
|
2250
|
+
}
|
|
2245
2251
|
const idx = [...this.#items.children].indexOf(e.target.closest('ful-item'));
|
|
2246
2252
|
if (idx === -1) {
|
|
2247
2253
|
return;
|
|
@@ -2252,7 +2258,7 @@ var ful = (function (exports, ftl) {
|
|
|
2252
2258
|
});
|
|
2253
2259
|
this.#badges.addEventListener('click', (e) => {
|
|
2254
2260
|
e.stopPropagation();
|
|
2255
|
-
if(this.disabled || this.readonly){
|
|
2261
|
+
if (this.disabled || this.readonly) {
|
|
2256
2262
|
return;
|
|
2257
2263
|
}
|
|
2258
2264
|
const idx = [...this.#badges.children].indexOf(e.target);
|
|
@@ -2277,7 +2283,7 @@ var ful = (function (exports, ftl) {
|
|
|
2277
2283
|
});
|
|
2278
2284
|
this.#input.addEventListener('keydown', e => {
|
|
2279
2285
|
e.stopPropagation();
|
|
2280
|
-
if(this.disabled || this.readonly){
|
|
2286
|
+
if (this.disabled || this.readonly) {
|
|
2281
2287
|
return;
|
|
2282
2288
|
}
|
|
2283
2289
|
switch (e.code) {
|
|
@@ -2316,7 +2322,7 @@ var ful = (function (exports, ftl) {
|
|
|
2316
2322
|
});
|
|
2317
2323
|
this.#input.addEventListener('input', e => {
|
|
2318
2324
|
e.stopPropagation();
|
|
2319
|
-
if(this.disabled || this.readonly){
|
|
2325
|
+
if (this.disabled || this.readonly) {
|
|
2320
2326
|
return;
|
|
2321
2327
|
}
|
|
2322
2328
|
dload();
|
|
@@ -2339,7 +2345,7 @@ var ful = (function (exports, ftl) {
|
|
|
2339
2345
|
await fn(this.#loader);
|
|
2340
2346
|
}
|
|
2341
2347
|
#changed() {
|
|
2342
|
-
const selection = [...this.#values.entries()].map(e => ({key: e[0], label: e[1][0], metadata: e[1].slice(1)}));
|
|
2348
|
+
const selection = [...this.#values.entries()].map(e => ({ key: e[0], label: e[1][0], metadata: e[1].slice(1) }));
|
|
2343
2349
|
const value = this.#multiple ? selection : (selection[0] ?? null);
|
|
2344
2350
|
this.dispatchEvent(new CustomEvent('change', {
|
|
2345
2351
|
bubbles: true,
|
|
@@ -2361,10 +2367,10 @@ var ful = (function (exports, ftl) {
|
|
|
2361
2367
|
this.template('items').withOverlay({ entries: this.#values.entries() }).renderTo(this.#items);
|
|
2362
2368
|
}
|
|
2363
2369
|
set value(vs) {
|
|
2364
|
-
if(vs === null){
|
|
2370
|
+
if (vs === null) {
|
|
2365
2371
|
this.#values = new Map();
|
|
2366
2372
|
this.#syncBadges();
|
|
2367
|
-
return;
|
|
2373
|
+
return;
|
|
2368
2374
|
}
|
|
2369
2375
|
(async () => {
|
|
2370
2376
|
const entries = await (this.#multiple ? this.#loader.exact(...vs) : this.#loader.exact(vs));
|
|
@@ -2385,14 +2391,14 @@ var ful = (function (exports, ftl) {
|
|
|
2385
2391
|
return [...this.#values.entries()][0] ?? null;
|
|
2386
2392
|
}
|
|
2387
2393
|
//@ts-ignore
|
|
2388
|
-
get disabled(){
|
|
2394
|
+
get disabled() {
|
|
2389
2395
|
return this.#input.hasAttribute('disabled');
|
|
2390
2396
|
}
|
|
2391
|
-
set disabled(d){
|
|
2397
|
+
set disabled(d) {
|
|
2392
2398
|
ftl.Attributes.toggle(this.#input, 'disabled', d);
|
|
2393
|
-
}
|
|
2394
|
-
get readonly(){
|
|
2395
|
-
return this.#input.readOnly;
|
|
2399
|
+
}
|
|
2400
|
+
get readonly() {
|
|
2401
|
+
return this.#input.readOnly;
|
|
2396
2402
|
}
|
|
2397
2403
|
set readonly(v) {
|
|
2398
2404
|
this.#input.readOnly = v;
|
|
@@ -2400,6 +2406,15 @@ var ful = (function (exports, ftl) {
|
|
|
2400
2406
|
ftl.Attributes.toggle(this, 'readonly', v);
|
|
2401
2407
|
});
|
|
2402
2408
|
}
|
|
2409
|
+
get required() {
|
|
2410
|
+
return this.#input.getAttribute('aria-required') === 'true';
|
|
2411
|
+
}
|
|
2412
|
+
set required(d) {
|
|
2413
|
+
ftl.Attributes.set(this.#input, "aria-required", d ? "true" : null);
|
|
2414
|
+
this.reflect(() => {
|
|
2415
|
+
ftl.Attributes.toggle(this, 'required', d);
|
|
2416
|
+
});
|
|
2417
|
+
}
|
|
2403
2418
|
#useItemlist;
|
|
2404
2419
|
get itemlist() {
|
|
2405
2420
|
return this.#useItemlist;
|
|
@@ -2425,7 +2440,7 @@ var ful = (function (exports, ftl) {
|
|
|
2425
2440
|
}
|
|
2426
2441
|
|
|
2427
2442
|
class RadioGroup extends ftl.ParsedElement {
|
|
2428
|
-
static observed = ['value', 'readonly:presence'];
|
|
2443
|
+
static observed = ['value', 'readonly:presence', "required:presence"];
|
|
2429
2444
|
static slots = true;
|
|
2430
2445
|
static template = `
|
|
2431
2446
|
<fieldset>
|
|
@@ -2489,6 +2504,7 @@ var ful = (function (exports, ftl) {
|
|
|
2489
2504
|
this.#fieldset = this.firstElementChild;
|
|
2490
2505
|
this.disabled = disabled;
|
|
2491
2506
|
this.readonly = observed.readonly;
|
|
2507
|
+
this.required = observed.required;
|
|
2492
2508
|
this.value = observed.value;
|
|
2493
2509
|
this.#fieldError = this.querySelector('ful-field-error');
|
|
2494
2510
|
this.ariaDescribedByElements = [this.#fieldError];
|
|
@@ -2529,6 +2545,15 @@ var ful = (function (exports, ftl) {
|
|
|
2529
2545
|
set disabled(d){
|
|
2530
2546
|
ftl.Attributes.toggle(this.#fieldset, 'disabled', d);
|
|
2531
2547
|
}
|
|
2548
|
+
get required() {
|
|
2549
|
+
return this.#fieldset.getAttribute('aria-required') === 'true';
|
|
2550
|
+
}
|
|
2551
|
+
set required(d) {
|
|
2552
|
+
ftl.Attributes.set(this.#fieldset, "aria-required", d ? "true" : null);
|
|
2553
|
+
this.reflect(() => {
|
|
2554
|
+
ftl.Attributes.toggle(this, 'required', d);
|
|
2555
|
+
});
|
|
2556
|
+
}
|
|
2532
2557
|
focus(options) {
|
|
2533
2558
|
this.#firstRadio.focus(options);
|
|
2534
2559
|
}
|
|
@@ -2544,7 +2569,7 @@ var ful = (function (exports, ftl) {
|
|
|
2544
2569
|
}
|
|
2545
2570
|
|
|
2546
2571
|
class Checkbox extends ftl.ParsedElement {
|
|
2547
|
-
static observed = ['value:bool', 'readonly:presence'];
|
|
2572
|
+
static observed = ['value:bool', 'readonly:presence', "required:presence"];
|
|
2548
2573
|
static slots = true;
|
|
2549
2574
|
static template = `
|
|
2550
2575
|
<div data-tpl-class="klass">
|
|
@@ -2575,6 +2600,7 @@ var ful = (function (exports, ftl) {
|
|
|
2575
2600
|
ftl.Attributes.forward('input-', this, this.#input);
|
|
2576
2601
|
this.disabled = disabled;
|
|
2577
2602
|
this.readonly = observed.readonly;
|
|
2603
|
+
this.required = observed.required;
|
|
2578
2604
|
this.value = observed.value;
|
|
2579
2605
|
this.#input.addEventListener('change', (evt) => {
|
|
2580
2606
|
evt.stopPropagation();
|
|
@@ -2621,6 +2647,15 @@ var ful = (function (exports, ftl) {
|
|
|
2621
2647
|
set disabled(d) {
|
|
2622
2648
|
ftl.Attributes.toggle(this.#input, 'disabled', d);
|
|
2623
2649
|
}
|
|
2650
|
+
get required() {
|
|
2651
|
+
return this.#input.getAttribute('aria-required') === 'true';
|
|
2652
|
+
}
|
|
2653
|
+
set required(d) {
|
|
2654
|
+
ftl.Attributes.set(this.#input, "aria-required", d ? "true" : null);
|
|
2655
|
+
this.reflect(() => {
|
|
2656
|
+
ftl.Attributes.toggle(this, 'required', d);
|
|
2657
|
+
});
|
|
2658
|
+
}
|
|
2624
2659
|
focus(options) {
|
|
2625
2660
|
this.#input.focus(options);
|
|
2626
2661
|
}
|
|
@@ -2868,7 +2903,8 @@ var ful = (function (exports, ftl) {
|
|
|
2868
2903
|
|
|
2869
2904
|
|
|
2870
2905
|
class TableLoader {
|
|
2871
|
-
static create(
|
|
2906
|
+
static create(el, conf) {
|
|
2907
|
+
const http = ftl.registry.component("http-client");
|
|
2872
2908
|
const url = el.getAttribute("src");
|
|
2873
2909
|
const method = el.getAttribute("method") ?? 'GET';
|
|
2874
2910
|
return new RemoteTableLoader(http, url, method);
|
|
@@ -2993,7 +3029,8 @@ var ful = (function (exports, ftl) {
|
|
|
2993
3029
|
}, this.#latestRequest.sortRequest, this.#latestRequest.filterRequest);
|
|
2994
3030
|
});
|
|
2995
3031
|
this.addEventListener('sort-requested', async (/** @type any */e) => {
|
|
2996
|
-
|
|
3032
|
+
const sortRequest = e.detail.value.order ? e.detail.value : null;
|
|
3033
|
+
await this.load(this.#latestRequest.pageRequest, sortRequest, this.#latestRequest.filterRequest);
|
|
2997
3034
|
this.#sorters.forEach(s => s.order = null);
|
|
2998
3035
|
e.target.order = e.detail.value.order;
|
|
2999
3036
|
});
|
|
@@ -3011,7 +3048,7 @@ var ful = (function (exports, ftl) {
|
|
|
3011
3048
|
this.#feedback.setAttribute("hidden", "");
|
|
3012
3049
|
this.#noAutoload.setAttribute("hidden", "");
|
|
3013
3050
|
try {
|
|
3014
|
-
const loader =
|
|
3051
|
+
const loader = ftl.registry.component(this.getAttribute("loader") ?? 'loaders:table').create(this);
|
|
3015
3052
|
const pageResponse = await loader.load(pageRequest, sortRequest, filterRequest);
|
|
3016
3053
|
this.#latestRequest = { pageRequest, sortRequest, filterRequest };
|
|
3017
3054
|
this.#update(pageRequest, sortRequest, filterRequest, pageResponse);
|
|
@@ -3048,7 +3085,7 @@ var ful = (function (exports, ftl) {
|
|
|
3048
3085
|
}
|
|
3049
3086
|
|
|
3050
3087
|
class InstantFilter extends Input {
|
|
3051
|
-
static observed = ['value:json', 'readonly:presence'];
|
|
3088
|
+
static observed = ['value:json', 'readonly:presence', 'required:presence'];
|
|
3052
3089
|
static template = `
|
|
3053
3090
|
<div class="form-label">
|
|
3054
3091
|
<label>{{{{ slots.default }}}}</label>
|
|
@@ -3078,10 +3115,14 @@ var ful = (function (exports, ftl) {
|
|
|
3078
3115
|
#value1;
|
|
3079
3116
|
#value2;
|
|
3080
3117
|
render(conf) {
|
|
3081
|
-
super.render({...conf,
|
|
3118
|
+
super.render({ ...conf, skipObservedSetup: true });
|
|
3082
3119
|
this.#operator = this.querySelector('[data-ref=operator]');
|
|
3083
3120
|
this.#value1 = this.querySelector('[data-ref=value1]');
|
|
3084
3121
|
this.#value2 = this.querySelector('[data-ref=value2]');
|
|
3122
|
+
|
|
3123
|
+
this.disabled = conf.disabled;
|
|
3124
|
+
this.readonly = conf.observed.readonly;
|
|
3125
|
+
this.required = conf.observed.required;
|
|
3085
3126
|
this.value = conf.observed.value;
|
|
3086
3127
|
|
|
3087
3128
|
this.addEventListener('click', (evt) => {
|
|
@@ -3103,7 +3144,7 @@ var ful = (function (exports, ftl) {
|
|
|
3103
3144
|
return values.some(v => v === '') ? undefined : [operator, ...values.map(v => new Date(v).toISOString())];
|
|
3104
3145
|
}
|
|
3105
3146
|
set value(v) {
|
|
3106
|
-
if (v
|
|
3147
|
+
if (v == null) {
|
|
3107
3148
|
this.#value1.value = '';
|
|
3108
3149
|
this.#value2.value = '';
|
|
3109
3150
|
return;
|
|
@@ -3113,10 +3154,18 @@ var ful = (function (exports, ftl) {
|
|
|
3113
3154
|
this.#value1.value = values[0] ? Instant.isoToLocal(values[0]) : values[0];
|
|
3114
3155
|
this.#value2.value = values[1] ? Instant.isoToLocal(values[1]) : values[1];
|
|
3115
3156
|
}
|
|
3157
|
+
set readonly(v) {
|
|
3158
|
+
this.#value2.readOnly = v;
|
|
3159
|
+
super.readonly = v;
|
|
3160
|
+
}
|
|
3161
|
+
set disabled(d) {
|
|
3162
|
+
ftl.Attributes.toggle(this.#value2, 'disabled', d);
|
|
3163
|
+
super.disabled = d;
|
|
3164
|
+
}
|
|
3116
3165
|
}
|
|
3117
3166
|
|
|
3118
3167
|
class LocalDateFilter extends Input {
|
|
3119
|
-
static observed = ["value:json", 'readonly:presence'];
|
|
3168
|
+
static observed = ["value:json", 'readonly:presence', 'required:presence'];
|
|
3120
3169
|
static template = `
|
|
3121
3170
|
<div class="form-label">
|
|
3122
3171
|
<label>{{{{ slots.default }}}}</label>
|
|
@@ -3146,13 +3195,17 @@ var ful = (function (exports, ftl) {
|
|
|
3146
3195
|
#value1;
|
|
3147
3196
|
#value2;
|
|
3148
3197
|
render(conf) {
|
|
3149
|
-
super.render({...conf,
|
|
3198
|
+
super.render({ ...conf, skipObservedSetup: true });
|
|
3150
3199
|
|
|
3151
3200
|
this.#operator = this.querySelector('[data-ref=operator]');
|
|
3152
3201
|
this.#value1 = this.querySelector('[data-ref=value1]');
|
|
3153
3202
|
this.#value2 = this.querySelector('[data-ref=value2]');
|
|
3203
|
+
|
|
3204
|
+
this.disabled = conf.disabled;
|
|
3205
|
+
this.readonly = conf.observed.readonly;
|
|
3206
|
+
this.required = conf.observed.required;
|
|
3154
3207
|
this.value = conf.observed.value;
|
|
3155
|
-
|
|
3208
|
+
|
|
3156
3209
|
this.addEventListener('click', (evt) => {
|
|
3157
3210
|
const target = /** @type HTMLElement */(evt.target);
|
|
3158
3211
|
if (!target.matches('ul > li > a')) {
|
|
@@ -3171,7 +3224,7 @@ var ful = (function (exports, ftl) {
|
|
|
3171
3224
|
return values.some(v => v === '') ? undefined : [operator, ...values];
|
|
3172
3225
|
}
|
|
3173
3226
|
set value(v) {
|
|
3174
|
-
if (v
|
|
3227
|
+
if (v == null) {
|
|
3175
3228
|
this.#value1.value = '';
|
|
3176
3229
|
this.#value2.value = '';
|
|
3177
3230
|
return;
|
|
@@ -3181,10 +3234,18 @@ var ful = (function (exports, ftl) {
|
|
|
3181
3234
|
this.#value1.value = values[0];
|
|
3182
3235
|
this.#value2.value = values[1];
|
|
3183
3236
|
}
|
|
3237
|
+
set readonly(v) {
|
|
3238
|
+
this.#value2.readOnly = v;
|
|
3239
|
+
super.readonly = v;
|
|
3240
|
+
}
|
|
3241
|
+
set disabled(d) {
|
|
3242
|
+
ftl.Attributes.toggle(this.#value2, 'disabled', d);
|
|
3243
|
+
super.disabled = d;
|
|
3244
|
+
}
|
|
3184
3245
|
}
|
|
3185
3246
|
|
|
3186
3247
|
class TextFilter extends Input {
|
|
3187
|
-
static observed = ["value:json", 'readonly:presence'];
|
|
3248
|
+
static observed = ["value:json", 'readonly:presence', 'required:presence'];
|
|
3188
3249
|
static template = `
|
|
3189
3250
|
<div class="form-label">
|
|
3190
3251
|
<label>{{{{ slots.default }}}}</label>
|
|
@@ -3209,10 +3270,14 @@ var ful = (function (exports, ftl) {
|
|
|
3209
3270
|
#operator;
|
|
3210
3271
|
#value;
|
|
3211
3272
|
render(conf) {
|
|
3212
|
-
super.render({...conf,
|
|
3273
|
+
super.render({ ...conf, skipObservedSetup: true });
|
|
3213
3274
|
|
|
3214
3275
|
this.#operator = this.querySelector('[data-ref=operator]');
|
|
3215
3276
|
this.#value = this.querySelector('[data-ref=value]');
|
|
3277
|
+
|
|
3278
|
+
this.disabled = conf.disabled;
|
|
3279
|
+
this.readonly = conf.observed.readonly;
|
|
3280
|
+
this.required = conf.observed.required;
|
|
3216
3281
|
this.value = conf.observed.value;
|
|
3217
3282
|
|
|
3218
3283
|
this.addEventListener('click', (evt) => {
|
|
@@ -3226,14 +3291,12 @@ var ful = (function (exports, ftl) {
|
|
|
3226
3291
|
btn.innerHTML = target.innerHTML;
|
|
3227
3292
|
});
|
|
3228
3293
|
}
|
|
3229
|
-
|
|
3230
3294
|
get value() {
|
|
3231
3295
|
const operator = this.#operator.getAttribute('value');
|
|
3232
3296
|
return this.#value.value === '' ? undefined : [operator, 'IGNORE_CASE', this.#value.value];
|
|
3233
3297
|
}
|
|
3234
|
-
|
|
3235
3298
|
set value(v) {
|
|
3236
|
-
if (v
|
|
3299
|
+
if (v == null) {
|
|
3237
3300
|
this.#value.value = '';
|
|
3238
3301
|
return;
|
|
3239
3302
|
}
|
|
@@ -3318,7 +3381,6 @@ var ful = (function (exports, ftl) {
|
|
|
3318
3381
|
exports.InputLocalTime = InputLocalTime;
|
|
3319
3382
|
exports.Instant = Instant;
|
|
3320
3383
|
exports.InstantFilter = InstantFilter;
|
|
3321
|
-
exports.Loaders = Loaders;
|
|
3322
3384
|
exports.LocalDate = LocalDate;
|
|
3323
3385
|
exports.LocalDateFilter = LocalDateFilter;
|
|
3324
3386
|
exports.LocalStorage = LocalStorage;
|