web-mojo 2.2.7 → 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-pFVev6ZD.js → ChatView-2mFEGsXL.js} +282 -96
- 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-DPGOKfct.js → Dialog-BBZUgBbz.js} +2 -2
- package/dist/chunks/{Dialog-DPGOKfct.js.map → Dialog-BBZUgBbz.js.map} +1 -1
- package/dist/chunks/{Dialog-LFifi2fg.js → Dialog-DrCs-ex1.js} +3 -3
- package/dist/chunks/{Dialog-LFifi2fg.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-Xb_l8AD5.js → FormView-CwYt4vH3.js} +400 -2
- package/dist/chunks/FormView-CwYt4vH3.js.map +1 -0
- package/dist/chunks/{MetricsMiniChartWidget-C8RQnqrd.js → MetricsMiniChartWidget-B3PHrgkn.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-C8RQnqrd.js.map → MetricsMiniChartWidget-B3PHrgkn.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-CzqYq7d2.js → MetricsMiniChartWidget-DdZ3zNve.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-CzqYq7d2.js.map → MetricsMiniChartWidget-DdZ3zNve.js.map} +1 -1
- package/dist/chunks/{PDFViewer-BCn-y_36.js → PDFViewer-CkKC_E0G.js} +2 -2
- package/dist/chunks/{PDFViewer-BCn-y_36.js.map → PDFViewer-CkKC_E0G.js.map} +1 -1
- package/dist/chunks/{PDFViewer-BeWHRAeX.js → PDFViewer-DaiTPsQH.js} +2 -2
- package/dist/chunks/{PDFViewer-BeWHRAeX.js.map → PDFViewer-DaiTPsQH.js.map} +1 -1
- package/dist/chunks/{TokenManager-D2pm6lM8.js → TokenManager-D9z35vwT.js} +2 -2
- package/dist/chunks/{TokenManager-D2pm6lM8.js.map → TokenManager-D9z35vwT.js.map} +1 -1
- package/dist/chunks/{TokenManager-DZwzcAzD.js → TokenManager-XwKaWaKd.js} +2 -2
- package/dist/chunks/{TokenManager-DZwzcAzD.js.map → TokenManager-XwKaWaKd.js.map} +1 -1
- package/dist/chunks/{version-aJXsYzYB.js → version-BQcvJscT.js} +4 -4
- package/dist/chunks/{version-aJXsYzYB.js.map → version-BQcvJscT.js.map} +1 -1
- package/dist/chunks/{version-CmZ8J2xW.js → version-DhSPKHUm.js} +2 -2
- package/dist/chunks/{version-CmZ8J2xW.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/package.json +1 -1
- package/dist/chunks/ChatView-B2iog5Hu.js +0 -2
- package/dist/chunks/ChatView-B2iog5Hu.js.map +0 -1
- package/dist/chunks/ChatView-pFVev6ZD.js.map +0 -1
- package/dist/chunks/FormView-Clc_mN0d.js +0 -3
- package/dist/chunks/FormView-Clc_mN0d.js.map +0 -1
- package/dist/chunks/FormView-Xb_l8AD5.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
|
|
@@ -4035,6 +4090,312 @@ class CollectionMultiSelectView extends View {
|
|
|
4035
4090
|
this.setValue(value);
|
|
4036
4091
|
}
|
|
4037
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
|
+
}
|
|
4038
4399
|
class DatePicker extends View {
|
|
4039
4400
|
constructor(options = {}) {
|
|
4040
4401
|
const {
|
|
@@ -5929,6 +6290,7 @@ class FormView extends View {
|
|
|
5929
6290
|
this.initializeImageFields();
|
|
5930
6291
|
this.initializeCustomComponents();
|
|
5931
6292
|
this.initializeTagInputs();
|
|
6293
|
+
this.initializeMultiSelectDropdowns();
|
|
5932
6294
|
this.initializeCollectionSelects();
|
|
5933
6295
|
this.initializeCollectionMultiSelects();
|
|
5934
6296
|
this.initializeDatePickers();
|
|
@@ -6057,6 +6419,42 @@ class FormView extends View {
|
|
|
6057
6419
|
}
|
|
6058
6420
|
});
|
|
6059
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
|
+
}
|
|
6060
6458
|
/**
|
|
6061
6459
|
* Initialize CollectionSelect components
|
|
6062
6460
|
*/
|
|
@@ -7893,4 +8291,4 @@ export {
|
|
|
7893
8291
|
applyFileDropMixin as a,
|
|
7894
8292
|
FormView$1 as b
|
|
7895
8293
|
};
|
|
7896
|
-
//# sourceMappingURL=FormView-
|
|
8294
|
+
//# sourceMappingURL=FormView-CwYt4vH3.js.map
|