@elrayes/dual-listbox 0.3.1 → 0.3.3
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/index.cjs +63 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +63 -54
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/dist/index.cjs
CHANGED
|
@@ -79,8 +79,10 @@ var DualListBox = class {
|
|
|
79
79
|
const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);
|
|
80
80
|
const theme = mergeTheme(themeBase, options.theme);
|
|
81
81
|
this.settings = { ...this.defaults, ...options, theme };
|
|
82
|
+
this.originalData = [...this.settings.dataArray];
|
|
82
83
|
this.groups = this.buildGroups(this.settings.dataArray);
|
|
83
84
|
this.selectedGroups = this.buildGroups(this.settings.selectedItems);
|
|
85
|
+
this.sortAllGroups();
|
|
84
86
|
this.removeDuplicatesFromLeft();
|
|
85
87
|
this.render();
|
|
86
88
|
this.bindEvents();
|
|
@@ -103,14 +105,32 @@ var DualListBox = class {
|
|
|
103
105
|
}
|
|
104
106
|
return id;
|
|
105
107
|
}
|
|
108
|
+
sortAllGroups() {
|
|
109
|
+
[this.groups, this.selectedGroups].forEach((groupSet) => {
|
|
110
|
+
Object.keys(groupSet).forEach((groupName) => {
|
|
111
|
+
this.sortGroup(groupSet[groupName]);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
sortGroup(group) {
|
|
116
|
+
group.sort((a, b) => {
|
|
117
|
+
const valA = String(a[this.settings.valueName]);
|
|
118
|
+
const valB = String(b[this.settings.valueName]);
|
|
119
|
+
const indexA = this.originalData.findIndex(
|
|
120
|
+
(item) => String(item[this.settings.valueName]) === valA
|
|
121
|
+
);
|
|
122
|
+
const indexB = this.originalData.findIndex(
|
|
123
|
+
(item) => String(item[this.settings.valueName]) === valB
|
|
124
|
+
);
|
|
125
|
+
return indexA - indexB;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
106
128
|
buildGroups(dataArray) {
|
|
107
129
|
const groups = {};
|
|
108
130
|
dataArray.forEach((item) => {
|
|
109
131
|
const group = item[this.settings.groupName] || "Ungrouped";
|
|
110
132
|
if (!groups[group]) groups[group] = [];
|
|
111
|
-
|
|
112
|
-
groups[group].push(item);
|
|
113
|
-
}
|
|
133
|
+
groups[group].push(item);
|
|
114
134
|
});
|
|
115
135
|
return groups;
|
|
116
136
|
}
|
|
@@ -119,7 +139,7 @@ var DualListBox = class {
|
|
|
119
139
|
if (this.groups[group]) {
|
|
120
140
|
this.selectedGroups[group].forEach((selectedItem) => {
|
|
121
141
|
this.groups[group] = this.groups[group].filter(
|
|
122
|
-
(item) => item[this.settings.valueName] !== selectedItem[this.settings.valueName]
|
|
142
|
+
(item) => String(item[this.settings.valueName]) !== String(selectedItem[this.settings.valueName])
|
|
123
143
|
);
|
|
124
144
|
});
|
|
125
145
|
if (this.settings.hideEmptyGroups) {
|
|
@@ -140,7 +160,7 @@ var DualListBox = class {
|
|
|
140
160
|
<div class="${t.card}">
|
|
141
161
|
<div class="${t.cardHeader}">${this.settings.tabNameText}</div>
|
|
142
162
|
<div class="${t.cardBody}">
|
|
143
|
-
<input id="dual_listbox_${this.instanceId}_left_search" type="text" class="${t.searchInput}" data-side="left" placeholder="${this.settings.searchPlaceholderText}">
|
|
163
|
+
<input id="dual_listbox_${this.instanceId}_left_search" type="text" class="${t.searchInput} dual-listbox-search" data-side="left" placeholder="${this.settings.searchPlaceholderText}">
|
|
144
164
|
<div class="dual-listbox-content">
|
|
145
165
|
${this.generateGroupedListHTML("left")}
|
|
146
166
|
</div>
|
|
@@ -152,14 +172,14 @@ var DualListBox = class {
|
|
|
152
172
|
</div>
|
|
153
173
|
</div>
|
|
154
174
|
<div class="${t.colCenter}">
|
|
155
|
-
<button class="${t.btn} dual-listbox-include ${t.btnInclude}" disabled>${this.settings.includeButtonText}</button>
|
|
156
|
-
<button class="${t.btn} dual-listbox-exclude ${t.btnExclude}" disabled>${this.settings.excludeButtonText}</button>
|
|
175
|
+
<button type="button" class="${t.btn} dual-listbox-include ${t.btnInclude}" disabled>${this.settings.includeButtonText}</button>
|
|
176
|
+
<button type="button" class="${t.btn} dual-listbox-exclude ${t.btnExclude}" disabled>${this.settings.excludeButtonText}</button>
|
|
157
177
|
</div>
|
|
158
178
|
<div class="${t.colRight}" id="dual_listbox_${this.instanceId}_right_side">
|
|
159
179
|
<div class="${t.card}">
|
|
160
180
|
<div class="${t.cardHeader}">${this.settings.rightTabNameText}</div>
|
|
161
181
|
<div class="${t.cardBody}">
|
|
162
|
-
<input id="dual_listbox_${this.instanceId}_right_search" type="text" class="${t.searchInput}" data-side="right" placeholder="${this.settings.searchPlaceholderText}">
|
|
182
|
+
<input id="dual_listbox_${this.instanceId}_right_search" type="text" class="${t.searchInput} dual-listbox-search" data-side="right" placeholder="${this.settings.searchPlaceholderText}">
|
|
163
183
|
<div class="dual-listbox-content">
|
|
164
184
|
${this.generateGroupedListHTML("right")}
|
|
165
185
|
</div>
|
|
@@ -284,9 +304,10 @@ var DualListBox = class {
|
|
|
284
304
|
const fromContainer = contents[fromSide === "left" ? 0 : 1];
|
|
285
305
|
const selectedLis = Array.from(fromContainer.querySelectorAll(".item-select:checked")).map((inp) => inp.closest("li"));
|
|
286
306
|
selectedLis.forEach((li) => {
|
|
287
|
-
var _a;
|
|
288
307
|
const value = String(li.getAttribute("data-value"));
|
|
289
308
|
const group = String(li.getAttribute("data-group"));
|
|
309
|
+
const originalItem = this.originalData.find((item) => String(item[this.settings.valueName]) === value);
|
|
310
|
+
if (!originalItem) return;
|
|
290
311
|
if (fromGroups[group]) {
|
|
291
312
|
fromGroups[group] = fromGroups[group].filter((i) => String(i[this.settings.valueName]) !== value);
|
|
292
313
|
if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== "left")) {
|
|
@@ -294,12 +315,10 @@ var DualListBox = class {
|
|
|
294
315
|
}
|
|
295
316
|
}
|
|
296
317
|
if (!toGroups[group]) toGroups[group] = [];
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
[this.settings.groupName]: group
|
|
302
|
-
});
|
|
318
|
+
if (!toGroups[group].some((i) => String(i[this.settings.valueName]) === value)) {
|
|
319
|
+
toGroups[group].push(originalItem);
|
|
320
|
+
}
|
|
321
|
+
this.sortGroup(toGroups[group]);
|
|
303
322
|
});
|
|
304
323
|
this.render();
|
|
305
324
|
}
|
|
@@ -347,10 +366,7 @@ var DualListBox = class {
|
|
|
347
366
|
console.error("Parent form not found!");
|
|
348
367
|
return;
|
|
349
368
|
}
|
|
350
|
-
const selectedValues =
|
|
351
|
-
Object.values(this.selectedGroups).forEach((items) => {
|
|
352
|
-
items.forEach((item) => selectedValues.push(item[this.settings.valueName]));
|
|
353
|
-
});
|
|
369
|
+
const selectedValues = this.selectedArray;
|
|
354
370
|
Array.from(this.formEl.querySelectorAll(`input[name="${this.settings.inputName}[]"]`)).forEach((el) => el.remove());
|
|
355
371
|
selectedValues.forEach((value) => {
|
|
356
372
|
const input = document.createElement("input");
|
|
@@ -362,26 +378,26 @@ var DualListBox = class {
|
|
|
362
378
|
}
|
|
363
379
|
getSelectedValues() {
|
|
364
380
|
return new Promise((resolve) => {
|
|
365
|
-
|
|
366
|
-
Object.keys(this.selectedGroups).forEach((groupName) => {
|
|
367
|
-
this.selectedGroups[groupName].forEach((item) => {
|
|
368
|
-
selectedValues.push(item[this.settings.valueName]);
|
|
369
|
-
});
|
|
370
|
-
});
|
|
371
|
-
resolve(selectedValues);
|
|
381
|
+
resolve(this.selectedArray);
|
|
372
382
|
});
|
|
373
383
|
}
|
|
374
384
|
get selected() {
|
|
375
385
|
return this.selectedGroups;
|
|
376
386
|
}
|
|
377
387
|
get selectedArray() {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
this.
|
|
381
|
-
|
|
382
|
-
|
|
388
|
+
const selectedValues = [];
|
|
389
|
+
this.originalData.forEach((item) => {
|
|
390
|
+
const val = item[this.settings.valueName];
|
|
391
|
+
const group = item[this.settings.groupName] || "Ungrouped";
|
|
392
|
+
if (this.selectedGroups[group]) {
|
|
393
|
+
const isSelected = this.selectedGroups[group].some(
|
|
394
|
+
(i) => String(i[this.settings.valueName]) === String(val)
|
|
395
|
+
);
|
|
396
|
+
if (isSelected) {
|
|
397
|
+
selectedValues.push(val);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
383
400
|
});
|
|
384
|
-
selectedValues = [...new Set(selectedValues)];
|
|
385
401
|
return selectedValues;
|
|
386
402
|
}
|
|
387
403
|
get unselected() {
|
|
@@ -392,34 +408,27 @@ var DualListBox = class {
|
|
|
392
408
|
}
|
|
393
409
|
// New API methods: return arrays without duplicates
|
|
394
410
|
getSelectedItems() {
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
411
|
+
const selected = [];
|
|
412
|
+
const values = this.selectedArray.map(String);
|
|
413
|
+
this.originalData.forEach((item) => {
|
|
414
|
+
if (values.includes(String(item[this.settings.valueName]))) {
|
|
415
|
+
selected.push(item);
|
|
416
|
+
}
|
|
401
417
|
});
|
|
402
|
-
return
|
|
418
|
+
return selected;
|
|
403
419
|
}
|
|
404
420
|
getUnselectedItems() {
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
421
|
+
const unselected = [];
|
|
422
|
+
const selectedValues = this.selectedArray.map(String);
|
|
423
|
+
this.originalData.forEach((item) => {
|
|
424
|
+
if (!selectedValues.includes(String(item[this.settings.valueName]))) {
|
|
425
|
+
unselected.push(item);
|
|
426
|
+
}
|
|
411
427
|
});
|
|
412
|
-
return
|
|
428
|
+
return unselected;
|
|
413
429
|
}
|
|
414
430
|
getAllItems() {
|
|
415
|
-
|
|
416
|
-
Object.values(this.groups).forEach((items) => {
|
|
417
|
-
items.forEach((item) => map.set(String(item[this.settings.valueName]), item));
|
|
418
|
-
});
|
|
419
|
-
Object.values(this.selectedGroups).forEach((items) => {
|
|
420
|
-
items.forEach((item) => map.set(String(item[this.settings.valueName]), item));
|
|
421
|
-
});
|
|
422
|
-
return Array.from(map.values());
|
|
431
|
+
return [...this.originalData];
|
|
423
432
|
}
|
|
424
433
|
getSettings() {
|
|
425
434
|
return this.settings;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/themePresets.ts","../src/lib/DualListBox.ts"],"names":["_a"],"mappings":"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","file":"index.cjs","sourcesContent":["import { DualListBoxTheme } from './types';\n\nexport const defaultTheme: DualListBoxTheme = {\n container: 'dual-listbox',\n row: 'row mb-3',\n colLeft: 'col-md-5',\n colCenter: 'col-md-2 d-flex justify-content-center flex-column gap-3',\n colRight: 'col-md-5',\n card: 'card h-100',\n cardHeader: 'card-header',\n cardBody: 'card-body',\n cardFooter: 'card-footer text-center',\n searchInput: 'form-control mb-3 dual-listbox-search',\n listGroup: 'list-group',\n listItem: 'list-group-item py-1 border-0',\n formCheck: 'form-check',\n formCheckInput: 'form-check-input',\n formCheckLabel: 'form-check-label',\n btn: 'btn btn-light w-100',\n btnInclude: '',\n btnExclude: '',\n};\n\nexport const bootstrapTheme: DualListBoxTheme = { ...defaultTheme };\n\nexport const tailwindTheme: DualListBoxTheme = {\n container: 'dual-listbox tw',\n row: 'grid grid-cols-1 md:grid-cols-5 gap-3',\n colLeft: 'md:col-span-2',\n colCenter: 'md:col-span-1 flex flex-col justify-center gap-3',\n colRight: 'md:col-span-2',\n card: 'h-full border rounded shadow-sm bg-white',\n cardHeader: 'px-4 py-2 border-b font-medium',\n cardBody: 'p-4',\n cardFooter: 'px-4 py-2 border-t text-center',\n searchInput: 'w-full mb-3 border rounded px-3 py-2 dual-listbox-search',\n listGroup: 'space-y-1',\n listItem: 'py-1',\n formCheck: 'flex items-center gap-2',\n formCheckInput: 'h-4 w-4',\n formCheckLabel: '',\n btn: 'w-full border rounded px-3 py-2 bg-gray-100 hover:bg-gray-200',\n btnInclude: 'mb-2',\n btnExclude: '',\n};\n","import type {DualListBoxItem, DualListBoxOptions, DualListBoxTheme} from './types';\nimport {defaultTheme} from './themePresets';\n\nfunction mergeTheme(base: DualListBoxTheme, override?: Partial<DualListBoxTheme>): DualListBoxTheme {\n return {...base, ...(override || {})} as DualListBoxTheme;\n}\n\n// Global theme state (module-level)\nlet GLOBAL_THEME: DualListBoxTheme = {...defaultTheme};\n\n/**\n * Set the global default theme for all new DualListBox instances.\n * Instance option `theme` still has highest priority.\n */\nexport function useTheme(theme: Partial<DualListBoxTheme> | DualListBoxTheme) {\n GLOBAL_THEME = mergeTheme(defaultTheme, theme as Partial<DualListBoxTheme>);\n}\n\n// Back-compat alias for older code that might call DualListBox.setTheme(...)\n// We will attach a static setTheme on the class after its definition.\n\nexport class DualListBox {\n private rootEl: Element;\n private formEl: HTMLFormElement | null;\n\n private instanceId: string;\n\n private defaults: Required<Omit<DualListBoxOptions, 'theme'>> & { theme: DualListBoxTheme };\n private settings: Required<DualListBoxOptions> & { theme: DualListBoxTheme };\n\n private groups: Record<string, DualListBoxItem[]> = {};\n private selectedGroups: Record<string, DualListBoxItem[]> = {};\n\n constructor(element: Element | string, options: DualListBoxOptions = {}) {\n this.rootEl = typeof element === 'string' ? (document.querySelector(element) as Element) : (element as Element);\n if (!this.rootEl) throw new Error('DualListBox root element not found');\n this.formEl = (this.rootEl.closest('form') as HTMLFormElement) || null;\n this.instanceId = this.generateInstanceId();\n this.defaults = {\n itemName: 'item',\n groupName: 'group',\n valueName: 'value',\n inputName: 'selectedItems',\n tabNameText: 'Available Items',\n rightTabNameText: 'Selected Items',\n searchPlaceholderText: 'Search...',\n includeButtonText: 'Include >>',\n excludeButtonText: '<< Exclude',\n dataArray: [],\n selectedItems: [],\n hideEmptyGroups: false,\n submitForm: true,\n onSubmit: null,\n theme: defaultTheme,\n } as any;\n\n // Effective theme precedence: options.theme > GLOBAL_THEME > defaultTheme\n const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);\n const theme = mergeTheme(themeBase, options.theme);\n this.settings = {...(this.defaults as any), ...(options as any), theme};\n\n this.groups = this.buildGroups(this.settings.dataArray);\n this.selectedGroups = this.buildGroups(this.settings.selectedItems);\n\n this.removeDuplicatesFromLeft();\n this.render();\n this.bindEvents();\n\n if (this.formEl) {\n this.formEl.addEventListener('submit', (event) => {\n if (typeof this.settings.onSubmit === 'function') {\n event.preventDefault();\n this.settings.onSubmit(this.selected, this.unselected, this.allItems, this.selectedArray);\n } else if (this.settings.submitForm) {\n this.appendSelectedGroupsOnSubmit();\n }\n });\n }\n }\n\n private generateInstanceId() {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let id = '';\n for (let i = 0; i < 36; i++) {\n id += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return id;\n }\n\n private buildGroups(dataArray: DualListBoxItem[]) {\n const groups: Record<string, DualListBoxItem[]> = {};\n dataArray.forEach((item) => {\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (!groups[group]) groups[group] = [];\n if (!groups[group].some((existing) => (existing as any)[this.settings.valueName] === (item as any)[this.settings.valueName])) {\n groups[group].push(item);\n }\n });\n return groups;\n }\n\n private removeDuplicatesFromLeft() {\n Object.keys(this.selectedGroups).forEach((group) => {\n if (this.groups[group]) {\n this.selectedGroups[group].forEach((selectedItem) => {\n this.groups[group] = this.groups[group].filter(\n (item) => (item as any)[this.settings.valueName] !== (selectedItem as any)[this.settings.valueName]\n );\n });\n if (this.settings.hideEmptyGroups) {\n if (!this.groups[group].length) {\n delete this.groups[group];\n }\n }\n }\n });\n this.render();\n }\n\n private render() {\n const t = this.settings.theme;\n const template = `\n <div class=\"${t.container}\" id=\"dual_listbox_${this.instanceId}\">\n <div class=\"${t.row}\">\n <div class=\"${t.colLeft}\" id=\"dual_listbox_${this.instanceId}_left_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.tabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_left_search\" type=\"text\" class=\"${t.searchInput}\" data-side=\"left\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('left')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-left\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-left-selected\">0</span>/<span class=\"dual-listbox-left-total\">0</span>)</label>\n </div>\n </div>\n </div>\n <div class=\"${t.colCenter}\">\n <button class=\"${t.btn} dual-listbox-include ${t.btnInclude}\" disabled>${this.settings.includeButtonText}</button>\n <button class=\"${t.btn} dual-listbox-exclude ${t.btnExclude}\" disabled>${this.settings.excludeButtonText}</button>\n </div>\n <div class=\"${t.colRight}\" id=\"dual_listbox_${this.instanceId}_right_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.rightTabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_right_search\" type=\"text\" class=\"${t.searchInput}\" data-side=\"right\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('right')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-right\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-right-selected\">0</span>/<span class=\"dual-listbox-right-total\">0</span>)</label>\n </div>\n </div>\n </div>\n </div>\n </div>`;\n this.rootEl.innerHTML = template;\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n\n private generateGroupedListHTML(side: 'left' | 'right') {\n const t = this.settings.theme;\n const groups = side === 'left' ? this.groups : this.selectedGroups;\n let html = '';\n const keys = Object.keys(groups);\n keys.forEach((groupName, index) => {\n const items = groups[groupName];\n const totalItems = items.length;\n const isGroupEmpty = totalItems === 0;\n const groupSelectAllInput = `group_${groupName}_${side}`;\n const isLast = index === keys.length - 1;\n html += `\n <div class=\"dual-listbox-group${!isLast ? ' mb-3' : ''}\">\n <div class=\"group-header mb-2\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupSelectAllInput}\" type=\"checkbox\" class=\"${t.formCheckInput} group-select-all\" ${isGroupEmpty ? 'checked disabled' : ''}>\n <label for=\"${groupSelectAllInput}\" class=\"${t.formCheckLabel}\">${groupName}</label>\n </div>\n </div>`;\n if (!isGroupEmpty) {\n html += `<ul class=\"${t.listGroup}\">`;\n items.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const name = (item as any)[this.settings.itemName];\n html += `\n <li class=\"${t.listItem}\" data-value=\"${val}\" data-group=\"${groupName}\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupName}_${val}\" type=\"checkbox\" class=\"${t.formCheckInput} item-select\" />\n <label for=\"${groupName}_${val}\" class=\"${t.formCheckLabel}\">${name}</label>\n </div>\n </li>`;\n });\n html += `</ul>`;\n }\n html += `</div>`;\n });\n return html;\n }\n\n private updateSelectAllInfo(side: 'left' | 'right') {\n const idx = side === 'left' ? 0 : 1;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[idx] as Element;\n const selectAll = this.rootEl.querySelector<HTMLInputElement>(`.dual-listbox-select-all-${side}`);\n const totalItems = content ? content.querySelectorAll('.item-select').length : 0;\n const selectedItems = content ? content.querySelectorAll('.item-select:checked').length : 0;\n const selSpan = this.rootEl.querySelector(`.dual-listbox-${side}-selected`);\n const totalSpan = this.rootEl.querySelector(`.dual-listbox-${side}-total`);\n if (selSpan) selSpan.textContent = String(selectedItems);\n if (totalSpan) totalSpan.textContent = String(totalItems);\n if (selectAll) {\n if (totalItems === 0) {\n selectAll.disabled = true;\n selectAll.checked = true;\n } else {\n selectAll.disabled = false;\n selectAll.checked = selectedItems === totalItems;\n }\n }\n\n // Enable/disable include/exclude buttons based on selections\n const includeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-include');\n const excludeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-exclude');\n const leftContent = contents[0] as Element | undefined;\n const rightContent = contents[1] as Element | undefined;\n const leftChecked = leftContent ? leftContent.querySelectorAll('.item-select:checked').length : 0;\n const rightChecked = rightContent ? rightContent.querySelectorAll('.item-select:checked').length : 0;\n if (includeBtn) includeBtn.disabled = leftChecked === 0;\n if (excludeBtn) excludeBtn.disabled = rightChecked === 0;\n }\n\n private bindEvents() {\n this.rootEl.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (target.closest('.dual-listbox-include')) {\n this.moveItems('left', 'right');\n } else if (target.closest('.dual-listbox-exclude')) {\n this.moveItems('right', 'left');\n }\n });\n this.rootEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-select-all-left')) {\n this.toggleSelectAll('left', target.checked);\n } else if (target.matches('.dual-listbox-select-all-right')) {\n this.toggleSelectAll('right', target.checked);\n } else if (target.matches('.group-select-all')) {\n const groupEl = target.closest('.dual-listbox-group') as Element;\n groupEl?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = target.checked));\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n } else if (target.matches('.item-select')) {\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n });\n this.rootEl.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-search')) {\n const side = (target.getAttribute('data-side') as 'left' | 'right') || 'left';\n const searchTerm = target.value || '';\n this.searchItems(side, searchTerm);\n }\n });\n }\n\n private moveItems(fromSide: 'left' | 'right', toSide: 'left' | 'right') {\n const fromGroups = fromSide === 'left' ? this.groups : this.selectedGroups;\n const toGroups = toSide === 'left' ? this.groups : this.selectedGroups;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const fromContainer = contents[fromSide === 'left' ? 0 : 1] as Element;\n const selectedLis = Array.from(fromContainer.querySelectorAll<HTMLInputElement>('.item-select:checked')).map((inp) => inp.closest('li') as HTMLLIElement);\n selectedLis.forEach((li) => {\n const value = String(li.getAttribute('data-value'));\n const group = String(li.getAttribute('data-group'));\n if (fromGroups[group]) {\n fromGroups[group] = fromGroups[group].filter((i) => String((i as any)[this.settings.valueName]) !== value);\n if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== 'left')) {\n delete (fromGroups as any)[group];\n }\n }\n if (!toGroups[group]) toGroups[group] = [];\n const label = li.querySelector('label')?.textContent || '';\n toGroups[group].push({\n [this.settings.itemName]: label,\n [this.settings.valueName]: value,\n [this.settings.groupName]: group,\n } as any);\n });\n this.render();\n }\n\n private toggleSelectAll(side: 'left' | 'right', isChecked: boolean) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[side === 'left' ? 0 : 1] as Element;\n content?.querySelectorAll<HTMLInputElement>('.group-select-all').forEach((inp) => (inp.checked = isChecked));\n content?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = isChecked));\n this.updateSelectAllInfo(side);\n }\n\n private searchItems(side: 'left' | 'right', searchTerm: string) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const container = contents[side === 'left' ? 0 : 1] as HTMLElement;\n const searchText = (searchTerm || '').toLowerCase();\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((groupEl) => {\n const groupName = (groupEl.querySelector('.group-header')?.textContent || '').toLowerCase();\n const items = groupEl.querySelectorAll<HTMLElement>('li');\n let showGroup = false;\n if (groupName.includes(searchText)) {\n groupEl.style.display = '';\n items.forEach((li) => (li.style.display = ''));\n showGroup = true;\n } else {\n items.forEach((li) => {\n const itemText = (li.querySelector('label')?.textContent || '').toLowerCase();\n if (itemText.includes(searchText)) {\n li.style.display = '';\n showGroup = true;\n } else {\n li.style.display = 'none';\n }\n });\n groupEl.style.display = showGroup ? '' : 'none';\n }\n });\n if (!searchText) {\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((g) => (g.style.display = ''));\n container?.querySelectorAll<HTMLElement>('li').forEach((li) => (li.style.display = ''));\n }\n }\n\n private appendSelectedGroupsOnSubmit() {\n if (!this.formEl) {\n console.error('Parent form not found!');\n return;\n }\n const selectedValues: (string | number)[] = [];\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => selectedValues.push((item as any)[this.settings.valueName]));\n });\n // remove existing\n Array.from(this.formEl.querySelectorAll(`input[name=\"${this.settings.inputName}[]\"]`)).forEach((el) => el.remove());\n // append new\n selectedValues.forEach((value) => {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = `${this.settings.inputName}[]`;\n input.value = String(value);\n this.formEl!.appendChild(input);\n });\n }\n\n getSelectedValues(): Promise<(string | number)[]> {\n return new Promise((resolve) => {\n const selectedValues: (string | number)[] = [];\n Object.keys(this.selectedGroups).forEach((groupName) => {\n this.selectedGroups[groupName].forEach((item) => {\n selectedValues.push((item as any)[this.settings.valueName]);\n });\n });\n resolve(selectedValues);\n });\n }\n\n get selected() {\n return this.selectedGroups;\n }\n\n get selectedArray() {\n let selectedValues: (string | number)[] = [];\n Object.keys(this.selectedGroups).forEach((groupName) => {\n this.selectedGroups[groupName].forEach((item) => {\n selectedValues.push((item as any)[this.settings.valueName]);\n });\n });\n selectedValues = [...new Set(selectedValues)];\n return selectedValues;\n }\n\n get unselected() {\n return this.groups;\n }\n\n get allItems() {\n return this.settings.dataArray;\n }\n\n // New API methods: return arrays without duplicates\n getSelectedItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => {\n const key = String((item as any)[this.settings.valueName]);\n if (!map.has(key)) map.set(key, item);\n });\n });\n return Array.from(map.values());\n }\n\n getUnselectedItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n Object.values(this.groups).forEach((items) => {\n items.forEach((item) => {\n const key = String((item as any)[this.settings.valueName]);\n if (!map.has(key)) map.set(key, item);\n });\n });\n return Array.from(map.values());\n }\n\n getAllItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n // include current left and right to reflect UI state\n Object.values(this.groups).forEach((items) => {\n items.forEach((item) => map.set(String((item as any)[this.settings.valueName]), item));\n });\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => map.set(String((item as any)[this.settings.valueName]), item));\n });\n return Array.from(map.values());\n }\n\n getSettings(): Required<DualListBoxOptions> & { theme: DualListBoxTheme } {\n return this.settings;\n }\n}\n\nexport function initDualListBox(selector: string | Element, options: DualListBoxOptions = {}) {\n return new DualListBox(selector, options);\n}\n\n// Attach back-compat static setTheme to the class\n// so existing code using DualListBox.setTheme(...) keeps working.\n(DualListBox as any).setTheme = (theme: Partial<DualListBoxTheme> | DualListBoxTheme) => useTheme(theme);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/themePresets.ts","../src/lib/DualListBox.ts"],"names":["_a"],"mappings":"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","file":"index.cjs","sourcesContent":["import { DualListBoxTheme } from './types';\n\nexport const defaultTheme: DualListBoxTheme = {\n container: 'dual-listbox',\n row: 'row mb-3',\n colLeft: 'col-md-5',\n colCenter: 'col-md-2 d-flex justify-content-center flex-column gap-3',\n colRight: 'col-md-5',\n card: 'card h-100',\n cardHeader: 'card-header',\n cardBody: 'card-body',\n cardFooter: 'card-footer text-center',\n searchInput: 'form-control mb-3 dual-listbox-search',\n listGroup: 'list-group',\n listItem: 'list-group-item py-1 border-0',\n formCheck: 'form-check',\n formCheckInput: 'form-check-input',\n formCheckLabel: 'form-check-label',\n btn: 'btn btn-light w-100',\n btnInclude: '',\n btnExclude: '',\n};\n\nexport const bootstrapTheme: DualListBoxTheme = { ...defaultTheme };\n\nexport const tailwindTheme: DualListBoxTheme = {\n container: 'dual-listbox tw',\n row: 'grid grid-cols-1 md:grid-cols-5 gap-3',\n colLeft: 'md:col-span-2',\n colCenter: 'md:col-span-1 flex flex-col justify-center gap-3',\n colRight: 'md:col-span-2',\n card: 'h-full border rounded shadow-sm bg-white',\n cardHeader: 'px-4 py-2 border-b font-medium',\n cardBody: 'p-4',\n cardFooter: 'px-4 py-2 border-t text-center',\n searchInput: 'w-full mb-3 border rounded px-3 py-2 dual-listbox-search',\n listGroup: 'space-y-1',\n listItem: 'py-1',\n formCheck: 'flex items-center gap-2',\n formCheckInput: 'h-4 w-4',\n formCheckLabel: '',\n btn: 'w-full border rounded px-3 py-2 bg-gray-100 hover:bg-gray-200',\n btnInclude: 'mb-2',\n btnExclude: '',\n};\n","import type {DualListBoxItem, DualListBoxOptions, DualListBoxTheme} from './types';\nimport {defaultTheme} from './themePresets';\n\nfunction mergeTheme(base: DualListBoxTheme, override?: Partial<DualListBoxTheme>): DualListBoxTheme {\n return {...base, ...(override || {})} as DualListBoxTheme;\n}\n\n// Global theme state (module-level)\nlet GLOBAL_THEME: DualListBoxTheme = {...defaultTheme};\n\n/**\n * Set the global default theme for all new DualListBox instances.\n * Instance option `theme` still has highest priority.\n */\nexport function useTheme(theme: Partial<DualListBoxTheme> | DualListBoxTheme) {\n GLOBAL_THEME = mergeTheme(defaultTheme, theme as Partial<DualListBoxTheme>);\n}\n\n// Back-compat alias for older code that might call DualListBox.setTheme(...)\n// We will attach a static setTheme on the class after its definition.\n\nexport class DualListBox {\n private rootEl: Element;\n private formEl: HTMLFormElement | null;\n\n private instanceId: string;\n private originalData: DualListBoxItem[];\n\n private defaults: Required<Omit<DualListBoxOptions, 'theme'>> & { theme: DualListBoxTheme };\n private settings: Required<DualListBoxOptions> & { theme: DualListBoxTheme };\n\n private groups: Record<string, DualListBoxItem[]> = {};\n private selectedGroups: Record<string, DualListBoxItem[]> = {};\n\n constructor(element: Element | string, options: DualListBoxOptions = {}) {\n this.rootEl = typeof element === 'string' ? (document.querySelector(element) as Element) : (element as Element);\n if (!this.rootEl) throw new Error('DualListBox root element not found');\n this.formEl = (this.rootEl.closest('form') as HTMLFormElement) || null;\n this.instanceId = this.generateInstanceId();\n this.defaults = {\n itemName: 'item',\n groupName: 'group',\n valueName: 'value',\n inputName: 'selectedItems',\n tabNameText: 'Available Items',\n rightTabNameText: 'Selected Items',\n searchPlaceholderText: 'Search...',\n includeButtonText: 'Include >>',\n excludeButtonText: '<< Exclude',\n dataArray: [],\n selectedItems: [],\n hideEmptyGroups: false,\n submitForm: true,\n onSubmit: null,\n theme: defaultTheme,\n } as any;\n\n // Effective theme precedence: options.theme > GLOBAL_THEME > defaultTheme\n const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);\n const theme = mergeTheme(themeBase, options.theme);\n this.settings = {...(this.defaults as any), ...(options as any), theme};\n\n this.originalData = [...this.settings.dataArray];\n this.groups = this.buildGroups(this.settings.dataArray);\n this.selectedGroups = this.buildGroups(this.settings.selectedItems);\n\n // Sort initial groups based on originalData order\n this.sortAllGroups();\n\n this.removeDuplicatesFromLeft();\n this.render();\n this.bindEvents();\n\n if (this.formEl) {\n this.formEl.addEventListener('submit', (event) => {\n if (typeof this.settings.onSubmit === 'function') {\n event.preventDefault();\n this.settings.onSubmit(this.selected, this.unselected, this.allItems, this.selectedArray);\n } else if (this.settings.submitForm) {\n this.appendSelectedGroupsOnSubmit();\n }\n });\n }\n }\n\n private generateInstanceId() {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let id = '';\n for (let i = 0; i < 36; i++) {\n id += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return id;\n }\n\n private sortAllGroups() {\n [this.groups, this.selectedGroups].forEach((groupSet) => {\n Object.keys(groupSet).forEach((groupName) => {\n this.sortGroup(groupSet[groupName]);\n });\n });\n }\n\n private sortGroup(group: DualListBoxItem[]) {\n group.sort((a, b) => {\n const valA = String((a as any)[this.settings.valueName]);\n const valB = String((b as any)[this.settings.valueName]);\n const indexA = this.originalData.findIndex(\n (item) => String((item as any)[this.settings.valueName]) === valA\n );\n const indexB = this.originalData.findIndex(\n (item) => String((item as any)[this.settings.valueName]) === valB\n );\n return indexA - indexB;\n });\n }\n\n private buildGroups(dataArray: DualListBoxItem[]) {\n const groups: Record<string, DualListBoxItem[]> = {};\n dataArray.forEach((item) => {\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (!groups[group]) groups[group] = [];\n groups[group].push(item);\n });\n return groups;\n }\n\n private removeDuplicatesFromLeft() {\n Object.keys(this.selectedGroups).forEach((group) => {\n if (this.groups[group]) {\n this.selectedGroups[group].forEach((selectedItem) => {\n this.groups[group] = this.groups[group].filter(\n (item) => String((item as any)[this.settings.valueName]) !== String((selectedItem as any)[this.settings.valueName])\n );\n });\n if (this.settings.hideEmptyGroups) {\n if (!this.groups[group].length) {\n delete this.groups[group];\n }\n }\n }\n });\n this.render();\n }\n\n private render() {\n const t = this.settings.theme;\n const template = `\n <div class=\"${t.container}\" id=\"dual_listbox_${this.instanceId}\">\n <div class=\"${t.row}\">\n <div class=\"${t.colLeft}\" id=\"dual_listbox_${this.instanceId}_left_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.tabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_left_search\" type=\"text\" class=\"${t.searchInput} dual-listbox-search\" data-side=\"left\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('left')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-left\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-left-selected\">0</span>/<span class=\"dual-listbox-left-total\">0</span>)</label>\n </div>\n </div>\n </div>\n <div class=\"${t.colCenter}\">\n <button type=\"button\" class=\"${t.btn} dual-listbox-include ${t.btnInclude}\" disabled>${this.settings.includeButtonText}</button>\n <button type=\"button\" class=\"${t.btn} dual-listbox-exclude ${t.btnExclude}\" disabled>${this.settings.excludeButtonText}</button>\n </div>\n <div class=\"${t.colRight}\" id=\"dual_listbox_${this.instanceId}_right_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.rightTabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_right_search\" type=\"text\" class=\"${t.searchInput} dual-listbox-search\" data-side=\"right\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('right')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-right\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-right-selected\">0</span>/<span class=\"dual-listbox-right-total\">0</span>)</label>\n </div>\n </div>\n </div>\n </div>\n </div>`;\n this.rootEl.innerHTML = template;\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n\n private generateGroupedListHTML(side: 'left' | 'right') {\n const t = this.settings.theme;\n const groups = side === 'left' ? this.groups : this.selectedGroups;\n let html = '';\n const keys = Object.keys(groups);\n keys.forEach((groupName, index) => {\n const items = groups[groupName];\n const totalItems = items.length;\n const isGroupEmpty = totalItems === 0;\n const groupSelectAllInput = `group_${groupName}_${side}`;\n const isLast = index === keys.length - 1;\n html += `\n <div class=\"dual-listbox-group${!isLast ? ' mb-3' : ''}\">\n <div class=\"group-header mb-2\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupSelectAllInput}\" type=\"checkbox\" class=\"${t.formCheckInput} group-select-all\" ${isGroupEmpty ? 'checked disabled' : ''}>\n <label for=\"${groupSelectAllInput}\" class=\"${t.formCheckLabel}\">${groupName}</label>\n </div>\n </div>`;\n if (!isGroupEmpty) {\n html += `<ul class=\"${t.listGroup}\">`;\n items.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const name = (item as any)[this.settings.itemName];\n html += `\n <li class=\"${t.listItem}\" data-value=\"${val}\" data-group=\"${groupName}\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupName}_${val}\" type=\"checkbox\" class=\"${t.formCheckInput} item-select\" />\n <label for=\"${groupName}_${val}\" class=\"${t.formCheckLabel}\">${name}</label>\n </div>\n </li>`;\n });\n html += `</ul>`;\n }\n html += `</div>`;\n });\n return html;\n }\n\n private updateSelectAllInfo(side: 'left' | 'right') {\n const idx = side === 'left' ? 0 : 1;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[idx] as Element;\n const selectAll = this.rootEl.querySelector<HTMLInputElement>(`.dual-listbox-select-all-${side}`);\n const totalItems = content ? content.querySelectorAll('.item-select').length : 0;\n const selectedItems = content ? content.querySelectorAll('.item-select:checked').length : 0;\n const selSpan = this.rootEl.querySelector(`.dual-listbox-${side}-selected`);\n const totalSpan = this.rootEl.querySelector(`.dual-listbox-${side}-total`);\n if (selSpan) selSpan.textContent = String(selectedItems);\n if (totalSpan) totalSpan.textContent = String(totalItems);\n if (selectAll) {\n if (totalItems === 0) {\n selectAll.disabled = true;\n selectAll.checked = true;\n } else {\n selectAll.disabled = false;\n selectAll.checked = selectedItems === totalItems;\n }\n }\n\n // Enable/disable include/exclude buttons based on selections\n const includeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-include');\n const excludeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-exclude');\n const leftContent = contents[0] as Element | undefined;\n const rightContent = contents[1] as Element | undefined;\n const leftChecked = leftContent ? leftContent.querySelectorAll('.item-select:checked').length : 0;\n const rightChecked = rightContent ? rightContent.querySelectorAll('.item-select:checked').length : 0;\n if (includeBtn) includeBtn.disabled = leftChecked === 0;\n if (excludeBtn) excludeBtn.disabled = rightChecked === 0;\n }\n\n private bindEvents() {\n this.rootEl.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (target.closest('.dual-listbox-include')) {\n this.moveItems('left', 'right');\n } else if (target.closest('.dual-listbox-exclude')) {\n this.moveItems('right', 'left');\n }\n });\n this.rootEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-select-all-left')) {\n this.toggleSelectAll('left', target.checked);\n } else if (target.matches('.dual-listbox-select-all-right')) {\n this.toggleSelectAll('right', target.checked);\n } else if (target.matches('.group-select-all')) {\n const groupEl = target.closest('.dual-listbox-group') as Element;\n groupEl?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = target.checked));\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n } else if (target.matches('.item-select')) {\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n });\n this.rootEl.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-search')) {\n const side = (target.getAttribute('data-side') as 'left' | 'right') || 'left';\n const searchTerm = target.value || '';\n this.searchItems(side, searchTerm);\n }\n });\n }\n\n private moveItems(fromSide: 'left' | 'right', toSide: 'left' | 'right') {\n const fromGroups = fromSide === 'left' ? this.groups : this.selectedGroups;\n const toGroups = toSide === 'left' ? this.groups : this.selectedGroups;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const fromContainer = contents[fromSide === 'left' ? 0 : 1] as Element;\n const selectedLis = Array.from(fromContainer.querySelectorAll<HTMLInputElement>('.item-select:checked')).map((inp) => inp.closest('li') as HTMLLIElement);\n \n selectedLis.forEach((li) => {\n const value = String(li.getAttribute('data-value'));\n const group = String(li.getAttribute('data-group'));\n \n // Find original item to preserve all properties\n const originalItem = this.originalData.find(item => String((item as any)[this.settings.valueName]) === value);\n if (!originalItem) return;\n\n if (fromGroups[group]) {\n fromGroups[group] = fromGroups[group].filter((i) => String((i as any)[this.settings.valueName]) !== value);\n if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== 'left')) {\n delete (fromGroups as any)[group];\n }\n }\n if (!toGroups[group]) toGroups[group] = [];\n \n // Avoid duplicates\n if (!toGroups[group].some(i => String((i as any)[this.settings.valueName]) === value)) {\n toGroups[group].push(originalItem);\n }\n\n // Sort toGroups[group] based on originalData order\n this.sortGroup(toGroups[group]);\n });\n this.render();\n }\n\n private toggleSelectAll(side: 'left' | 'right', isChecked: boolean) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[side === 'left' ? 0 : 1] as Element;\n content?.querySelectorAll<HTMLInputElement>('.group-select-all').forEach((inp) => (inp.checked = isChecked));\n content?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = isChecked));\n this.updateSelectAllInfo(side);\n }\n\n private searchItems(side: 'left' | 'right', searchTerm: string) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const container = contents[side === 'left' ? 0 : 1] as HTMLElement;\n const searchText = (searchTerm || '').toLowerCase();\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((groupEl) => {\n const groupName = (groupEl.querySelector('.group-header')?.textContent || '').toLowerCase();\n const items = groupEl.querySelectorAll<HTMLElement>('li');\n let showGroup = false;\n if (groupName.includes(searchText)) {\n groupEl.style.display = '';\n items.forEach((li) => (li.style.display = ''));\n showGroup = true;\n } else {\n items.forEach((li) => {\n const itemText = (li.querySelector('label')?.textContent || '').toLowerCase();\n if (itemText.includes(searchText)) {\n li.style.display = '';\n showGroup = true;\n } else {\n li.style.display = 'none';\n }\n });\n groupEl.style.display = showGroup ? '' : 'none';\n }\n });\n if (!searchText) {\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((g) => (g.style.display = ''));\n container?.querySelectorAll<HTMLElement>('li').forEach((li) => (li.style.display = ''));\n }\n }\n\n private appendSelectedGroupsOnSubmit() {\n if (!this.formEl) {\n console.error('Parent form not found!');\n return;\n }\n const selectedValues: (string | number)[] = this.selectedArray;\n // remove existing\n Array.from(this.formEl.querySelectorAll(`input[name=\"${this.settings.inputName}[]\"]`)).forEach((el) => el.remove());\n // append new\n selectedValues.forEach((value) => {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = `${this.settings.inputName}[]`;\n input.value = String(value);\n this.formEl!.appendChild(input);\n });\n }\n\n getSelectedValues(): Promise<(string | number)[]> {\n return new Promise((resolve) => {\n resolve(this.selectedArray);\n });\n }\n\n get selected() {\n return this.selectedGroups;\n }\n\n get selectedArray() {\n const selectedValues: (string | number)[] = [];\n this.originalData.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (this.selectedGroups[group]) {\n const isSelected = this.selectedGroups[group].some(\n (i) => String((i as any)[this.settings.valueName]) === String(val)\n );\n if (isSelected) {\n selectedValues.push(val);\n }\n }\n });\n return selectedValues;\n }\n\n get unselected() {\n return this.groups;\n }\n\n get allItems() {\n return this.settings.dataArray;\n }\n\n // New API methods: return arrays without duplicates\n getSelectedItems(): DualListBoxItem[] {\n const selected: DualListBoxItem[] = [];\n const values = this.selectedArray.map(String);\n this.originalData.forEach((item) => {\n if (values.includes(String((item as any)[this.settings.valueName]))) {\n selected.push(item);\n }\n });\n return selected;\n }\n\n getUnselectedItems(): DualListBoxItem[] {\n const unselected: DualListBoxItem[] = [];\n const selectedValues = this.selectedArray.map(String);\n this.originalData.forEach((item) => {\n if (!selectedValues.includes(String((item as any)[this.settings.valueName]))) {\n unselected.push(item);\n }\n });\n return unselected;\n }\n\n getAllItems(): DualListBoxItem[] {\n return [...this.originalData];\n }\n\n getSettings(): Required<DualListBoxOptions> & { theme: DualListBoxTheme } {\n return this.settings;\n }\n}\n\nexport function initDualListBox(selector: string | Element, options: DualListBoxOptions = {}) {\n return new DualListBox(selector, options);\n}\n\n// Attach back-compat static setTheme to the class\n// so existing code using DualListBox.setTheme(...) keeps working.\n(DualListBox as any).setTheme = (theme: Partial<DualListBoxTheme> | DualListBoxTheme) => useTheme(theme);\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -49,12 +49,15 @@ declare class DualListBox {
|
|
|
49
49
|
private rootEl;
|
|
50
50
|
private formEl;
|
|
51
51
|
private instanceId;
|
|
52
|
+
private originalData;
|
|
52
53
|
private defaults;
|
|
53
54
|
private settings;
|
|
54
55
|
private groups;
|
|
55
56
|
private selectedGroups;
|
|
56
57
|
constructor(element: Element | string, options?: DualListBoxOptions);
|
|
57
58
|
private generateInstanceId;
|
|
59
|
+
private sortAllGroups;
|
|
60
|
+
private sortGroup;
|
|
58
61
|
private buildGroups;
|
|
59
62
|
private removeDuplicatesFromLeft;
|
|
60
63
|
private render;
|
package/dist/index.mjs
CHANGED
|
@@ -77,8 +77,10 @@ var DualListBox = class {
|
|
|
77
77
|
const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);
|
|
78
78
|
const theme = mergeTheme(themeBase, options.theme);
|
|
79
79
|
this.settings = { ...this.defaults, ...options, theme };
|
|
80
|
+
this.originalData = [...this.settings.dataArray];
|
|
80
81
|
this.groups = this.buildGroups(this.settings.dataArray);
|
|
81
82
|
this.selectedGroups = this.buildGroups(this.settings.selectedItems);
|
|
83
|
+
this.sortAllGroups();
|
|
82
84
|
this.removeDuplicatesFromLeft();
|
|
83
85
|
this.render();
|
|
84
86
|
this.bindEvents();
|
|
@@ -101,14 +103,32 @@ var DualListBox = class {
|
|
|
101
103
|
}
|
|
102
104
|
return id;
|
|
103
105
|
}
|
|
106
|
+
sortAllGroups() {
|
|
107
|
+
[this.groups, this.selectedGroups].forEach((groupSet) => {
|
|
108
|
+
Object.keys(groupSet).forEach((groupName) => {
|
|
109
|
+
this.sortGroup(groupSet[groupName]);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
sortGroup(group) {
|
|
114
|
+
group.sort((a, b) => {
|
|
115
|
+
const valA = String(a[this.settings.valueName]);
|
|
116
|
+
const valB = String(b[this.settings.valueName]);
|
|
117
|
+
const indexA = this.originalData.findIndex(
|
|
118
|
+
(item) => String(item[this.settings.valueName]) === valA
|
|
119
|
+
);
|
|
120
|
+
const indexB = this.originalData.findIndex(
|
|
121
|
+
(item) => String(item[this.settings.valueName]) === valB
|
|
122
|
+
);
|
|
123
|
+
return indexA - indexB;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
104
126
|
buildGroups(dataArray) {
|
|
105
127
|
const groups = {};
|
|
106
128
|
dataArray.forEach((item) => {
|
|
107
129
|
const group = item[this.settings.groupName] || "Ungrouped";
|
|
108
130
|
if (!groups[group]) groups[group] = [];
|
|
109
|
-
|
|
110
|
-
groups[group].push(item);
|
|
111
|
-
}
|
|
131
|
+
groups[group].push(item);
|
|
112
132
|
});
|
|
113
133
|
return groups;
|
|
114
134
|
}
|
|
@@ -117,7 +137,7 @@ var DualListBox = class {
|
|
|
117
137
|
if (this.groups[group]) {
|
|
118
138
|
this.selectedGroups[group].forEach((selectedItem) => {
|
|
119
139
|
this.groups[group] = this.groups[group].filter(
|
|
120
|
-
(item) => item[this.settings.valueName] !== selectedItem[this.settings.valueName]
|
|
140
|
+
(item) => String(item[this.settings.valueName]) !== String(selectedItem[this.settings.valueName])
|
|
121
141
|
);
|
|
122
142
|
});
|
|
123
143
|
if (this.settings.hideEmptyGroups) {
|
|
@@ -138,7 +158,7 @@ var DualListBox = class {
|
|
|
138
158
|
<div class="${t.card}">
|
|
139
159
|
<div class="${t.cardHeader}">${this.settings.tabNameText}</div>
|
|
140
160
|
<div class="${t.cardBody}">
|
|
141
|
-
<input id="dual_listbox_${this.instanceId}_left_search" type="text" class="${t.searchInput}" data-side="left" placeholder="${this.settings.searchPlaceholderText}">
|
|
161
|
+
<input id="dual_listbox_${this.instanceId}_left_search" type="text" class="${t.searchInput} dual-listbox-search" data-side="left" placeholder="${this.settings.searchPlaceholderText}">
|
|
142
162
|
<div class="dual-listbox-content">
|
|
143
163
|
${this.generateGroupedListHTML("left")}
|
|
144
164
|
</div>
|
|
@@ -150,14 +170,14 @@ var DualListBox = class {
|
|
|
150
170
|
</div>
|
|
151
171
|
</div>
|
|
152
172
|
<div class="${t.colCenter}">
|
|
153
|
-
<button class="${t.btn} dual-listbox-include ${t.btnInclude}" disabled>${this.settings.includeButtonText}</button>
|
|
154
|
-
<button class="${t.btn} dual-listbox-exclude ${t.btnExclude}" disabled>${this.settings.excludeButtonText}</button>
|
|
173
|
+
<button type="button" class="${t.btn} dual-listbox-include ${t.btnInclude}" disabled>${this.settings.includeButtonText}</button>
|
|
174
|
+
<button type="button" class="${t.btn} dual-listbox-exclude ${t.btnExclude}" disabled>${this.settings.excludeButtonText}</button>
|
|
155
175
|
</div>
|
|
156
176
|
<div class="${t.colRight}" id="dual_listbox_${this.instanceId}_right_side">
|
|
157
177
|
<div class="${t.card}">
|
|
158
178
|
<div class="${t.cardHeader}">${this.settings.rightTabNameText}</div>
|
|
159
179
|
<div class="${t.cardBody}">
|
|
160
|
-
<input id="dual_listbox_${this.instanceId}_right_search" type="text" class="${t.searchInput}" data-side="right" placeholder="${this.settings.searchPlaceholderText}">
|
|
180
|
+
<input id="dual_listbox_${this.instanceId}_right_search" type="text" class="${t.searchInput} dual-listbox-search" data-side="right" placeholder="${this.settings.searchPlaceholderText}">
|
|
161
181
|
<div class="dual-listbox-content">
|
|
162
182
|
${this.generateGroupedListHTML("right")}
|
|
163
183
|
</div>
|
|
@@ -282,9 +302,10 @@ var DualListBox = class {
|
|
|
282
302
|
const fromContainer = contents[fromSide === "left" ? 0 : 1];
|
|
283
303
|
const selectedLis = Array.from(fromContainer.querySelectorAll(".item-select:checked")).map((inp) => inp.closest("li"));
|
|
284
304
|
selectedLis.forEach((li) => {
|
|
285
|
-
var _a;
|
|
286
305
|
const value = String(li.getAttribute("data-value"));
|
|
287
306
|
const group = String(li.getAttribute("data-group"));
|
|
307
|
+
const originalItem = this.originalData.find((item) => String(item[this.settings.valueName]) === value);
|
|
308
|
+
if (!originalItem) return;
|
|
288
309
|
if (fromGroups[group]) {
|
|
289
310
|
fromGroups[group] = fromGroups[group].filter((i) => String(i[this.settings.valueName]) !== value);
|
|
290
311
|
if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== "left")) {
|
|
@@ -292,12 +313,10 @@ var DualListBox = class {
|
|
|
292
313
|
}
|
|
293
314
|
}
|
|
294
315
|
if (!toGroups[group]) toGroups[group] = [];
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
[this.settings.groupName]: group
|
|
300
|
-
});
|
|
316
|
+
if (!toGroups[group].some((i) => String(i[this.settings.valueName]) === value)) {
|
|
317
|
+
toGroups[group].push(originalItem);
|
|
318
|
+
}
|
|
319
|
+
this.sortGroup(toGroups[group]);
|
|
301
320
|
});
|
|
302
321
|
this.render();
|
|
303
322
|
}
|
|
@@ -345,10 +364,7 @@ var DualListBox = class {
|
|
|
345
364
|
console.error("Parent form not found!");
|
|
346
365
|
return;
|
|
347
366
|
}
|
|
348
|
-
const selectedValues =
|
|
349
|
-
Object.values(this.selectedGroups).forEach((items) => {
|
|
350
|
-
items.forEach((item) => selectedValues.push(item[this.settings.valueName]));
|
|
351
|
-
});
|
|
367
|
+
const selectedValues = this.selectedArray;
|
|
352
368
|
Array.from(this.formEl.querySelectorAll(`input[name="${this.settings.inputName}[]"]`)).forEach((el) => el.remove());
|
|
353
369
|
selectedValues.forEach((value) => {
|
|
354
370
|
const input = document.createElement("input");
|
|
@@ -360,26 +376,26 @@ var DualListBox = class {
|
|
|
360
376
|
}
|
|
361
377
|
getSelectedValues() {
|
|
362
378
|
return new Promise((resolve) => {
|
|
363
|
-
|
|
364
|
-
Object.keys(this.selectedGroups).forEach((groupName) => {
|
|
365
|
-
this.selectedGroups[groupName].forEach((item) => {
|
|
366
|
-
selectedValues.push(item[this.settings.valueName]);
|
|
367
|
-
});
|
|
368
|
-
});
|
|
369
|
-
resolve(selectedValues);
|
|
379
|
+
resolve(this.selectedArray);
|
|
370
380
|
});
|
|
371
381
|
}
|
|
372
382
|
get selected() {
|
|
373
383
|
return this.selectedGroups;
|
|
374
384
|
}
|
|
375
385
|
get selectedArray() {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
this.
|
|
379
|
-
|
|
380
|
-
|
|
386
|
+
const selectedValues = [];
|
|
387
|
+
this.originalData.forEach((item) => {
|
|
388
|
+
const val = item[this.settings.valueName];
|
|
389
|
+
const group = item[this.settings.groupName] || "Ungrouped";
|
|
390
|
+
if (this.selectedGroups[group]) {
|
|
391
|
+
const isSelected = this.selectedGroups[group].some(
|
|
392
|
+
(i) => String(i[this.settings.valueName]) === String(val)
|
|
393
|
+
);
|
|
394
|
+
if (isSelected) {
|
|
395
|
+
selectedValues.push(val);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
381
398
|
});
|
|
382
|
-
selectedValues = [...new Set(selectedValues)];
|
|
383
399
|
return selectedValues;
|
|
384
400
|
}
|
|
385
401
|
get unselected() {
|
|
@@ -390,34 +406,27 @@ var DualListBox = class {
|
|
|
390
406
|
}
|
|
391
407
|
// New API methods: return arrays without duplicates
|
|
392
408
|
getSelectedItems() {
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
409
|
+
const selected = [];
|
|
410
|
+
const values = this.selectedArray.map(String);
|
|
411
|
+
this.originalData.forEach((item) => {
|
|
412
|
+
if (values.includes(String(item[this.settings.valueName]))) {
|
|
413
|
+
selected.push(item);
|
|
414
|
+
}
|
|
399
415
|
});
|
|
400
|
-
return
|
|
416
|
+
return selected;
|
|
401
417
|
}
|
|
402
418
|
getUnselectedItems() {
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
}
|
|
419
|
+
const unselected = [];
|
|
420
|
+
const selectedValues = this.selectedArray.map(String);
|
|
421
|
+
this.originalData.forEach((item) => {
|
|
422
|
+
if (!selectedValues.includes(String(item[this.settings.valueName]))) {
|
|
423
|
+
unselected.push(item);
|
|
424
|
+
}
|
|
409
425
|
});
|
|
410
|
-
return
|
|
426
|
+
return unselected;
|
|
411
427
|
}
|
|
412
428
|
getAllItems() {
|
|
413
|
-
|
|
414
|
-
Object.values(this.groups).forEach((items) => {
|
|
415
|
-
items.forEach((item) => map.set(String(item[this.settings.valueName]), item));
|
|
416
|
-
});
|
|
417
|
-
Object.values(this.selectedGroups).forEach((items) => {
|
|
418
|
-
items.forEach((item) => map.set(String(item[this.settings.valueName]), item));
|
|
419
|
-
});
|
|
420
|
-
return Array.from(map.values());
|
|
429
|
+
return [...this.originalData];
|
|
421
430
|
}
|
|
422
431
|
getSettings() {
|
|
423
432
|
return this.settings;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/themePresets.ts","../src/lib/DualListBox.ts"],"names":["_a"],"mappings":"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","file":"index.mjs","sourcesContent":["import { DualListBoxTheme } from './types';\n\nexport const defaultTheme: DualListBoxTheme = {\n container: 'dual-listbox',\n row: 'row mb-3',\n colLeft: 'col-md-5',\n colCenter: 'col-md-2 d-flex justify-content-center flex-column gap-3',\n colRight: 'col-md-5',\n card: 'card h-100',\n cardHeader: 'card-header',\n cardBody: 'card-body',\n cardFooter: 'card-footer text-center',\n searchInput: 'form-control mb-3 dual-listbox-search',\n listGroup: 'list-group',\n listItem: 'list-group-item py-1 border-0',\n formCheck: 'form-check',\n formCheckInput: 'form-check-input',\n formCheckLabel: 'form-check-label',\n btn: 'btn btn-light w-100',\n btnInclude: '',\n btnExclude: '',\n};\n\nexport const bootstrapTheme: DualListBoxTheme = { ...defaultTheme };\n\nexport const tailwindTheme: DualListBoxTheme = {\n container: 'dual-listbox tw',\n row: 'grid grid-cols-1 md:grid-cols-5 gap-3',\n colLeft: 'md:col-span-2',\n colCenter: 'md:col-span-1 flex flex-col justify-center gap-3',\n colRight: 'md:col-span-2',\n card: 'h-full border rounded shadow-sm bg-white',\n cardHeader: 'px-4 py-2 border-b font-medium',\n cardBody: 'p-4',\n cardFooter: 'px-4 py-2 border-t text-center',\n searchInput: 'w-full mb-3 border rounded px-3 py-2 dual-listbox-search',\n listGroup: 'space-y-1',\n listItem: 'py-1',\n formCheck: 'flex items-center gap-2',\n formCheckInput: 'h-4 w-4',\n formCheckLabel: '',\n btn: 'w-full border rounded px-3 py-2 bg-gray-100 hover:bg-gray-200',\n btnInclude: 'mb-2',\n btnExclude: '',\n};\n","import type {DualListBoxItem, DualListBoxOptions, DualListBoxTheme} from './types';\nimport {defaultTheme} from './themePresets';\n\nfunction mergeTheme(base: DualListBoxTheme, override?: Partial<DualListBoxTheme>): DualListBoxTheme {\n return {...base, ...(override || {})} as DualListBoxTheme;\n}\n\n// Global theme state (module-level)\nlet GLOBAL_THEME: DualListBoxTheme = {...defaultTheme};\n\n/**\n * Set the global default theme for all new DualListBox instances.\n * Instance option `theme` still has highest priority.\n */\nexport function useTheme(theme: Partial<DualListBoxTheme> | DualListBoxTheme) {\n GLOBAL_THEME = mergeTheme(defaultTheme, theme as Partial<DualListBoxTheme>);\n}\n\n// Back-compat alias for older code that might call DualListBox.setTheme(...)\n// We will attach a static setTheme on the class after its definition.\n\nexport class DualListBox {\n private rootEl: Element;\n private formEl: HTMLFormElement | null;\n\n private instanceId: string;\n\n private defaults: Required<Omit<DualListBoxOptions, 'theme'>> & { theme: DualListBoxTheme };\n private settings: Required<DualListBoxOptions> & { theme: DualListBoxTheme };\n\n private groups: Record<string, DualListBoxItem[]> = {};\n private selectedGroups: Record<string, DualListBoxItem[]> = {};\n\n constructor(element: Element | string, options: DualListBoxOptions = {}) {\n this.rootEl = typeof element === 'string' ? (document.querySelector(element) as Element) : (element as Element);\n if (!this.rootEl) throw new Error('DualListBox root element not found');\n this.formEl = (this.rootEl.closest('form') as HTMLFormElement) || null;\n this.instanceId = this.generateInstanceId();\n this.defaults = {\n itemName: 'item',\n groupName: 'group',\n valueName: 'value',\n inputName: 'selectedItems',\n tabNameText: 'Available Items',\n rightTabNameText: 'Selected Items',\n searchPlaceholderText: 'Search...',\n includeButtonText: 'Include >>',\n excludeButtonText: '<< Exclude',\n dataArray: [],\n selectedItems: [],\n hideEmptyGroups: false,\n submitForm: true,\n onSubmit: null,\n theme: defaultTheme,\n } as any;\n\n // Effective theme precedence: options.theme > GLOBAL_THEME > defaultTheme\n const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);\n const theme = mergeTheme(themeBase, options.theme);\n this.settings = {...(this.defaults as any), ...(options as any), theme};\n\n this.groups = this.buildGroups(this.settings.dataArray);\n this.selectedGroups = this.buildGroups(this.settings.selectedItems);\n\n this.removeDuplicatesFromLeft();\n this.render();\n this.bindEvents();\n\n if (this.formEl) {\n this.formEl.addEventListener('submit', (event) => {\n if (typeof this.settings.onSubmit === 'function') {\n event.preventDefault();\n this.settings.onSubmit(this.selected, this.unselected, this.allItems, this.selectedArray);\n } else if (this.settings.submitForm) {\n this.appendSelectedGroupsOnSubmit();\n }\n });\n }\n }\n\n private generateInstanceId() {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let id = '';\n for (let i = 0; i < 36; i++) {\n id += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return id;\n }\n\n private buildGroups(dataArray: DualListBoxItem[]) {\n const groups: Record<string, DualListBoxItem[]> = {};\n dataArray.forEach((item) => {\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (!groups[group]) groups[group] = [];\n if (!groups[group].some((existing) => (existing as any)[this.settings.valueName] === (item as any)[this.settings.valueName])) {\n groups[group].push(item);\n }\n });\n return groups;\n }\n\n private removeDuplicatesFromLeft() {\n Object.keys(this.selectedGroups).forEach((group) => {\n if (this.groups[group]) {\n this.selectedGroups[group].forEach((selectedItem) => {\n this.groups[group] = this.groups[group].filter(\n (item) => (item as any)[this.settings.valueName] !== (selectedItem as any)[this.settings.valueName]\n );\n });\n if (this.settings.hideEmptyGroups) {\n if (!this.groups[group].length) {\n delete this.groups[group];\n }\n }\n }\n });\n this.render();\n }\n\n private render() {\n const t = this.settings.theme;\n const template = `\n <div class=\"${t.container}\" id=\"dual_listbox_${this.instanceId}\">\n <div class=\"${t.row}\">\n <div class=\"${t.colLeft}\" id=\"dual_listbox_${this.instanceId}_left_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.tabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_left_search\" type=\"text\" class=\"${t.searchInput}\" data-side=\"left\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('left')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-left\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-left-selected\">0</span>/<span class=\"dual-listbox-left-total\">0</span>)</label>\n </div>\n </div>\n </div>\n <div class=\"${t.colCenter}\">\n <button class=\"${t.btn} dual-listbox-include ${t.btnInclude}\" disabled>${this.settings.includeButtonText}</button>\n <button class=\"${t.btn} dual-listbox-exclude ${t.btnExclude}\" disabled>${this.settings.excludeButtonText}</button>\n </div>\n <div class=\"${t.colRight}\" id=\"dual_listbox_${this.instanceId}_right_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.rightTabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_right_search\" type=\"text\" class=\"${t.searchInput}\" data-side=\"right\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('right')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-right\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-right-selected\">0</span>/<span class=\"dual-listbox-right-total\">0</span>)</label>\n </div>\n </div>\n </div>\n </div>\n </div>`;\n this.rootEl.innerHTML = template;\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n\n private generateGroupedListHTML(side: 'left' | 'right') {\n const t = this.settings.theme;\n const groups = side === 'left' ? this.groups : this.selectedGroups;\n let html = '';\n const keys = Object.keys(groups);\n keys.forEach((groupName, index) => {\n const items = groups[groupName];\n const totalItems = items.length;\n const isGroupEmpty = totalItems === 0;\n const groupSelectAllInput = `group_${groupName}_${side}`;\n const isLast = index === keys.length - 1;\n html += `\n <div class=\"dual-listbox-group${!isLast ? ' mb-3' : ''}\">\n <div class=\"group-header mb-2\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupSelectAllInput}\" type=\"checkbox\" class=\"${t.formCheckInput} group-select-all\" ${isGroupEmpty ? 'checked disabled' : ''}>\n <label for=\"${groupSelectAllInput}\" class=\"${t.formCheckLabel}\">${groupName}</label>\n </div>\n </div>`;\n if (!isGroupEmpty) {\n html += `<ul class=\"${t.listGroup}\">`;\n items.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const name = (item as any)[this.settings.itemName];\n html += `\n <li class=\"${t.listItem}\" data-value=\"${val}\" data-group=\"${groupName}\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupName}_${val}\" type=\"checkbox\" class=\"${t.formCheckInput} item-select\" />\n <label for=\"${groupName}_${val}\" class=\"${t.formCheckLabel}\">${name}</label>\n </div>\n </li>`;\n });\n html += `</ul>`;\n }\n html += `</div>`;\n });\n return html;\n }\n\n private updateSelectAllInfo(side: 'left' | 'right') {\n const idx = side === 'left' ? 0 : 1;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[idx] as Element;\n const selectAll = this.rootEl.querySelector<HTMLInputElement>(`.dual-listbox-select-all-${side}`);\n const totalItems = content ? content.querySelectorAll('.item-select').length : 0;\n const selectedItems = content ? content.querySelectorAll('.item-select:checked').length : 0;\n const selSpan = this.rootEl.querySelector(`.dual-listbox-${side}-selected`);\n const totalSpan = this.rootEl.querySelector(`.dual-listbox-${side}-total`);\n if (selSpan) selSpan.textContent = String(selectedItems);\n if (totalSpan) totalSpan.textContent = String(totalItems);\n if (selectAll) {\n if (totalItems === 0) {\n selectAll.disabled = true;\n selectAll.checked = true;\n } else {\n selectAll.disabled = false;\n selectAll.checked = selectedItems === totalItems;\n }\n }\n\n // Enable/disable include/exclude buttons based on selections\n const includeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-include');\n const excludeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-exclude');\n const leftContent = contents[0] as Element | undefined;\n const rightContent = contents[1] as Element | undefined;\n const leftChecked = leftContent ? leftContent.querySelectorAll('.item-select:checked').length : 0;\n const rightChecked = rightContent ? rightContent.querySelectorAll('.item-select:checked').length : 0;\n if (includeBtn) includeBtn.disabled = leftChecked === 0;\n if (excludeBtn) excludeBtn.disabled = rightChecked === 0;\n }\n\n private bindEvents() {\n this.rootEl.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (target.closest('.dual-listbox-include')) {\n this.moveItems('left', 'right');\n } else if (target.closest('.dual-listbox-exclude')) {\n this.moveItems('right', 'left');\n }\n });\n this.rootEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-select-all-left')) {\n this.toggleSelectAll('left', target.checked);\n } else if (target.matches('.dual-listbox-select-all-right')) {\n this.toggleSelectAll('right', target.checked);\n } else if (target.matches('.group-select-all')) {\n const groupEl = target.closest('.dual-listbox-group') as Element;\n groupEl?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = target.checked));\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n } else if (target.matches('.item-select')) {\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n });\n this.rootEl.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-search')) {\n const side = (target.getAttribute('data-side') as 'left' | 'right') || 'left';\n const searchTerm = target.value || '';\n this.searchItems(side, searchTerm);\n }\n });\n }\n\n private moveItems(fromSide: 'left' | 'right', toSide: 'left' | 'right') {\n const fromGroups = fromSide === 'left' ? this.groups : this.selectedGroups;\n const toGroups = toSide === 'left' ? this.groups : this.selectedGroups;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const fromContainer = contents[fromSide === 'left' ? 0 : 1] as Element;\n const selectedLis = Array.from(fromContainer.querySelectorAll<HTMLInputElement>('.item-select:checked')).map((inp) => inp.closest('li') as HTMLLIElement);\n selectedLis.forEach((li) => {\n const value = String(li.getAttribute('data-value'));\n const group = String(li.getAttribute('data-group'));\n if (fromGroups[group]) {\n fromGroups[group] = fromGroups[group].filter((i) => String((i as any)[this.settings.valueName]) !== value);\n if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== 'left')) {\n delete (fromGroups as any)[group];\n }\n }\n if (!toGroups[group]) toGroups[group] = [];\n const label = li.querySelector('label')?.textContent || '';\n toGroups[group].push({\n [this.settings.itemName]: label,\n [this.settings.valueName]: value,\n [this.settings.groupName]: group,\n } as any);\n });\n this.render();\n }\n\n private toggleSelectAll(side: 'left' | 'right', isChecked: boolean) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[side === 'left' ? 0 : 1] as Element;\n content?.querySelectorAll<HTMLInputElement>('.group-select-all').forEach((inp) => (inp.checked = isChecked));\n content?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = isChecked));\n this.updateSelectAllInfo(side);\n }\n\n private searchItems(side: 'left' | 'right', searchTerm: string) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const container = contents[side === 'left' ? 0 : 1] as HTMLElement;\n const searchText = (searchTerm || '').toLowerCase();\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((groupEl) => {\n const groupName = (groupEl.querySelector('.group-header')?.textContent || '').toLowerCase();\n const items = groupEl.querySelectorAll<HTMLElement>('li');\n let showGroup = false;\n if (groupName.includes(searchText)) {\n groupEl.style.display = '';\n items.forEach((li) => (li.style.display = ''));\n showGroup = true;\n } else {\n items.forEach((li) => {\n const itemText = (li.querySelector('label')?.textContent || '').toLowerCase();\n if (itemText.includes(searchText)) {\n li.style.display = '';\n showGroup = true;\n } else {\n li.style.display = 'none';\n }\n });\n groupEl.style.display = showGroup ? '' : 'none';\n }\n });\n if (!searchText) {\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((g) => (g.style.display = ''));\n container?.querySelectorAll<HTMLElement>('li').forEach((li) => (li.style.display = ''));\n }\n }\n\n private appendSelectedGroupsOnSubmit() {\n if (!this.formEl) {\n console.error('Parent form not found!');\n return;\n }\n const selectedValues: (string | number)[] = [];\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => selectedValues.push((item as any)[this.settings.valueName]));\n });\n // remove existing\n Array.from(this.formEl.querySelectorAll(`input[name=\"${this.settings.inputName}[]\"]`)).forEach((el) => el.remove());\n // append new\n selectedValues.forEach((value) => {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = `${this.settings.inputName}[]`;\n input.value = String(value);\n this.formEl!.appendChild(input);\n });\n }\n\n getSelectedValues(): Promise<(string | number)[]> {\n return new Promise((resolve) => {\n const selectedValues: (string | number)[] = [];\n Object.keys(this.selectedGroups).forEach((groupName) => {\n this.selectedGroups[groupName].forEach((item) => {\n selectedValues.push((item as any)[this.settings.valueName]);\n });\n });\n resolve(selectedValues);\n });\n }\n\n get selected() {\n return this.selectedGroups;\n }\n\n get selectedArray() {\n let selectedValues: (string | number)[] = [];\n Object.keys(this.selectedGroups).forEach((groupName) => {\n this.selectedGroups[groupName].forEach((item) => {\n selectedValues.push((item as any)[this.settings.valueName]);\n });\n });\n selectedValues = [...new Set(selectedValues)];\n return selectedValues;\n }\n\n get unselected() {\n return this.groups;\n }\n\n get allItems() {\n return this.settings.dataArray;\n }\n\n // New API methods: return arrays without duplicates\n getSelectedItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => {\n const key = String((item as any)[this.settings.valueName]);\n if (!map.has(key)) map.set(key, item);\n });\n });\n return Array.from(map.values());\n }\n\n getUnselectedItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n Object.values(this.groups).forEach((items) => {\n items.forEach((item) => {\n const key = String((item as any)[this.settings.valueName]);\n if (!map.has(key)) map.set(key, item);\n });\n });\n return Array.from(map.values());\n }\n\n getAllItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n // include current left and right to reflect UI state\n Object.values(this.groups).forEach((items) => {\n items.forEach((item) => map.set(String((item as any)[this.settings.valueName]), item));\n });\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => map.set(String((item as any)[this.settings.valueName]), item));\n });\n return Array.from(map.values());\n }\n\n getSettings(): Required<DualListBoxOptions> & { theme: DualListBoxTheme } {\n return this.settings;\n }\n}\n\nexport function initDualListBox(selector: string | Element, options: DualListBoxOptions = {}) {\n return new DualListBox(selector, options);\n}\n\n// Attach back-compat static setTheme to the class\n// so existing code using DualListBox.setTheme(...) keeps working.\n(DualListBox as any).setTheme = (theme: Partial<DualListBoxTheme> | DualListBoxTheme) => useTheme(theme);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/themePresets.ts","../src/lib/DualListBox.ts"],"names":["_a"],"mappings":"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","file":"index.mjs","sourcesContent":["import { DualListBoxTheme } from './types';\n\nexport const defaultTheme: DualListBoxTheme = {\n container: 'dual-listbox',\n row: 'row mb-3',\n colLeft: 'col-md-5',\n colCenter: 'col-md-2 d-flex justify-content-center flex-column gap-3',\n colRight: 'col-md-5',\n card: 'card h-100',\n cardHeader: 'card-header',\n cardBody: 'card-body',\n cardFooter: 'card-footer text-center',\n searchInput: 'form-control mb-3 dual-listbox-search',\n listGroup: 'list-group',\n listItem: 'list-group-item py-1 border-0',\n formCheck: 'form-check',\n formCheckInput: 'form-check-input',\n formCheckLabel: 'form-check-label',\n btn: 'btn btn-light w-100',\n btnInclude: '',\n btnExclude: '',\n};\n\nexport const bootstrapTheme: DualListBoxTheme = { ...defaultTheme };\n\nexport const tailwindTheme: DualListBoxTheme = {\n container: 'dual-listbox tw',\n row: 'grid grid-cols-1 md:grid-cols-5 gap-3',\n colLeft: 'md:col-span-2',\n colCenter: 'md:col-span-1 flex flex-col justify-center gap-3',\n colRight: 'md:col-span-2',\n card: 'h-full border rounded shadow-sm bg-white',\n cardHeader: 'px-4 py-2 border-b font-medium',\n cardBody: 'p-4',\n cardFooter: 'px-4 py-2 border-t text-center',\n searchInput: 'w-full mb-3 border rounded px-3 py-2 dual-listbox-search',\n listGroup: 'space-y-1',\n listItem: 'py-1',\n formCheck: 'flex items-center gap-2',\n formCheckInput: 'h-4 w-4',\n formCheckLabel: '',\n btn: 'w-full border rounded px-3 py-2 bg-gray-100 hover:bg-gray-200',\n btnInclude: 'mb-2',\n btnExclude: '',\n};\n","import type {DualListBoxItem, DualListBoxOptions, DualListBoxTheme} from './types';\nimport {defaultTheme} from './themePresets';\n\nfunction mergeTheme(base: DualListBoxTheme, override?: Partial<DualListBoxTheme>): DualListBoxTheme {\n return {...base, ...(override || {})} as DualListBoxTheme;\n}\n\n// Global theme state (module-level)\nlet GLOBAL_THEME: DualListBoxTheme = {...defaultTheme};\n\n/**\n * Set the global default theme for all new DualListBox instances.\n * Instance option `theme` still has highest priority.\n */\nexport function useTheme(theme: Partial<DualListBoxTheme> | DualListBoxTheme) {\n GLOBAL_THEME = mergeTheme(defaultTheme, theme as Partial<DualListBoxTheme>);\n}\n\n// Back-compat alias for older code that might call DualListBox.setTheme(...)\n// We will attach a static setTheme on the class after its definition.\n\nexport class DualListBox {\n private rootEl: Element;\n private formEl: HTMLFormElement | null;\n\n private instanceId: string;\n private originalData: DualListBoxItem[];\n\n private defaults: Required<Omit<DualListBoxOptions, 'theme'>> & { theme: DualListBoxTheme };\n private settings: Required<DualListBoxOptions> & { theme: DualListBoxTheme };\n\n private groups: Record<string, DualListBoxItem[]> = {};\n private selectedGroups: Record<string, DualListBoxItem[]> = {};\n\n constructor(element: Element | string, options: DualListBoxOptions = {}) {\n this.rootEl = typeof element === 'string' ? (document.querySelector(element) as Element) : (element as Element);\n if (!this.rootEl) throw new Error('DualListBox root element not found');\n this.formEl = (this.rootEl.closest('form') as HTMLFormElement) || null;\n this.instanceId = this.generateInstanceId();\n this.defaults = {\n itemName: 'item',\n groupName: 'group',\n valueName: 'value',\n inputName: 'selectedItems',\n tabNameText: 'Available Items',\n rightTabNameText: 'Selected Items',\n searchPlaceholderText: 'Search...',\n includeButtonText: 'Include >>',\n excludeButtonText: '<< Exclude',\n dataArray: [],\n selectedItems: [],\n hideEmptyGroups: false,\n submitForm: true,\n onSubmit: null,\n theme: defaultTheme,\n } as any;\n\n // Effective theme precedence: options.theme > GLOBAL_THEME > defaultTheme\n const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);\n const theme = mergeTheme(themeBase, options.theme);\n this.settings = {...(this.defaults as any), ...(options as any), theme};\n\n this.originalData = [...this.settings.dataArray];\n this.groups = this.buildGroups(this.settings.dataArray);\n this.selectedGroups = this.buildGroups(this.settings.selectedItems);\n\n // Sort initial groups based on originalData order\n this.sortAllGroups();\n\n this.removeDuplicatesFromLeft();\n this.render();\n this.bindEvents();\n\n if (this.formEl) {\n this.formEl.addEventListener('submit', (event) => {\n if (typeof this.settings.onSubmit === 'function') {\n event.preventDefault();\n this.settings.onSubmit(this.selected, this.unselected, this.allItems, this.selectedArray);\n } else if (this.settings.submitForm) {\n this.appendSelectedGroupsOnSubmit();\n }\n });\n }\n }\n\n private generateInstanceId() {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let id = '';\n for (let i = 0; i < 36; i++) {\n id += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return id;\n }\n\n private sortAllGroups() {\n [this.groups, this.selectedGroups].forEach((groupSet) => {\n Object.keys(groupSet).forEach((groupName) => {\n this.sortGroup(groupSet[groupName]);\n });\n });\n }\n\n private sortGroup(group: DualListBoxItem[]) {\n group.sort((a, b) => {\n const valA = String((a as any)[this.settings.valueName]);\n const valB = String((b as any)[this.settings.valueName]);\n const indexA = this.originalData.findIndex(\n (item) => String((item as any)[this.settings.valueName]) === valA\n );\n const indexB = this.originalData.findIndex(\n (item) => String((item as any)[this.settings.valueName]) === valB\n );\n return indexA - indexB;\n });\n }\n\n private buildGroups(dataArray: DualListBoxItem[]) {\n const groups: Record<string, DualListBoxItem[]> = {};\n dataArray.forEach((item) => {\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (!groups[group]) groups[group] = [];\n groups[group].push(item);\n });\n return groups;\n }\n\n private removeDuplicatesFromLeft() {\n Object.keys(this.selectedGroups).forEach((group) => {\n if (this.groups[group]) {\n this.selectedGroups[group].forEach((selectedItem) => {\n this.groups[group] = this.groups[group].filter(\n (item) => String((item as any)[this.settings.valueName]) !== String((selectedItem as any)[this.settings.valueName])\n );\n });\n if (this.settings.hideEmptyGroups) {\n if (!this.groups[group].length) {\n delete this.groups[group];\n }\n }\n }\n });\n this.render();\n }\n\n private render() {\n const t = this.settings.theme;\n const template = `\n <div class=\"${t.container}\" id=\"dual_listbox_${this.instanceId}\">\n <div class=\"${t.row}\">\n <div class=\"${t.colLeft}\" id=\"dual_listbox_${this.instanceId}_left_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.tabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_left_search\" type=\"text\" class=\"${t.searchInput} dual-listbox-search\" data-side=\"left\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('left')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-left\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-left-selected\">0</span>/<span class=\"dual-listbox-left-total\">0</span>)</label>\n </div>\n </div>\n </div>\n <div class=\"${t.colCenter}\">\n <button type=\"button\" class=\"${t.btn} dual-listbox-include ${t.btnInclude}\" disabled>${this.settings.includeButtonText}</button>\n <button type=\"button\" class=\"${t.btn} dual-listbox-exclude ${t.btnExclude}\" disabled>${this.settings.excludeButtonText}</button>\n </div>\n <div class=\"${t.colRight}\" id=\"dual_listbox_${this.instanceId}_right_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.rightTabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_right_search\" type=\"text\" class=\"${t.searchInput} dual-listbox-search\" data-side=\"right\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('right')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-right\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-right-selected\">0</span>/<span class=\"dual-listbox-right-total\">0</span>)</label>\n </div>\n </div>\n </div>\n </div>\n </div>`;\n this.rootEl.innerHTML = template;\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n\n private generateGroupedListHTML(side: 'left' | 'right') {\n const t = this.settings.theme;\n const groups = side === 'left' ? this.groups : this.selectedGroups;\n let html = '';\n const keys = Object.keys(groups);\n keys.forEach((groupName, index) => {\n const items = groups[groupName];\n const totalItems = items.length;\n const isGroupEmpty = totalItems === 0;\n const groupSelectAllInput = `group_${groupName}_${side}`;\n const isLast = index === keys.length - 1;\n html += `\n <div class=\"dual-listbox-group${!isLast ? ' mb-3' : ''}\">\n <div class=\"group-header mb-2\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupSelectAllInput}\" type=\"checkbox\" class=\"${t.formCheckInput} group-select-all\" ${isGroupEmpty ? 'checked disabled' : ''}>\n <label for=\"${groupSelectAllInput}\" class=\"${t.formCheckLabel}\">${groupName}</label>\n </div>\n </div>`;\n if (!isGroupEmpty) {\n html += `<ul class=\"${t.listGroup}\">`;\n items.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const name = (item as any)[this.settings.itemName];\n html += `\n <li class=\"${t.listItem}\" data-value=\"${val}\" data-group=\"${groupName}\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupName}_${val}\" type=\"checkbox\" class=\"${t.formCheckInput} item-select\" />\n <label for=\"${groupName}_${val}\" class=\"${t.formCheckLabel}\">${name}</label>\n </div>\n </li>`;\n });\n html += `</ul>`;\n }\n html += `</div>`;\n });\n return html;\n }\n\n private updateSelectAllInfo(side: 'left' | 'right') {\n const idx = side === 'left' ? 0 : 1;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[idx] as Element;\n const selectAll = this.rootEl.querySelector<HTMLInputElement>(`.dual-listbox-select-all-${side}`);\n const totalItems = content ? content.querySelectorAll('.item-select').length : 0;\n const selectedItems = content ? content.querySelectorAll('.item-select:checked').length : 0;\n const selSpan = this.rootEl.querySelector(`.dual-listbox-${side}-selected`);\n const totalSpan = this.rootEl.querySelector(`.dual-listbox-${side}-total`);\n if (selSpan) selSpan.textContent = String(selectedItems);\n if (totalSpan) totalSpan.textContent = String(totalItems);\n if (selectAll) {\n if (totalItems === 0) {\n selectAll.disabled = true;\n selectAll.checked = true;\n } else {\n selectAll.disabled = false;\n selectAll.checked = selectedItems === totalItems;\n }\n }\n\n // Enable/disable include/exclude buttons based on selections\n const includeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-include');\n const excludeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-exclude');\n const leftContent = contents[0] as Element | undefined;\n const rightContent = contents[1] as Element | undefined;\n const leftChecked = leftContent ? leftContent.querySelectorAll('.item-select:checked').length : 0;\n const rightChecked = rightContent ? rightContent.querySelectorAll('.item-select:checked').length : 0;\n if (includeBtn) includeBtn.disabled = leftChecked === 0;\n if (excludeBtn) excludeBtn.disabled = rightChecked === 0;\n }\n\n private bindEvents() {\n this.rootEl.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (target.closest('.dual-listbox-include')) {\n this.moveItems('left', 'right');\n } else if (target.closest('.dual-listbox-exclude')) {\n this.moveItems('right', 'left');\n }\n });\n this.rootEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-select-all-left')) {\n this.toggleSelectAll('left', target.checked);\n } else if (target.matches('.dual-listbox-select-all-right')) {\n this.toggleSelectAll('right', target.checked);\n } else if (target.matches('.group-select-all')) {\n const groupEl = target.closest('.dual-listbox-group') as Element;\n groupEl?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = target.checked));\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n } else if (target.matches('.item-select')) {\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n });\n this.rootEl.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-search')) {\n const side = (target.getAttribute('data-side') as 'left' | 'right') || 'left';\n const searchTerm = target.value || '';\n this.searchItems(side, searchTerm);\n }\n });\n }\n\n private moveItems(fromSide: 'left' | 'right', toSide: 'left' | 'right') {\n const fromGroups = fromSide === 'left' ? this.groups : this.selectedGroups;\n const toGroups = toSide === 'left' ? this.groups : this.selectedGroups;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const fromContainer = contents[fromSide === 'left' ? 0 : 1] as Element;\n const selectedLis = Array.from(fromContainer.querySelectorAll<HTMLInputElement>('.item-select:checked')).map((inp) => inp.closest('li') as HTMLLIElement);\n \n selectedLis.forEach((li) => {\n const value = String(li.getAttribute('data-value'));\n const group = String(li.getAttribute('data-group'));\n \n // Find original item to preserve all properties\n const originalItem = this.originalData.find(item => String((item as any)[this.settings.valueName]) === value);\n if (!originalItem) return;\n\n if (fromGroups[group]) {\n fromGroups[group] = fromGroups[group].filter((i) => String((i as any)[this.settings.valueName]) !== value);\n if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== 'left')) {\n delete (fromGroups as any)[group];\n }\n }\n if (!toGroups[group]) toGroups[group] = [];\n \n // Avoid duplicates\n if (!toGroups[group].some(i => String((i as any)[this.settings.valueName]) === value)) {\n toGroups[group].push(originalItem);\n }\n\n // Sort toGroups[group] based on originalData order\n this.sortGroup(toGroups[group]);\n });\n this.render();\n }\n\n private toggleSelectAll(side: 'left' | 'right', isChecked: boolean) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[side === 'left' ? 0 : 1] as Element;\n content?.querySelectorAll<HTMLInputElement>('.group-select-all').forEach((inp) => (inp.checked = isChecked));\n content?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = isChecked));\n this.updateSelectAllInfo(side);\n }\n\n private searchItems(side: 'left' | 'right', searchTerm: string) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const container = contents[side === 'left' ? 0 : 1] as HTMLElement;\n const searchText = (searchTerm || '').toLowerCase();\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((groupEl) => {\n const groupName = (groupEl.querySelector('.group-header')?.textContent || '').toLowerCase();\n const items = groupEl.querySelectorAll<HTMLElement>('li');\n let showGroup = false;\n if (groupName.includes(searchText)) {\n groupEl.style.display = '';\n items.forEach((li) => (li.style.display = ''));\n showGroup = true;\n } else {\n items.forEach((li) => {\n const itemText = (li.querySelector('label')?.textContent || '').toLowerCase();\n if (itemText.includes(searchText)) {\n li.style.display = '';\n showGroup = true;\n } else {\n li.style.display = 'none';\n }\n });\n groupEl.style.display = showGroup ? '' : 'none';\n }\n });\n if (!searchText) {\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((g) => (g.style.display = ''));\n container?.querySelectorAll<HTMLElement>('li').forEach((li) => (li.style.display = ''));\n }\n }\n\n private appendSelectedGroupsOnSubmit() {\n if (!this.formEl) {\n console.error('Parent form not found!');\n return;\n }\n const selectedValues: (string | number)[] = this.selectedArray;\n // remove existing\n Array.from(this.formEl.querySelectorAll(`input[name=\"${this.settings.inputName}[]\"]`)).forEach((el) => el.remove());\n // append new\n selectedValues.forEach((value) => {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = `${this.settings.inputName}[]`;\n input.value = String(value);\n this.formEl!.appendChild(input);\n });\n }\n\n getSelectedValues(): Promise<(string | number)[]> {\n return new Promise((resolve) => {\n resolve(this.selectedArray);\n });\n }\n\n get selected() {\n return this.selectedGroups;\n }\n\n get selectedArray() {\n const selectedValues: (string | number)[] = [];\n this.originalData.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (this.selectedGroups[group]) {\n const isSelected = this.selectedGroups[group].some(\n (i) => String((i as any)[this.settings.valueName]) === String(val)\n );\n if (isSelected) {\n selectedValues.push(val);\n }\n }\n });\n return selectedValues;\n }\n\n get unselected() {\n return this.groups;\n }\n\n get allItems() {\n return this.settings.dataArray;\n }\n\n // New API methods: return arrays without duplicates\n getSelectedItems(): DualListBoxItem[] {\n const selected: DualListBoxItem[] = [];\n const values = this.selectedArray.map(String);\n this.originalData.forEach((item) => {\n if (values.includes(String((item as any)[this.settings.valueName]))) {\n selected.push(item);\n }\n });\n return selected;\n }\n\n getUnselectedItems(): DualListBoxItem[] {\n const unselected: DualListBoxItem[] = [];\n const selectedValues = this.selectedArray.map(String);\n this.originalData.forEach((item) => {\n if (!selectedValues.includes(String((item as any)[this.settings.valueName]))) {\n unselected.push(item);\n }\n });\n return unselected;\n }\n\n getAllItems(): DualListBoxItem[] {\n return [...this.originalData];\n }\n\n getSettings(): Required<DualListBoxOptions> & { theme: DualListBoxTheme } {\n return this.settings;\n }\n}\n\nexport function initDualListBox(selector: string | Element, options: DualListBoxOptions = {}) {\n return new DualListBox(selector, options);\n}\n\n// Attach back-compat static setTheme to the class\n// so existing code using DualListBox.setTheme(...) keeps working.\n(DualListBox as any).setTheme = (theme: Partial<DualListBoxTheme> | DualListBoxTheme) => useTheme(theme);\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elrayes/dual-listbox",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
4
7
|
"type": "module",
|
|
5
8
|
"description": "A zero-dependency (vanilla JS) dual list box with grouping, search, select-all, theming (Bootstrap/Tailwind), and TypeScript types.",
|
|
6
9
|
"main": "./dist/index.cjs",
|