selective-ui 1.0.3 → 1.0.4
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/selective-ui.esm.js +153 -14
- package/dist/selective-ui.esm.js.map +1 -1
- package/dist/selective-ui.esm.min.js +1 -1
- package/dist/selective-ui.esm.min.js.br +0 -0
- package/dist/selective-ui.min.js +2 -2
- package/dist/selective-ui.min.js.br +0 -0
- package/dist/selective-ui.umd.js +153 -14
- package/dist/selective-ui.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/js/components/selectbox.js +69 -12
- package/src/js/core/search-controller.js +82 -0
- package/src/js/index.js +1 -1
package/dist/selective-ui.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Selective UI v1.0.
|
|
1
|
+
/*! Selective UI v1.0.4 | MIT License */
|
|
2
2
|
/**
|
|
3
3
|
* @class
|
|
4
4
|
*/
|
|
@@ -4184,6 +4184,88 @@ class SearchController {
|
|
|
4184
4184
|
return !(!this.#ajaxConfig);
|
|
4185
4185
|
}
|
|
4186
4186
|
|
|
4187
|
+
/**
|
|
4188
|
+
* Load specific options by their values from server
|
|
4189
|
+
* @param {string|string[]} values - Values to load
|
|
4190
|
+
* @returns {Promise<{success: boolean, items: Array, message?: string}>}
|
|
4191
|
+
*/
|
|
4192
|
+
async loadByValues(values) {
|
|
4193
|
+
if (!this.#ajaxConfig) {
|
|
4194
|
+
return { success: false, items: [], message: "Ajax not configured" };
|
|
4195
|
+
}
|
|
4196
|
+
|
|
4197
|
+
const valuesArray = Array.isArray(values) ? values : [values];
|
|
4198
|
+
if (valuesArray.length === 0) {
|
|
4199
|
+
return { success: true, items: [] };
|
|
4200
|
+
}
|
|
4201
|
+
|
|
4202
|
+
try {
|
|
4203
|
+
const cfg = this.#ajaxConfig;
|
|
4204
|
+
|
|
4205
|
+
let payload;
|
|
4206
|
+
if (typeof cfg.dataByValues === "function") {
|
|
4207
|
+
payload = cfg.dataByValues(valuesArray);
|
|
4208
|
+
} else {
|
|
4209
|
+
payload = {
|
|
4210
|
+
values: valuesArray.join(","),
|
|
4211
|
+
load_by_values: "1",
|
|
4212
|
+
...(typeof cfg.data === "function" ? cfg.data("", 0) : (cfg.data || {}))
|
|
4213
|
+
};
|
|
4214
|
+
}
|
|
4215
|
+
|
|
4216
|
+
let response;
|
|
4217
|
+
if (cfg.method === "POST") {
|
|
4218
|
+
const formData = new URLSearchParams();
|
|
4219
|
+
Object.keys(payload).forEach(key => {
|
|
4220
|
+
formData.append(key, payload[key]);
|
|
4221
|
+
});
|
|
4222
|
+
|
|
4223
|
+
response = await fetch(cfg.url, {
|
|
4224
|
+
method: "POST",
|
|
4225
|
+
body: formData,
|
|
4226
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" }
|
|
4227
|
+
});
|
|
4228
|
+
} else {
|
|
4229
|
+
const params = new URLSearchParams(payload).toString();
|
|
4230
|
+
response = await fetch(`${cfg.url}?${params}`);
|
|
4231
|
+
}
|
|
4232
|
+
|
|
4233
|
+
if (!response.ok) {
|
|
4234
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
4235
|
+
}
|
|
4236
|
+
|
|
4237
|
+
const data = await response.json();
|
|
4238
|
+
const result = this.#parseResponse(data);
|
|
4239
|
+
|
|
4240
|
+
return {
|
|
4241
|
+
success: true,
|
|
4242
|
+
items: result.items
|
|
4243
|
+
};
|
|
4244
|
+
} catch (error) {
|
|
4245
|
+
console.error("Load by values error:", error);
|
|
4246
|
+
return {
|
|
4247
|
+
success: false,
|
|
4248
|
+
message: error.message,
|
|
4249
|
+
items: []
|
|
4250
|
+
};
|
|
4251
|
+
}
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4254
|
+
/**
|
|
4255
|
+
* Check if values exist in current options
|
|
4256
|
+
* @param {string[]} values - Values to check
|
|
4257
|
+
* @returns {{existing: string[], missing: string[]}}
|
|
4258
|
+
*/
|
|
4259
|
+
checkMissingValues(values) {
|
|
4260
|
+
const allOptions = Array.from(this.#select.options);
|
|
4261
|
+
const existingValues = allOptions.map(opt => opt.value);
|
|
4262
|
+
|
|
4263
|
+
const existing = values.filter(v => existingValues.includes(v));
|
|
4264
|
+
const missing = values.filter(v => !existingValues.includes(v));
|
|
4265
|
+
|
|
4266
|
+
return { existing, missing };
|
|
4267
|
+
}
|
|
4268
|
+
|
|
4187
4269
|
/**
|
|
4188
4270
|
* Configures AJAX settings used for remote searching and pagination.
|
|
4189
4271
|
*
|
|
@@ -4916,13 +4998,7 @@ class SelectBox {
|
|
|
4916
4998
|
tag: {
|
|
4917
4999
|
node: "div",
|
|
4918
5000
|
classList: "selective-ui-view",
|
|
4919
|
-
tabIndex: 0,
|
|
4920
|
-
role: "combobox",
|
|
4921
|
-
ariaExpanded: "false",
|
|
4922
|
-
ariaLabelledby: options.SEID_HOLDER,
|
|
4923
|
-
ariaControls: options.SEID_LIST,
|
|
4924
|
-
ariaHaspopup: "true",
|
|
4925
|
-
ariaMultiselectable: options.multiple ? "true" : "false",
|
|
5001
|
+
tabIndex: 0,
|
|
4926
5002
|
onkeydown: (e) => {
|
|
4927
5003
|
if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
|
|
4928
5004
|
e.preventDefault();
|
|
@@ -5242,10 +5318,21 @@ class SelectBox {
|
|
|
5242
5318
|
},
|
|
5243
5319
|
setValue(evtToken = null, value, trigger = true, force = false) {
|
|
5244
5320
|
!Array.isArray(value) && (value = [value]);
|
|
5321
|
+
|
|
5322
|
+
value = value.filter(v => v !== "" && v != null);
|
|
5323
|
+
|
|
5324
|
+
if (value.length === 0) {
|
|
5325
|
+
superThis.getModelOption().forEach(modelOption => {
|
|
5326
|
+
modelOption["selectedNonTrigger"] = false;
|
|
5327
|
+
});
|
|
5328
|
+
this.change(false, trigger);
|
|
5329
|
+
return;
|
|
5330
|
+
}
|
|
5245
5331
|
|
|
5246
5332
|
if (bindedOptions.multiple && bindedOptions.maxSelected > 0) {
|
|
5247
5333
|
if (value.length > bindedOptions.maxSelected) {
|
|
5248
|
-
|
|
5334
|
+
console.warn(`Cannot select more than ${bindedOptions.maxSelected} items`);
|
|
5335
|
+
return;
|
|
5249
5336
|
}
|
|
5250
5337
|
}
|
|
5251
5338
|
|
|
@@ -5253,12 +5340,58 @@ class SelectBox {
|
|
|
5253
5340
|
return;
|
|
5254
5341
|
}
|
|
5255
5342
|
|
|
5343
|
+
if (container.searchController?.isAjax()) {
|
|
5344
|
+
const { existing, missing } = container.searchController.checkMissingValues(value);
|
|
5345
|
+
|
|
5346
|
+
if (missing.length > 0) {
|
|
5347
|
+
console.log(`Loading ${missing.length} missing values from server...`);
|
|
5348
|
+
|
|
5349
|
+
(async () => {
|
|
5350
|
+
if (bindedOptions.loadingfield) {
|
|
5351
|
+
container.popup?.showLoading();
|
|
5352
|
+
}
|
|
5353
|
+
|
|
5354
|
+
try {
|
|
5355
|
+
const result = await container.searchController.loadByValues(missing);
|
|
5356
|
+
|
|
5357
|
+
if (result.success && result.items.length > 0) {
|
|
5358
|
+
result.items.forEach(item => {
|
|
5359
|
+
if (missing.includes(item.value)) {
|
|
5360
|
+
item.selected = true;
|
|
5361
|
+
}
|
|
5362
|
+
});
|
|
5363
|
+
|
|
5364
|
+
container.searchController['#applyAjaxResult'](
|
|
5365
|
+
result.items,
|
|
5366
|
+
true,
|
|
5367
|
+
true
|
|
5368
|
+
);
|
|
5369
|
+
|
|
5370
|
+
setTimeout(() => {
|
|
5371
|
+
superThis.getModelOption().forEach(modelOption => {
|
|
5372
|
+
modelOption["selectedNonTrigger"] = value.some(v => v == modelOption["value"]);
|
|
5373
|
+
});
|
|
5374
|
+
this.change(false, false);
|
|
5375
|
+
}, 100);
|
|
5376
|
+
} else if (missing.length > 0) {
|
|
5377
|
+
console.warn(`Could not load ${missing.length} values:`, missing);
|
|
5378
|
+
}
|
|
5379
|
+
} catch (error) {
|
|
5380
|
+
console.error("Error loading missing values:", error);
|
|
5381
|
+
} finally {
|
|
5382
|
+
if (bindedOptions.loadingfield) {
|
|
5383
|
+
container.popup?.hideLoading();
|
|
5384
|
+
}
|
|
5385
|
+
}
|
|
5386
|
+
})();
|
|
5387
|
+
}
|
|
5388
|
+
}
|
|
5389
|
+
|
|
5256
5390
|
if (trigger) {
|
|
5257
5391
|
const beforeChangeToken = iEvents.callEvent([this], ...bindedOptions.on.beforeChange);
|
|
5258
5392
|
if (beforeChangeToken.isCancel) {
|
|
5259
5393
|
return;
|
|
5260
5394
|
}
|
|
5261
|
-
|
|
5262
5395
|
superThis.oldValue = this.value;
|
|
5263
5396
|
}
|
|
5264
5397
|
|
|
@@ -5266,7 +5399,7 @@ class SelectBox {
|
|
|
5266
5399
|
modelOption["selectedNonTrigger"] = value.some(v => v == modelOption["value"]);
|
|
5267
5400
|
});
|
|
5268
5401
|
|
|
5269
|
-
if (!bindedOptions.multiple){
|
|
5402
|
+
if (!bindedOptions.multiple && value.length > 0) {
|
|
5270
5403
|
container.targetElement.value = value[0];
|
|
5271
5404
|
}
|
|
5272
5405
|
|
|
@@ -5318,8 +5451,14 @@ class SelectBox {
|
|
|
5318
5451
|
|
|
5319
5452
|
container.popup.open();
|
|
5320
5453
|
container.searchbox.show();
|
|
5321
|
-
|
|
5322
|
-
|
|
5454
|
+
const ViewPanel = /** @type {HTMLElement} */ (container.tags.ViewPanel);
|
|
5455
|
+
ViewPanel.setAttribute("aria-expanded", "true");
|
|
5456
|
+
ViewPanel.setAttribute("aria-controls", bindedOptions.SEID_LIST);
|
|
5457
|
+
ViewPanel.setAttribute("aria-haspopup", "listbox");
|
|
5458
|
+
ViewPanel.setAttribute("aria-labelledby", bindedOptions.SEID_HOLDER);
|
|
5459
|
+
if (bindedOptions.multiple) {
|
|
5460
|
+
ViewPanel.setAttribute("aria-multiselectable", "true");
|
|
5461
|
+
}
|
|
5323
5462
|
|
|
5324
5463
|
iEvents.callEvent([this], ...bindedOptions.on.show);
|
|
5325
5464
|
|
|
@@ -5987,7 +6126,7 @@ function markLoaded(name, version, api) {
|
|
|
5987
6126
|
console.log(`[${name}] v${version} loaded successfully`);
|
|
5988
6127
|
}
|
|
5989
6128
|
|
|
5990
|
-
const version = "1.0.
|
|
6129
|
+
const version = "1.0.4";
|
|
5991
6130
|
const name = "SelectiveUI";
|
|
5992
6131
|
|
|
5993
6132
|
const alreadyLoaded = checkDuplicate(name);
|