web-mojo 2.2.6 → 2.2.8
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/admin.cjs.js +1 -1
- package/dist/admin.cjs.js.map +1 -1
- package/dist/admin.es.js +26 -7
- package/dist/admin.es.js.map +1 -1
- package/dist/auth.cjs.js +1 -1
- package/dist/auth.es.js +1 -1
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.es.js +3 -3
- package/dist/chunks/{ChatView-BcPvM8jM.js → ChatView-2mFEGsXL.js} +283 -97
- package/dist/chunks/ChatView-2mFEGsXL.js.map +1 -0
- package/dist/chunks/ChatView-DfKH7ep8.js +2 -0
- package/dist/chunks/ChatView-DfKH7ep8.js.map +1 -0
- package/dist/chunks/{Dialog-C-Xl4SYW.js → Dialog-BBZUgBbz.js} +2 -2
- package/dist/chunks/{Dialog-C-Xl4SYW.js.map → Dialog-BBZUgBbz.js.map} +1 -1
- package/dist/chunks/{Dialog-D_TcKXUc.js → Dialog-DrCs-ex1.js} +3 -3
- package/dist/chunks/{Dialog-D_TcKXUc.js.map → Dialog-DrCs-ex1.js.map} +1 -1
- package/dist/chunks/FormView-CNkSOc2U.js +3 -0
- package/dist/chunks/FormView-CNkSOc2U.js.map +1 -0
- package/dist/chunks/{FormView-UtTgxKhq.js → FormView-CwYt4vH3.js} +406 -3
- package/dist/chunks/FormView-CwYt4vH3.js.map +1 -0
- package/dist/chunks/{ListView-C9OoIPfC.js → ListView-DoF-Sr56.js} +4 -1
- package/dist/chunks/ListView-DoF-Sr56.js.map +1 -0
- package/dist/chunks/ListView-OWwlcGGg.js +2 -0
- package/dist/chunks/ListView-OWwlcGGg.js.map +1 -0
- package/dist/chunks/{MetricsMiniChartWidget-DDDtbxVu.js → MetricsMiniChartWidget-B3PHrgkn.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-DDDtbxVu.js.map → MetricsMiniChartWidget-B3PHrgkn.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-CJZo6Mzi.js → MetricsMiniChartWidget-DdZ3zNve.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-CJZo6Mzi.js.map → MetricsMiniChartWidget-DdZ3zNve.js.map} +1 -1
- package/dist/chunks/{PDFViewer-BGvS4SV2.js → PDFViewer-CkKC_E0G.js} +2 -2
- package/dist/chunks/{PDFViewer-BGvS4SV2.js.map → PDFViewer-CkKC_E0G.js.map} +1 -1
- package/dist/chunks/{PDFViewer-CBMSMWI8.js → PDFViewer-DaiTPsQH.js} +2 -2
- package/dist/chunks/{PDFViewer-CBMSMWI8.js.map → PDFViewer-DaiTPsQH.js.map} +1 -1
- package/dist/chunks/{TokenManager-sw1FUivr.js → TokenManager-D9z35vwT.js} +2 -2
- package/dist/chunks/{TokenManager-sw1FUivr.js.map → TokenManager-D9z35vwT.js.map} +1 -1
- package/dist/chunks/{TokenManager-BCgqjJTM.js → TokenManager-XwKaWaKd.js} +2 -2
- package/dist/chunks/{TokenManager-BCgqjJTM.js.map → TokenManager-XwKaWaKd.js.map} +1 -1
- package/dist/chunks/{version-Cg90gIP7.js → version-BQcvJscT.js} +4 -4
- package/dist/chunks/{version-Cg90gIP7.js.map → version-BQcvJscT.js.map} +1 -1
- package/dist/chunks/{version-e45B_7me.js → version-DhSPKHUm.js} +2 -2
- package/dist/chunks/{version-e45B_7me.js.map → version-DhSPKHUm.js.map} +1 -1
- package/dist/core.css +118 -0
- package/dist/css/web-mojo.css +1 -1
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.es.js +3 -3
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +96 -92
- package/dist/index.es.js.map +1 -1
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.es.js +4 -4
- package/dist/timeline.cjs.js +1 -1
- package/dist/timeline.es.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/ChatView-BLe7SAMj.js +0 -2
- package/dist/chunks/ChatView-BLe7SAMj.js.map +0 -1
- package/dist/chunks/ChatView-BcPvM8jM.js.map +0 -1
- package/dist/chunks/FormView-DCtLjTmF.js +0 -3
- package/dist/chunks/FormView-DCtLjTmF.js.map +0 -1
- package/dist/chunks/FormView-UtTgxKhq.js.map +0 -1
- package/dist/chunks/ListView-9b-jQTQZ.js +0 -2
- package/dist/chunks/ListView-9b-jQTQZ.js.map +0 -1
- package/dist/chunks/ListView-C9OoIPfC.js.map +0 -1
|
@@ -652,7 +652,6 @@ class FormBuilder {
|
|
|
652
652
|
}
|
|
653
653
|
}
|
|
654
654
|
if (!fieldHTML) {
|
|
655
|
-
console.log("buildFieldHTML - Processing field type:", type, "for field:", field.name);
|
|
656
655
|
switch (type) {
|
|
657
656
|
case "text":
|
|
658
657
|
fieldHTML = this.renderTextField(field);
|
|
@@ -687,6 +686,9 @@ class FormBuilder {
|
|
|
687
686
|
case "select":
|
|
688
687
|
fieldHTML = this.renderSelectField(field);
|
|
689
688
|
break;
|
|
689
|
+
case "multiselect":
|
|
690
|
+
fieldHTML = this.renderMultiSelectField(field);
|
|
691
|
+
break;
|
|
690
692
|
case "checkbox":
|
|
691
693
|
fieldHTML = this.renderCheckboxField(field);
|
|
692
694
|
break;
|
|
@@ -1189,6 +1191,59 @@ class FormBuilder {
|
|
|
1189
1191
|
};
|
|
1190
1192
|
return Mustache.render(this.templates.select, context);
|
|
1191
1193
|
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Render multiselect dropdown field
|
|
1196
|
+
* @param {Object} field - Field configuration
|
|
1197
|
+
* @returns {string} Field HTML
|
|
1198
|
+
*/
|
|
1199
|
+
renderMultiSelectField(field) {
|
|
1200
|
+
const {
|
|
1201
|
+
name,
|
|
1202
|
+
label,
|
|
1203
|
+
options = [],
|
|
1204
|
+
value = [],
|
|
1205
|
+
required = false,
|
|
1206
|
+
disabled = false,
|
|
1207
|
+
maxHeight = 300,
|
|
1208
|
+
help = field.helpText || field.help || ""
|
|
1209
|
+
} = field;
|
|
1210
|
+
const placeholder = field.placeholder || field.placeHolder || "Select...";
|
|
1211
|
+
this.getFieldId(name);
|
|
1212
|
+
const error = this.errors[name];
|
|
1213
|
+
const fieldValue = field.value ?? this.getFieldValue(name) ?? value;
|
|
1214
|
+
return `
|
|
1215
|
+
<div class="mojo-form-control">
|
|
1216
|
+
${label ? `<label class="${this.options.labelClass}">${this.escapeHtml(label)}${required ? '<span class="text-danger">*</span>' : ""}</label>` : ""}
|
|
1217
|
+
<div class="multiselect-placeholder"
|
|
1218
|
+
data-field-name="${name}"
|
|
1219
|
+
data-field-type="multiselect"
|
|
1220
|
+
data-field-config='${JSON.stringify({
|
|
1221
|
+
name,
|
|
1222
|
+
value: fieldValue,
|
|
1223
|
+
placeholder,
|
|
1224
|
+
maxHeight,
|
|
1225
|
+
disabled,
|
|
1226
|
+
required
|
|
1227
|
+
})}'>
|
|
1228
|
+
<input type="hidden" name="${name}" value="${this.escapeHtml(JSON.stringify(fieldValue))}">
|
|
1229
|
+
<select class="form-select${error ? " is-invalid" : ""}"
|
|
1230
|
+
multiple
|
|
1231
|
+
${disabled ? "disabled" : ""}
|
|
1232
|
+
${required ? "required" : ""}>
|
|
1233
|
+
${options.map((opt) => {
|
|
1234
|
+
const optValue = typeof opt === "string" ? opt : opt.value;
|
|
1235
|
+
const optLabel = typeof opt === "string" ? opt : opt.label || opt.value;
|
|
1236
|
+
const selected = Array.isArray(fieldValue) && fieldValue.includes(optValue) ? "selected" : "";
|
|
1237
|
+
return `<option value="${this.escapeHtml(optValue)}" ${selected}>${this.escapeHtml(optLabel)}</option>`;
|
|
1238
|
+
}).join("")}
|
|
1239
|
+
</select>
|
|
1240
|
+
<small class="form-text text-muted">This will be enhanced with MultiSelectDropdown component</small>
|
|
1241
|
+
</div>
|
|
1242
|
+
${help ? `<div class="${this.options.helpClass}">${this.escapeHtml(help)}</div>` : ""}
|
|
1243
|
+
${error ? `<div class="${this.options.errorClass}">${this.escapeHtml(error)}</div>` : ""}
|
|
1244
|
+
</div>
|
|
1245
|
+
`;
|
|
1246
|
+
}
|
|
1192
1247
|
/**
|
|
1193
1248
|
* Render checkbox field
|
|
1194
1249
|
* @param {Object} field - Field configuration
|
|
@@ -2203,7 +2258,12 @@ class FormBuilder {
|
|
|
2203
2258
|
const panes = tabs.map((t, i) => {
|
|
2204
2259
|
const id = `${safe}-pane-${i}`;
|
|
2205
2260
|
const isActive = i === 0;
|
|
2206
|
-
const fieldsHTML = (t.fields || []).map((f) =>
|
|
2261
|
+
const fieldsHTML = (t.fields || []).map((f) => {
|
|
2262
|
+
if (f.type === "group") {
|
|
2263
|
+
return this.buildGroupHTML(f);
|
|
2264
|
+
}
|
|
2265
|
+
return this.buildFieldHTML(f);
|
|
2266
|
+
}).join("");
|
|
2207
2267
|
return `
|
|
2208
2268
|
<div class="tab-pane fade ${isActive ? "show active" : ""}"
|
|
2209
2269
|
id="${id}"
|
|
@@ -4030,6 +4090,312 @@ class CollectionMultiSelectView extends View {
|
|
|
4030
4090
|
this.setValue(value);
|
|
4031
4091
|
}
|
|
4032
4092
|
}
|
|
4093
|
+
class MultiSelectItemsView extends View {
|
|
4094
|
+
constructor(options = {}) {
|
|
4095
|
+
super({
|
|
4096
|
+
tagName: "div",
|
|
4097
|
+
className: "multiselect-items",
|
|
4098
|
+
template: `
|
|
4099
|
+
{{#items.length}}
|
|
4100
|
+
<div class="multiselect-list" style="max-height: {{maxHeight}}px; overflow-y: auto;">
|
|
4101
|
+
{{#items}}
|
|
4102
|
+
<div class="multiselect-item form-check px-3 py-2"
|
|
4103
|
+
data-action="toggle"
|
|
4104
|
+
data-value="{{value}}"
|
|
4105
|
+
data-index="{{index}}">
|
|
4106
|
+
<input type="checkbox"
|
|
4107
|
+
class="form-check-input"
|
|
4108
|
+
id="{{id}}"
|
|
4109
|
+
{{#selected}}checked{{/selected}}
|
|
4110
|
+
{{#disabled}}disabled{{/disabled}}>
|
|
4111
|
+
<label class="form-check-label w-100" for="{{id}}">
|
|
4112
|
+
{{label}}
|
|
4113
|
+
</label>
|
|
4114
|
+
</div>
|
|
4115
|
+
{{/items}}
|
|
4116
|
+
</div>
|
|
4117
|
+
<div class="multiselect-footer border-top p-2">
|
|
4118
|
+
<button type="button" class="btn btn-sm btn-primary w-100" data-action="close-dropdown">
|
|
4119
|
+
Done
|
|
4120
|
+
</button>
|
|
4121
|
+
</div>
|
|
4122
|
+
{{/items.length}}
|
|
4123
|
+
|
|
4124
|
+
{{^items.length}}
|
|
4125
|
+
<div class="multiselect-empty text-muted text-center py-3">
|
|
4126
|
+
<small>No options available</small>
|
|
4127
|
+
</div>
|
|
4128
|
+
{{/items.length}}
|
|
4129
|
+
`,
|
|
4130
|
+
...options
|
|
4131
|
+
});
|
|
4132
|
+
this.items = options.items || [];
|
|
4133
|
+
this.maxHeight = options.maxHeight || 300;
|
|
4134
|
+
}
|
|
4135
|
+
/**
|
|
4136
|
+
* Handle item toggle
|
|
4137
|
+
*/
|
|
4138
|
+
handleActionToggle(event, element) {
|
|
4139
|
+
const value = element.getAttribute("data-value");
|
|
4140
|
+
const index = parseInt(element.getAttribute("data-index"), 10);
|
|
4141
|
+
const item = this.items[index];
|
|
4142
|
+
if (!item || item.disabled) return;
|
|
4143
|
+
item.selected = !item.selected;
|
|
4144
|
+
const checkbox = element.querySelector('input[type="checkbox"]');
|
|
4145
|
+
if (checkbox) {
|
|
4146
|
+
checkbox.checked = item.selected;
|
|
4147
|
+
}
|
|
4148
|
+
this.emit("toggle", { value, index, selected: item.selected });
|
|
4149
|
+
}
|
|
4150
|
+
/**
|
|
4151
|
+
* Handle close dropdown button
|
|
4152
|
+
*/
|
|
4153
|
+
handleActionCloseDropdown(event, element) {
|
|
4154
|
+
this.emit("close-dropdown");
|
|
4155
|
+
}
|
|
4156
|
+
/**
|
|
4157
|
+
* Get currently selected values
|
|
4158
|
+
*/
|
|
4159
|
+
getValue() {
|
|
4160
|
+
return this.items.filter((item) => item.selected).map((item) => item.value);
|
|
4161
|
+
}
|
|
4162
|
+
/**
|
|
4163
|
+
* Set selected values
|
|
4164
|
+
*/
|
|
4165
|
+
setValue(values) {
|
|
4166
|
+
const valueSet = new Set(Array.isArray(values) ? values : [values]);
|
|
4167
|
+
this.items.forEach((item) => {
|
|
4168
|
+
item.selected = valueSet.has(item.value);
|
|
4169
|
+
});
|
|
4170
|
+
this.render(false);
|
|
4171
|
+
}
|
|
4172
|
+
/**
|
|
4173
|
+
* Update items and re-render
|
|
4174
|
+
*/
|
|
4175
|
+
updateItems(items) {
|
|
4176
|
+
this.items = items;
|
|
4177
|
+
this.render(false);
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
class MultiSelectDropdown extends View {
|
|
4181
|
+
constructor(options = {}) {
|
|
4182
|
+
super({
|
|
4183
|
+
tagName: "div",
|
|
4184
|
+
className: "multiselect-dropdown",
|
|
4185
|
+
template: `
|
|
4186
|
+
<div class="mojo-form-control">
|
|
4187
|
+
{{#label}}
|
|
4188
|
+
<label class="form-label">
|
|
4189
|
+
{{label}}{{#required}}<span class="text-danger">*</span>{{/required}}
|
|
4190
|
+
</label>
|
|
4191
|
+
{{/label}}
|
|
4192
|
+
|
|
4193
|
+
<div class="dropdown w-100">
|
|
4194
|
+
<button class="btn btn-outline-secondary dropdown-toggle w-100 text-start d-flex justify-content-between align-items-center"
|
|
4195
|
+
type="button"
|
|
4196
|
+
data-bs-toggle="dropdown"
|
|
4197
|
+
aria-expanded="false"
|
|
4198
|
+
{{#disabled}}disabled{{/disabled}}>
|
|
4199
|
+
<span class="multiselect-button-text">{{buttonText}}</span>
|
|
4200
|
+
<i class="bi bi-chevron-down"></i>
|
|
4201
|
+
</button>
|
|
4202
|
+
<div class="dropdown-menu w-100" data-bs-auto-close="outside" data-container="items"></div>
|
|
4203
|
+
</div>
|
|
4204
|
+
|
|
4205
|
+
{{#help}}
|
|
4206
|
+
<div class="form-text">{{help}}</div>
|
|
4207
|
+
{{/help}}
|
|
4208
|
+
{{#error}}
|
|
4209
|
+
<div class="invalid-feedback d-block">{{error}}</div>
|
|
4210
|
+
{{/error}}
|
|
4211
|
+
</div>
|
|
4212
|
+
`,
|
|
4213
|
+
...options
|
|
4214
|
+
});
|
|
4215
|
+
this.name = options.name || "multiselect";
|
|
4216
|
+
this.label = options.label || "";
|
|
4217
|
+
this.help = options.help || "";
|
|
4218
|
+
this.error = options.error || "";
|
|
4219
|
+
this.required = options.required || false;
|
|
4220
|
+
this.disabled = options.disabled || false;
|
|
4221
|
+
this.placeholder = options.placeholder || options.placeHolder || "Select...";
|
|
4222
|
+
this.maxHeight = options.maxHeight || 300;
|
|
4223
|
+
this.showSelectedLabels = options.showSelectedLabels !== false;
|
|
4224
|
+
this.maxLabelsToShow = options.maxLabelsToShow || 3;
|
|
4225
|
+
this.options = options.options || [];
|
|
4226
|
+
this.selectedValues = Array.isArray(options.value) ? options.value : [];
|
|
4227
|
+
this.buttonText = this.computeButtonText();
|
|
4228
|
+
this.listView = null;
|
|
4229
|
+
}
|
|
4230
|
+
/**
|
|
4231
|
+
* Compute button text based on current selection
|
|
4232
|
+
*/
|
|
4233
|
+
computeButtonText() {
|
|
4234
|
+
const count = this.selectedValues.length;
|
|
4235
|
+
if (count === 0) {
|
|
4236
|
+
return this.placeholder || "Select...";
|
|
4237
|
+
} else if (this.showSelectedLabels && count <= this.maxLabelsToShow) {
|
|
4238
|
+
const labels = this.selectedValues.map((value) => {
|
|
4239
|
+
const selectedOption = this.options.find((opt) => {
|
|
4240
|
+
const optValue = typeof opt === "string" ? opt : opt.value;
|
|
4241
|
+
return optValue === value;
|
|
4242
|
+
});
|
|
4243
|
+
return typeof selectedOption === "string" ? selectedOption : selectedOption?.label || selectedOption?.value || value;
|
|
4244
|
+
});
|
|
4245
|
+
return labels.join(", ");
|
|
4246
|
+
} else {
|
|
4247
|
+
return `${count} selected`;
|
|
4248
|
+
}
|
|
4249
|
+
}
|
|
4250
|
+
/**
|
|
4251
|
+
* Initialize child view after render
|
|
4252
|
+
*/
|
|
4253
|
+
async onAfterRender() {
|
|
4254
|
+
await super.onAfterRender();
|
|
4255
|
+
this.createListView();
|
|
4256
|
+
}
|
|
4257
|
+
/**
|
|
4258
|
+
* Create and mount the items list view
|
|
4259
|
+
*/
|
|
4260
|
+
createListView() {
|
|
4261
|
+
const container = this.element?.querySelector('[data-container="items"]');
|
|
4262
|
+
if (!container) return;
|
|
4263
|
+
const items = this.options.map((option, index) => {
|
|
4264
|
+
const value = typeof option === "string" ? option : option.value;
|
|
4265
|
+
const label = typeof option === "string" ? option : option.label || option.text || option.value;
|
|
4266
|
+
const disabled = typeof option === "object" ? option.disabled : false;
|
|
4267
|
+
return {
|
|
4268
|
+
id: `${this.name}_${index}`,
|
|
4269
|
+
value,
|
|
4270
|
+
label,
|
|
4271
|
+
index,
|
|
4272
|
+
selected: this.selectedValues.includes(value),
|
|
4273
|
+
disabled
|
|
4274
|
+
};
|
|
4275
|
+
});
|
|
4276
|
+
this.listView = new MultiSelectItemsView({
|
|
4277
|
+
items,
|
|
4278
|
+
maxHeight: this.maxHeight
|
|
4279
|
+
});
|
|
4280
|
+
this.listView.on("toggle", (data) => {
|
|
4281
|
+
this.handleToggle(data);
|
|
4282
|
+
});
|
|
4283
|
+
this.listView.on("close-dropdown", () => {
|
|
4284
|
+
this.closeDropdown();
|
|
4285
|
+
});
|
|
4286
|
+
this.listView.render(true, container);
|
|
4287
|
+
}
|
|
4288
|
+
/**
|
|
4289
|
+
* Close the dropdown programmatically
|
|
4290
|
+
*/
|
|
4291
|
+
closeDropdown() {
|
|
4292
|
+
const dropdownButton = this.element?.querySelector(".dropdown-toggle");
|
|
4293
|
+
if (dropdownButton && window.bootstrap?.Dropdown) {
|
|
4294
|
+
const dropdownInstance = window.bootstrap.Dropdown.getInstance(dropdownButton);
|
|
4295
|
+
if (dropdownInstance) {
|
|
4296
|
+
dropdownInstance.hide();
|
|
4297
|
+
}
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
/**
|
|
4301
|
+
* Handle item toggle
|
|
4302
|
+
*/
|
|
4303
|
+
handleToggle(data) {
|
|
4304
|
+
const { value, selected } = data;
|
|
4305
|
+
if (selected) {
|
|
4306
|
+
if (!this.selectedValues.includes(value)) {
|
|
4307
|
+
this.selectedValues.push(value);
|
|
4308
|
+
}
|
|
4309
|
+
} else {
|
|
4310
|
+
this.selectedValues = this.selectedValues.filter((v) => v !== value);
|
|
4311
|
+
}
|
|
4312
|
+
this.updateButtonText();
|
|
4313
|
+
this.emit("change", {
|
|
4314
|
+
value: this.selectedValues,
|
|
4315
|
+
name: this.name
|
|
4316
|
+
});
|
|
4317
|
+
}
|
|
4318
|
+
/**
|
|
4319
|
+
* Update button text based on selection
|
|
4320
|
+
*/
|
|
4321
|
+
updateButtonText() {
|
|
4322
|
+
const button = this.element?.querySelector(".multiselect-button-text");
|
|
4323
|
+
if (!button) return;
|
|
4324
|
+
const count = this.selectedValues.length;
|
|
4325
|
+
this.buttonText = this.computeButtonText();
|
|
4326
|
+
button.textContent = this.buttonText;
|
|
4327
|
+
if (count === 0) {
|
|
4328
|
+
button.classList.add("text-muted");
|
|
4329
|
+
} else {
|
|
4330
|
+
button.classList.remove("text-muted");
|
|
4331
|
+
}
|
|
4332
|
+
}
|
|
4333
|
+
/**
|
|
4334
|
+
* Get current selected values
|
|
4335
|
+
*/
|
|
4336
|
+
getValue() {
|
|
4337
|
+
return this.selectedValues;
|
|
4338
|
+
}
|
|
4339
|
+
/**
|
|
4340
|
+
* Set selected values
|
|
4341
|
+
*/
|
|
4342
|
+
setValue(values) {
|
|
4343
|
+
this.selectedValues = Array.isArray(values) ? values : values ? [values] : [];
|
|
4344
|
+
if (this.listView) {
|
|
4345
|
+
this.listView.setValue(this.selectedValues);
|
|
4346
|
+
}
|
|
4347
|
+
this.updateButtonText();
|
|
4348
|
+
}
|
|
4349
|
+
/**
|
|
4350
|
+
* Update options list
|
|
4351
|
+
*/
|
|
4352
|
+
setOptions(options) {
|
|
4353
|
+
this.options = options;
|
|
4354
|
+
if (this.listView) {
|
|
4355
|
+
const items = this.options.map((option, index) => {
|
|
4356
|
+
const value = typeof option === "string" ? option : option.value;
|
|
4357
|
+
const label = typeof option === "string" ? option : option.label || option.text || option.value;
|
|
4358
|
+
const disabled = typeof option === "object" ? option.disabled : false;
|
|
4359
|
+
return {
|
|
4360
|
+
id: `${this.name}_${index}`,
|
|
4361
|
+
value,
|
|
4362
|
+
label,
|
|
4363
|
+
index,
|
|
4364
|
+
selected: this.selectedValues.includes(value),
|
|
4365
|
+
disabled
|
|
4366
|
+
};
|
|
4367
|
+
});
|
|
4368
|
+
this.listView.updateItems(items);
|
|
4369
|
+
}
|
|
4370
|
+
}
|
|
4371
|
+
/**
|
|
4372
|
+
* Clear all selections
|
|
4373
|
+
*/
|
|
4374
|
+
clear() {
|
|
4375
|
+
this.setValue([]);
|
|
4376
|
+
}
|
|
4377
|
+
/**
|
|
4378
|
+
* Get form value (for form integration)
|
|
4379
|
+
*/
|
|
4380
|
+
getFormValue() {
|
|
4381
|
+
return this.getValue();
|
|
4382
|
+
}
|
|
4383
|
+
/**
|
|
4384
|
+
* Set form value (for form integration)
|
|
4385
|
+
*/
|
|
4386
|
+
setFormValue(value) {
|
|
4387
|
+
this.setValue(value);
|
|
4388
|
+
}
|
|
4389
|
+
/**
|
|
4390
|
+
* Cleanup child view on destroy
|
|
4391
|
+
*/
|
|
4392
|
+
async onBeforeDestroy() {
|
|
4393
|
+
await super.onBeforeDestroy();
|
|
4394
|
+
if (this.listView) {
|
|
4395
|
+
this.listView.destroy();
|
|
4396
|
+
}
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4033
4399
|
class DatePicker extends View {
|
|
4034
4400
|
constructor(options = {}) {
|
|
4035
4401
|
const {
|
|
@@ -5924,6 +6290,7 @@ class FormView extends View {
|
|
|
5924
6290
|
this.initializeImageFields();
|
|
5925
6291
|
this.initializeCustomComponents();
|
|
5926
6292
|
this.initializeTagInputs();
|
|
6293
|
+
this.initializeMultiSelectDropdowns();
|
|
5927
6294
|
this.initializeCollectionSelects();
|
|
5928
6295
|
this.initializeCollectionMultiSelects();
|
|
5929
6296
|
this.initializeDatePickers();
|
|
@@ -6052,6 +6419,42 @@ class FormView extends View {
|
|
|
6052
6419
|
}
|
|
6053
6420
|
});
|
|
6054
6421
|
}
|
|
6422
|
+
/**
|
|
6423
|
+
* Initialize MultiSelectDropdown components
|
|
6424
|
+
*/
|
|
6425
|
+
initializeMultiSelectDropdowns() {
|
|
6426
|
+
const multiselectPlaceholders = this.element.querySelectorAll('[data-field-type="multiselect"]');
|
|
6427
|
+
multiselectPlaceholders.forEach((placeholder) => {
|
|
6428
|
+
try {
|
|
6429
|
+
const fieldName = placeholder.getAttribute("data-field-name");
|
|
6430
|
+
const configData = placeholder.getAttribute("data-field-config");
|
|
6431
|
+
const config = JSON.parse(configData);
|
|
6432
|
+
const fieldConfig = this.getFormFieldConfig(fieldName);
|
|
6433
|
+
if (!fieldConfig) {
|
|
6434
|
+
return;
|
|
6435
|
+
}
|
|
6436
|
+
const multiselect = new MultiSelectDropdown({
|
|
6437
|
+
...config,
|
|
6438
|
+
options: fieldConfig.options || [],
|
|
6439
|
+
placeholder: fieldConfig.placeholder || config.placeholder || "Select...",
|
|
6440
|
+
label: fieldConfig.label,
|
|
6441
|
+
containerId: null
|
|
6442
|
+
// We'll mount directly
|
|
6443
|
+
});
|
|
6444
|
+
let value = config.value ?? MOJOUtils.getContextData(this.data, fieldName);
|
|
6445
|
+
if (value) {
|
|
6446
|
+
multiselect.setFormValue(value);
|
|
6447
|
+
}
|
|
6448
|
+
multiselect.render(true, placeholder);
|
|
6449
|
+
this.customComponents.set(fieldName, multiselect);
|
|
6450
|
+
multiselect.on("change", (data) => {
|
|
6451
|
+
this.handleFieldChange(fieldName, data.value);
|
|
6452
|
+
});
|
|
6453
|
+
} catch (error) {
|
|
6454
|
+
console.error("MultiSelectDropdown initialization failed:", error);
|
|
6455
|
+
}
|
|
6456
|
+
});
|
|
6457
|
+
}
|
|
6055
6458
|
/**
|
|
6056
6459
|
* Initialize CollectionSelect components
|
|
6057
6460
|
*/
|
|
@@ -7888,4 +8291,4 @@ export {
|
|
|
7888
8291
|
applyFileDropMixin as a,
|
|
7889
8292
|
FormView$1 as b
|
|
7890
8293
|
};
|
|
7891
|
-
//# sourceMappingURL=FormView-
|
|
8294
|
+
//# sourceMappingURL=FormView-CwYt4vH3.js.map
|