lisichatbot 1.2.3 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +167 -7
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -267,6 +267,10 @@ function renderOptions(options, field, isSingleSelect = true) {
|
|
|
267
267
|
return;
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
// Get existing data for this field (for pre-filling when editing)
|
|
271
|
+
const existingData = chatState.data[field];
|
|
272
|
+
console.log(`📝 Pre-filling ${field}:`, existingData);
|
|
273
|
+
|
|
270
274
|
// Create wrapper to hold all options
|
|
271
275
|
const optionsWrapper = document.createElement('div');
|
|
272
276
|
optionsWrapper.setAttribute('data-chat-element', 'options-wrapper');
|
|
@@ -284,9 +288,27 @@ function renderOptions(options, field, isSingleSelect = true) {
|
|
|
284
288
|
// Make clone visible (remove display:none from template)
|
|
285
289
|
clone.style.display = '';
|
|
286
290
|
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
291
|
+
// Check if this option should be pre-selected
|
|
292
|
+
let shouldBeChecked = false;
|
|
293
|
+
if (isSingleSelect) {
|
|
294
|
+
// For single-select, check if value matches existing data
|
|
295
|
+
shouldBeChecked = existingData !== undefined &&
|
|
296
|
+
JSON.stringify(existingData) === JSON.stringify(optionValue);
|
|
297
|
+
} else {
|
|
298
|
+
// For multi-select, check if value is in array
|
|
299
|
+
shouldBeChecked = Array.isArray(existingData) &&
|
|
300
|
+
existingData.some(v => JSON.stringify(v) === JSON.stringify(optionValue));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Set checked state
|
|
304
|
+
if (shouldBeChecked) {
|
|
305
|
+
clone.classList.add('cf-checked');
|
|
306
|
+
clone.style.backgroundColor = config.selectedBackground;
|
|
307
|
+
console.log(` ✅ Pre-selected: ${optionName}`);
|
|
308
|
+
} else {
|
|
309
|
+
clone.classList.remove('cf-checked');
|
|
310
|
+
clone.style.backgroundColor = 'transparent';
|
|
311
|
+
}
|
|
290
312
|
|
|
291
313
|
// Set data attributes on container
|
|
292
314
|
clone.setAttribute('data-chat-element', inputTypeAttr);
|
|
@@ -301,14 +323,14 @@ function renderOptions(options, field, isSingleSelect = true) {
|
|
|
301
323
|
input.setAttribute('data-chat-element', inputTypeAttr);
|
|
302
324
|
input.name = field;
|
|
303
325
|
input.value = valueStr;
|
|
304
|
-
input.checked =
|
|
326
|
+
input.checked = shouldBeChecked; // Pre-check if needed
|
|
305
327
|
input.onclick = (e) => e.stopPropagation(); // Prevent click bubbling
|
|
306
328
|
}
|
|
307
329
|
|
|
308
|
-
// Find and
|
|
330
|
+
// Find and set tick icon visibility
|
|
309
331
|
const tickIcon = clone.querySelector('[data-chat-input-element="tick-icon"]');
|
|
310
332
|
if (tickIcon) {
|
|
311
|
-
tickIcon.style.display = 'none';
|
|
333
|
+
tickIcon.style.display = shouldBeChecked ? 'block' : 'none';
|
|
312
334
|
}
|
|
313
335
|
|
|
314
336
|
// Find and set text
|
|
@@ -343,6 +365,124 @@ function renderOptions(options, field, isSingleSelect = true) {
|
|
|
343
365
|
});
|
|
344
366
|
}
|
|
345
367
|
|
|
368
|
+
// =============================================================================
|
|
369
|
+
// MULTI-SELECT-COLOR OPTIONS RENDERING
|
|
370
|
+
// =============================================================================
|
|
371
|
+
|
|
372
|
+
function renderColorOptions(options, field) {
|
|
373
|
+
if (!elements.messages) return;
|
|
374
|
+
|
|
375
|
+
// Find existing color option element in HTML by data-chat-element
|
|
376
|
+
const optionSelector = '[data-chat-element="multi-select-color"]';
|
|
377
|
+
const existingOption = document.querySelector(optionSelector);
|
|
378
|
+
|
|
379
|
+
if (!existingOption) {
|
|
380
|
+
console.error(`Element with ${optionSelector} not found in HTML. Please add it to your HTML.`);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Get existing data for this field (for pre-filling when editing)
|
|
385
|
+
const existingData = chatState.data[field];
|
|
386
|
+
console.log(`📝 Pre-filling ${field} (color):`, existingData);
|
|
387
|
+
|
|
388
|
+
// Create wrapper to hold all options
|
|
389
|
+
const optionsWrapper = document.createElement('div');
|
|
390
|
+
optionsWrapper.setAttribute('data-chat-element', 'options-wrapper');
|
|
391
|
+
|
|
392
|
+
// Clone and fill option element for each option
|
|
393
|
+
options.forEach((option, index) => {
|
|
394
|
+
const optionName = option.name || option;
|
|
395
|
+
const optionValue = option.value !== undefined ? option.value : option;
|
|
396
|
+
const optionColor = option.color || '#cccccc'; // Default gray if no color
|
|
397
|
+
const valueStr = typeof optionValue === 'object' ?
|
|
398
|
+
JSON.stringify(optionValue) : String(optionValue);
|
|
399
|
+
|
|
400
|
+
// Clone existing option element
|
|
401
|
+
const clone = existingOption.cloneNode(true);
|
|
402
|
+
|
|
403
|
+
// Make clone visible (remove display:none from template)
|
|
404
|
+
clone.style.display = '';
|
|
405
|
+
|
|
406
|
+
// Check if this option should be pre-selected (multi-select behavior)
|
|
407
|
+
const shouldBeChecked = Array.isArray(existingData) &&
|
|
408
|
+
existingData.some(v => JSON.stringify(v) === JSON.stringify(optionValue));
|
|
409
|
+
|
|
410
|
+
// Set checked state
|
|
411
|
+
if (shouldBeChecked) {
|
|
412
|
+
clone.classList.add('cf-checked');
|
|
413
|
+
clone.style.backgroundColor = config.selectedBackground;
|
|
414
|
+
console.log(` ✅ Pre-selected color: ${optionName}`);
|
|
415
|
+
} else {
|
|
416
|
+
clone.classList.remove('cf-checked');
|
|
417
|
+
clone.style.backgroundColor = 'transparent';
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Set data attributes on container
|
|
421
|
+
clone.setAttribute('data-chat-element', 'multi-select-color');
|
|
422
|
+
clone.setAttribute('data-field', field);
|
|
423
|
+
clone.setAttribute('data-value', valueStr);
|
|
424
|
+
clone.setAttribute('data-name', optionName);
|
|
425
|
+
clone.setAttribute('data-index', index);
|
|
426
|
+
clone.setAttribute('data-color', optionColor);
|
|
427
|
+
|
|
428
|
+
// Find and set input
|
|
429
|
+
const input = clone.querySelector('[data-chat-input-element="input"]');
|
|
430
|
+
if (input) {
|
|
431
|
+
input.setAttribute('data-chat-element', 'multi-select-color');
|
|
432
|
+
input.name = field;
|
|
433
|
+
input.value = valueStr;
|
|
434
|
+
input.checked = shouldBeChecked; // Pre-check if needed
|
|
435
|
+
input.onclick = (e) => e.stopPropagation(); // Prevent click bubbling
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Find and set tick icon visibility
|
|
439
|
+
const tickIcon = clone.querySelector('[data-chat-input-element="tick-icon"]');
|
|
440
|
+
if (tickIcon) {
|
|
441
|
+
tickIcon.style.display = shouldBeChecked ? 'block' : 'none';
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Find and set color block
|
|
445
|
+
const colorBlock = clone.querySelector('[data-chat-input-element="color-block"]');
|
|
446
|
+
if (colorBlock) {
|
|
447
|
+
colorBlock.style.backgroundColor = optionColor;
|
|
448
|
+
colorBlock.style.display = ''; // Make sure it's visible
|
|
449
|
+
} else {
|
|
450
|
+
console.warn('Color block element not found in multi-select-color template');
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Find and set text
|
|
454
|
+
const textElement = clone.querySelector('[data-chat-input-element="text"]');
|
|
455
|
+
if (textElement) {
|
|
456
|
+
textElement.textContent = optionName;
|
|
457
|
+
textElement.style.display = ''; // Make sure text is visible
|
|
458
|
+
} else {
|
|
459
|
+
console.error('Text element not found in option');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Append to wrapper
|
|
463
|
+
optionsWrapper.appendChild(clone);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
// Append wrapper to messages
|
|
467
|
+
elements.messages.appendChild(optionsWrapper);
|
|
468
|
+
scrollToBottom();
|
|
469
|
+
|
|
470
|
+
// Add click handlers with proper event handling
|
|
471
|
+
const optionElements = optionsWrapper.querySelectorAll('[data-chat-input-element="container"]');
|
|
472
|
+
optionElements.forEach(el => {
|
|
473
|
+
// Clear any existing onclick
|
|
474
|
+
el.onclick = null;
|
|
475
|
+
|
|
476
|
+
// Add new click handler with stopPropagation
|
|
477
|
+
el.onclick = (e) => {
|
|
478
|
+
e.stopPropagation(); // Prevent bubbling
|
|
479
|
+
e.preventDefault(); // Prevent default behavior
|
|
480
|
+
// Use multi-select behavior (isSingleSelect = false)
|
|
481
|
+
handleOptionClick(el, field, false);
|
|
482
|
+
};
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
|
|
346
486
|
// =============================================================================
|
|
347
487
|
// TEXT/NUMBER INPUT RENDERING
|
|
348
488
|
// =============================================================================
|
|
@@ -362,6 +502,10 @@ function renderTextInput(field, inputType = 'text') {
|
|
|
362
502
|
return;
|
|
363
503
|
}
|
|
364
504
|
|
|
505
|
+
// Get existing data for this field (for pre-filling when editing)
|
|
506
|
+
const existingValue = chatState.data[field];
|
|
507
|
+
console.log(`📝 Pre-filling ${field}:`, existingValue);
|
|
508
|
+
|
|
365
509
|
// Clone existing input element
|
|
366
510
|
const clone = existingInput.cloneNode(true);
|
|
367
511
|
|
|
@@ -376,7 +520,15 @@ function renderTextInput(field, inputType = 'text') {
|
|
|
376
520
|
if (inputElement) {
|
|
377
521
|
inputElement.setAttribute('data-field', field);
|
|
378
522
|
inputElement.name = field;
|
|
379
|
-
|
|
523
|
+
|
|
524
|
+
// Pre-fill value if it exists
|
|
525
|
+
if (existingValue !== undefined && existingValue !== null) {
|
|
526
|
+
inputElement.value = existingValue;
|
|
527
|
+
console.log(` ✅ Pre-filled with: ${existingValue}`);
|
|
528
|
+
} else {
|
|
529
|
+
inputElement.value = '';
|
|
530
|
+
}
|
|
531
|
+
|
|
380
532
|
inputElement.type = inputType === 'number' ? 'number' : 'text';
|
|
381
533
|
|
|
382
534
|
// Add input event to enable Next button when user types
|
|
@@ -668,6 +820,14 @@ async function showNextStep() {
|
|
|
668
820
|
} else {
|
|
669
821
|
enableNextButton();
|
|
670
822
|
}
|
|
823
|
+
} else if (inputType === 'multi-select-color') {
|
|
824
|
+
// Render color options with color blocks
|
|
825
|
+
renderColorOptions(nextStep.input.options, nextStep.input.field);
|
|
826
|
+
|
|
827
|
+
// Enable Next button if input not required (default behavior)
|
|
828
|
+
if (!inputRequired) {
|
|
829
|
+
enableNextButton();
|
|
830
|
+
}
|
|
671
831
|
} else {
|
|
672
832
|
// Render options (single-select or multi-select)
|
|
673
833
|
const isSingleSelect = inputType === 'single-select';
|