tsgrid-ui 2.7.1 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +217 -0
- package/dist/base.d.ts +148 -0
- package/dist/base.es6.js +11 -0
- package/dist/base.es6.js.map +1 -0
- package/dist/chunks/chunk-3NYH6545.js +2423 -0
- package/dist/chunks/chunk-3NYH6545.js.map +1 -0
- package/dist/chunks/chunk-6MOFFUV2.js +2305 -0
- package/dist/chunks/chunk-6MOFFUV2.js.map +1 -0
- package/dist/chunks/chunk-6UCGFWIQ.js +865 -0
- package/dist/chunks/chunk-6UCGFWIQ.js.map +1 -0
- package/dist/chunks/chunk-DXZJHS4M.js +1283 -0
- package/dist/chunks/chunk-DXZJHS4M.js.map +1 -0
- package/dist/chunks/chunk-DZSFZLV6.js +1638 -0
- package/dist/chunks/chunk-DZSFZLV6.js.map +1 -0
- package/dist/chunks/chunk-EQK6JAHT.js +33 -0
- package/dist/chunks/chunk-EQK6JAHT.js.map +1 -0
- package/dist/chunks/chunk-FAIRNXQR.js +3020 -0
- package/dist/chunks/chunk-FAIRNXQR.js.map +1 -0
- package/dist/chunks/chunk-GZFWK4LZ.js +677 -0
- package/dist/chunks/chunk-GZFWK4LZ.js.map +1 -0
- package/dist/chunks/chunk-IYF3Q7GX.js +127 -0
- package/dist/chunks/chunk-IYF3Q7GX.js.map +1 -0
- package/dist/chunks/chunk-KLJ35UAH.js +1795 -0
- package/dist/chunks/chunk-KLJ35UAH.js.map +1 -0
- package/dist/chunks/chunk-LUSNRF73.js +1212 -0
- package/dist/chunks/chunk-LUSNRF73.js.map +1 -0
- package/dist/chunks/chunk-N3GASHTI.js +1127 -0
- package/dist/chunks/chunk-N3GASHTI.js.map +1 -0
- package/dist/field.d.ts +329 -0
- package/dist/field.es6.js +12 -0
- package/dist/field.es6.js.map +1 -0
- package/dist/form.d.ts +162 -0
- package/dist/form.es6.js +15 -0
- package/dist/form.es6.js.map +1 -0
- package/dist/layout.d.ts +108 -0
- package/dist/layout.es6.js +14 -0
- package/dist/layout.es6.js.map +1 -0
- package/dist/locale.d.ts +30 -0
- package/dist/locale.es6.js +7 -0
- package/dist/locale.es6.js.map +1 -0
- package/dist/popup.d.ts +97 -0
- package/dist/popup.es6.js +21 -0
- package/dist/popup.es6.js.map +1 -0
- package/dist/query-CKGg5Ugv.d.ts +81 -0
- package/dist/sidebar.d.ts +138 -0
- package/dist/sidebar.es6.js +12 -0
- package/dist/sidebar.es6.js.map +1 -0
- package/dist/tabs.d.ts +63 -0
- package/dist/tabs.es6.js +12 -0
- package/dist/tabs.es6.js.map +1 -0
- package/dist/toolbar.d.ts +97 -0
- package/dist/toolbar.es6.js +12 -0
- package/dist/toolbar.es6.js.map +1 -0
- package/dist/tooltip.d.ts +330 -0
- package/dist/tooltip.es6.js +21 -0
- package/dist/tooltip.es6.js.map +1 -0
- package/dist/tsgrid-ui.css +2 -2
- package/dist/tsgrid-ui.d.ts +16 -2004
- package/dist/tsgrid-ui.es6.js +7751 -23830
- package/dist/tsgrid-ui.es6.js.map +1 -1
- package/dist/tsgrid-ui.es6.min.js +37 -37
- package/dist/tsgrid-ui.js +150 -22
- package/dist/tsgrid-ui.min.css +2 -2
- package/dist/tsgrid-ui.min.js +39 -39
- package/dist/tsutils-message-CogFtVtO.d.ts +82 -0
- package/dist/utils.d.ts +418 -0
- package/dist/utils.es6.js +14 -0
- package/dist/utils.es6.js.map +1 -0
- package/package.json +25 -5
|
@@ -0,0 +1,1795 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TsColor,
|
|
3
|
+
TsDate,
|
|
4
|
+
TsMenu,
|
|
5
|
+
TsTooltip
|
|
6
|
+
} from "./chunk-FAIRNXQR.js";
|
|
7
|
+
import {
|
|
8
|
+
TsUtils
|
|
9
|
+
} from "./chunk-3NYH6545.js";
|
|
10
|
+
import {
|
|
11
|
+
TsBase,
|
|
12
|
+
query
|
|
13
|
+
} from "./chunk-DXZJHS4M.js";
|
|
14
|
+
|
|
15
|
+
// src/tsfield.ts
|
|
16
|
+
var query2 = query;
|
|
17
|
+
var TsMenu2 = TsMenu;
|
|
18
|
+
var TsColor2 = TsColor;
|
|
19
|
+
var TsDate2 = TsDate;
|
|
20
|
+
var TsTooltip2 = TsTooltip;
|
|
21
|
+
var TsField = class extends TsBase {
|
|
22
|
+
el;
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
|
+
selected;
|
|
25
|
+
// any: can be null, an object (list), or an array (enum/file)
|
|
26
|
+
helpers;
|
|
27
|
+
type;
|
|
28
|
+
options;
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
onClick;
|
|
31
|
+
// any: event callback
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
onAdd;
|
|
34
|
+
// any: event callback
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
+
onNew;
|
|
37
|
+
// any: event callback
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
+
onRemove;
|
|
40
|
+
// any: event callback
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
+
onMouseEnter;
|
|
43
|
+
// any: event callback
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
onMouseLeave;
|
|
46
|
+
// any: event callback
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
onScroll;
|
|
49
|
+
// any: event callback
|
|
50
|
+
tmp;
|
|
51
|
+
constructor(type, options) {
|
|
52
|
+
super();
|
|
53
|
+
if (typeof type == "string" && options == null) {
|
|
54
|
+
options = { type };
|
|
55
|
+
}
|
|
56
|
+
if (typeof type == "object" && options == null) {
|
|
57
|
+
options = TsUtils.clone(type);
|
|
58
|
+
}
|
|
59
|
+
if (typeof type == "string" && typeof options == "object") {
|
|
60
|
+
options.type = type;
|
|
61
|
+
}
|
|
62
|
+
const opts = options;
|
|
63
|
+
opts.type = String(opts.type).toLowerCase();
|
|
64
|
+
this.el = opts.el ?? null;
|
|
65
|
+
this.selected = null;
|
|
66
|
+
this.helpers = {};
|
|
67
|
+
this.type = opts.type ?? "text";
|
|
68
|
+
this.options = TsUtils.clone(opts);
|
|
69
|
+
this.onClick = opts.onClick ?? null;
|
|
70
|
+
this.onAdd = opts.onAdd ?? null;
|
|
71
|
+
this.onNew = opts.onNew ?? null;
|
|
72
|
+
this.onRemove = opts.onRemove ?? null;
|
|
73
|
+
this.onMouseEnter = opts.onMouseEnter ?? null;
|
|
74
|
+
this.onMouseLeave = opts.onMouseLeave ?? null;
|
|
75
|
+
this.onScroll = opts.onScroll ?? null;
|
|
76
|
+
this.tmp = {};
|
|
77
|
+
delete this.options.type;
|
|
78
|
+
delete this.options.onClick;
|
|
79
|
+
delete this.options.onMouseEnter;
|
|
80
|
+
delete this.options.onMouseLeave;
|
|
81
|
+
delete this.options.onScroll;
|
|
82
|
+
if (this.el) {
|
|
83
|
+
this.render(this.el);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
render(el) {
|
|
87
|
+
if (!(el instanceof HTMLElement)) {
|
|
88
|
+
console.log("ERROR: Cannot init TsField on empty subject");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const fieldEl = el;
|
|
92
|
+
fieldEl._w2field?.reset?.();
|
|
93
|
+
fieldEl._w2field = this;
|
|
94
|
+
this.el = fieldEl;
|
|
95
|
+
this.init();
|
|
96
|
+
}
|
|
97
|
+
init() {
|
|
98
|
+
let options = this.options;
|
|
99
|
+
let defaults;
|
|
100
|
+
if (this.el == null || !["INPUT", "TEXTAREA"].includes(this.el.tagName.toUpperCase())) {
|
|
101
|
+
console.log("ERROR: TsField could only be applied to INPUT or TEXTAREA.", this.el);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const _fieldEl = this.el;
|
|
105
|
+
switch (this.type) {
|
|
106
|
+
case "text":
|
|
107
|
+
case "int":
|
|
108
|
+
case "float":
|
|
109
|
+
case "money":
|
|
110
|
+
case "currency":
|
|
111
|
+
case "percent":
|
|
112
|
+
case "alphanumeric":
|
|
113
|
+
case "bin":
|
|
114
|
+
case "hex": {
|
|
115
|
+
defaults = {
|
|
116
|
+
min: null,
|
|
117
|
+
max: null,
|
|
118
|
+
step: 1,
|
|
119
|
+
autoFormat: true,
|
|
120
|
+
autoCorrect: true,
|
|
121
|
+
currency: {
|
|
122
|
+
prefix: TsUtils.settings.currencyPrefix,
|
|
123
|
+
suffix: TsUtils.settings.currencySuffix,
|
|
124
|
+
precision: TsUtils.settings.currencyPrecision
|
|
125
|
+
},
|
|
126
|
+
decimalSymbol: TsUtils.settings.decimalSymbol,
|
|
127
|
+
groupSymbol: TsUtils.settings.groupSymbol,
|
|
128
|
+
arrows: false,
|
|
129
|
+
keyboard: true,
|
|
130
|
+
precision: null,
|
|
131
|
+
prefix: "",
|
|
132
|
+
suffix: ""
|
|
133
|
+
};
|
|
134
|
+
this.options = TsUtils.extend({}, defaults, options);
|
|
135
|
+
options = this.options;
|
|
136
|
+
options.numberRE = new RegExp("[" + options.groupSymbol + "]", "g");
|
|
137
|
+
options.moneyRE = new RegExp("[" + options.currency.prefix + options.currency.suffix + options.groupSymbol + "]", "g");
|
|
138
|
+
options.percentRE = new RegExp("[" + options.groupSymbol + "%]", "g");
|
|
139
|
+
if (["text", "alphanumeric", "hex", "bin"].includes(this.type)) {
|
|
140
|
+
options.arrows = false;
|
|
141
|
+
options.keyboard = false;
|
|
142
|
+
}
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
case "color": {
|
|
146
|
+
const size = parseInt(getComputedStyle(this.el)["font-size"] ?? "12") || 12;
|
|
147
|
+
defaults = {
|
|
148
|
+
prefix: "#",
|
|
149
|
+
suffix: `<div style="width: ${size}px; height: ${size}px; margin-top: -2px;
|
|
150
|
+
position: relative; top: 50%; transform: translateY(-50%);"> </div>`,
|
|
151
|
+
arrows: false,
|
|
152
|
+
advanced: null,
|
|
153
|
+
// open advanced by default
|
|
154
|
+
transparent: true
|
|
155
|
+
};
|
|
156
|
+
this.options = TsUtils.extend({}, defaults, options);
|
|
157
|
+
options = this.options;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case "date": {
|
|
161
|
+
defaults = {
|
|
162
|
+
format: TsUtils.settings.dateFormat,
|
|
163
|
+
// date format
|
|
164
|
+
keyboard: true,
|
|
165
|
+
// if true, allows to select date with format
|
|
166
|
+
autoCorrect: true,
|
|
167
|
+
// correc date or shows the error
|
|
168
|
+
start: null,
|
|
169
|
+
// first date allowed to select
|
|
170
|
+
end: null,
|
|
171
|
+
// last date allowed to select
|
|
172
|
+
blockDates: [],
|
|
173
|
+
// array of blocked dates
|
|
174
|
+
blockWeekdays: [],
|
|
175
|
+
// blocked weekdays 0 - sunday, 1 - monday, etc
|
|
176
|
+
colored: {},
|
|
177
|
+
// ex: { '3/13/2022': 'bg-color|text-color' }
|
|
178
|
+
btnNow: true
|
|
179
|
+
// if true, displays Now button
|
|
180
|
+
};
|
|
181
|
+
this.options = TsUtils.extend({ type: "date" }, defaults, options);
|
|
182
|
+
options = this.options;
|
|
183
|
+
if (query2(this.el).attr("placeholder") == null) {
|
|
184
|
+
query2(this.el).attr("placeholder", options.format);
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case "time": {
|
|
189
|
+
defaults = {
|
|
190
|
+
format: TsUtils.settings.timeFormat,
|
|
191
|
+
keyboard: true,
|
|
192
|
+
autoCorrect: true,
|
|
193
|
+
start: null,
|
|
194
|
+
end: null,
|
|
195
|
+
btnNow: true,
|
|
196
|
+
noMinutes: false
|
|
197
|
+
};
|
|
198
|
+
this.options = TsUtils.extend({ type: "time" }, defaults, options);
|
|
199
|
+
options = this.options;
|
|
200
|
+
if (query2(this.el).attr("placeholder") == null) {
|
|
201
|
+
query2(this.el).attr("placeholder", options.format);
|
|
202
|
+
}
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
case "datetime": {
|
|
206
|
+
defaults = {
|
|
207
|
+
format: TsUtils.settings.dateFormat + "|" + TsUtils.settings.timeFormat,
|
|
208
|
+
keyboard: true,
|
|
209
|
+
autoCorrect: true,
|
|
210
|
+
start: null,
|
|
211
|
+
end: null,
|
|
212
|
+
startTime: null,
|
|
213
|
+
endTime: null,
|
|
214
|
+
blockDates: [],
|
|
215
|
+
// array of blocked dates
|
|
216
|
+
blockWeekdays: [],
|
|
217
|
+
// blocked weekdays 0 - sunday, 1 - monday, etc
|
|
218
|
+
colored: {},
|
|
219
|
+
// ex: { '3/13/2022': 'bg-color|text-color' }
|
|
220
|
+
btnNow: true,
|
|
221
|
+
noMinutes: false
|
|
222
|
+
};
|
|
223
|
+
this.options = TsUtils.extend({ type: "datetime" }, defaults, options);
|
|
224
|
+
options = this.options;
|
|
225
|
+
if (query2(this.el).attr("placeholder") == null) {
|
|
226
|
+
query2(this.el).attr("placeholder", options.placeholder || options.format);
|
|
227
|
+
}
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
case "list":
|
|
231
|
+
case "combo": {
|
|
232
|
+
defaults = {
|
|
233
|
+
items: [],
|
|
234
|
+
// array of items, can be a function
|
|
235
|
+
selected: {},
|
|
236
|
+
// selected item
|
|
237
|
+
itemMap: null,
|
|
238
|
+
// can be { id: 'id', text: 'text' } to specify field mapping for an item
|
|
239
|
+
match: "begins",
|
|
240
|
+
// ['contains', 'is', 'begins', 'ends']
|
|
241
|
+
filter: true,
|
|
242
|
+
// weather to filter at all
|
|
243
|
+
compare: null,
|
|
244
|
+
// compare function for filtering
|
|
245
|
+
prefix: "",
|
|
246
|
+
// prefix for input
|
|
247
|
+
suffix: "",
|
|
248
|
+
// sufix for input
|
|
249
|
+
icon: null,
|
|
250
|
+
// icon class for selected item
|
|
251
|
+
iconStyle: "",
|
|
252
|
+
// icon style for selected item
|
|
253
|
+
// -- remote items --
|
|
254
|
+
url: null,
|
|
255
|
+
// remove data source for items
|
|
256
|
+
method: null,
|
|
257
|
+
// default comes from TsUtils.settings.dataType
|
|
258
|
+
postData: {},
|
|
259
|
+
// additional data to submit to URL
|
|
260
|
+
recId: null,
|
|
261
|
+
// map retrieved data from url to id, can be string or function
|
|
262
|
+
recText: null,
|
|
263
|
+
// map retrieved data from url to text, can be string or function
|
|
264
|
+
debounce: 250,
|
|
265
|
+
// number of ms to wait before sending server call on search
|
|
266
|
+
minLength: 1,
|
|
267
|
+
// min number of chars when trigger search
|
|
268
|
+
cacheMax: 250,
|
|
269
|
+
// -- drop items --
|
|
270
|
+
renderDrop: null,
|
|
271
|
+
// render function for drop down item
|
|
272
|
+
maxDropHeight: 350,
|
|
273
|
+
// max height for drop down menu
|
|
274
|
+
maxDropWidth: null,
|
|
275
|
+
// if null then auto set
|
|
276
|
+
minDropWidth: null,
|
|
277
|
+
// if null then auto set
|
|
278
|
+
// -- misc --
|
|
279
|
+
markSearch: false,
|
|
280
|
+
// if true, highlights search phrase
|
|
281
|
+
align: "both",
|
|
282
|
+
// align with the input ['left', 'right', 'both', 'none']
|
|
283
|
+
altRows: true,
|
|
284
|
+
// alternate row color for drop itesm
|
|
285
|
+
openOnFocus: false,
|
|
286
|
+
// if true, shows drop items on focus
|
|
287
|
+
hideSelected: false,
|
|
288
|
+
// hide selected item from drop down
|
|
289
|
+
msgNoItems: "No matches",
|
|
290
|
+
msgSearch: "Type to search...",
|
|
291
|
+
// -- events --
|
|
292
|
+
onSearch: null,
|
|
293
|
+
// when search needs to be performed
|
|
294
|
+
onRequest: null,
|
|
295
|
+
// when request is submitted
|
|
296
|
+
onLoad: null,
|
|
297
|
+
// when data is received
|
|
298
|
+
onError: null
|
|
299
|
+
// when data fails to load due to server error
|
|
300
|
+
};
|
|
301
|
+
if (typeof options.items == "function") {
|
|
302
|
+
options._items_fun = options.items;
|
|
303
|
+
}
|
|
304
|
+
options.items = TsUtils.normMenu.call(this, options.items, options);
|
|
305
|
+
if (this.type === "list") {
|
|
306
|
+
query2(this.el).addClass("tsg-select");
|
|
307
|
+
if (!TsUtils.isPlainObject(options.selected) && Array.isArray(options.items)) {
|
|
308
|
+
options.items.forEach((item) => {
|
|
309
|
+
if (item && item.id === options.selected) {
|
|
310
|
+
options.selected = TsUtils.clone(item);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
options = TsUtils.extend({}, defaults, options);
|
|
316
|
+
const valid = ["is", "begins", "contains", "ends"];
|
|
317
|
+
if (!valid.includes(options.match)) {
|
|
318
|
+
console.log(`ERROR: invalid value "${options.match}" for option.match. It should be one of following: ${valid.join(", ")}.`);
|
|
319
|
+
}
|
|
320
|
+
this.options = options;
|
|
321
|
+
if (!TsUtils.isPlainObject(options.selected)) options.selected = {};
|
|
322
|
+
this.selected = options.selected;
|
|
323
|
+
query2(this.el).attr("autocapitalize", "off").attr("autocomplete", "off").attr("autocorrect", "off").attr("spellcheck", "false");
|
|
324
|
+
if (options.selected.text != null) {
|
|
325
|
+
query2(this.el).val(options.selected.text);
|
|
326
|
+
}
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
case "enum": {
|
|
330
|
+
defaults = {
|
|
331
|
+
items: [],
|
|
332
|
+
// id, text, tooltip, icon
|
|
333
|
+
selected: [],
|
|
334
|
+
itemMap: null,
|
|
335
|
+
// can be { id: 'id', text: 'text' } to specify field mapping for an item
|
|
336
|
+
max: 0,
|
|
337
|
+
// max number of selected items, 0 - unlimited
|
|
338
|
+
match: "begins",
|
|
339
|
+
// ['contains', 'is', 'begins', 'ends']
|
|
340
|
+
filter: true,
|
|
341
|
+
// if true, will apply filtering
|
|
342
|
+
compare: null,
|
|
343
|
+
// compare function for filtering
|
|
344
|
+
// -- remote items --
|
|
345
|
+
url: null,
|
|
346
|
+
// remove source for items
|
|
347
|
+
method: null,
|
|
348
|
+
// default httpMethod
|
|
349
|
+
postData: {},
|
|
350
|
+
recId: null,
|
|
351
|
+
// map retrieved data from url to id, can be string or function
|
|
352
|
+
recText: null,
|
|
353
|
+
// map retrieved data from url to text, can be string or function
|
|
354
|
+
debounce: 250,
|
|
355
|
+
// number of ms to wait before sending server call on search
|
|
356
|
+
minLength: 1,
|
|
357
|
+
// min number of chars when trigger search
|
|
358
|
+
cacheMax: 250,
|
|
359
|
+
// -- item and drop items --
|
|
360
|
+
maxItemWidth: 250,
|
|
361
|
+
// max width for a single item
|
|
362
|
+
maxDropHeight: 350,
|
|
363
|
+
// max height for drop down menu
|
|
364
|
+
maxDropWidth: null,
|
|
365
|
+
// if null then auto set
|
|
366
|
+
renderItem: null,
|
|
367
|
+
// render selected item
|
|
368
|
+
renderDrop: null,
|
|
369
|
+
// render function for drop down item
|
|
370
|
+
// -- misc --
|
|
371
|
+
style: "",
|
|
372
|
+
// style for container div
|
|
373
|
+
openOnFocus: false,
|
|
374
|
+
// if true, opens drop down on focus
|
|
375
|
+
markSearch: false,
|
|
376
|
+
// if true, highlights search phrase
|
|
377
|
+
align: "both",
|
|
378
|
+
// align with the input ['left', 'right', 'both', 'none']
|
|
379
|
+
altRows: true,
|
|
380
|
+
// if ture, will use alternate row colors
|
|
381
|
+
hideSelected: true,
|
|
382
|
+
// hide selected items from drop down
|
|
383
|
+
msgNoItems: "No matches",
|
|
384
|
+
msgSearch: "Type to search...",
|
|
385
|
+
// -- events --
|
|
386
|
+
onAdd: null,
|
|
387
|
+
// when item is selected from drop down
|
|
388
|
+
onNew: null,
|
|
389
|
+
// when new item should be added
|
|
390
|
+
onRemove: null,
|
|
391
|
+
// when item is removed
|
|
392
|
+
onSearch: null,
|
|
393
|
+
// when search is triggered
|
|
394
|
+
onClick: null,
|
|
395
|
+
// when item is clicked
|
|
396
|
+
onRequest: null,
|
|
397
|
+
// when data is requested
|
|
398
|
+
onLoad: null,
|
|
399
|
+
// when data is received
|
|
400
|
+
onError: null,
|
|
401
|
+
// when data fails to load due to server error
|
|
402
|
+
onScroll: null,
|
|
403
|
+
// when div with selected items is scrolled
|
|
404
|
+
onMouseEnter: null,
|
|
405
|
+
// when mouse enters item
|
|
406
|
+
onMouseLeave: null
|
|
407
|
+
// when mouse leaves item
|
|
408
|
+
};
|
|
409
|
+
options = TsUtils.extend({}, defaults, options, { suffix: "" });
|
|
410
|
+
if (typeof options.items == "function") {
|
|
411
|
+
options._items_fun = options.items;
|
|
412
|
+
}
|
|
413
|
+
const valid = ["is", "begins", "contains", "ends"];
|
|
414
|
+
if (!valid.includes(options.match)) {
|
|
415
|
+
console.log(`ERROR: invalid value "${options.match}" for option.match. It should be one of following: ${valid.join(", ")}.`);
|
|
416
|
+
}
|
|
417
|
+
options.items = TsUtils.normMenu.call(this, options.items, options);
|
|
418
|
+
options.selected = TsUtils.normMenu.call(this, options.selected, options);
|
|
419
|
+
this.options = options;
|
|
420
|
+
if (!Array.isArray(options.selected)) options.selected = [];
|
|
421
|
+
this.selected = options.selected;
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
case "file": {
|
|
425
|
+
defaults = {
|
|
426
|
+
selected: [],
|
|
427
|
+
// array of selected files
|
|
428
|
+
max: 0,
|
|
429
|
+
// max number of selected files, 0 - unlim
|
|
430
|
+
maxSize: 0,
|
|
431
|
+
// max size of all files, 0 - unlimited
|
|
432
|
+
maxFileSize: 0,
|
|
433
|
+
// max size of a single file, 0 -unlimited
|
|
434
|
+
renderItem: null,
|
|
435
|
+
// render function fo the selected item
|
|
436
|
+
// -- misc --
|
|
437
|
+
maxItemWidth: 250,
|
|
438
|
+
// max width for a single item
|
|
439
|
+
maxDropHeight: 350,
|
|
440
|
+
// max height for drop down menu
|
|
441
|
+
maxDropWidth: null,
|
|
442
|
+
// if null then auto set
|
|
443
|
+
readContent: true,
|
|
444
|
+
// if true, it will readAsDataURL content of the file
|
|
445
|
+
showErrors: true,
|
|
446
|
+
// if not true, will show errors
|
|
447
|
+
align: "both",
|
|
448
|
+
// align with the input ['left', 'right', 'both', 'none']
|
|
449
|
+
altRows: true,
|
|
450
|
+
// alternate row color for drop itesm
|
|
451
|
+
style: "",
|
|
452
|
+
// style for container div
|
|
453
|
+
// -- events --
|
|
454
|
+
onClick: null,
|
|
455
|
+
// when item is clicked
|
|
456
|
+
onAdd: null,
|
|
457
|
+
// when item is added
|
|
458
|
+
onRemove: null,
|
|
459
|
+
// when item is removed
|
|
460
|
+
onMouseEnter: null,
|
|
461
|
+
// when item is mouse over
|
|
462
|
+
onMouseLeave: null
|
|
463
|
+
// when item is mouse out
|
|
464
|
+
};
|
|
465
|
+
options = TsUtils.extend({}, defaults, options);
|
|
466
|
+
this.options = options;
|
|
467
|
+
if (!Array.isArray(options.selected)) options.selected = [];
|
|
468
|
+
this.selected = options.selected;
|
|
469
|
+
if (query2(this.el).attr("placeholder") == null) {
|
|
470
|
+
query2(this.el).attr("placeholder", TsUtils.lang("Attach files by dragging and dropping or Click to Select"));
|
|
471
|
+
}
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
default: {
|
|
475
|
+
console.log(`ERROR: field type "${this.type}" is not supported.`);
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
const $elInit = query2(this.el);
|
|
480
|
+
$elInit.css("box-sizing", "border-box");
|
|
481
|
+
$elInit.addClass("TsField tsg-input").off(".TsField").on("change.TsField", (event) => {
|
|
482
|
+
this.change(event);
|
|
483
|
+
}).on("click.TsField", (event) => {
|
|
484
|
+
this.click(event);
|
|
485
|
+
}).on("focus.TsField", (event) => {
|
|
486
|
+
this.focus(event);
|
|
487
|
+
}).on("blur.TsField", (event) => {
|
|
488
|
+
if (this.type !== "list") this.blur(event);
|
|
489
|
+
}).on("keydown.TsField", (event) => {
|
|
490
|
+
this.keyDown(event);
|
|
491
|
+
}).on("keyup.TsField", (event) => {
|
|
492
|
+
this.keyUp(event);
|
|
493
|
+
});
|
|
494
|
+
this.addPrefix();
|
|
495
|
+
this.addSuffix();
|
|
496
|
+
this.addSearch();
|
|
497
|
+
this.addMultiSearch();
|
|
498
|
+
this.change(new Event("change"));
|
|
499
|
+
}
|
|
500
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
501
|
+
get() {
|
|
502
|
+
let ret;
|
|
503
|
+
if (["list", "enum", "file"].indexOf(this.type) !== -1) {
|
|
504
|
+
ret = this.selected;
|
|
505
|
+
} else {
|
|
506
|
+
ret = query2(this.el).val();
|
|
507
|
+
}
|
|
508
|
+
return ret;
|
|
509
|
+
}
|
|
510
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
511
|
+
set(val, append) {
|
|
512
|
+
if (["list", "enum", "file"].indexOf(this.type) !== -1) {
|
|
513
|
+
const overlay = TsMenu2.get(this.el.id + "_menu");
|
|
514
|
+
overlay?.hide();
|
|
515
|
+
if (this.type !== "list" && append) {
|
|
516
|
+
if (!Array.isArray(this.selected)) this.selected = [];
|
|
517
|
+
this.selected.push(val);
|
|
518
|
+
if (overlay) overlay.options.selected = this.selected;
|
|
519
|
+
query2(this.el).trigger("input").trigger("change");
|
|
520
|
+
} else {
|
|
521
|
+
if (val == null) val = [];
|
|
522
|
+
const it = this.type === "enum" && !Array.isArray(val) ? [val] : val;
|
|
523
|
+
this.selected = it;
|
|
524
|
+
query2(this.el).trigger("input").trigger("change");
|
|
525
|
+
}
|
|
526
|
+
this.refresh();
|
|
527
|
+
} else {
|
|
528
|
+
query2(this.el).val(val);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
setIndex(ind, append) {
|
|
532
|
+
if (["list", "enum"].indexOf(this.type) !== -1) {
|
|
533
|
+
const overlay = TsMenu2.get(this.el.id + "_menu");
|
|
534
|
+
overlay?.hide();
|
|
535
|
+
const items = this.options.items;
|
|
536
|
+
if (items && items[ind]) {
|
|
537
|
+
if (this.type == "list") {
|
|
538
|
+
this.selected = items[ind];
|
|
539
|
+
}
|
|
540
|
+
if (this.type == "enum") {
|
|
541
|
+
if (!append) this.selected = [];
|
|
542
|
+
this.selected.push(items[ind]);
|
|
543
|
+
}
|
|
544
|
+
if (overlay) overlay.options.selected = this.selected;
|
|
545
|
+
query2(this.el).trigger("input").trigger("change");
|
|
546
|
+
this.refresh();
|
|
547
|
+
return true;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
refresh() {
|
|
553
|
+
const options = this.options;
|
|
554
|
+
const time = Date.now();
|
|
555
|
+
const styles = getComputedStyle(this.el);
|
|
556
|
+
if (this.type == "color") {
|
|
557
|
+
let color = this.el.value;
|
|
558
|
+
if (color.substr(0, 1) != "#" && color.substr(0, 3) != "rgb") {
|
|
559
|
+
color = "#" + color;
|
|
560
|
+
}
|
|
561
|
+
query2(this.helpers.suffix).find(":scope > div").css("background-color", color);
|
|
562
|
+
}
|
|
563
|
+
if (this.type == "list") {
|
|
564
|
+
if (this.helpers.prefix) query2(this.helpers.prefix).hide();
|
|
565
|
+
if (!this.helpers.search) return Date.now() - time;
|
|
566
|
+
if (this.selected == null && options.icon) {
|
|
567
|
+
options.prefix = `
|
|
568
|
+
<span class="tsg-icon ${options.icon} "style="cursor: pointer; font-size: 14px;
|
|
569
|
+
display: inline-block; margin-top: -1px; color: #7F98AD; ${options.iconStyle}">
|
|
570
|
+
</span>`;
|
|
571
|
+
this.addPrefix();
|
|
572
|
+
} else {
|
|
573
|
+
options.prefix = "";
|
|
574
|
+
this.addPrefix();
|
|
575
|
+
}
|
|
576
|
+
const focus = query2(this.helpers.search_focus);
|
|
577
|
+
const icon = query2(focus.get(0).previousElementSibling);
|
|
578
|
+
focus.css({ outline: "none" });
|
|
579
|
+
if (focus.val() === "") {
|
|
580
|
+
focus.css("opacity", 0);
|
|
581
|
+
icon.css("opacity", 0);
|
|
582
|
+
if (this.selected?.id != null) {
|
|
583
|
+
const text = this.selected.text;
|
|
584
|
+
const ind = this.findItemIndex(options.items, this.selected.id);
|
|
585
|
+
if (text != null) {
|
|
586
|
+
;
|
|
587
|
+
query2(this.el).val(TsUtils.lang(text)).data({
|
|
588
|
+
selected: text,
|
|
589
|
+
selectedIndex: ind[0]
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
} else {
|
|
593
|
+
this.el.value = "";
|
|
594
|
+
query2(this.el).removeData("selected selectedIndex");
|
|
595
|
+
}
|
|
596
|
+
} else {
|
|
597
|
+
focus.css("opacity", 1);
|
|
598
|
+
icon.css("opacity", 1);
|
|
599
|
+
query2(this.el).val("");
|
|
600
|
+
setTimeout(() => {
|
|
601
|
+
if (this.helpers.prefix) query2(this.helpers.prefix).hide();
|
|
602
|
+
if (options.icon) {
|
|
603
|
+
focus.css("margin-left", "17px");
|
|
604
|
+
query2(this.helpers.search).find(".tsg-icon-search").addClass("show-search");
|
|
605
|
+
} else {
|
|
606
|
+
focus.css("margin-left", "0px");
|
|
607
|
+
query2(this.helpers.search).find(".tsg-icon-search").removeClass("show-search");
|
|
608
|
+
}
|
|
609
|
+
}, 1);
|
|
610
|
+
}
|
|
611
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) {
|
|
612
|
+
setTimeout(() => {
|
|
613
|
+
if (this.helpers.prefix) query2(this.helpers.prefix).css("opacity", "0.6");
|
|
614
|
+
if (this.helpers.suffix) query2(this.helpers.suffix).css("opacity", "0.6");
|
|
615
|
+
}, 1);
|
|
616
|
+
} else {
|
|
617
|
+
setTimeout(() => {
|
|
618
|
+
if (this.helpers.prefix) query2(this.helpers.prefix).css("opacity", "1");
|
|
619
|
+
if (this.helpers.suffix) query2(this.helpers.suffix).css("opacity", "1");
|
|
620
|
+
}, 1);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
const div = this.helpers.multi;
|
|
624
|
+
if (["enum", "file"].includes(this.type) && div) {
|
|
625
|
+
let html = "";
|
|
626
|
+
if (Array.isArray(this.selected)) {
|
|
627
|
+
this.selected.forEach((it, ind) => {
|
|
628
|
+
if (it == null) return;
|
|
629
|
+
html += `
|
|
630
|
+
<div class="li-item" index="${ind}" style="max-width: ${parseInt(options.maxItemWidth)}px; ${it.style ? it.style : ""}">
|
|
631
|
+
${typeof options.renderItem === "function" ? options.renderItem(it, ind, `<div class="tsg-list-remove" index="${ind}">  </div>`) : `
|
|
632
|
+
${it.icon ? `<span class="tsg-icon ${it.icon}"></span>` : ""}
|
|
633
|
+
<div class="tsg-list-remove" index="${ind}">  </div>
|
|
634
|
+
${(this.type === "enum" ? it.text : it.name) ?? it.id ?? it}
|
|
635
|
+
${it.size ? `<span class="file-size"> - ${TsUtils.formatSize(it.size)}</span>` : ""}
|
|
636
|
+
`}
|
|
637
|
+
</div>`;
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
const ul = div.find(".tsg-multi-items");
|
|
641
|
+
if (options.style) {
|
|
642
|
+
div.attr("style", div.attr("style") + ";" + options.style);
|
|
643
|
+
}
|
|
644
|
+
query2(this.el).css("z-index", "-1");
|
|
645
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) {
|
|
646
|
+
setTimeout(() => {
|
|
647
|
+
div.get(0).scrollTop = 0;
|
|
648
|
+
div.addClass("tsg-readonly").find(".li-item").css("opacity", "0.9");
|
|
649
|
+
div.find(".li-item").parent().find(".li-search").hide().find("input").prop("readOnly", true).closest(".tsg-multi-items").find(".tsg-list-remove").hide();
|
|
650
|
+
}, 1);
|
|
651
|
+
} else {
|
|
652
|
+
setTimeout(() => {
|
|
653
|
+
div.removeClass("tsg-readonly").find(".li-item").css("opacity", "1");
|
|
654
|
+
div.find(".li-item").parent().find(".li-search").show().find("input").prop("readOnly", false).closest(".tsg-multi-items").find(".tsg-list-remove").show();
|
|
655
|
+
}, 1);
|
|
656
|
+
}
|
|
657
|
+
if (this.selected?.length > 0) {
|
|
658
|
+
query2(this.el).attr("placeholder", "");
|
|
659
|
+
}
|
|
660
|
+
div.find(".tsg-enum-placeholder").remove();
|
|
661
|
+
ul.find(".li-item").remove();
|
|
662
|
+
if (html !== "") {
|
|
663
|
+
ul.prepend(html);
|
|
664
|
+
} else if (query2(this.el).attr("placeholder") != null && div.find("input").val() === "") {
|
|
665
|
+
const style = TsUtils.stripSpaces(`
|
|
666
|
+
padding-top: ${styles["padding-top"]};
|
|
667
|
+
padding-left: ${styles["padding-left"]};
|
|
668
|
+
box-sizing: ${styles["box-sizing"]};
|
|
669
|
+
line-height: ${styles["line-height"]};
|
|
670
|
+
font-size: ${styles["font-size"]};
|
|
671
|
+
font-family: ${styles["font-family"]};
|
|
672
|
+
`);
|
|
673
|
+
div.prepend(`<div class="tsg-enum-placeholder" style="${style}">${query2(this.el).attr("placeholder")}</div>`);
|
|
674
|
+
}
|
|
675
|
+
div.off(".w2item").on("scroll.w2item", (event) => {
|
|
676
|
+
const edata = this.trigger("scroll", { target: this.el, originalEvent: event });
|
|
677
|
+
if (edata.isCancelled === true) return;
|
|
678
|
+
TsTooltip2.hide(this.el.id + "_preview");
|
|
679
|
+
edata.finish();
|
|
680
|
+
}).find(".li-item").on("click.w2item", (event) => {
|
|
681
|
+
const mouseEvent = event;
|
|
682
|
+
const target = query2(mouseEvent.target).closest(".li-item");
|
|
683
|
+
const index = target.attr("index");
|
|
684
|
+
const item = index != null ? this.selected[Number(index)] : void 0;
|
|
685
|
+
if (query2(target).hasClass("li-search")) return;
|
|
686
|
+
mouseEvent.stopPropagation();
|
|
687
|
+
let edata;
|
|
688
|
+
if (query2(mouseEvent.target).hasClass("tsg-list-remove")) {
|
|
689
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
690
|
+
edata = this.trigger("remove", { target: this.el, originalEvent: mouseEvent, item });
|
|
691
|
+
if (edata.isCancelled === true) return;
|
|
692
|
+
const transfer = new DataTransfer();
|
|
693
|
+
const input = query2(mouseEvent.target).closest(".tsg-list").find("input.file-input").get(0);
|
|
694
|
+
if (input) {
|
|
695
|
+
Array.from(input.files ?? []).filter((f) => f.name != item.name).forEach((f) => transfer.items.add(f));
|
|
696
|
+
input.files = transfer.files;
|
|
697
|
+
}
|
|
698
|
+
if (index != null) this.selected.splice(Number(index), 1);
|
|
699
|
+
query2(this.el).trigger("input").trigger("change");
|
|
700
|
+
query2(mouseEvent.target).remove();
|
|
701
|
+
} else {
|
|
702
|
+
edata = this.trigger("click", { target: this.el, originalEvent: mouseEvent.originalEvent, item });
|
|
703
|
+
if (edata.isCancelled === true) return;
|
|
704
|
+
let preview = item.tooltip;
|
|
705
|
+
if (this.type === "file") {
|
|
706
|
+
if (/image/i.test(item.type)) {
|
|
707
|
+
preview = `
|
|
708
|
+
<div class="tsg-file-preview">
|
|
709
|
+
<img src="${item.content ? "data:" + item.type + ";base64," + item.content : ""}"
|
|
710
|
+
style="max-width: 300px">
|
|
711
|
+
</div>`;
|
|
712
|
+
}
|
|
713
|
+
preview += `
|
|
714
|
+
<div class="tsg-file-info">
|
|
715
|
+
<div class="file-caption">${TsUtils.lang("Name")}:</div>
|
|
716
|
+
<div class="file-value">${item.name}</div>
|
|
717
|
+
<div class="file-caption">${TsUtils.lang("Size")}:</div>
|
|
718
|
+
<div class="file-value">${TsUtils.formatSize(item.size)}</div>
|
|
719
|
+
<div class="file-caption">${TsUtils.lang("Type")}:</div>
|
|
720
|
+
<div class="file-value file-type">${item.type}</div>
|
|
721
|
+
<div class="file-caption">${TsUtils.lang("Modified")}:</div>
|
|
722
|
+
<div class="file-value">${TsUtils.date(item.modified)}</div>
|
|
723
|
+
</div>`;
|
|
724
|
+
}
|
|
725
|
+
if (preview) {
|
|
726
|
+
const name = this.el.id + "_preview";
|
|
727
|
+
TsTooltip2.show({
|
|
728
|
+
name,
|
|
729
|
+
anchor: target.get(0),
|
|
730
|
+
html: preview,
|
|
731
|
+
hideOn: ["doc-click"],
|
|
732
|
+
class: ""
|
|
733
|
+
}).show((_event) => {
|
|
734
|
+
const $img = query2(`#w2overlay-${name} img`);
|
|
735
|
+
$img.on("load", function(_event2) {
|
|
736
|
+
const w = this.clientWidth;
|
|
737
|
+
const h = this.clientHeight;
|
|
738
|
+
if (w < 300 && h < 300) return;
|
|
739
|
+
if (w >= h && w > 300) query2(this).css("width", "300px");
|
|
740
|
+
if (w < h && h > 300) query2(this).css("height", "300px");
|
|
741
|
+
}).on("error", function(_event2) {
|
|
742
|
+
this.style.display = "none";
|
|
743
|
+
});
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
edata.finish();
|
|
748
|
+
}).on("mouseenter.w2item", (event) => {
|
|
749
|
+
const mouseEvent = event;
|
|
750
|
+
const target = query2(mouseEvent.target).closest(".li-item");
|
|
751
|
+
if (query2(target).hasClass("li-search")) return;
|
|
752
|
+
const idx = query2(mouseEvent.target).attr("index");
|
|
753
|
+
const item = idx != null ? this.selected[Number(idx)] : void 0;
|
|
754
|
+
const edata = this.trigger("mouseEnter", { target: this.el, originalEvent: mouseEvent, item });
|
|
755
|
+
if (edata.isCancelled === true) return;
|
|
756
|
+
edata.finish();
|
|
757
|
+
}).on("mouseleave.w2item", (event) => {
|
|
758
|
+
const mouseEvent = event;
|
|
759
|
+
const target = query2(mouseEvent.target).closest(".li-item");
|
|
760
|
+
if (query2(target).hasClass("li-search")) return;
|
|
761
|
+
const idx = query2(mouseEvent.target).attr("index");
|
|
762
|
+
const item = idx != null ? this.selected[Number(idx)] : void 0;
|
|
763
|
+
const edata = this.trigger("mouseLeave", { target: this.el, originalEvent: mouseEvent, item });
|
|
764
|
+
if (edata.isCancelled === true) return;
|
|
765
|
+
edata.finish();
|
|
766
|
+
});
|
|
767
|
+
if (this.type === "enum") {
|
|
768
|
+
const search = this.helpers.multi?.find("input");
|
|
769
|
+
search?.css({ width: "15px" });
|
|
770
|
+
} else {
|
|
771
|
+
this.helpers.multi?.find(".li-search").hide();
|
|
772
|
+
}
|
|
773
|
+
this.resize();
|
|
774
|
+
}
|
|
775
|
+
return Date.now() - time;
|
|
776
|
+
}
|
|
777
|
+
// resizing width of list, enum, file controls
|
|
778
|
+
resize() {
|
|
779
|
+
const width = this.el.clientWidth;
|
|
780
|
+
const styles = getComputedStyle(this.el);
|
|
781
|
+
const focus = this.helpers.search;
|
|
782
|
+
const multi = this.helpers.multi;
|
|
783
|
+
const suffix = this.helpers.suffix;
|
|
784
|
+
const prefix = this.helpers.prefix;
|
|
785
|
+
if (focus) {
|
|
786
|
+
query2(focus).css("width", width);
|
|
787
|
+
}
|
|
788
|
+
if (multi) {
|
|
789
|
+
query2(multi).css("width", width - parseInt(styles["margin-left"], 10) - parseInt(styles["margin-right"], 10));
|
|
790
|
+
}
|
|
791
|
+
if (suffix) {
|
|
792
|
+
this.addSuffix();
|
|
793
|
+
}
|
|
794
|
+
if (prefix) {
|
|
795
|
+
this.addPrefix();
|
|
796
|
+
}
|
|
797
|
+
const div = this.helpers.multi;
|
|
798
|
+
if (["enum", "file"].includes(this.type) && div) {
|
|
799
|
+
query2(this.el).css("height", "");
|
|
800
|
+
let cntHeight = query2(div).find(":scope div.tsg-multi-items").get(0).clientHeight + 5;
|
|
801
|
+
if (cntHeight < 20) cntHeight = 20;
|
|
802
|
+
if (this.tmp["max-height"] != null && cntHeight > this.tmp["max-height"]) {
|
|
803
|
+
cntHeight = this.tmp["max-height"] ?? cntHeight;
|
|
804
|
+
}
|
|
805
|
+
if (this.tmp["min-height"] != null && cntHeight < this.tmp["min-height"]) {
|
|
806
|
+
cntHeight = this.tmp["min-height"] ?? cntHeight;
|
|
807
|
+
}
|
|
808
|
+
const inpHeight = TsUtils.getSize(this.el, "height") - 2;
|
|
809
|
+
if (inpHeight > cntHeight) cntHeight = inpHeight;
|
|
810
|
+
query2(div).css({
|
|
811
|
+
"height": cntHeight + "px",
|
|
812
|
+
overflow: cntHeight == this.tmp["max-height"] ? "auto" : "hidden"
|
|
813
|
+
});
|
|
814
|
+
query2(div).css("height", cntHeight + "px");
|
|
815
|
+
query2(this.el).css({ "height": cntHeight + "px" });
|
|
816
|
+
}
|
|
817
|
+
this.tmp.current_width = width;
|
|
818
|
+
}
|
|
819
|
+
reset() {
|
|
820
|
+
if (this.tmp != null) {
|
|
821
|
+
query2(this.el).css("height", "");
|
|
822
|
+
["padding-left", "padding-right", "background-color", "border-color"].forEach((prop) => {
|
|
823
|
+
if (this.tmp && this.tmp["old-" + prop] != null) {
|
|
824
|
+
query2(this.el).css(prop, this.tmp["old-" + prop]);
|
|
825
|
+
delete this.tmp["old-" + prop];
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
clearInterval(this.tmp.sizeTimer);
|
|
829
|
+
}
|
|
830
|
+
;
|
|
831
|
+
query2(this.el).val(this.clean(query2(this.el).val())).removeClass("TsField tsg-input").removeData("selected selectedIndex").off(".TsField");
|
|
832
|
+
Object.keys(this.helpers).forEach((key) => {
|
|
833
|
+
query2(this.helpers[key]).remove();
|
|
834
|
+
});
|
|
835
|
+
this.helpers = {};
|
|
836
|
+
delete this.el._w2field;
|
|
837
|
+
}
|
|
838
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
839
|
+
clean(val) {
|
|
840
|
+
if (typeof val === "number") {
|
|
841
|
+
return val;
|
|
842
|
+
}
|
|
843
|
+
const options = this.options;
|
|
844
|
+
val = String(val).trim();
|
|
845
|
+
if (["int", "float", "money", "currency", "percent"].includes(this.type)) {
|
|
846
|
+
if (typeof val === "string") {
|
|
847
|
+
if (options.autoFormat) {
|
|
848
|
+
if (["money", "currency"].includes(this.type)) {
|
|
849
|
+
val = String(val).replace(options.moneyRE, "");
|
|
850
|
+
}
|
|
851
|
+
if (this.type === "percent") {
|
|
852
|
+
val = String(val).replace(options.percentRE, "");
|
|
853
|
+
}
|
|
854
|
+
if (["int", "float"].includes(this.type)) {
|
|
855
|
+
val = String(val).replace(options.numberRE, "");
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
const esc_gsroupSymbol = options.groupSymbol.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
859
|
+
const esc_decimalSymbol = options.decimalSymbol.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
860
|
+
val = val.replace(/\s+/g, "").replace(new RegExp(esc_gsroupSymbol, "g"), "").replace(new RegExp(esc_decimalSymbol, "g"), ".");
|
|
861
|
+
}
|
|
862
|
+
if (val !== "" && TsUtils.isFloat(val)) val = Number(val);
|
|
863
|
+
else val = "";
|
|
864
|
+
}
|
|
865
|
+
return val;
|
|
866
|
+
}
|
|
867
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
868
|
+
format(val) {
|
|
869
|
+
const options = this.options;
|
|
870
|
+
if (options.autoFormat && val !== "") {
|
|
871
|
+
switch (this.type) {
|
|
872
|
+
case "money":
|
|
873
|
+
case "currency":
|
|
874
|
+
val = TsUtils.formatNumber(val, options.currency.precision, true);
|
|
875
|
+
if (val !== "") val = options.currency.prefix + val + options.currency.suffix;
|
|
876
|
+
break;
|
|
877
|
+
case "percent":
|
|
878
|
+
val = TsUtils.formatNumber(val, options.precision, true);
|
|
879
|
+
if (val !== "") val += "%";
|
|
880
|
+
break;
|
|
881
|
+
case "float":
|
|
882
|
+
val = TsUtils.formatNumber(val, options.precision, true);
|
|
883
|
+
break;
|
|
884
|
+
case "int":
|
|
885
|
+
val = TsUtils.formatNumber(val, 0, true);
|
|
886
|
+
break;
|
|
887
|
+
}
|
|
888
|
+
const group = 1e3.toLocaleString(TsUtils.settings.locale, { useGrouping: true }).slice(1, 2);
|
|
889
|
+
if (group !== this.options.groupSymbol) {
|
|
890
|
+
val = val.replaceAll(group, this.options.groupSymbol);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
return val;
|
|
894
|
+
}
|
|
895
|
+
change(event) {
|
|
896
|
+
if (["int", "float", "money", "currency", "percent"].indexOf(this.type) !== -1) {
|
|
897
|
+
const val = query2(this.el).val();
|
|
898
|
+
const new_val = this.format(this.clean(query2(this.el).val()));
|
|
899
|
+
if (val !== "" && val != new_val) {
|
|
900
|
+
query2(this.el).val(new_val);
|
|
901
|
+
event.stopPropagation();
|
|
902
|
+
event.preventDefault();
|
|
903
|
+
return false;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (this.type === "color") {
|
|
907
|
+
let color = query2(this.el).val();
|
|
908
|
+
if (color.substr(0, 3).toLowerCase() !== "rgb") {
|
|
909
|
+
color = "#" + color;
|
|
910
|
+
const len = query2(this.el).val().length;
|
|
911
|
+
if (len !== 8 && len !== 6 && len !== 3) color = "";
|
|
912
|
+
}
|
|
913
|
+
const next = query2(this.el).get(0).nextElementSibling;
|
|
914
|
+
query2(next).find("div").css("background-color", color);
|
|
915
|
+
if (query2(this.el).hasClass("has-focus")) {
|
|
916
|
+
this.updateOverlay();
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
if (["list", "enum", "file"].indexOf(this.type) !== -1) {
|
|
920
|
+
this.refresh();
|
|
921
|
+
}
|
|
922
|
+
if (["date", "time", "datetime"].indexOf(this.type) !== -1) {
|
|
923
|
+
let tmp = parseInt(this.el.value);
|
|
924
|
+
if (TsUtils.isInt(this.el.value) && tmp > 3e3) {
|
|
925
|
+
if (this.type === "time") tmp = TsUtils.formatTime(new Date(tmp), this.options.format);
|
|
926
|
+
if (this.type === "date") tmp = TsUtils.formatDate(new Date(tmp), this.options.format);
|
|
927
|
+
if (this.type === "datetime") tmp = TsUtils.formatDateTime(new Date(tmp), this.options.format);
|
|
928
|
+
query2(this.el).val(String(tmp)).trigger("input").trigger("change");
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
click(event) {
|
|
933
|
+
if (["list", "combo", "enum"].includes(this.type)) {
|
|
934
|
+
if (!query2(this.el).hasClass("has-focus")) {
|
|
935
|
+
this.focus(event);
|
|
936
|
+
}
|
|
937
|
+
if (this.type == "list" || this.type == "combo") {
|
|
938
|
+
if (!this.tmp.openedOnFocus) {
|
|
939
|
+
const name = this.el.id + "_menu";
|
|
940
|
+
const overlay = TsMenu2.get(name);
|
|
941
|
+
if (overlay?.displayed) {
|
|
942
|
+
TsMenu2.hide(name);
|
|
943
|
+
} else {
|
|
944
|
+
this.updateOverlay();
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
delete this.tmp.openedOnFocus;
|
|
948
|
+
if (this.type == "list") {
|
|
949
|
+
event.stopPropagation();
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
if (this.type == "enum") {
|
|
953
|
+
this.updateOverlay();
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
if (["date", "time", "datetime", "color"].includes(this.type)) {
|
|
957
|
+
this.updateOverlay();
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
focus(event) {
|
|
961
|
+
if (this.type == "list" && document.activeElement == this.el) {
|
|
962
|
+
this.helpers.search_focus?.focus();
|
|
963
|
+
if (event.showMenu !== false && this.options.openOnFocus !== false && query2(this.el).hasClass("has-focus") && !this.tmp.overlay?.overlay?.displayed) {
|
|
964
|
+
setTimeout(() => {
|
|
965
|
+
this.tmp.openedOnFocus = true;
|
|
966
|
+
this.updateOverlay();
|
|
967
|
+
}, 0);
|
|
968
|
+
}
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
if (["color", "date", "time", "datetime"].indexOf(this.type) !== -1) {
|
|
972
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
973
|
+
this.updateOverlay();
|
|
974
|
+
}
|
|
975
|
+
if (["list", "combo", "enum"].indexOf(this.type) !== -1) {
|
|
976
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) {
|
|
977
|
+
query2(this.el).addClass("has-focus");
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
if (typeof this.options._items_fun == "function") {
|
|
981
|
+
;
|
|
982
|
+
this.options.items = TsUtils.normMenu.call(this, this.options._items_fun, this.options);
|
|
983
|
+
}
|
|
984
|
+
if (this.helpers.search) {
|
|
985
|
+
const search = this.helpers.search_focus;
|
|
986
|
+
if (search) {
|
|
987
|
+
search.value = "";
|
|
988
|
+
search.select();
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
if (this.type == "enum") {
|
|
992
|
+
const search = query2(this.el.previousElementSibling).find(".li-search input").get(0);
|
|
993
|
+
if (document.activeElement !== search) {
|
|
994
|
+
search.focus();
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
this.resize();
|
|
998
|
+
if (event.showMenu !== false && this.options.openOnFocus !== false && query2(this.el).hasClass("has-focus") && !this.tmp.overlay?.overlay?.displayed) {
|
|
999
|
+
setTimeout(() => {
|
|
1000
|
+
this.tmp.openedOnFocus = true;
|
|
1001
|
+
this.updateOverlay();
|
|
1002
|
+
}, 0);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
if (this.type == "file") {
|
|
1006
|
+
const prev = query2(this.el).get(0).previousElementSibling;
|
|
1007
|
+
query2(prev).addClass("has-focus");
|
|
1008
|
+
}
|
|
1009
|
+
query2(this.el).addClass("has-focus");
|
|
1010
|
+
}
|
|
1011
|
+
blur(_event) {
|
|
1012
|
+
const val = query2(this.el).val().trim();
|
|
1013
|
+
query2(this.el).removeClass("has-focus");
|
|
1014
|
+
if (["int", "float", "money", "currency", "percent"].includes(this.type)) {
|
|
1015
|
+
if (val !== "") {
|
|
1016
|
+
let newVal = val;
|
|
1017
|
+
let error = "";
|
|
1018
|
+
if (!this.isStrValid(val)) {
|
|
1019
|
+
newVal = "";
|
|
1020
|
+
} else {
|
|
1021
|
+
const rVal = this.clean(val);
|
|
1022
|
+
const options = this.options;
|
|
1023
|
+
if (options.min != null && rVal < options.min) {
|
|
1024
|
+
newVal = options.min;
|
|
1025
|
+
error = `Should be >= ${options.min}`;
|
|
1026
|
+
}
|
|
1027
|
+
if (options.max != null && rVal > options.max) {
|
|
1028
|
+
newVal = options.max;
|
|
1029
|
+
error = `Should be <= ${options.max}`;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
if (this.options.autoCorrect) {
|
|
1033
|
+
;
|
|
1034
|
+
query2(this.el).val(newVal).trigger("input").trigger("change");
|
|
1035
|
+
if (error) {
|
|
1036
|
+
TsTooltip2.show({
|
|
1037
|
+
name: this.el.id + "_error",
|
|
1038
|
+
anchor: this.el,
|
|
1039
|
+
html: error
|
|
1040
|
+
});
|
|
1041
|
+
setTimeout(() => {
|
|
1042
|
+
TsTooltip2.hide(this.el.id + "_error");
|
|
1043
|
+
}, 3e3);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
if (["date", "time", "datetime"].includes(this.type) && this.options.autoCorrect) {
|
|
1049
|
+
if (val !== "") {
|
|
1050
|
+
const check = this.type == "date" ? TsUtils.isDate : this.type == "time" ? TsUtils.isTime : TsUtils.isDateTime;
|
|
1051
|
+
if (!TsDate2.inRange(this.el.value, this.options) || !check.bind(TsUtils)(this.el.value, this.options.format)) {
|
|
1052
|
+
;
|
|
1053
|
+
query2(this.el).val("").trigger("input").trigger("change");
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
if (this.type === "enum") {
|
|
1058
|
+
;
|
|
1059
|
+
query2(this.helpers.multi).find("input").val("").css("width", "15px");
|
|
1060
|
+
}
|
|
1061
|
+
if (this.type == "file") {
|
|
1062
|
+
const prev = this.el.previousElementSibling;
|
|
1063
|
+
query2(prev).removeClass("has-focus");
|
|
1064
|
+
}
|
|
1065
|
+
if (this.type === "list") {
|
|
1066
|
+
this.el.value = this.selected?.text ?? "";
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
keyDown(event, extra) {
|
|
1070
|
+
const options = this.options;
|
|
1071
|
+
const key = event.keyCode || extra && extra.keyCode;
|
|
1072
|
+
let cancel = false;
|
|
1073
|
+
let val, inc, daymil, dt, newValue, newDT;
|
|
1074
|
+
if (["int", "float", "money", "currency", "percent", "hex", "bin", "color", "alphanumeric"].includes(this.type)) {
|
|
1075
|
+
if (!event.metaKey && !event.ctrlKey && !event.altKey) {
|
|
1076
|
+
if (!this.isStrValid(event.key ?? "1", true) && // valid & is not arrows, dot, comma, etc keys
|
|
1077
|
+
![9, 8, 13, 27, 37, 38, 39, 40, 46].includes(event.keyCode)) {
|
|
1078
|
+
event.preventDefault();
|
|
1079
|
+
if (event.stopPropagation) event.stopPropagation();
|
|
1080
|
+
else event.cancelBubble = true;
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
if (["int", "float", "money", "currency", "percent"].includes(this.type)) {
|
|
1086
|
+
if (!options.keyboard || query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
1087
|
+
val = parseFloat(query2(this.el).val().replace(options.moneyRE, "")) || 0;
|
|
1088
|
+
inc = options.step;
|
|
1089
|
+
if (event.ctrlKey || event.metaKey) inc = options.step * 10;
|
|
1090
|
+
switch (key) {
|
|
1091
|
+
case 38:
|
|
1092
|
+
if (event.shiftKey) break;
|
|
1093
|
+
newValue = val + inc <= options.max || options.max == null ? Number((val + inc).toFixed(12)) : options.max;
|
|
1094
|
+
query2(this.el).val(String(newValue)).trigger("input").trigger("change");
|
|
1095
|
+
cancel = true;
|
|
1096
|
+
break;
|
|
1097
|
+
case 40:
|
|
1098
|
+
if (event.shiftKey) break;
|
|
1099
|
+
newValue = val - inc >= options.min || options.min == null ? Number((val - inc).toFixed(12)) : options.min;
|
|
1100
|
+
query2(this.el).val(String(newValue)).trigger("input").trigger("change");
|
|
1101
|
+
cancel = true;
|
|
1102
|
+
break;
|
|
1103
|
+
}
|
|
1104
|
+
if (cancel) {
|
|
1105
|
+
event.preventDefault();
|
|
1106
|
+
this.moveCaret2end();
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
if (["date", "datetime"].includes(this.type)) {
|
|
1110
|
+
if (!options.keyboard || query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
1111
|
+
const is = (this.type == "date" ? TsUtils.isDate : TsUtils.isDateTime).bind(TsUtils);
|
|
1112
|
+
const format = (this.type == "date" ? TsUtils.formatDate : TsUtils.formatDateTime).bind(TsUtils);
|
|
1113
|
+
daymil = 24 * 60 * 60 * 1e3;
|
|
1114
|
+
inc = 1;
|
|
1115
|
+
if (event.ctrlKey || event.metaKey) inc = 10;
|
|
1116
|
+
dt = is(query2(this.el).val(), options.format, true);
|
|
1117
|
+
if (!dt) {
|
|
1118
|
+
dt = /* @__PURE__ */ new Date();
|
|
1119
|
+
daymil = 0;
|
|
1120
|
+
}
|
|
1121
|
+
switch (key) {
|
|
1122
|
+
case 38:
|
|
1123
|
+
if (event.shiftKey) break;
|
|
1124
|
+
if (inc == 10) {
|
|
1125
|
+
dt.setMonth(dt.getMonth() + 1);
|
|
1126
|
+
} else {
|
|
1127
|
+
dt.setTime(dt.getTime() + daymil);
|
|
1128
|
+
}
|
|
1129
|
+
newDT = format(dt.getTime(), options.format);
|
|
1130
|
+
query2(this.el).val(newDT).trigger("input").trigger("change");
|
|
1131
|
+
cancel = true;
|
|
1132
|
+
break;
|
|
1133
|
+
case 40:
|
|
1134
|
+
if (event.shiftKey) break;
|
|
1135
|
+
if (inc == 10) {
|
|
1136
|
+
dt.setMonth(dt.getMonth() - 1);
|
|
1137
|
+
} else {
|
|
1138
|
+
dt.setTime(dt.getTime() - daymil);
|
|
1139
|
+
}
|
|
1140
|
+
newDT = format(dt.getTime(), options.format);
|
|
1141
|
+
query2(this.el).val(newDT).trigger("input").trigger("change");
|
|
1142
|
+
cancel = true;
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
if (cancel) {
|
|
1146
|
+
event.preventDefault();
|
|
1147
|
+
this.moveCaret2end();
|
|
1148
|
+
this.updateOverlay();
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
if (this.type === "time") {
|
|
1152
|
+
if (!options.keyboard || query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
1153
|
+
inc = event.ctrlKey || event.metaKey ? 60 : 1;
|
|
1154
|
+
val = query2(this.el).val();
|
|
1155
|
+
let time = TsDate2.str2min(val) || TsDate2.str2min((/* @__PURE__ */ new Date()).getHours() + ":" + ((/* @__PURE__ */ new Date()).getMinutes() - 1));
|
|
1156
|
+
switch (key) {
|
|
1157
|
+
case 38:
|
|
1158
|
+
if (event.shiftKey) break;
|
|
1159
|
+
time += inc;
|
|
1160
|
+
cancel = true;
|
|
1161
|
+
break;
|
|
1162
|
+
case 40:
|
|
1163
|
+
if (event.shiftKey) break;
|
|
1164
|
+
time -= inc;
|
|
1165
|
+
cancel = true;
|
|
1166
|
+
break;
|
|
1167
|
+
}
|
|
1168
|
+
if (cancel) {
|
|
1169
|
+
event.preventDefault();
|
|
1170
|
+
query2(this.el).val(TsDate2.min2str(time)).trigger("input").trigger("change");
|
|
1171
|
+
this.moveCaret2end();
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
if (["list", "enum"].includes(this.type)) {
|
|
1175
|
+
switch (key) {
|
|
1176
|
+
case 8:
|
|
1177
|
+
// delete
|
|
1178
|
+
case 46:
|
|
1179
|
+
if (this.type == "list") {
|
|
1180
|
+
const search = query2(this.helpers.search_focus);
|
|
1181
|
+
if (search.val() == "") {
|
|
1182
|
+
const edata = this.trigger("remove", { target: this.el, originalEvent: event, item: this.selected });
|
|
1183
|
+
if (edata.isCancelled === true) return;
|
|
1184
|
+
this.selected = null;
|
|
1185
|
+
TsMenu2.hide(this.el.id + "_menu");
|
|
1186
|
+
query2(this.el).val("").trigger("input").trigger("change");
|
|
1187
|
+
edata.finish();
|
|
1188
|
+
}
|
|
1189
|
+
} else {
|
|
1190
|
+
const search = query2(this.helpers.multi).find("input");
|
|
1191
|
+
if (search.val() == "") {
|
|
1192
|
+
const edata = this.trigger("remove", { target: this.el, originalEvent: event, item: this.selected[this.selected.length - 1] });
|
|
1193
|
+
if (edata.isCancelled === true) return;
|
|
1194
|
+
TsMenu2.hide(this.el.id + "_menu");
|
|
1195
|
+
this.selected.pop();
|
|
1196
|
+
const overlay = TsMenu2.get(this.el.id + "_menu");
|
|
1197
|
+
if (overlay) overlay.options.selected = this.selected;
|
|
1198
|
+
this.refresh();
|
|
1199
|
+
edata.finish();
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
break;
|
|
1203
|
+
case 9:
|
|
1204
|
+
// tab key
|
|
1205
|
+
case 16:
|
|
1206
|
+
TsMenu2.hide(this.el.id + "_menu");
|
|
1207
|
+
break;
|
|
1208
|
+
case 27:
|
|
1209
|
+
TsMenu2.hide(this.el.id + "_menu");
|
|
1210
|
+
this.refresh();
|
|
1211
|
+
break;
|
|
1212
|
+
default: {
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
keyUp(event) {
|
|
1218
|
+
if (this.type == "list") {
|
|
1219
|
+
const search = query2(this.helpers.search_focus);
|
|
1220
|
+
if (search.val() !== "") {
|
|
1221
|
+
query2(this.el).attr("placeholder", "");
|
|
1222
|
+
} else {
|
|
1223
|
+
query2(this.el).attr("placeholder", this.tmp.pholder);
|
|
1224
|
+
}
|
|
1225
|
+
if (event.keyCode == 13) {
|
|
1226
|
+
setTimeout(() => {
|
|
1227
|
+
search.val("");
|
|
1228
|
+
TsMenu2.hide(this.el.id + "_menu");
|
|
1229
|
+
this.refresh();
|
|
1230
|
+
}, 1);
|
|
1231
|
+
}
|
|
1232
|
+
if ([38, 40].includes(event.keyCode) && !this.tmp.overlay?.overlay?.displayed) {
|
|
1233
|
+
this.updateOverlay();
|
|
1234
|
+
}
|
|
1235
|
+
this.refresh();
|
|
1236
|
+
}
|
|
1237
|
+
if (this.type == "combo") {
|
|
1238
|
+
if (![9, 16, 27].includes(event.keyCode) && this.options.openOnFocus !== true) {
|
|
1239
|
+
this.updateOverlay();
|
|
1240
|
+
}
|
|
1241
|
+
if ([38, 40].includes(event.keyCode) && !this.tmp.overlay?.overlay?.displayed) {
|
|
1242
|
+
this.updateOverlay();
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
if (this.type == "enum") {
|
|
1246
|
+
const search = this.helpers.multi?.find("input");
|
|
1247
|
+
const styles = getComputedStyle(search?.get(0));
|
|
1248
|
+
const width = TsUtils.getStrWidth(
|
|
1249
|
+
search?.val(),
|
|
1250
|
+
`font-family: ${styles["font-family"]}; font-size: ${styles["font-size"]};`,
|
|
1251
|
+
void 0
|
|
1252
|
+
);
|
|
1253
|
+
search?.css({ width: width + 15 + "px" });
|
|
1254
|
+
this.resize();
|
|
1255
|
+
if ([8, 46, 9, 16, 27].includes(event.keyCode)) {
|
|
1256
|
+
if (this.tmp.overlay?.overlay?.displayed) {
|
|
1257
|
+
TsMenu2.hide(this.el.id + "_menu");
|
|
1258
|
+
}
|
|
1259
|
+
} else {
|
|
1260
|
+
this.updateOverlay();
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1265
|
+
findItemIndex(items, id, parents) {
|
|
1266
|
+
let inds = [];
|
|
1267
|
+
if (!parents) parents = [];
|
|
1268
|
+
if (["list", "combo", "enum"].includes(this.type) && this.options.url) {
|
|
1269
|
+
const overlay = TsMenu2.get(this.el.id + "_menu");
|
|
1270
|
+
if (overlay) {
|
|
1271
|
+
items = overlay.options.items;
|
|
1272
|
+
this.options.items = items;
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
items.forEach((item, ind) => {
|
|
1276
|
+
if (item.id === id) {
|
|
1277
|
+
inds = parents.concat([ind]);
|
|
1278
|
+
this.options.index = [ind];
|
|
1279
|
+
}
|
|
1280
|
+
if (inds.length == 0 && item.items && item.items.length > 0) {
|
|
1281
|
+
parents.push(ind);
|
|
1282
|
+
inds = this.findItemIndex(item.items, id, parents);
|
|
1283
|
+
parents.pop();
|
|
1284
|
+
}
|
|
1285
|
+
});
|
|
1286
|
+
return inds;
|
|
1287
|
+
}
|
|
1288
|
+
updateOverlay(_indexOnly) {
|
|
1289
|
+
const options = this.options;
|
|
1290
|
+
let params;
|
|
1291
|
+
if (this.type === "color") {
|
|
1292
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
1293
|
+
TsColor2.show(TsUtils.extend({
|
|
1294
|
+
name: this.el.id + "_color",
|
|
1295
|
+
anchor: this.el,
|
|
1296
|
+
transparent: options.transparent,
|
|
1297
|
+
advanced: options.advanced,
|
|
1298
|
+
color: this.el.value,
|
|
1299
|
+
liveUpdate: true
|
|
1300
|
+
}, this.options)).select((event) => {
|
|
1301
|
+
const color = event.detail["color"];
|
|
1302
|
+
query2(this.el).val(color).trigger("input").trigger("change");
|
|
1303
|
+
}).liveUpdate((event) => {
|
|
1304
|
+
const color = event.detail["color"];
|
|
1305
|
+
query2(this.helpers.suffix).find(":scope > div").css("background-color", "#" + color);
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
if (["list", "combo", "enum"].includes(this.type)) {
|
|
1309
|
+
let el = this.el;
|
|
1310
|
+
let input = this.el;
|
|
1311
|
+
if (this.type === "enum") {
|
|
1312
|
+
el = this.helpers.multi?.get(0) ?? this.el;
|
|
1313
|
+
input = query2(el).find("input").get(0) ?? this.el;
|
|
1314
|
+
}
|
|
1315
|
+
if (this.type === "list") {
|
|
1316
|
+
const sel = this.selected;
|
|
1317
|
+
if (TsUtils.isPlainObject(sel) && Object.keys(sel).length > 0) {
|
|
1318
|
+
const ind = this.findItemIndex(options.items, sel.id);
|
|
1319
|
+
if (ind.length > 0) {
|
|
1320
|
+
options.index = ind;
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
input = this.helpers.search_focus ?? this.el;
|
|
1324
|
+
}
|
|
1325
|
+
if (query2(this.el).hasClass("has-focus") && !this.el.readOnly && !this.el.disabled) {
|
|
1326
|
+
params = TsUtils.extend({}, options, {
|
|
1327
|
+
name: this.el.id + "_menu",
|
|
1328
|
+
anchor: input,
|
|
1329
|
+
selected: this.selected,
|
|
1330
|
+
search: false,
|
|
1331
|
+
render: options.renderDrop,
|
|
1332
|
+
anchorClass: "",
|
|
1333
|
+
offsetY: 5,
|
|
1334
|
+
maxHeight: options.maxDropHeight,
|
|
1335
|
+
// TODO: check
|
|
1336
|
+
maxWidth: options.maxDropWidth,
|
|
1337
|
+
// TODO: check
|
|
1338
|
+
minWidth: options.minDropWidth
|
|
1339
|
+
// TODO: check
|
|
1340
|
+
});
|
|
1341
|
+
this.tmp.overlay = TsMenu2.show(params).select((event) => {
|
|
1342
|
+
if (["list", "combo"].includes(this.type)) {
|
|
1343
|
+
this.selected = event.detail["item"];
|
|
1344
|
+
query2(input).val("");
|
|
1345
|
+
query2(this.el).val(this.selected.text).trigger("input").trigger("change");
|
|
1346
|
+
this.focus({ showMenu: false });
|
|
1347
|
+
} else {
|
|
1348
|
+
const selected = this.selected;
|
|
1349
|
+
const newItem = event.detail?.["item"];
|
|
1350
|
+
if (newItem) {
|
|
1351
|
+
const edata = this.trigger("add", { target: this.el, item: newItem, originalEvent: event });
|
|
1352
|
+
if (edata.isCancelled === true) return;
|
|
1353
|
+
if (selected.length >= options.max && options.max > 0) selected.pop();
|
|
1354
|
+
delete newItem.hidden;
|
|
1355
|
+
selected.push(newItem);
|
|
1356
|
+
query2(this.el).trigger("input").trigger("change");
|
|
1357
|
+
query2(this.helpers.multi).find("input").val("");
|
|
1358
|
+
const overlay = TsMenu2.get(this.el.id + "_menu");
|
|
1359
|
+
if (overlay) overlay.options.selected = this.selected;
|
|
1360
|
+
edata.finish();
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
if (["date", "time", "datetime"].includes(this.type)) {
|
|
1367
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
1368
|
+
TsDate2.show(TsUtils.extend({
|
|
1369
|
+
name: this.el.id + "_date",
|
|
1370
|
+
anchor: this.el,
|
|
1371
|
+
value: this.el.value
|
|
1372
|
+
}, this.options)).select((event) => {
|
|
1373
|
+
const date = event.detail["date"];
|
|
1374
|
+
if (date != null) {
|
|
1375
|
+
;
|
|
1376
|
+
query2(this.el).val(date).trigger("input").trigger("change");
|
|
1377
|
+
}
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
/*
|
|
1382
|
+
* INTERNAL FUNCTIONS
|
|
1383
|
+
*/
|
|
1384
|
+
isStrValid(ch, loose) {
|
|
1385
|
+
let isValid = true;
|
|
1386
|
+
switch (this.type) {
|
|
1387
|
+
case "int":
|
|
1388
|
+
if (loose && ["-", this.options.groupSymbol].includes(ch)) {
|
|
1389
|
+
isValid = true;
|
|
1390
|
+
} else {
|
|
1391
|
+
isValid = TsUtils.isInt(ch.replace(this.options.numberRE, ""));
|
|
1392
|
+
}
|
|
1393
|
+
break;
|
|
1394
|
+
case "percent":
|
|
1395
|
+
ch = ch.replace(/%/g, "");
|
|
1396
|
+
// falls through to float
|
|
1397
|
+
case "float":
|
|
1398
|
+
if (loose && ["-", "", this.options.decimalSymbol, this.options.groupSymbol].includes(ch)) {
|
|
1399
|
+
isValid = true;
|
|
1400
|
+
} else {
|
|
1401
|
+
isValid = TsUtils.isFloat(ch.replace(this.options.numberRE, ""));
|
|
1402
|
+
}
|
|
1403
|
+
break;
|
|
1404
|
+
case "money":
|
|
1405
|
+
case "currency":
|
|
1406
|
+
if (loose && [
|
|
1407
|
+
"-",
|
|
1408
|
+
this.options.decimalSymbol,
|
|
1409
|
+
this.options.groupSymbol,
|
|
1410
|
+
this.options.currency.prefix,
|
|
1411
|
+
// any: cast-to-any for dynamic dispatch; TsField instance shape varies by `type` (text/list/date/color/etc) at runtime
|
|
1412
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1413
|
+
this.options.currency.suffix
|
|
1414
|
+
].includes(ch)) {
|
|
1415
|
+
isValid = true;
|
|
1416
|
+
} else {
|
|
1417
|
+
isValid = TsUtils.isFloat(ch.replace(this.options.moneyRE, ""));
|
|
1418
|
+
}
|
|
1419
|
+
break;
|
|
1420
|
+
case "bin":
|
|
1421
|
+
isValid = TsUtils.isBin(ch);
|
|
1422
|
+
break;
|
|
1423
|
+
case "color":
|
|
1424
|
+
case "hex":
|
|
1425
|
+
isValid = TsUtils.isHex(ch);
|
|
1426
|
+
break;
|
|
1427
|
+
case "alphanumeric":
|
|
1428
|
+
isValid = TsUtils.isAlphaNumeric(ch);
|
|
1429
|
+
break;
|
|
1430
|
+
}
|
|
1431
|
+
return isValid;
|
|
1432
|
+
}
|
|
1433
|
+
addPrefix() {
|
|
1434
|
+
if (!this.options.prefix) {
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
const styles = getComputedStyle(this.el);
|
|
1438
|
+
if (this.tmp["old-padding-left"] == null) {
|
|
1439
|
+
this.tmp["old-padding-left"] = styles["padding-left"];
|
|
1440
|
+
}
|
|
1441
|
+
if (this.helpers.prefix) query2(this.helpers.prefix).remove();
|
|
1442
|
+
query2(this.el).before(`<div class="tsg-field-helper">${this.options.prefix}</div>`);
|
|
1443
|
+
const helper = query2(this.el).get(0).previousElementSibling;
|
|
1444
|
+
query2(helper).css({
|
|
1445
|
+
"color": styles["color"],
|
|
1446
|
+
"font-family": styles["font-family"],
|
|
1447
|
+
"font-size": styles["font-size"],
|
|
1448
|
+
"height": this.el.clientHeight + "px",
|
|
1449
|
+
"padding-top": parseInt(styles["padding-top"], 10) + 1 + "px",
|
|
1450
|
+
"padding-bottom": parseInt(styles["padding-bottom"], 10) - 1 + "px",
|
|
1451
|
+
"padding-left": this.tmp["old-padding-left"] ?? "",
|
|
1452
|
+
"padding-right": 0,
|
|
1453
|
+
"margin-top": parseInt(styles["margin-top"], 10) + "px",
|
|
1454
|
+
"margin-bottom": parseInt(styles["margin-bottom"], 10) + "px",
|
|
1455
|
+
"margin-left": styles["margin-left"],
|
|
1456
|
+
"margin-right": 0,
|
|
1457
|
+
"z-index": 1,
|
|
1458
|
+
"display": "inline-flex",
|
|
1459
|
+
"align-items": "center"
|
|
1460
|
+
});
|
|
1461
|
+
query2(this.el).css("padding-left", helper.clientWidth + "px !important");
|
|
1462
|
+
this.helpers.prefix = helper;
|
|
1463
|
+
}
|
|
1464
|
+
addSuffix() {
|
|
1465
|
+
if (!this.options.suffix && !this.options.arrows) {
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
const styles = getComputedStyle(this.el);
|
|
1469
|
+
if (this.tmp["old-padding-right"] == null) {
|
|
1470
|
+
this.tmp["old-padding-right"] = styles["padding-right"];
|
|
1471
|
+
}
|
|
1472
|
+
let pr = parseInt(styles["padding-right"] || "0");
|
|
1473
|
+
if (this.options.arrows) {
|
|
1474
|
+
if (this.helpers.arrows) query2(this.helpers.arrows).remove();
|
|
1475
|
+
query2(this.el).after(
|
|
1476
|
+
'<div class="tsg-field-helper" style="border: 1px solid transparent">  <div class="tsg-field-up" type="up"> <div class="arrow-up" type="up"></div> </div> <div class="tsg-field-down" type="down"> <div class="arrow-down" type="down"></div> </div></div>'
|
|
1477
|
+
);
|
|
1478
|
+
const arrowHelper = query2(this.el).get(0).nextElementSibling;
|
|
1479
|
+
const $arrowHelper = query2(arrowHelper);
|
|
1480
|
+
$arrowHelper.css({
|
|
1481
|
+
"color": styles["color"],
|
|
1482
|
+
"font-family": styles["font-family"],
|
|
1483
|
+
"font-size": styles["font-size"],
|
|
1484
|
+
"height": this.el.clientHeight + "px",
|
|
1485
|
+
"padding": 0,
|
|
1486
|
+
"margin-top": parseInt(styles["margin-top"], 10) + 1 + "px",
|
|
1487
|
+
"margin-bottom": 0,
|
|
1488
|
+
"border-left": "1px solid silver",
|
|
1489
|
+
"width": "16px",
|
|
1490
|
+
"transform": "translateX(-100%)"
|
|
1491
|
+
});
|
|
1492
|
+
$arrowHelper.on("mousedown", (event) => {
|
|
1493
|
+
const mouseEvent = event;
|
|
1494
|
+
if (query2(mouseEvent.target).hasClass("arrow-up")) {
|
|
1495
|
+
this.keyDown(mouseEvent, { keyCode: 38 });
|
|
1496
|
+
}
|
|
1497
|
+
if (query2(mouseEvent.target).hasClass("arrow-down")) {
|
|
1498
|
+
this.keyDown(mouseEvent, { keyCode: 40 });
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
pr += arrowHelper.clientWidth;
|
|
1502
|
+
query2(this.el).css("padding-right", pr + "px !important");
|
|
1503
|
+
this.helpers.arrows = arrowHelper;
|
|
1504
|
+
}
|
|
1505
|
+
if (this.options.suffix !== "") {
|
|
1506
|
+
if (this.helpers.suffix) query2(this.helpers.suffix).remove();
|
|
1507
|
+
query2(this.el).after(`<div class="tsg-field-helper">${this.options.suffix}</div>`);
|
|
1508
|
+
const suffixHelper = query2(this.el).get(0).nextElementSibling;
|
|
1509
|
+
query2(suffixHelper).css({
|
|
1510
|
+
"color": styles["color"],
|
|
1511
|
+
"font-family": styles["font-family"],
|
|
1512
|
+
"font-size": styles["font-size"],
|
|
1513
|
+
"height": this.el.clientHeight + "px",
|
|
1514
|
+
"padding-top": styles["padding-top"],
|
|
1515
|
+
"padding-bottom": styles["padding-bottom"],
|
|
1516
|
+
"padding-left": 0,
|
|
1517
|
+
"padding-right": styles["padding-right"],
|
|
1518
|
+
"margin-top": parseInt(styles["margin-top"], 10) + 2 + "px",
|
|
1519
|
+
"margin-bottom": parseInt(styles["margin-bottom"], 10) + 1 + "px",
|
|
1520
|
+
"transform": "translateX(-100%)"
|
|
1521
|
+
});
|
|
1522
|
+
query2(this.el).css("padding-right", suffixHelper.clientWidth + "px !important");
|
|
1523
|
+
this.helpers.suffix = suffixHelper;
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
// Only used for list
|
|
1527
|
+
addSearch() {
|
|
1528
|
+
if (this.type !== "list") return;
|
|
1529
|
+
if (this.helpers.search) query2(this.helpers.search).remove();
|
|
1530
|
+
let tabIndex = parseInt(query2(this.el).attr("tabIndex"));
|
|
1531
|
+
if (!isNaN(tabIndex) && tabIndex !== -1) this.tmp["old-tabIndex"] = tabIndex;
|
|
1532
|
+
if (this.tmp["old-tabIndex"]) tabIndex = this.tmp["old-tabIndex"];
|
|
1533
|
+
if (tabIndex == null || isNaN(tabIndex)) tabIndex = 0;
|
|
1534
|
+
let searchId = "";
|
|
1535
|
+
if (query2(this.el).attr("id") != null) {
|
|
1536
|
+
searchId = 'id="' + query2(this.el).attr("id") + '_search"';
|
|
1537
|
+
}
|
|
1538
|
+
const html = `
|
|
1539
|
+
<div class="tsg-field-helper">
|
|
1540
|
+
<span class="tsg-icon tsg-icon-search"></span>
|
|
1541
|
+
<input ${searchId} type="text" tabIndex="${tabIndex}" ${query2(this.el).prop("readOnly") ? "readonly" : ""}
|
|
1542
|
+
autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false"/>
|
|
1543
|
+
</div>`;
|
|
1544
|
+
query2(this.el).attr("tabindex", String(-1)).before(html);
|
|
1545
|
+
const helper = query2(this.el).get(0).previousElementSibling;
|
|
1546
|
+
this.helpers.search = helper;
|
|
1547
|
+
this.helpers.search_focus = query2(helper).find("input").get(0);
|
|
1548
|
+
const styles = getComputedStyle(this.el);
|
|
1549
|
+
const $helperSearch = query2(helper);
|
|
1550
|
+
$helperSearch.css({
|
|
1551
|
+
width: this.el.clientWidth + "px",
|
|
1552
|
+
"margin-top": styles["margin-top"],
|
|
1553
|
+
"margin-left": styles["margin-left"],
|
|
1554
|
+
"margin-bottom": styles["margin-bottom"],
|
|
1555
|
+
"margin-right": styles["margin-right"]
|
|
1556
|
+
});
|
|
1557
|
+
$helperSearch.find("input").css({
|
|
1558
|
+
cursor: "default",
|
|
1559
|
+
width: "100%",
|
|
1560
|
+
opacity: 1,
|
|
1561
|
+
padding: styles["padding"],
|
|
1562
|
+
margin: styles["margin"],
|
|
1563
|
+
border: "1px solid transparent",
|
|
1564
|
+
"background-color": "transparent"
|
|
1565
|
+
});
|
|
1566
|
+
query2(helper).find("input").off(".tsg-helper").on("focus.tsg-helper", (event) => {
|
|
1567
|
+
const focusEvent = event;
|
|
1568
|
+
query2(focusEvent.target).val("");
|
|
1569
|
+
this.tmp.pholder = query2(this.el).attr("placeholder") ?? "";
|
|
1570
|
+
this.focus(focusEvent);
|
|
1571
|
+
focusEvent.stopPropagation();
|
|
1572
|
+
}).on("blur.tsg-helper", (event) => {
|
|
1573
|
+
const focusEvent = event;
|
|
1574
|
+
query2(focusEvent.target).val("");
|
|
1575
|
+
if (this.tmp.pholder != null) query2(this.el).attr("placeholder", this.tmp.pholder);
|
|
1576
|
+
this.blur(focusEvent);
|
|
1577
|
+
focusEvent.stopPropagation();
|
|
1578
|
+
}).on("keydown.tsg-helper", (event) => {
|
|
1579
|
+
this.keyDown(event);
|
|
1580
|
+
}).on("keyup.tsg-helper", (event) => {
|
|
1581
|
+
this.keyUp(event);
|
|
1582
|
+
});
|
|
1583
|
+
query2(helper).off(".tsg-helper").on("click.tsg-helper", (_event) => {
|
|
1584
|
+
query2(helper).find("input").get(0).focus();
|
|
1585
|
+
});
|
|
1586
|
+
}
|
|
1587
|
+
// Used in enum/file
|
|
1588
|
+
addMultiSearch() {
|
|
1589
|
+
if (!["enum", "file"].includes(this.type)) {
|
|
1590
|
+
return;
|
|
1591
|
+
}
|
|
1592
|
+
query2(this.helpers.multi).remove();
|
|
1593
|
+
let html = "";
|
|
1594
|
+
const styles = getComputedStyle(this.el);
|
|
1595
|
+
const margin = TsUtils.stripSpaces(`
|
|
1596
|
+
margin-top: 0px;
|
|
1597
|
+
margin-bottom: 0px;
|
|
1598
|
+
margin-left: ${styles["margin-left"]};
|
|
1599
|
+
margin-right: ${styles["margin-right"]};
|
|
1600
|
+
width: ${TsUtils.getSize(this.el, "width") - parseInt(styles["margin-left"], 10) - parseInt(styles["margin-right"], 10)}px;
|
|
1601
|
+
`);
|
|
1602
|
+
if (this.tmp["min-height"] == null) {
|
|
1603
|
+
const min = this.tmp["min-height"] = parseInt((styles["min-height"] != "none" ? styles["min-height"] : "0") || "0");
|
|
1604
|
+
const current = parseInt(styles["height"]);
|
|
1605
|
+
this.tmp["min-height"] = Math.max(min, current);
|
|
1606
|
+
}
|
|
1607
|
+
if (this.tmp["max-height"] == null && styles["max-height"] != "none") {
|
|
1608
|
+
this.tmp["max-height"] = parseInt(styles["max-height"]);
|
|
1609
|
+
}
|
|
1610
|
+
let searchId = "";
|
|
1611
|
+
if (query2(this.el).attr("id") != null) {
|
|
1612
|
+
searchId = `id="${query2(this.el).attr("id")}_search"`;
|
|
1613
|
+
}
|
|
1614
|
+
let tabIndex = parseInt(query2(this.el).attr("tabIndex"));
|
|
1615
|
+
if (!isNaN(tabIndex) && tabIndex !== -1) this.tmp["old-tabIndex"] = tabIndex;
|
|
1616
|
+
if (this.tmp["old-tabIndex"]) tabIndex = this.tmp["old-tabIndex"];
|
|
1617
|
+
if (tabIndex == null || isNaN(tabIndex)) tabIndex = 0;
|
|
1618
|
+
if (this.type === "enum") {
|
|
1619
|
+
html = `
|
|
1620
|
+
<div class="tsg-field-helper tsg-list" style="${margin}">
|
|
1621
|
+
<div class="tsg-multi-items">
|
|
1622
|
+
<div class="li-search">
|
|
1623
|
+
<input ${searchId} type="text" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false"
|
|
1624
|
+
tabindex="${tabIndex}"
|
|
1625
|
+
${query2(this.el).prop("readOnly") ? "readonly" : ""}
|
|
1626
|
+
${query2(this.el).prop("disabled") ? "disabled" : ""}>
|
|
1627
|
+
</div>
|
|
1628
|
+
</div>
|
|
1629
|
+
</div>`;
|
|
1630
|
+
}
|
|
1631
|
+
if (this.type === "file") {
|
|
1632
|
+
html = `
|
|
1633
|
+
<div class="tsg-field-helper tsg-list" style="${margin}">
|
|
1634
|
+
<div class="tsg-multi-file">
|
|
1635
|
+
<input name="attachment" class="file-input" type="file" tabindex="-1"'
|
|
1636
|
+
style="width: 100%; height: 100%; opacity: 0" title=""
|
|
1637
|
+
${this.options.max !== 1 ? "multiple" : ""}
|
|
1638
|
+
${query2(this.el).prop("readOnly") || query2(this.el).prop("disabled") ? "disabled" : ""}
|
|
1639
|
+
${query2(this.el).attr("accept") ? ' accept="' + query2(this.el).attr("accept") + '"' : ""}>
|
|
1640
|
+
</div>
|
|
1641
|
+
<div class="tsg-multi-items">
|
|
1642
|
+
<div class="li-search" style="display: none">
|
|
1643
|
+
<input ${searchId} type="text" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false"
|
|
1644
|
+
tabindex="${tabIndex}"
|
|
1645
|
+
${query2(this.el).prop("readOnly") ? "readonly" : ""}
|
|
1646
|
+
${query2(this.el).prop("disabled") ? "disabled" : ""}>
|
|
1647
|
+
</div>
|
|
1648
|
+
</div>
|
|
1649
|
+
</div>`;
|
|
1650
|
+
}
|
|
1651
|
+
this.tmp["old-background-color"] = styles["background-color"];
|
|
1652
|
+
this.tmp["old-border-color"] = styles["border-color"];
|
|
1653
|
+
query2(this.el).before(html).css({
|
|
1654
|
+
"border-color": "transparent",
|
|
1655
|
+
"background-color": "transparent"
|
|
1656
|
+
});
|
|
1657
|
+
const div = query2(this.el.previousElementSibling);
|
|
1658
|
+
this.helpers.multi = div;
|
|
1659
|
+
query2(this.el).attr("tabindex", String(-1));
|
|
1660
|
+
div.on("mousedown", (event) => {
|
|
1661
|
+
query2(event.target).addClass("has-focus");
|
|
1662
|
+
}).on("mouseup", (event) => {
|
|
1663
|
+
query2(event.target).removeClass("has-focus");
|
|
1664
|
+
}).on("click", (event) => {
|
|
1665
|
+
this.focus(event);
|
|
1666
|
+
this.updateOverlay();
|
|
1667
|
+
});
|
|
1668
|
+
div.find("input:not(.file-input)").on("click", (event) => {
|
|
1669
|
+
this.click(event);
|
|
1670
|
+
}).on("focus", (event) => {
|
|
1671
|
+
this.focus(event);
|
|
1672
|
+
}).on("blur", (event) => {
|
|
1673
|
+
this.blur(event);
|
|
1674
|
+
}).on("keydown", (event) => {
|
|
1675
|
+
this.keyDown(event);
|
|
1676
|
+
}).on("keyup", (event) => {
|
|
1677
|
+
this.keyUp(event);
|
|
1678
|
+
});
|
|
1679
|
+
if (this.type === "file") {
|
|
1680
|
+
div.find("input.file-input").off(".drag").on("click.drag", (event) => {
|
|
1681
|
+
const mouseEvent = event;
|
|
1682
|
+
mouseEvent.stopPropagation();
|
|
1683
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
1684
|
+
this.focus(mouseEvent);
|
|
1685
|
+
}).on("dragenter.drag", (_event) => {
|
|
1686
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
1687
|
+
div.addClass("tsg-file-dragover");
|
|
1688
|
+
}).on("dragleave.drag", (_event) => {
|
|
1689
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
1690
|
+
div.removeClass("tsg-file-dragover");
|
|
1691
|
+
}).on("drop.drag", (event) => {
|
|
1692
|
+
const dragEvent = event;
|
|
1693
|
+
if (query2(this.el).prop("readOnly") || query2(this.el).prop("disabled")) return;
|
|
1694
|
+
div.removeClass("tsg-file-dragover");
|
|
1695
|
+
const files = Array.from(dragEvent.dataTransfer?.files ?? []);
|
|
1696
|
+
files.forEach((file) => {
|
|
1697
|
+
this.addFile(file);
|
|
1698
|
+
});
|
|
1699
|
+
this.focus(dragEvent);
|
|
1700
|
+
dragEvent.preventDefault();
|
|
1701
|
+
dragEvent.stopPropagation();
|
|
1702
|
+
}).on("dragover.drag", (event) => {
|
|
1703
|
+
const dragEvent = event;
|
|
1704
|
+
dragEvent.preventDefault();
|
|
1705
|
+
dragEvent.stopPropagation();
|
|
1706
|
+
}).on("change.drag", (event) => {
|
|
1707
|
+
const target = event.target;
|
|
1708
|
+
if (target.files != null) {
|
|
1709
|
+
Array.from(target.files).forEach((file) => {
|
|
1710
|
+
this.addFile(file);
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
this.focus(event);
|
|
1714
|
+
});
|
|
1715
|
+
}
|
|
1716
|
+
this.refresh();
|
|
1717
|
+
}
|
|
1718
|
+
addFile(file) {
|
|
1719
|
+
const options = this.options;
|
|
1720
|
+
const selected = this.selected;
|
|
1721
|
+
const newItem = {
|
|
1722
|
+
name: file.name,
|
|
1723
|
+
type: file.type,
|
|
1724
|
+
modified: new Date(file.lastModified),
|
|
1725
|
+
size: file.size,
|
|
1726
|
+
content: null,
|
|
1727
|
+
file
|
|
1728
|
+
};
|
|
1729
|
+
let size = 0;
|
|
1730
|
+
let cnt = 0;
|
|
1731
|
+
const errors = [];
|
|
1732
|
+
if (Array.isArray(selected)) {
|
|
1733
|
+
selected.forEach((item) => {
|
|
1734
|
+
if (item.name == file.name && item.size == file.size) {
|
|
1735
|
+
errors.push(TsUtils.lang('The file "${name}" (${size}) is already added.', {
|
|
1736
|
+
name: file.name,
|
|
1737
|
+
size: String(TsUtils.formatSize(file.size))
|
|
1738
|
+
}));
|
|
1739
|
+
}
|
|
1740
|
+
size += item.size;
|
|
1741
|
+
cnt++;
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
if (options.maxFileSize !== 0 && newItem.size > options.maxFileSize) {
|
|
1745
|
+
errors.push(TsUtils.lang("Maximum file size is ${size}", { size: String(TsUtils.formatSize(options.maxFileSize)) }));
|
|
1746
|
+
}
|
|
1747
|
+
if (options.maxSize !== 0 && size + newItem.size > options.maxSize) {
|
|
1748
|
+
errors.push(TsUtils.lang("Maximum total size is ${size}", { size: String(TsUtils.formatSize(options.maxSize)) }));
|
|
1749
|
+
}
|
|
1750
|
+
if (options.max !== 0 && cnt >= options.max) {
|
|
1751
|
+
errors.push(TsUtils.lang("Maximum number of files is ${count}", { count: options.max }));
|
|
1752
|
+
}
|
|
1753
|
+
const edata = this.trigger("add", { target: this.el, file: newItem, total: cnt, totalSize: size, errors });
|
|
1754
|
+
if (edata.isCancelled === true) return;
|
|
1755
|
+
if (errors.length > 0) {
|
|
1756
|
+
if (options.showErrors) {
|
|
1757
|
+
TsTooltip2.show({
|
|
1758
|
+
anchor: this.el,
|
|
1759
|
+
html: "Errors: " + errors.join("<br>"),
|
|
1760
|
+
hideOn: ["input", "doc-click"]
|
|
1761
|
+
});
|
|
1762
|
+
}
|
|
1763
|
+
console.log("ERRORS (while adding files): ", errors);
|
|
1764
|
+
return;
|
|
1765
|
+
}
|
|
1766
|
+
selected.push(newItem);
|
|
1767
|
+
if (typeof FileReader !== "undefined" && options.readContent === true) {
|
|
1768
|
+
const reader = new FileReader();
|
|
1769
|
+
reader.onload = (event) => {
|
|
1770
|
+
const fl = event.target?.result ?? "";
|
|
1771
|
+
const ind = fl.indexOf(",");
|
|
1772
|
+
newItem.content = fl.substr(ind + 1);
|
|
1773
|
+
this.refresh();
|
|
1774
|
+
query2(this.el).trigger("input").trigger("change");
|
|
1775
|
+
edata.finish();
|
|
1776
|
+
};
|
|
1777
|
+
reader.readAsDataURL(file);
|
|
1778
|
+
} else {
|
|
1779
|
+
this.refresh();
|
|
1780
|
+
query2(this.el).trigger("input").trigger("change");
|
|
1781
|
+
edata.finish();
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
// move cursror to end
|
|
1785
|
+
moveCaret2end() {
|
|
1786
|
+
setTimeout(() => {
|
|
1787
|
+
this.el.setSelectionRange(this.el.value.length, this.el.value.length);
|
|
1788
|
+
}, 0);
|
|
1789
|
+
}
|
|
1790
|
+
};
|
|
1791
|
+
|
|
1792
|
+
export {
|
|
1793
|
+
TsField
|
|
1794
|
+
};
|
|
1795
|
+
//# sourceMappingURL=chunk-KLJ35UAH.js.map
|